Example #1
0
        void IZiPatchCommand.Handle(BinaryReader reader, long commandSize, ZiPatchExecute execute)
        {
            reader.BaseStream.Position += 2;

            PatchVersion = reader.ReadByte();

            reader.BaseStream.Position++;

            PatchType = Encoding.ASCII.GetString(reader.ReadBytes(4));

            reader.BaseStream.Position += 0xEC;
        }
Example #2
0
        private static void InstallPatch(string path, string gamePath, string repository)
        {
            var execute = new ZiPatchExecute(gamePath, repository);

            try
            {
                execute.Execute(path);
            }
            catch (Exception e)
            {
                Log.Error(e, "Failed to execute ZiPatch.");
                throw;
            }
        }
Example #3
0
        private (ulong OutputOffset, ulong OutputLength, string path) ReadFileCommandInfo(BinaryReader reader)
        {
            var outputOffset = reader.ReadUInt64BE();
            var outputLength = reader.ReadUInt64BE();

            var fileNameLength = reader.ReadUInt32BE();

            var expansionId = reader.ReadUInt16BE();

            reader.BaseStream.Position += 2;

            var path = $"{ZiPatchExecute.ResolveExId((byte) expansionId)}\\{Encoding.ASCII.GetString(reader.ReadBytes((int) fileNameLength))}";

            // Cut null byte from end of path
            path = path.Substring(0, path.Length - 1);

            //Log.Verbose("   -> SQPK FILECMDINFO: outputOffset:{0} outputLen:{1}     {2}", outputOffset, outputLength, path);

            return(outputOffset, outputLength, path);
        }
Example #4
0
        public void Handle(BinaryReader reader, long commandSize, ZiPatchExecute execute)
        {
            if (commandSize > MAX_HEADER_SIZE)
            {
                Log.Debug($"Detected file header with size > {MAX_HEADER_SIZE}");

                throw new ArgumentException("Patch file is invalid or not ZiPatch.");
            }

            reader.ReadBytes(2);

            PatchVersion = reader.ReadByte();

            reader.ReadByte();

            PatchType = Encoding.ASCII.GetString(reader.ReadBytes(4));

            //reader.BaseStream.Position += 0xEC;
            reader.ReadBytes(0xEC);
        }
Example #5
0
        void IZiPatchCommand.Handle(BinaryReader reader, long commandSize, ZiPatchExecute execute)
        {
            var sqpkCommandSize = reader.ReadUInt32BE();
            var sqpkCommandType = (char)reader.ReadByte();

            switch (sqpkCommandType)
            {
            case 'A':
            {
                CommandType = SqPackCommandType.Add;
                reader.BaseStream.Position += 3;

                var file = execute.ResolveSqPackFile(reader);

                var blockInfo = ReadBlockInfo(reader);

                var data = reader.ReadBytes((int)(blockInfo.BlockCount * SQPK_FILE_BLOCK_SIZE));
                //data.Dump();

                if (!ZiPatchExecute.IsDryRun)
                {
                    file.Write(data, (int)blockInfo.BlockOffset, data.Length);
                }

                file.Close();

                Log.Verbose("   -> SQPK ADD command executed for offset {0} with data of {1}", blockInfo.BlockOffset.ToString("X"), data.Length.ToString("X"));
                break;
            }



            case 'D':
            {
                CommandType = SqPackCommandType.Delete;
                reader.BaseStream.Position += 3;

                var file = execute.ResolveSqPackFile(reader);

                var blockInfo = ReadBlockInfo(reader);

                file.Close();

                break;
            }



            case 'E':
            {
                CommandType = SqPackCommandType.Expand;

                var operation = reader.ReadByte();

                reader.BaseStream.Position += 2;     // Skipped

                var file = execute.ResolveSqPackFile(reader);

                var blockInfo = ReadBlockInfo(reader);

                reader.BaseStream.Position++;     // Skipped

                file.Close();

                break;
            }



            // HEADER command - Overwrite the header of the specified SqPack DAT file with the 1024 byte payload
            case 'H':
            {
                CommandType = SqPackCommandType.Header;

                var targetType = (char)reader.ReadByte();
                var headerType = (char)reader.ReadByte();
                reader.BaseStream.Position++;     // Skipped

                var file = execute.ResolveSqPackFile(reader);

                var headerData = reader.ReadBytes(1024);
                headerData.Dump();

                if (targetType == 'D')
                {
                    var offset = 0;

                    if (sqpkCommandSize != 0x410)
                    {
                        throw new Exception("HEADER command has invalid size: " + sqpkCommandSize);
                    }

                    if (headerType != 'V')
                    {
                        if (headerType != 'D')
                        {
                            throw new Exception("Unknown HEADER headerType: " + headerType);
                        }

                        offset = 0x400;
                    }

                    if (!ZiPatchExecute.IsDryRun)
                    {
                        file.Write(headerData, offset, headerData.Length);
                    }

                    file.Close();

                    Log.Verbose("   -> SQPK HEADER command executed for offset {0}", offset.ToString("X"));
                }
                else
                {
                    throw new NotImplementedException("Unimplemented HEADER target type: " + targetType);
                }

                break;
            }



            // FILE command - Extract file data at specified offset
            case 'F':
                CommandType = SqPackCommandType.File;
                reader.BaseStream.Position += 3;

                var fileCommandInfo = ReadFileCommandInfo(reader);

                HandleFileWrite(reader, null, fileCommandInfo.OutputOffset, fileCommandInfo.OutputLength);
                break;



            // PATCHINFO? - Unknown
            case 'T':
                CommandType = SqPackCommandType.PatchInfo;
                reader.BaseStream.Position += commandSize - 5;
                break;



            // INDEX -
            case 'I':
                CommandType = SqPackCommandType.Index;
                reader.BaseStream.Position += commandSize - 5;
                break;



            // Not quite sure?
            case 'X':
                CommandType = SqPackCommandType.Unknown;
                reader.BaseStream.Position += commandSize - 5;
                break;

            default:
                throw new NotImplementedException("Unimplemented ZiPatch SQPK subcommand type: " + sqpkCommandType);
            }

            Log.Verbose("   -> SQPK: type:{0}", CommandType);
        }
Example #6
0
        public ZiPatchCommandPack(BinaryReader reader, ZiPatchExecute execute)
        {
            _execute = execute;

            Read(reader);
        }