Example #1
0
        public static void Decode(string arg)
        {
            LocalizedTexts texts;

            using (var stream = new FileStream(arg, FileMode.Open, FileAccess.Read, FileShare.Read))
                using (var reader = new BinaryReader(stream))
                {
                    if (arg.ToLower().EndsWith(".item"))
                    {
                        stream.Position = 0x3C;
                    }
                    else
                    {
                        stream.Position = 4;
                        var metadataLength = reader.ReadInt32();
                        if ((metadataLength & 7) != 0)
                        {
                            Console.WriteLine("WARNING: The first offset doesn't seem to be valid.");
                        }
                        stream.Position = ((metadataLength >> 3) << 3) - 4;
                    }
                    stream.Position = reader.ReadInt32();
                    var numStrings = reader.ReadInt32();
                    if (numStrings <= 0)
                    {
                        throw new NoStringException();
                    }
                    texts = new LocalizedTexts(numStrings);
                    var numPointers    = reader.ReadInt32();
                    var stringPointers = new StringPointer[numStrings];
                    for (var i = 0; i < numStrings; i++)
                    {
                        stringPointers[i] = new StringPointer(reader);
                    }
                    var pointerPointers = new LanguagePointer[numPointers];
                    for (var i = 0; i < numPointers; i++)
                    {
                        pointerPointers[i] = new LanguagePointer(reader);
                    }
                    var baseOffset = stream.Position;
                    foreach (var stringPointer in stringPointers)
                    {
                        var text = new LocalizedText(stringPointer.Count);
                        for (var i = 0; i < stringPointer.Count; i++)
                        {
                            var pointer = pointerPointers[stringPointer.Index + i];
                            stream.Position = baseOffset + pointer.Offset;
                            text.Add(pointer.LanguageID, ReadString(reader));
                        }
                        texts.Add(text);
                    }
                }
            File.WriteAllText(arg + ".xml", texts.ToString());
        }
Example #2
0
        public static void Encode(string arg)
        {
            var texts = new LocalizedTexts(XDocument.Load(arg).Element("strings"));
            var stringPointers = new StringPointer[texts.Count];
            var pointerPointers = new List <LanguagePointer>(texts.Count);
            var stringOffsets = new Dictionary <string, int>();
            int pointerIndex = 0, offset = 0;

            for (var i = 0; i < texts.Count; i++)
            {
                stringPointers[i].Index = pointerIndex;
                pointerIndex           += stringPointers[i].Count = texts[i].Count;
                foreach (var pair in texts[i])
                {
                    if (!stringOffsets.ContainsKey(pair.Value))
                    {
                        pointerPointers.Add(new LanguagePointer(pair.Key, offset));
                        stringOffsets.Add(pair.Value, offset);
                        offset += Encoding.UTF8.GetByteCount(pair.Value) + 1;
                    }
                    else
                    {
                        pointerPointers.Add(new LanguagePointer(pair.Key, stringOffsets[pair.Value]));
                    }
                }
            }
            using (var stream = new FileStream(arg.Remove(arg.Length - 4), FileMode.Open, FileAccess.ReadWrite, FileShare.Read))
            {
                var    reader = new BinaryReader(stream);
                var    writer = new BinaryWriter(stream);
                int    offsetOffset;
                byte[] oldBytes;
                var    isItem = arg.ToLower().EndsWith(".item.xml");
                if (isItem)
                {
                    stream.Position = 0x40;
                    var extraBytesCount = reader.ReadInt32();
                    stream.Position = reader.ReadInt32();
                    oldBytes        = reader.ReadBytes(extraBytesCount + 3);
                    offsetOffset    = 0x3C;
                }
                else
                {
                    stream.Position = 4;
                    var metadataLength = reader.ReadInt32();
                    if ((metadataLength & 7) != 0)
                    {
                        Console.WriteLine("WARNING: The first offset doesn't seem to be valid.");
                    }
                    offsetOffset = ((metadataLength >> 3) << 3) - 4;
                    oldBytes     = new byte[0];
                }
                stream.Position = offsetOffset;
                var tableOffset = stream.Position = reader.ReadInt32();
                writer.Write(texts.Count);
                writer.Write(pointerPointers.Count);
                foreach (var pointer in stringPointers)
                {
                    writer.Write(pointer.Index);
                    writer.Write(pointer.Count);
                }
                foreach (var pointer in pointerPointers)
                {
                    writer.Write(pointer.LanguageID);
                    writer.Write(pointer.Offset);
                }
                foreach (var pair in stringOffsets.OrderBy(p => p.Value))
                {
                    writer.Write(Encoding.UTF8.GetBytes(pair.Key));
                    writer.Write((byte)0);
                }
                var oldBytesOffset = (int)stream.Position;
                writer.Write(oldBytes);
                writer.Flush();
                if (stream.Position < stream.Length)
                {
                    stream.SetLength(stream.Position);
                }
                stream.Position = offsetOffset - 4;
                writer.Write((int)(stream.Length - tableOffset - oldBytes.LongLength));
                if (!isItem)
                {
                    return;
                }
                stream.Position += 8;
                writer.Write(oldBytesOffset);
            }
        }