protected override long WriteSubtitle(ExtendedBinaryWriter output, Subtitle subtitle, long offset, bool returnToPos)
        {
            var result = offset;
            var pos    = output.Position;

            if (subtitle == null || offset == 0)
            {
                output.Write((ushort)0);
            }
            else
            {
                output.Write((ushort)offset);

                output.Seek(offset, SeekOrigin.Begin);
                output.WriteString(subtitle.Translation);

                result = output.Position;
            }

            if (returnToPos)
            {
                output.Seek(pos + 2, SeekOrigin.Begin);
            }

            return(result);
        }
示例#2
0
        public void SendDiagnostics(DiagnosticsEventKind kind, Action <ExtendedBinaryWriter> writerDelegate)
        {
            if (_communicationErrorCount > MaxCommunicationErrorCount)
            {
                return;
            }

            lock (_currentWriterLock)
            {
                if (_finished)
                {
                    throw new Exception("unexpected call of " + nameof(SendDiagnostics));
                }

                if (_currentWriter == null)
                {
                    _currentWriter = new ExtendedBinaryWriter(new MemoryStream(), Encoding.UTF8);
                }

                _currentWriter.Write((byte)kind);
                var eventDataLengthPos = (int)_currentWriter.BaseStream.Position;
                _currentWriter.Write(0);

                var startPos = (int)_currentWriter.BaseStream.Position;
                _currentWriter.Write(DateTime.Now.Ticks);

                writerDelegate?.Invoke(_currentWriter);
                var endPos = (int)_currentWriter.BaseStream.Position;
                _currentWriter.Seek(eventDataLengthPos, SeekOrigin.Begin);
                _currentWriter.Write(endPos - startPos);
                _currentWriter.Seek(endPos, SeekOrigin.Begin);
            }
        }
        public override void Rebuild(string outputFolder)
        {
            var outputPath = System.IO.Path.Combine(outputFolder, RelativePath);

            Directory.CreateDirectory(System.IO.Path.GetDirectoryName(outputPath));
            System.IO.File.Copy(Path, outputPath, true);

            var subtitles = GetSubtitles();

            using (var fs = new FileStream(outputPath, FileMode.Open))
                using (var output = new ExtendedBinaryWriter(fs, FileEncoding, Endianness.BigEndian))
                {
                    foreach (var subtitle in subtitles)
                    {
                        if (subtitle.Offset > 0)
                        {
                            output.Seek(subtitle.Offset, SeekOrigin.Begin);

                            var zeros = new byte[MAX_SIZE];
                            output.Write(zeros);

                            output.Seek(subtitle.Offset, SeekOrigin.Begin);
                            output.WriteString(subtitle.Translation);
                        }
                    }
                }
        }
示例#4
0
        private void WriteSubtitle(ExtendedBinaryWriter output, IList <Subtitle> subtitles, int offset)
        {
            output.Seek(offset, SeekOrigin.Begin);
            var zeros = new byte[64];

            output.Write(zeros);

            WriteSubtitle(output, subtitles, offset, offset);

            output.Seek(offset + 64, SeekOrigin.Begin);
        }
        protected virtual long WriteSubtitle(ExtendedBinaryWriter output, Subtitle subtitle, long offset, bool returnToPos)
        {
            var pos = output.Position;

            output.Seek(offset, SeekOrigin.Begin);
            output.WriteString(subtitle.Translation);

            var result = output.Position;

            if (returnToPos)
            {
                output.Seek(pos, SeekOrigin.Begin);
            }

            return(result);
        }
        private void RebuildFontTable(string outputFile)
        {
            if (!System.IO.File.Exists(outputFile))
            {
                System.IO.File.Copy(Path, outputFile);
            }

            var data = GetFontTable();

            using (var fs = new FileStream(outputFile, FileMode.Open))
                using (var output = new ExtendedBinaryWriter(fs, FileEncoding))
                {
                    output.Seek(FontTableOffset, SeekOrigin.Begin);

                    for (var i = 0; i < 256; i++)
                    {
                        output.Write(data[i][0]);
                        output.Write(data[i][1]);
                        output.Write(data[i][2]);
                        output.Write(data[i][3]);
                        output.Write(data[i][4]);
                        output.Write(data[i][5]);
                    }
                }
        }
        private void RebuildPatches(string outputFile)
        {
            if (!System.IO.File.Exists(outputFile))
            {
                System.IO.File.Copy(Path, outputFile);
            }

            var data = GetPatches();

            using (var fs = new FileStream(outputFile, FileMode.Open))
                using (var output = new ExtendedBinaryWriter(fs, FileEncoding))
                {
                    foreach (var patch in data)
                    {
                        if (patch.Enabled)
                        {
                            foreach (var patchInfo in patch.Patches)
                            {
                                output.Seek(patchInfo.Item1, SeekOrigin.Begin);
                                output.Write(patchInfo.Item2);
                            }
                        }
                    }
                }
        }
        private long WriteItem(ExtendedBinaryWriter output, IList <Subtitle> subtitles, ItemElement item, long outputOffset)
        {
            output.Write((ushort)outputOffset);
            var returnPos = output.Position;

            output.Seek(outputOffset, SeekOrigin.Begin);

            var subtitle = subtitles.First(x => x.Offset == item.Title.Offset);

            var currentOffset = outputOffset + 4;

            currentOffset = WriteSubtitle(output, subtitle, currentOffset, true);

            subtitle      = subtitles.First(x => x.Offset == item.Description.Offset);
            currentOffset = WriteSubtitle(output, subtitle, currentOffset, true);

            output.Seek(returnPos, SeekOrigin.Begin);

            return(currentOffset);
        }
示例#9
0
        public void WriteInfo(ExtendedBinaryWriter output)
        {
            var pos = output.Position;

            output.WriteString(Name, 48);
            output.Seek(pos + 48, SeekOrigin.Begin);
            output.Write(Type);
            output.Write(DataCount);
            output.Write(GetSize(output.Encoding));
            output.Write(0);
        }
        private long WriteItem(ExtendedBinaryWriter output, IList <Subtitle> subtitles, DTElement item, long outputOffset)
        {
            output.Write((ushort)outputOffset);
            var returnPos = output.Position;

            output.Seek(outputOffset, SeekOrigin.Begin);
            output.Write(item.Id);
            output.Write(item.Unknown);

            var currentOffset = outputOffset + 2 + UnknownSize + 2 * NumStringsPerItem;

            foreach (var str in item.Strings)
            {
                var subtitle = subtitles.First(x => x.Offset == str.Offset);
                currentOffset = WriteSubtitle(output, subtitle, currentOffset, true);
            }

            output.Seek(returnPos, SeekOrigin.Begin);

            return(currentOffset);
        }
示例#11
0
        protected override long WriteSubtitle(ExtendedBinaryWriter output, IList <Subtitle> subtitles, long inputOffset, long outputOffset)
        {
            var sub = subtitles.First(x => x.Offset == inputOffset);

            output.Write((ushort)outputOffset);
            var returnPos = output.Position;

            var evaluator = new MatchEvaluator(SubtitleMatchEvaluator);

            var newSub = Regex.Replace(sub.Translation, @"<Color: (?<colorValue>[0-9A-Fa-f]{2})>", evaluator);

            newSub = Regex.Replace(newSub, @"<Item: (?<itemValue>[0-9A-Fa-f]{4})>", evaluator);

            output.Seek(outputOffset, SeekOrigin.Begin);
            output.WriteString(newSub);

            var result = output.Position;

            output.Seek(returnPos, SeekOrigin.Begin);
            return(result);
        }
        protected override long WriteSubtitle(ExtendedBinaryWriter output, Subtitle subtitle, long offset, bool returnToPos)
        {
            var result = offset;
            var pos    = output.Position;

            output.Write((ushort)offset);
            output.Seek(offset, SeekOrigin.Begin);

            if (!string.IsNullOrEmpty(subtitle.Text))
            {
                output.WriteString(subtitle.Translation);

                result = output.Position;
            }

            if (returnToPos)
            {
                output.Seek(pos + 2, SeekOrigin.Begin);
            }

            return(result);
        }
示例#13
0
        // NOTE: This method doesn't compress the data yet.
        // TODO: Make a Proper Write/Save Method.
        public override void Save(Stream fileStream)
        {
            // HEADER
            var  files      = GetFiles(false);
            var  writer     = new ExtendedBinaryWriter(fileStream, Encoding.ASCII, true);
            uint dataOffset = (uint)((stringBufferSize + 16) * files.Count + 16);

            writer.Write((uint)files.Count); // File Count
            writer.Write(0x10u);             // File Entry Offset
            writer.Write(dataOffset);        // File Data Offset
            writer.Write(0x0u);              // Unknown1

            // DATA
            char[] stringBuffer;
            int    length = 0;

            for (int i = 0; i < files.Count; ++i)
            {
                var file = files[i];

                // TODO: Create a PRS Compression method in HedgeLib
                var compressedBytes = file.Data; // Compressed Data

                length = (file.Name.Length > stringBufferSize)
                    ? stringBufferSize : file.Name.Length;

                stringBuffer = new char[stringBufferSize];

                file.Name.CopyTo(0, stringBuffer, 0, length);

                writer.Write(stringBuffer);                 // Writes StringBuffer to stream (+0x000000)
                writer.Write((uint)i);                      // FileIndex (+0x000020)
                writer.Write(dataOffset);                   // DataOffset (+0x000024)
                writer.Write((uint)compressedBytes.Length); // Compressed FileSize (+0x000028)
                writer.Write((uint)file.Data.Length);       // Uncompressed FileSize (+0x00002C)
                // Adds Compressed FileSize to dataOffset.
                dataOffset += (uint)compressedBytes.Length; // Offset to where the next file is located
            }

            // Seeks to dataOffset
            writer.Seek((stringBufferSize + 16) * files.Count + 16, SeekOrigin.Begin);

            // Writes all the compressed data
            for (int i = 0; i < files.Count; ++i)
            {
                // TODO: Create a PRS Compression method in HedgeLib
                var compressedBytes = files[i].Data;
                writer.Write(compressedBytes); // Compressed data
            }
        }
        private long WriteItem(ExtendedBinaryWriter output, IList <Subtitle> subtitles, ShopElement item, long outputOffset)
        {
            output.Write((ushort)outputOffset);
            var returnPos = output.Position;

            output.Seek(outputOffset, SeekOrigin.Begin);
            output.Write(item.Id);
            output.Write(item.Unknown1);
            output.Write((ushort)0x0000);

            var subtitle = subtitles.First(x => x.Offset == item.Title.Offset);

            var currentOffset = outputOffset + 2 + 0x0C + 4;

            currentOffset = WriteSubtitle(output, subtitle, currentOffset, true);
            output.Seek(outputOffset + 2 + 0x0C, SeekOrigin.Begin);
            output.Write((ushort)currentOffset);
            output.Seek(currentOffset, SeekOrigin.Begin);
            output.Write(item.Unknown2);
            currentOffset = output.Position;
            output.Seek(returnPos, SeekOrigin.Begin);

            return(currentOffset);
        }
        private long WriteItem(ExtendedBinaryWriter output, IList <Subtitle> subtitles, TownElement item, long outputOffset)
        {
            var returnPos = output.Position + 2;

            var subtitle = subtitles.First(x => x.Offset == item.Title.Offset);

            WriteSubtitle(output, subtitle, outputOffset, false);
            output.Write(item.Unknown);

            var currentOffset = output.Position;

            output.Seek(returnPos, SeekOrigin.Begin);

            return(currentOffset);
        }
示例#16
0
        public int GetTextDictionaryKey(string text)
        {
            if (text == null)
            {
                return(0);
            }

            lock (_textDictionary)
            {
                if (!_textDictionary.TryGetValue(text, out var key))
                {
                    key = _textDictionary.Count + 1;
                    _textDictionary.Add(text, key);

                    if (_currentDictionaryWriter == null)
                    {
                        _currentDictionaryWriter = new ExtendedBinaryWriter(new MemoryStream(), Encoding.UTF8);
                    }

                    _currentDictionaryWriter.Write((byte)DiagnosticsEventKind.TextDictionaryKeyAdded);
                    var eventDataLengthPos = (int)_currentDictionaryWriter.BaseStream.Position;
                    _currentDictionaryWriter.Write(0);
                    var startPos = (int)_currentDictionaryWriter.BaseStream.Position;

                    _currentDictionaryWriter.Write7BitEncodedInt(key);
                    _currentDictionaryWriter.WriteNullable(text);

                    var endPos = (int)_currentDictionaryWriter.BaseStream.Position;
                    _currentDictionaryWriter.Seek(eventDataLengthPos, SeekOrigin.Begin);
                    _currentDictionaryWriter.Write(endPos - startPos);
                    _currentDictionaryWriter.Seek(endPos, SeekOrigin.Begin);
                }

                return(key);
            }
        }
示例#17
0
        private void WriteString(ExtendedBinaryWriter output, Subtitle dds, long offset)
        {
            var pos = output.Position;

            if (dds == null || dds.Offset == 0)
            {
                output.Write(0);
            }
            else
            {
                output.Write((int)offset);
                base.WriteSubtitle(output, dds, offset, false);
            }

            output.Seek(pos + 4, SeekOrigin.Begin);
        }
        protected override long WriteSubtitle(ExtendedBinaryWriter output, Subtitle subtitle, long offset, bool returnToPos)
        {
            var result = offset;
            var pos    = output.Position;

            if (subtitle == null || offset == 0)
            {
                output.Write(0);
            }
            else
            {
                output.Write((int)offset);
                result = base.WriteSubtitle(output, subtitle, offset, false);
            }

            if (returnToPos)
            {
                output.Seek(pos + 4, SeekOrigin.Begin); // Le añado 4 para que vuelva después de escribir el offset
            }

            return(result);
        }
示例#19
0
        public override void Rebuild(string outputFolder)
        {
            var outputPath = System.IO.Path.Combine(outputFolder, RelativePath);

            Directory.CreateDirectory(System.IO.Path.GetDirectoryName(outputPath));

            var subtitles = GetSubtitles();

            using (var fsInput = new FileStream(Path, FileMode.Open))
                using (var input = new ExtendedBinaryReader(fsInput, FileEncoding, Endianness.BigEndian))
                    using (var fsOutput = new FileStream(outputPath, FileMode.Create))
                        using (var output = new ExtendedBinaryWriter(fsOutput, FileEncoding, Endianness.BigEndian))
                        {
                            output.Write(input.ReadBytes(3));
                            var count = input.ReadByte();
                            output.Write(count);
                            output.Write(input.ReadBytes(4));
                            var inputPointer1      = input.ReadInt32();
                            var inputCountPointer1 = input.ReadInt16();

                            var dataPointer1 = new byte[inputCountPointer1 * 16];
                            if (inputCountPointer1 > 0)
                            {
                                input.Seek(inputPointer1, SeekOrigin.Begin);
                                dataPointer1 = input.ReadBytes(inputCountPointer1 * 16);
                                input.Seek(14, SeekOrigin.Begin);
                            }

                            output.Write(0); // Si no es 0, ya lo rellenaré luego
                            output.Write(inputCountPointer1);

                            var numTalkers = input.ReadInt16();
                            output.Write(numTalkers);

                            var inputPointerTalkers = input.ReadInt32();
                            output.Write(0); // Si no es 0, ya lo rellenaré luego

                            var inputPointerRemainder = input.ReadInt32();
                            output.Write(0); // Si no es 0, ya lo rellenaré luego

                            using (var unknownMemoryStream = new MemoryStream())
                                using (var outputUnknown = new ExtendedBinaryWriter(unknownMemoryStream, FileEncoding, Endianness.BigEndian))
                                    using (var propertiesMemoryStream = new MemoryStream())
                                        using (var outputProperties = new ExtendedBinaryWriter(propertiesMemoryStream, FileEncoding, Endianness.BigEndian))
                                            using (var stringsMemoryStream = new MemoryStream())
                                                using (var outputStrings = new ExtendedBinaryWriter(stringsMemoryStream, FileEncoding, Endianness.BigEndian))
                                                {
                                                    var stringLengths     = new List <short>();
                                                    var stringOffsets     = new List <int>();
                                                    var propertiesCount   = new List <byte>();
                                                    var propertiesOffsets = new List <int>();
                                                    var unknownOffsets    = new List <int>();

                                                    var unknownSectionOffset = 0;
                                                    var strOffset            = 0;
                                                    var propOffset           = 0;
                                                    var totalStrCount        = 0;
                                                    for (var i = 0; i < count; i++)
                                                    {
                                                        input.Seek(0x18 + i * 0x10, SeekOrigin.Begin);

                                                        var unknownOffset = input.ReadInt32();
                                                        output.Write(0); // Si no es 0, ya lo rellenaré luego

                                                        var groupOffset = input.ReadInt32();
                                                        output.Write(groupOffset);
                                                        var unknownCount = input.ReadByte();
                                                        output.Write(unknownCount);

                                                        var stringCount = input.ReadByte();
                                                        output.Write(stringCount);
                                                        totalStrCount += stringCount;
                                                        output.Write(input.ReadBytes(6));

                                                        if (unknownOffset != 0)
                                                        {
                                                            var returnPos = input.Position;
                                                            input.Seek(unknownOffset, SeekOrigin.Begin);
                                                            outputUnknown.Write(input.ReadBytes(unknownCount * 12));
                                                            unknownOffsets.Add(unknownSectionOffset);
                                                            unknownSectionOffset = (int)outputUnknown.Position;
                                                            input.Seek(returnPos, SeekOrigin.Begin);
                                                        }
                                                        else
                                                        {
                                                            unknownOffsets.Add(-1);
                                                        }

                                                        input.Seek(groupOffset, SeekOrigin.Begin);

                                                        for (var j = 0; j < stringCount; j++)
                                                        {
                                                            var inputStringLength    = input.ReadInt16();
                                                            var inputPropertiesCount = input.ReadByte();
                                                            var zero = input.ReadByte();
                                                            var inputStringOffset     = input.ReadInt32();
                                                            var inputPropertiesOffset = input.ReadInt32();

                                                            if (inputStringLength == 0)
                                                            {
                                                                stringLengths.Add(0);
                                                                propertiesCount.Add(inputPropertiesCount);
                                                                stringOffsets.Add(strOffset);
                                                                propertiesOffsets.Add(propOffset);

                                                                outputStrings.WriteString(string.Empty);
                                                                strOffset = (int)outputStrings.Position;

                                                                var ret = input.Position;
                                                                input.Seek(inputPropertiesOffset, SeekOrigin.Begin);
                                                                var prop = input.ReadBytes(inputPropertiesCount * 16);
                                                                input.Seek(ret, SeekOrigin.Begin);

                                                                outputProperties.Write(prop);
                                                                propOffset = (int)outputProperties.Position;
                                                            }
                                                            else
                                                            {
                                                                var sub = (Subtitle)subtitles.First(x => x.Offset == inputStringOffset);

                                                                stringLengths.Add((short)FileEncoding.GetByteCount(sub.Translation));
                                                                propertiesCount.Add((byte)sub.TranslationProperties.Count);
                                                                stringOffsets.Add(strOffset);
                                                                propertiesOffsets.Add(propOffset);

                                                                outputStrings.WriteString(sub.Translation);
                                                                strOffset = (int)outputStrings.Position;
                                                                outputProperties.Write(sub.TranslationProperties.ToByteArray());
                                                                propOffset = (int)outputProperties.Position;
                                                            }
                                                        }
                                                    }

                                                    var unknownBytes    = unknownMemoryStream.ToArray();
                                                    var propertiesBytes = propertiesMemoryStream.ToArray();
                                                    var stringsBytes    = stringsMemoryStream.ToArray();

                                                    var propBase    = (int)output.Position + totalStrCount * 12;
                                                    var unknownBase = propBase + propertiesBytes.Length;
                                                    var strBase     = unknownBase + unknownBytes.Length;

                                                    var outputReturnPos = output.Position;
                                                    for (var i = 0; i < count; i++)
                                                    {
                                                        output.Seek(0x18 + i * 0x10, SeekOrigin.Begin);
                                                        if (unknownOffsets[i] >= 0)
                                                        {
                                                            output.Write(unknownOffsets[i] + unknownBase);
                                                        }
                                                    }

                                                    output.Seek(outputReturnPos, SeekOrigin.Begin);

                                                    for (var i = 0; i < totalStrCount; i++)
                                                    {
                                                        output.Write(stringLengths[i]);
                                                        output.Write(propertiesCount[i]);
                                                        output.Write((byte)0);
                                                        output.Write(stringOffsets[i] + strBase);
                                                        output.Write(propertiesOffsets[i] + propBase);
                                                    }

                                                    output.Write(propertiesBytes);
                                                    if (unknownBytes.Length > 0)
                                                    {
                                                        output.Write(unknownBytes);
                                                    }
                                                    output.Write(stringsBytes);
                                                    output.WritePadding(4);
                                                }

                            if (inputPointer1 > 0)
                            {
                                var outputPointer1 = (int)output.Position;
                                output.Seek(8, SeekOrigin.Begin);
                                output.Write(outputPointer1);
                                output.Seek(outputPointer1, SeekOrigin.Begin);
                                output.Write(dataPointer1);
                            }

                            if (inputPointerTalkers > 0)
                            {
                                var outputPointerTalkers = (int)output.Position;
                                output.Seek(16, SeekOrigin.Begin);
                                output.Write(outputPointerTalkers);
                                output.Seek(outputPointerTalkers, SeekOrigin.Begin);

                                input.Seek(inputPointerTalkers, SeekOrigin.Begin);

                                using (var stringsMemoryStream = new MemoryStream())
                                    using (var outputStrings =
                                               new ExtendedBinaryWriter(stringsMemoryStream, FileEncoding, Endianness.BigEndian))
                                    {
                                        var baseOffset = (int)output.Position + numTalkers * 4;
                                        var strOffset  = baseOffset;
                                        for (var i = 0; i < numTalkers; i++)
                                        {
                                            var offset = input.ReadInt32();
                                            var sub    = subtitles.FirstOrDefault(x => x.Offset == offset);
                                            output.Write(strOffset);
                                            if (sub != null)
                                            {
                                                outputStrings.WriteString(sub.Translation);
                                            }
                                            else
                                            {
                                                outputStrings.WriteString(string.Empty);
                                            }


                                            strOffset = baseOffset + (int)outputStrings.Position;
                                        }

                                        output.Write(stringsMemoryStream.ToArray());
                                    }
                            }

                            if (inputPointerRemainder > 0)
                            {
                                var outputPointerRemainder = (int)output.Position;
                                output.Seek(20, SeekOrigin.Begin);
                                output.Write(outputPointerRemainder);
                                output.Seek(outputPointerRemainder, SeekOrigin.Begin);

                                input.Seek(inputPointerRemainder, SeekOrigin.Begin);
                                var data = input.ReadBytes((int)(input.Length - inputPointerRemainder));
                                output.Write(data);
                            }
                        }
        }
示例#20
0
        private void RebuildSubtitles(string outputFile)
        {
            var data = GetSubtitles();

            if (data.Any(x => x.Text != x.Translation))
            {
                CreateExeFile(outputFile);

                var peInfo = WindowsAssembly.FromFile(outputFile);

                using (var inputFs = new FileStream(Path, FileMode.Open))
                    using (var input = new ExtendedBinaryReader(inputFs, FileEncoding))
                        using (var outputFs = new FileStream(outputFile, FileMode.Open))
                            using (var output = new ExtendedBinaryWriter(outputFs, FileEncoding))
                            {
                                var pointerSection      = peInfo.GetSectionByName(PointerSectionName);
                                var pointerSectionStart = pointerSection.Header.PointerToRawData;
                                var pointerCount        = pointerSection.GetPhysicalLength() / 8;

                                var stringsSection     = peInfo.GetSectionByName(StringsSectionName);
                                var stringsSectionBase = (long)(peInfo.NtHeaders.OptionalHeader.ImageBase +
                                                                (stringsSection.Header.VirtualAddress -
                                                                 stringsSection.Header.PointerToRawData));

                                var translationSection     = peInfo.GetSectionByName(".trad\0\0\0");
                                var translationSectionBase = (long)(peInfo.NtHeaders.OptionalHeader.ImageBase +
                                                                    (translationSection.Header.VirtualAddress -
                                                                     translationSection.Header.PointerToRawData));

                                var used = new Dictionary <long, long>();

                                var outputOffset = (long)translationSection.Header.PointerToRawData;

                                for (var i = 0; i < pointerCount; i++)
                                {
                                    input.Seek(pointerSectionStart + i * 8, SeekOrigin.Begin);
                                    output.Seek(pointerSectionStart + i * 8, SeekOrigin.Begin);

                                    var value = input.ReadInt64();
                                    if (value != 0)
                                    {
                                        var possibleStringOffset = value - stringsSectionBase;

                                        bool allowed;
                                        if (AllowedStringOffsets != null)
                                        {
                                            allowed = AllowedStringOffsets.Any(x =>
                                                                               x.Item1 <= possibleStringOffset && x.Item2 >= possibleStringOffset);
                                        }
                                        else
                                        {
                                            allowed = (stringsSection.Header.PointerToRawData <= possibleStringOffset) &&
                                                      (possibleStringOffset < (stringsSection.Header.PointerToRawData + stringsSection.Header.SizeOfRawData));
                                        }

                                        if (allowed)
                                        {
                                            var exists = used.ContainsKey(possibleStringOffset);

                                            if (exists)
                                            {
                                                output.Write(used[possibleStringOffset]);
                                            }
                                            else
                                            {
                                                var newOffset = outputOffset + translationSectionBase;
                                                output.Write(newOffset);
                                                used[possibleStringOffset] = newOffset;

                                                outputOffset = WriteSubtitle(output, data, possibleStringOffset, outputOffset);
                                            }
                                        }
                                    }
                                }
                            }
            }
        }
示例#21
0
        public void Save(string path)
        {
            var fourByteArray = new byte[4];

            byte[] buffer = new byte[0x8000];
            int    size;
            int    read = 0;

            if (File.Exists(path))
            {
                File.Delete(path);
            }

            using (var w = new ExtendedBinaryWriter(File.OpenWrite(path)))
            {
                buf.Position = 0;
                w.Write(buf.ReadBytes((int)data_offset));

                int objCount = assets.Count;

                long[] offsetArray = new long[objCount];
                uint[] sizeArray   = new uint[objCount];

                for (int i = 0; i < objCount; i++)
                {
                    var objInfo = assets.ElementAt(i).Value;

                    offsetArray[i] = w.BaseStream.Position - data_offset;

                    if (replaceDict.ContainsKey(objInfo.pathID))
                    {
                        w.Write(replaceDict[objInfo.pathID]);
                        sizeArray[i] = (uint)replaceDict[objInfo.pathID].Length;
                    }
                    else
                    {
                        buf.Position = objInfo.RealOffset;
                        size         = (int)objInfo.size;
                        while (size > 0 && (read = buf.Read(buffer, 0, Math.Min(buffer.Length, size))) > 0)
                        {
                            w.Write(buffer, 0, read);
                            size -= read;
                        }
                        sizeArray[i] = objInfo.size;
                    }

                    var pos = w.BaseStream.Position;
                    var mod = pos % 4;
                    if (mod != 0)
                    {
                        w.Write(new byte[4 - mod]);
                    }
                    else
                    {
                        w.Write(fourByteArray);
                    }
                }

                long totalSize = w.BaseStream.Position;

                w.BaseStream.Position = objectsIndexOffset;

                for (int i = 0; i < objCount; i++)
                {
                    if (format >= 14)
                    {
                        w.AlignStream();
                        w.Seek(8, SeekOrigin.Current);
                    }
                    else if (longObjectIDs)
                    {
                        w.Seek(8, SeekOrigin.Current);
                    }
                    else
                    {
                        w.Seek(4, SeekOrigin.Current);
                    }

                    if (format >= 22)
                    {
                        w.Write(offsetArray[i]);
                    }
                    else
                    {
                        w.Write((uint)offsetArray[i]);
                    }
                    w.Write(sizeArray[i]);

                    w.Seek(4, SeekOrigin.Current);

                    if (format < 16)
                    {
                        w.Seek(4, SeekOrigin.Current);
                    }

                    if (format == 15 || format == 16)
                    {
                        w.Seek(1, SeekOrigin.Current);
                    }
                }

                if (format >= 22)
                {
                    w.Seek(0x18, SeekOrigin.Begin);
                    var sizeBytes = BitConverter.GetBytes(totalSize);
                    Array.Reverse(sizeBytes);
                    w.Write(sizeBytes);
                }
                else
                {
                    w.Seek(4, SeekOrigin.Begin);
                    var sizeBytes = BitConverter.GetBytes((uint)totalSize);
                    Array.Reverse(sizeBytes);
                    w.Write(sizeBytes);
                }
            }
        }
示例#22
0
        public override void Rebuild(string outputFolder)
        {
            var outputPath = System.IO.Path.Combine(outputFolder, RelativePath);

            Directory.CreateDirectory(System.IO.Path.GetDirectoryName(outputPath));

            var subtitles = GetSubtitles();

            using (var fsInput = new FileStream(Path, FileMode.Open))
                using (var input = new ExtendedBinaryReader(fsInput, FileEncoding, Endianness.BigEndian))
                    using (var fsOutput = new FileStream(outputPath, FileMode.Create))
                        using (var output = new ExtendedBinaryWriter(fsOutput, FileEncoding, Endianness.BigEndian))
                        {
                            output.Write(input.ReadBytes(0x08));

                            var count1 = input.ReadInt32();
                            var start1 = input.ReadInt32();
                            var count2 = input.ReadInt32();
                            var start2 = input.ReadInt32();

                            output.Write(count1);
                            output.Write(start1);
                            output.Write(count2);
                            output.Write(start2);

                            long outputOffset = 0x18 + 0x10 * (count1 + count2);

                            var inputStringOffsets  = new int[count1 + count2];
                            var inputUnknownOffsets = new int[count1 + count2];
                            var inputUnknownSizes   = new int[count1 + count2];
                            for (var i = 0; i < count1 + count2; i++)
                            {
                                input.Seek(0x18 + 0x10 * i, SeekOrigin.Begin);
                                input.Skip(8);
                                inputStringOffsets[i]  = input.ReadInt32();
                                inputUnknownOffsets[i] = input.ReadInt32();
                            }

                            for (var i = 0; i < count1 + count2 - 1; i++)
                            {
                                inputUnknownSizes[i] = (inputStringOffsets[i + 1] - inputUnknownOffsets[i]);
                            }

                            inputUnknownSizes[count1 + count2 - 1] = (int)(input.Length - inputUnknownOffsets[count1 + count2 - 1]);

                            for (var i = 0; i < count1 + count2; i++)
                            {
                                input.Seek(0x18 + 0x10 * i, SeekOrigin.Begin);
                                output.Seek(0x18 + 0x10 * i, SeekOrigin.Begin);

                                output.Write(input.ReadBytes(8));

                                var inputSubtitle = ReadSubtitle(input);
                                outputOffset = WriteSubtitle(output, subtitles, inputSubtitle.Offset, outputOffset);

                                var inputOffset = input.ReadInt32();
                                output.Write((int)outputOffset);

                                input.Seek(inputOffset, SeekOrigin.Begin);
                                output.Seek(outputOffset, SeekOrigin.Begin);

                                output.Write(input.ReadBytes(inputUnknownSizes[i]));
                                outputOffset += inputUnknownSizes[i];
                            }
                        }
        }
        public static void Repack(string inputFolder, string outputPath, bool useCompression)
        {
            var logFile = Path.Combine(inputFolder, "Extract_Data.tf");

            var dir = Path.GetDirectoryName(outputPath);

            Directory.CreateDirectory(dir);

            using (var output = new ExtendedBinaryWriter(new FileStream(outputPath, FileMode.Create), Encoding.UTF8, Endianness.BigEndian))
                using (var log = new ExtendedBinaryReader(new FileStream(logFile, FileMode.Open), Encoding.UTF8, Endianness.BigEndian))
                {
                    var numFiles = log.ReadInt32();

                    output.Write((short)numFiles);
                    output.Write(log.ReadBytes(6));

                    var outputOffset = 0x10 + 0x10 * numFiles;

                    for (var i = 0; i < numFiles; i++)
                    {
                        output.Seek(8 + i * 16, SeekOrigin.Begin);

                        var unknown = log.ReadInt32();
                        output.Write(unknown);

                        var hasMsg       = log.ReadInt32() != 0;
                        var hasRemainder = log.ReadInt32() != 0;

                        if (hasMsg)
                        {
                            var msgFile = Path.Combine(inputFolder, $"{i:0000}.msg");
                            var msg     = File.ReadAllBytes(msgFile);

                            output.Write(outputOffset);

                            var returnPos = output.Position;
                            output.Seek(outputOffset, SeekOrigin.Begin);
                            output.Write(msg);
                            output.WritePadding(0x04);
                            outputOffset = (int)output.Position;
                            output.Seek(returnPos + 4, SeekOrigin.Begin);
                            output.Write((short)msg.Length);
                            output.Seek(-6, SeekOrigin.Current);
                        }
                        else
                        {
                            output.Write(0);
                            output.Skip(4);
                            output.Write((short)0);
                            output.Seek(-6, SeekOrigin.Current);
                        }

                        if (hasRemainder)
                        {
                            var sizeRemainder = log.ReadInt32();
                            var remainder     = log.ReadBytes(sizeRemainder);

                            output.Write(outputOffset);

                            var returnPos = output.Position;
                            output.Seek(outputOffset, SeekOrigin.Begin);
                            output.Write(remainder);
                            output.WritePadding(0x04);
                            outputOffset = (int)output.Position;
                            output.Seek(returnPos + 2, SeekOrigin.Begin);
                            output.Write((short)sizeRemainder);
                        }
                        else
                        {
                            output.Write(0);
                            output.Skip(2);
                            output.Write((short)0);
                        }
                    }
                }
        }
        public override void Rebuild(string outputFolder)
        {
            var outputPath = System.IO.Path.Combine(outputFolder, RelativePath);

            Directory.CreateDirectory(System.IO.Path.GetDirectoryName(outputPath));

            var subtitles = GetSubtitles();

            using (var fsInput = new FileStream(Path, FileMode.Open))
                using (var input = new ExtendedBinaryReader(fsInput, FileEncoding, Endianness.BigEndian))
                    using (var fsOutput = new FileStream(outputPath, FileMode.Create))
                        using (var output = new ExtendedBinaryWriter(fsOutput, FileEncoding, Endianness.BigEndian))
                        {
                            input.Skip(0x38);
                            var stringsOffset = input.ReadInt32();

                            input.Seek(0, SeekOrigin.Begin);

                            output.Write(input.ReadBytes(stringsOffset));

                            Subtitle subtitle;
                            var      dict = new Dictionary <long, long>(subtitles.Count);

                            while (input.Position < input.Length)
                            {
                                subtitle = ReadSubtitle(input);

                                var newSubtitle = subtitles.FirstOrDefault(x => x.Offset == subtitle.Offset);
                                if (newSubtitle != null)
                                {
                                    dict.Add(subtitle.Offset, output.Position);
                                    output.WriteString(newSubtitle.Translation);
                                }
                            }

                            input.Seek(0x10, SeekOrigin.Begin);
                            var count1  = input.ReadInt32();
                            var offset1 = input.ReadInt32();

                            input.Skip(8);

                            var count2  = input.ReadInt32();
                            var offset2 = input.ReadInt32();

                            input.Seek(offset1, SeekOrigin.Begin);
                            output.Seek(offset1, SeekOrigin.Begin);

                            for (var i = 0; i < count1; i++)
                            {
                                input.Skip(4);
                                output.Skip(4);

                                var stringOffset = input.ReadInt32();
                                output.Write((int)dict[stringOffset]);

                                input.Skip(16);
                                output.Skip(16);
                            }

                            input.Seek(offset2, SeekOrigin.Begin);
                            output.Seek(offset2, SeekOrigin.Begin);

                            for (var i = 0; i < count2; i++)
                            {
                                var stringOffset = input.ReadInt32();
                                if (dict.ContainsKey(stringOffset))
                                {
                                    output.Write((int)dict[stringOffset]);
                                }
                                else
                                {
                                    output.Skip(4);
                                }
                            }
                        }
        }
示例#25
0
        public override void Rebuild(string outputFolder)
        {
            var outputPath = System.IO.Path.Combine(outputFolder, RelativePath);

            Directory.CreateDirectory(System.IO.Path.GetDirectoryName(outputPath));

            var subtitles = GetSubtitles();

            using (var fsInput = new FileStream(Path, FileMode.Open))
                using (var input = new ExtendedBinaryReader(fsInput, FileEncoding))
                    using (var fsOutput = new FileStream(outputPath, FileMode.Create))
                        using (var output = new ExtendedBinaryWriter(fsOutput, FileEncoding))
                        {
                            output.Write(input.ReadBytes(0x20)); // Escribo la cabecera, aunque al final tendré que editarla

                            output.Write(input.ReadInt32());

                            var stringCount1 = input.ReadInt32();
                            output.Write(stringCount1);
                            var aux = input.ReadInt32();
                            output.Write(aux);
                            var stringCount2 = input.ReadInt32();
                            output.Write(stringCount2);

                            output.Write(input.ReadInt32());

                            if (aux == 3)
                            {
                                output.Write(input.ReadInt32());
                            }

                            var language = input.ReadInt32();
                            output.Write(language);

                            var base1       = input.Position;
                            var base2       = base1 + 4 * stringCount1;
                            var stringsBase = base2 + aux * 4 * stringCount1;

                            var outputOffset = 0;

                            for (var i = 0; i < stringCount1; i++)
                            {
                                input.Seek(base1 + 4 * i, SeekOrigin.Begin);
                                output.Seek(base1 + 4 * i, SeekOrigin.Begin);
                                var index1 = input.ReadInt32();
                                output.Write(index1);

                                input.Seek(base2 + 4 * index1, SeekOrigin.Begin);
                                output.Seek(base2 + 4 * index1, SeekOrigin.Begin);
                                output.Write(input.ReadInt32());

                                if (aux == 3)
                                {
                                    output.Write(input.ReadInt32());
                                }

                                var strOffset = input.ReadInt32();
                                output.Write(outputOffset);

                                input.Seek(stringsBase + strOffset, SeekOrigin.Begin);
                                output.Seek(stringsBase + outputOffset, SeekOrigin.Begin);

                                var originalSize = input.ReadInt32();
                                var subtitle     = ReadSubtitle(input);

                                var outputSubtitle = subtitles.FirstOrDefault(x => x.Offset == subtitle.Offset);

                                if (outputSubtitle != null)
                                {
                                    var translationSize = FileEncoding.GetByteCount(outputSubtitle.Translation);
                                    output.Write((int)translationSize);
                                    WriteSubtitle(output, outputSubtitle, output.Position, false);
                                }
                                else
                                {
                                    output.Write(originalSize);
                                    WriteSubtitle(output, subtitle, output.Position, false);
                                }

                                output.WritePadding(0x04);

                                outputOffset = (int)(output.Position - stringsBase);
                            }

                            output.WritePadding(0x10);

                            var size = output.Position - 0x20;

                            input.Seek(-0x80, SeekOrigin.End);
                            output.Write(input.ReadBytes(0x80));

                            output.Seek(0x04, SeekOrigin.Begin);
                            output.Write((int)(size + 0x60));
                            output.Skip(12);
                            output.Write((int)size);
                        }
        }
        public override void Rebuild(string outputFolder)
        {
            var outputPath = System.IO.Path.Combine(outputFolder, RelativePath);

            Directory.CreateDirectory(System.IO.Path.GetDirectoryName(outputPath));

            var subtitles = GetSubtitles();

            using (var fsInput = new FileStream(Path, FileMode.Open))
                using (var input = new ExtendedBinaryReader(fsInput, FileEncoding))
                    using (var fsOutput = new FileStream(outputPath, FileMode.Create))
                        using (var output = new ExtendedBinaryWriter(fsOutput, FileEncoding))
                        {
                            input.Seek(0x0C, SeekOrigin.Begin);
                            var lengthTableOffset  = input.ReadInt32();
                            var stringOffsetTable  = input.ReadInt32();
                            var stringBase         = input.ReadInt32();
                            var stringOffsetTable2 = input.ReadInt32();
                            var stringBase2        = input.ReadInt32();

                            input.Seek(0x2C, SeekOrigin.Begin);
                            var lengthCount  = input.ReadInt32();
                            var stringCount  = input.ReadInt32();
                            var stringCount2 = input.ReadInt32();

                            input.Seek(0, SeekOrigin.Begin);
                            output.Write(input.ReadBytes(stringOffsetTable));

                            long outputOffset = stringBase;
                            var  lengths      = new Dictionary <int, short>();

                            for (var i = 0; i < stringCount; i++)
                            {
                                input.Seek(stringOffsetTable + 4 * i, SeekOrigin.Begin);
                                var offset = input.ReadInt32();

                                output.Seek(stringOffsetTable + 4 * i, SeekOrigin.Begin);
                                output.Write((int)(outputOffset - stringBase));

                                output.Seek(outputOffset, SeekOrigin.Begin);
                                var newOutputOffset = WriteSubtitle(output, subtitles, stringBase + offset, outputOffset);
                                var length          = newOutputOffset - outputOffset - 1;
                                lengths.Add(i, (short)length);
                                outputOffset = newOutputOffset;
                            }

                            output.WritePadding(0x10);

                            var newStringBase2 = output.Position;

                            input.Seek(stringOffsetTable2, SeekOrigin.Begin);
                            output.Seek(stringOffsetTable2, SeekOrigin.Begin);
                            output.Write(input.ReadBytes(stringCount2 * 4));

                            input.Seek(stringBase2, SeekOrigin.Begin);
                            output.Seek(newStringBase2, SeekOrigin.Begin);
                            output.Write(input.ReadBytes((int)(input.Length - stringBase2)));

                            output.Seek(0x1C, SeekOrigin.Begin);
                            output.Write((int)newStringBase2);

                            for (var i = 0; i < lengthCount; i++)
                            {
                                input.Seek(lengthTableOffset + i * 16, SeekOrigin.Begin);
                                var id = input.ReadInt32();
                                output.Seek(lengthTableOffset + i * 16 + 4, SeekOrigin.Begin);
                                output.Write(lengths[id]);
                            }
                        }

            WriteBoxSizes(System.IO.Path.GetDirectoryName(outputPath), subtitles);
        }
示例#27
0
        public override void Rebuild(string outputFolder)
        {
            var outputPath = System.IO.Path.Combine(outputFolder, RelativePath);

            Directory.CreateDirectory(System.IO.Path.GetDirectoryName(outputPath));

            var subtitles = GetSubtitles();

            using (var fsInput = new FileStream(Path, FileMode.Open))
                using (var input = new ExtendedBinaryReader(fsInput, FileEncoding, Endianness.BigEndian))
                    using (var fsOutput = new FileStream(outputPath, FileMode.Create))
                        using (var output = new ExtendedBinaryWriter(fsOutput, FileEncoding, Endianness.BigEndian))
                            using (var tempMemoryStream = new MemoryStream())
                            {
                                var offsets = new List <int>();

                                input.Skip(0x24);
                                var firstStringOffset = input.ReadInt32() + 4;
                                input.Skip(0x4);
                                var inputLastPointer = input.ReadInt32();

                                input.Seek(0, SeekOrigin.Begin);

                                output.Write(input.ReadBytes(firstStringOffset)); // Copia de la cabecera

                                input.Seek(0x38, SeekOrigin.Begin);
                                var pointer = input.ReadInt32();
                                var count   = input.ReadInt32();

                                input.Seek(pointer, SeekOrigin.Begin);
                                using (var temp = new ExtendedBinaryWriter(tempMemoryStream, FileEncoding, Endianness.BigEndian))
                                {
                                    for (var i = 0; i < count; i++)
                                    {
                                        var offset = input.ReadInt32();
                                        if (offset == 0)
                                        {
                                            offsets.Add(0);
                                        }
                                        else
                                        {
                                            var outputOffset = WriteString(temp, subtitles, offset);
                                            offsets.Add(outputOffset);
                                        }
                                    }
                                }

                                var strings = tempMemoryStream.ToArray();

                                output.Write(strings);

                                output.WritePadding(16);

                                var outputOffsetsPointer = output.Position;

                                foreach (var offset in offsets)
                                {
                                    output.Write(offset + firstStringOffset);
                                }

                                var outputRemainderPointer = output.Position;

                                output.Write(input.ReadBytes((int)(inputLastPointer - input.Position)));
                                var outputLastPointer = output.Position;
                                output.Write((int)(outputRemainderPointer + 8));

                                output.WritePadding(16);

                                var outputTotalLength = output.Position;

                                output.Seek(0x0C, SeekOrigin.Begin);
                                output.Write((int)outputTotalLength);

                                output.Seek(0x28, SeekOrigin.Begin);
                                output.Write((int)outputRemainderPointer);
                                output.Write((int)outputLastPointer);

                                output.Seek(0x34, SeekOrigin.Begin);
                                output.Write((int)(outputRemainderPointer + 4));
                                output.Write((int)outputOffsetsPointer);
                            }
        }
        public static void Repack(string inputFolder, string outputPath, bool useCompression)
        {
            var dir = Path.GetDirectoryName(outputPath);

            Directory.CreateDirectory(dir);

            var datFileName = Path.GetFileNameWithoutExtension(outputPath);
            var dirFile     = Path.Combine(dir, $"{datFileName}.dir");

            var logFile = Path.Combine(inputFolder, "Extract_Data.tf");

            using (var dirOutput = new ExtendedBinaryWriter(new FileStream(dirFile, FileMode.Create), Encoding.GetEncoding(1252)))
                using (var datOutput = new ExtendedBinaryWriter(new FileStream(outputPath, FileMode.Create), Encoding.UTF8))
                    using (var log = new ExtendedBinaryReader(new FileStream(logFile, FileMode.Open), Encoding.GetEncoding(1252)))
                    {
                        dirOutput.Write(DIR_HEADER);
                        datOutput.Write(DAT_HEADER);

                        var maxNumFiles = log.ReadInt64();
                        dirOutput.Write(maxNumFiles);
                        datOutput.Write(maxNumFiles);

                        var files = ReadFileInfo(log);

                        var compressedData = new ConcurrentDictionary <string, byte[]>();

                        Parallel.ForEach(files, file =>
                        {
                            if (file.CompressedSize > 0)
                            {
                                var fileToInsert = Path.Combine(inputFolder, file.FileName);
                                var data         = GetData(fileToInsert, file.IsCompressed, useCompression);
                                compressedData[file.FileName] = data;
                            }
                        });

                        var fileOffset = 0x10 + maxNumFiles * 4 + 0x04; // Posición en la que hay que empezar a insertar los ficheros

                        for (var i = 0; i < files.Count; i++)
                        {
                            var file = files[i];

                            dirOutput.WriteString(file.FileName, 16);

                            datOutput.Seek(0x10 + i * 4, SeekOrigin.Begin);

                            if (file.OriginalOffset != 0)
                            {
                                datOutput.Write((int)fileOffset);
                            }
                            else
                            {
                                datOutput.Write(0);
                            }

                            if (file.CompressedSize == 0)
                            {
                                // Solo tiene ceros
                                dirOutput.Write(file.CompressedSize);
                                dirOutput.Write(file.MaxSize);
                                dirOutput.Write(file.Unknown);
                                dirOutput.Write(file.TimeStamp);
                                if (file.OriginalOffset != 0)
                                {
                                    dirOutput.Write((int)fileOffset);
                                }
                                else
                                {
                                    dirOutput.Write(0);
                                }
                            }
                            else
                            {
                                datOutput.Seek(fileOffset, SeekOrigin.Begin);

                                var data = compressedData[file.FileName];

                                datOutput.Write(data);

                                dirOutput.Write(data.Length);

                                if (data.Length <= file.MaxSize)
                                {
                                    dirOutput.Write(file.MaxSize);
                                    dirOutput.Write(file.Unknown);
                                    dirOutput.Write(file.TimeStamp);
                                    dirOutput.Write((int)fileOffset);

                                    fileOffset += data.Length;
                                }
                                else
                                {
                                    dirOutput.Write(file.MaxSize * 2);
                                    dirOutput.Write(file.MaxSize * 2);
                                    dirOutput.Write(file.TimeStamp);
                                    dirOutput.Write((int)fileOffset);

                                    fileOffset += data.Length;
                                }
                            }
                        }
                    }
        }
示例#29
0
        public static byte[] Compress(byte[] uncompressedData)
        {
            using (var ms = new MemoryStream())
                using (var output = new ExtendedBinaryWriter(ms, Encoding.GetEncoding(1252), Endianness.BigEndian))
                {
                    output.Write((uint)0x534c4c5a);
                    output.Write((byte)0x00);
                    output.Write((byte)0x01);

                    output.Endianness = Endianness.LittleEndian;

                    output.Write((ushort)0x0010);
                    output.Write((uint)uncompressedData.Length);
                    output.Write((uint)0);

                    var uncompressedSize = uncompressedData.Length;
                    var currentPosition  = 0;

                    var manager = new BitManager(output);

                    var queue        = new Queue <SllzItem>();
                    var itemsToWrite = 7; // La primera vez se escriben 7 elementos, el resto de las veces, 8

                    while (currentPosition < uncompressedSize)
                    {
                        var match = FindMatch(uncompressedData, currentPosition, true);

                        if (!match.Found)
                        {
                            var item = new SllzItem
                            {
                                IsLiteral = true,
                                Literal   = uncompressedData[currentPosition],
                                CopyFlags = 0
                            };

                            queue.Enqueue(item);

                            manager.SetFlagType(FlagType.Literal);
                        }
                        else
                        {
                            manager.SetFlagType(FlagType.Copy);

                            var copyCount    = (short)((match.Length - 3) & 0x0F);
                            var copyDistance = (short)((match.Distance - 1) << 4);
                            var tuple        = (short)(copyDistance | copyCount);

                            var item = new SllzItem
                            {
                                IsLiteral = false,
                                Literal   = 0,
                                CopyFlags = tuple
                            };

                            queue.Enqueue(item);
                        }

                        currentPosition += match.Length;

                        if (manager.IsByteChange)
                        {
                            for (var i = 0; i < itemsToWrite; i++)
                            {
                                var item = queue.Dequeue();
                                if (item.IsLiteral)
                                {
                                    output.Write(item.Literal);
                                }
                                else
                                {
                                    output.Write(item.CopyFlags);
                                }
                            }

                            itemsToWrite = 8;
                        }
                    }

                    manager.Flush();

                    if (queue.Count > 0)
                    {
                        while (queue.Count > 0)
                        {
                            var item = queue.Dequeue();
                            if (item.IsLiteral)
                            {
                                output.Write(item.Literal);
                            }
                            else
                            {
                                output.Write(item.CopyFlags);
                            }
                        }
                    }

                    var length = output.Length;
                    output.Seek(0x0C, SeekOrigin.Begin);
                    output.Write((uint)length);
                    return(ms.ToArray());
                }
        }
示例#30
0
        public override void Rebuild(string outputFolder)
        {
            var outputPath = System.IO.Path.Combine(outputFolder, RelativePath);

            Directory.CreateDirectory(System.IO.Path.GetDirectoryName(outputPath));

            var subtitles = GetSubtitles();

            var used = new Dictionary <long, long>();

            using (var fsInput = new FileStream(Path, FileMode.Open))
                using (var input = new ExtendedBinaryReader(fsInput, FileEncoding, Endianness.BigEndian))
                    using (var fsOutput = new FileStream(outputPath, FileMode.Create))
                        using (var output = new ExtendedBinaryWriter(fsOutput, FileEncoding, Endianness.BigEndian))
                        {
                            output.Write(input.ReadBytes(4));
                            var count = input.ReadInt32();
                            output.Write(count);
                            output.Write(input.ReadBytes(8));

                            long outputOffset = input.PeekInt32();

                            for (var i = 0; i < count; i++)
                            {
                                var offset = input.ReadInt32();
                                outputOffset = WriteString(output, subtitles, used, offset, outputOffset);

                                offset       = input.ReadInt32();
                                outputOffset = WriteString(output, subtitles, used, offset, outputOffset);

                                var pointer = input.ReadInt32();
                                output.Write(pointer);
                                var numLines = input.ReadInt32();
                                output.Write(numLines);

                                offset       = input.ReadInt32();
                                outputOffset = WriteString(output, subtitles, used, offset, outputOffset);

                                offset       = input.ReadInt32();
                                outputOffset = WriteString(output, subtitles, used, offset, outputOffset);

                                output.Write(input.ReadBytes(4));

                                offset       = input.ReadInt32();
                                outputOffset = WriteString(output, subtitles, used, offset, outputOffset);

                                var pos = input.Position;

                                input.Seek(pointer, SeekOrigin.Begin);
                                output.Seek(pointer, SeekOrigin.Begin);

                                for (var j = 0; j < numLines; j++)
                                {
                                    offset       = input.ReadInt32();
                                    outputOffset = WriteString(output, subtitles, used, offset, outputOffset);
                                }

                                input.Seek(pos, SeekOrigin.Begin);
                                output.Seek(pos, SeekOrigin.Begin);

                                output.Write(input.ReadBytes(36));
                            }
                        }
        }