Пример #1
0
        private void ReadDataItems(Stream s)
        {
            _signature = s.ReadValueS32(Endianness);
            var elementCount = s.ReadValueS32(Endianness);

            var indexBase  = 16;
            var stringBase = indexBase + elementCount * 0x1C;

            _dataList = new List <DataItem>();
            var i = 0;

            while (i < elementCount)
            {
                s.Seek(indexBase + i * 0x1C, SeekOrigin.Begin);
                var item = new DataItem();
                item.Index.Id           = s.ReadBytes(0xC);
                item.Index.Id2          = s.ReadBytes(0xC);
                item.Index.StringOffset = s.ReadValueS32(Endianness);

                s.Seek(stringBase + item.Index.StringOffset, SeekOrigin.Begin);

                item.Data = ReadString(s);

                _dataList.Add(item);
                i++;
            }
        }
Пример #2
0
        public override void Read(Stream s)
        {
            _dataList = new List <TFString>();

            s.Seek(0x24, SeekOrigin.Begin);

            var pointer1 = s.ReadValueS32(Endianness);

            if (pointer1 != -1)
            {
                s.Seek(pointer1, SeekOrigin.Begin);

                var pointer2 = s.ReadValueS32(Endianness);

                s.Seek(pointer2, SeekOrigin.Begin);

                var str = s.ReadStringZ(Encoding);
                if (!string.IsNullOrEmpty(str.TrimEnd('\0')))
                {
                    str = Yakuza0Project.ReadingReplacements(str);
                }

                var item = new TFString
                {
                    FileId      = Id,
                    Offset      = pointer2,
                    Section     = pointer1.ToString("X8"),
                    Original    = str,
                    Translation = str,
                    Visible     = !string.IsNullOrEmpty(str.TrimEnd('\0'))
                };

                _dataList.Add(item);
            }
        }
Пример #3
0
        void IChunk.Deserialize(IChunk parent, Stream input, Endian endian)
        {
            var count = input.ReadValueU32(endian);

            this.Items.Clear();
            for (uint i = 0; i < count; i++)
            {
                var node = new Node();

                node.NameHash             = input.ReadValueU32(endian);
                node.NextSiblingIndex     = input.ReadValueS32(endian);
                node.FirstChildIndex      = input.ReadValueS32(endian);
                node.PreviousSiblingIndex = input.ReadValueS32(endian);
                node.Unknown10            = input.ReadValueF32(endian);
                node.Unknown14            = input.ReadValueF32(endian);
                node.Unknown18            = input.ReadValueF32(endian);
                node.Unknown1C            = input.ReadValueF32(endian);
                node.Unknown20            = input.ReadValueF32(endian);
                node.Unknown24            = input.ReadValueF32(endian);
                node.Unknown28            = input.ReadValueF32(endian);
                node.Unknown2C            = input.ReadValueF32(endian);
                node.Unknown30            = input.ReadValueF32(endian);
                node.Unknown34            = input.ReadValueF32(endian);
                node.O2BMIndex            = input.ReadValueS32(endian);
                node.Unknown3C            = input.ReadValueF32(endian);
                node.Unknown40            = input.ReadValueF32(endian);

                var length = input.ReadValueU32(endian);
                node.Name = input.ReadString(length);
                input.Seek(1, SeekOrigin.Current); // skip null

                this.Items.Add(node);
            }
        }
Пример #4
0
        public void Read(Stream input, long debugOffset)
        {
            this.DebugOffset = debugOffset + input.Position;

            this.Version = input.ReadValueS16();
            if (this.Version < 1 || this.Version > 2)
            {
                throw new Exception();
            }
            int size = input.ReadValueS32();

            this.Data = new MemoryStream();
            this.Data.WriteValueS16(this.Version);
            this.Data.WriteValueS32(size);

            byte[] data = new byte[size - (4 + 2)];
            input.Read(data, 0, data.Length);
            this.Data.Write(data, 0, data.Length);

            this.Items = new Dictionary <UInt32, int>();
            short count = input.ReadValueS16();

            for (short i = 0; i < count; i++)
            {
                UInt32 hash   = input.ReadValueU32();
                int    offset = input.ReadValueS32();
                this.Items.Add(hash, offset);
            }
        }
Пример #5
0
        private void ReadFields(Stream s)
        {
            _dataList = new List <DataItem>(_itemCount);

            for (var i = 0; i < _itemCount; i++)
            {
                var pos   = s.Position;
                var field = new DataItem
                {
                    Name = s.ReadStringZ(Encoding)
                };

                s.Seek(pos + 48, SeekOrigin.Begin);

                field.DataType   = s.ReadValueS32(Endianness);
                field.DataCount  = s.ReadValueS32(Endianness);
                field.DataLength = s.ReadValueS32(Endianness);

                s.ReadValueS32(Endianness); // Leemos el 0 que hay al final

                field.Data             = new List <TFString>();
                field.AdditionalValues = new List <short>();

                _dataList.Add(field);
            }
        }
Пример #6
0
        public override void Read(Stream s)
        {
            s.Seek(8, SeekOrigin.Begin);
            _firstStringOffset = s.ReadValueS32(Endianness);

            var currentIndex = s.FindPattern(PATTERN);

            while (currentIndex != -1)
            {
                var localOffset = s.ReadValueS32(Endianness);
                var control     = s.ReadValueS16(Endianness);

                if (control == 0 || control == 8)
                {
                    // Es un texto que hay que añadir
                    var item = new DataItem
                    {
                        RelativeOffset         = localOffset,
                        RelativeOffsetPosition = (int)(s.Position - 6)
                    };

                    var pos = s.Position;
                    s.Seek(_firstStringOffset + localOffset, SeekOrigin.Begin);

                    item.Data = ReadString(s);

                    s.Seek(currentIndex + 4, SeekOrigin.Begin);

                    _strings.Add(item);
                }

                currentIndex = s.FindPattern(PATTERN);
            }
        }
Пример #7
0
 private void ReadHeader(Stream s)
 {
     _unknown1  = s.ReadValueS32(Endianness);
     _itemCount = s.ReadValueS32(Endianness);
     _unknown2  = s.ReadValueS32(Endianness);
     _unknown3  = s.ReadValueS32(Endianness);
 }
Пример #8
0
 private void ReadHeader(Stream s)
 {
     _signature = s.ReadValueS32(Endianness); // 20 07 03 19
     _itemCount = s.ReadValueS32(Endianness);
     _unknown1  = s.ReadValueS32(Endianness);
     _unknown2  = s.ReadValueS32(Endianness); // 0
 }
Пример #9
0
        public ME2ExportEntry(ME2Package pccFile, Stream stream) : base(pccFile)
        {
            //determine header length
            long start = stream.Position;

            stream.Seek(40, SeekOrigin.Current);
            int count = stream.ReadValueS32();

            stream.Seek(4 + count * 12, SeekOrigin.Current);
            count = stream.ReadValueS32();
            stream.Seek(16, SeekOrigin.Current);
            stream.Seek(4 + count * 4, SeekOrigin.Current);
            long end = stream.Position;

            stream.Seek(start, SeekOrigin.Begin);

            //read header
            Header           = stream.ReadBytes((int)(end - start));
            headerOffset     = (uint)start;
            OriginalDataSize = DataSize;

            //read data
            stream.Seek(DataOffset, SeekOrigin.Begin);
            _data = stream.ReadBytes(DataSize);
            stream.Seek(end, SeekOrigin.Begin);
            if ((ObjectFlags & (ulong)UnrealFlags.EObjectFlags.HasStack) != 0)
            {
                ReadsFromConfig = (Data[25] & 64) != 0;
            }
            else
            {
                ReadsFromConfig = false;
            }
        }
Пример #10
0
        public ME1ExportEntry(ME1Package pccFile, Stream stream) : base(pccFile)
        {
            //determine header length
            long start = stream.Position;

            stream.Seek(40, SeekOrigin.Current);
            int count = stream.ReadValueS32();

            stream.Seek(4 + count * 12, SeekOrigin.Current);
            count = stream.ReadValueS32();
            stream.Seek(16, SeekOrigin.Current);
            stream.Seek(4 + count * 4, SeekOrigin.Current);
            long end = stream.Position;

            stream.Seek(start, SeekOrigin.Begin);

            //read header
            Header           = stream.ReadBytes((int)(end - start));
            headerOffset     = (uint)start;
            OriginalDataSize = DataSize;

            //read data
            stream.Seek(DataOffset, SeekOrigin.Begin);
            _data = stream.ReadBytes(DataSize);
            stream.Seek(end, SeekOrigin.Begin);
            if (ClassName.Contains("Property"))
            {
                ReadsFromConfig = Data.Length > 25 && (Data[25] & 64) != 0;
            }
            else
            {
                ReadsFromConfig = false;
            }
        }
Пример #11
0
            public void Deserialize(Stream input)
            {
                this.Unknown00    = input.ReadValueU32();
                this.Comment      = input.ReadString(16, true, Encoding.GetEncoding(932));
                this.TextureIndex = input.ReadValueS32();
                this.Unknown18    = input.ReadValueU32();
                this.Unknown1C    = new byte[16];
                input.Read(this.Unknown1C, 0, this.Unknown1C.Length);
                this.Unknown2C = input.ReadValueU32();
                this.Unknown30 = new byte[12];
                input.Read(this.Unknown30, 0, this.Unknown30.Length);
                this.Unknown3C = input.ReadValueU32();
                this.Unknown40 = input.ReadValueU32();
                this.Unknown44 = input.ReadValueU32();
                this.Unknown48 = input.ReadValueU32();
                this.Unknown4C = new byte[8];
                input.Read(this.Unknown4C, 0, this.Unknown4C.Length);
                this.Left      = input.ReadValueS32();
                this.Top       = input.ReadValueS32();
                this.Right     = input.ReadValueS32();
                this.Bottom    = input.ReadValueS32();
                this.Unknown64 = new byte[16];
                input.Read(this.Unknown64, 0, this.Unknown64.Length);
                this.Unknown74 = input.ReadValueS16();
                this.Unknown76 = input.ReadValueS16();
                this.Unknown78 = new byte[8];
                input.Read(this.Unknown78, 0, this.Unknown78.Length);

                foreach (var u1C in this.Unknown1C)
                {
                    if (u1C != 0)
                    {
                        throw new FormatException();
                    }
                }

                foreach (var u4C in this.Unknown4C)
                {
                    if (u4C != 0)
                    {
                        throw new FormatException();
                    }
                }

                foreach (var u64 in this.Unknown64)
                {
                    if (u64 != 128 && u64 != 255)
                    {
                        //throw new FormatException();
                    }
                }

                foreach (var u78 in this.Unknown78)
                {
                    if (u78 != 0)
                    {
                        throw new FormatException();
                    }
                }
            }
        protected override DataFormats.Ranged <int> Read(Stream input, Endian endian)
        {
            var range = input.ReadValueS32(endian);
            var value = input.ReadValueS32(endian);

            return(new DataFormats.Ranged <int>(range, value));
        }
Пример #13
0
            public static RawItem Read(Stream input, Endian endian)
            {
                var instance = new RawItem();

                instance.Name        = input.ReadValueU32(endian);
                instance.BaseName    = input.ReadValueU32(endian);
                instance.Type        = input.ReadValueS32(endian);
                instance.Purchasable = input.ReadValueS32(endian);
                instance.Consumable  = input.ReadValueS32(endian);
                instance.Rewardable  = input.ReadValueS32(endian);
                instance.Collectable = input.ReadValueS32(endian);
                input.Seek(4, SeekOrigin.Current);
                instance.FeatOffset        = input.ReadValueS64(endian);
                instance.FeatCount         = input.ReadValueS64(endian);
                instance.Region            = input.ReadValueU32(endian);
                instance.RebelDropTimer    = input.ReadValueS32(endian);
                instance.MaxInventory      = input.ReadValueS32(endian);
                instance.UIType            = input.ReadValueS32(endian);
                instance.UIFlag            = input.ReadValueS32(endian);
                instance.UIDisplayOrder    = input.ReadValueS32(endian);
                instance.UIName            = input.ReadValueU32(endian);
                instance.UIDescription     = input.ReadValueU32(endian);
                instance.UITypeDescription = input.ReadValueU32(endian);
                instance.UIFlagDescription = input.ReadValueU32(endian);
                instance.UIImagePathOffset = input.ReadValueS64(endian);
                instance.UIVideoPathOffset = input.ReadValueS64(endian);
                instance.UIPar0            = input.ReadValueF32(endian);
                instance.UIPar1            = input.ReadValueF32(endian);
                instance.UIPar2            = input.ReadValueF32(endian);
                instance.UIPar3            = input.ReadValueF32(endian);
                instance.UIPar4            = input.ReadValueF32(endian);
                input.Seek(4, SeekOrigin.Current);
                return(instance);
            }
Пример #14
0
 private void ReadHeader(Stream s)
 {
     _signature = s.ReadValueS32(Endianness);
     _unknown1  = s.ReadValueS32(Endianness); // 65536
     _unknown2  = s.ReadValueS32(Endianness); // 1
     _unknown3  = s.ReadValueS32(Endianness); // 0
     _itemCount = s.ReadValueS32(Endianness);
 }
Пример #15
0
        public static ArrayEntry Read(Stream input, Endian endian)
        {
            ArrayEntry instance;

            instance.DataOffset = input.ReadValueU32(endian);
            instance.ItemCount  = input.ReadValueS32(endian);
            instance.TypeIndex  = input.ReadValueS32(endian);
            return(instance);
        }
 public void Deserialize(Stream input, Endian endian)
 {
     this.Name       = input.ReadStringU16(0x40, Encoding.ASCII, endian);
     this.Type       = input.ReadValueU8();
     this.Allocator  = input.ReadValueU8();
     this.Unknown3   = input.ReadValueU8();
     this.Unknown4   = input.ReadValueU8();
     this.HeaderSize = input.ReadValueS32(endian);
     this.DataSize   = input.ReadValueS32(endian);
 }
 public void Deserialize(Stream input, Endian endian)
 {
     this.Name       = input.ReadStringU16(0x40, Encoding.ASCII, endian);
     this.Type       = input.ReadValueU8();
     this.Allocator  = input.ReadValueU8();
     this.Flags      = (PrimitiveFlags)input.ReadValueU8();
     this.SplitIndex = input.ReadValueU8();
     this.CPUSize    = input.ReadValueS32(endian);
     this.GPUSize    = input.ReadValueS32(endian);
     this.Unknown7   = input.ReadValueU8();
 }
Пример #18
0
        public override void Deserialize(Stream input)
        {
            this.Name         = input.ReadStringAlignedU8();
            this.Language     = (byte)input.ReadValueS32();
            this.Modulo       = input.ReadValueU32();
            this.SizeOfBuffer = input.ReadValueU32();
            var length = input.ReadValueS32();

            this.Buffer = new byte[length];
            input.Read(this.Buffer, 0, this.Buffer.Length);
        }
Пример #19
0
            internal static ItemReward Read(Stream input, Endian endian)
            {
                var instance = new ItemReward();

                instance.Item      = input.ReadValueU32(endian);
                instance.Permanent = input.ReadValueS32(endian);
                instance.Duration  = input.ReadValueS32(endian);
                instance.Quantity  = input.ReadValueS32(endian);
                instance.Delivery  = input.ReadValueS32(endian);
                return(instance);
            }
        void PropertyContainerFile.IRawVariant.Deserialize(Stream input, Endian endian)
        {
            int count  = input.ReadValueS32(endian);
            var values = new int[count];

            for (int i = 0; i < count; i++)
            {
                values[i] = input.ReadValueS32(endian);
            }
            this._Values.Clear();
            this._Values.AddRange(values);
        }
Пример #21
0
            public static RawReward Read(Stream input, Endian endian)
            {
                var instance = new RawReward();

                instance.Skillpoints         = input.ReadValueS32(endian);
                instance.Chaos               = input.ReadValueS32(endian);
                instance.ItemRewardSemantics = input.ReadValueS32(endian);
                input.Seek(4, SeekOrigin.Current);
                instance.ItemOffset = input.ReadValueS64(endian);
                instance.ItemCount  = input.ReadValueS64(endian);
                return(instance);
            }
Пример #22
0
        public void Deserialize(Stream input)
        {
            var directoryCount = input.ReadValueS32();

            if (input.Position + (directoryCount * 8) > input.Length)
            {
                throw new EndOfStreamException();
            }

            // don't need to load this information for our uses :)

            /*
             * for (int i = 0; i < directoryCount; i++)
             * {
             *  var directoryId = input.ReadValueU32();
             *  var firstFileIndex = input.ReadValueU32();
             * }
             */
            input.Seek(directoryCount * 8, SeekOrigin.Current);

            var fileCount = input.ReadValueS32();

            if (input.Position + (fileCount * 12) > input.Length)
            {
                throw new EndOfStreamException();
            }

            byte[] fileData = new byte[fileCount * 12];
            input.Read(fileData, 0, fileData.Length);

            var directoryNameSize = input.ReadValueU32();
            var fileNameSize      = input.ReadValueU32();

            input.Seek(directoryNameSize, SeekOrigin.Current); // don't need to load directory names
            var fileNames = input.ReadToMemoryStream(fileNameSize);

            this.Entries.Clear();
            for (int i = 0; i < fileCount; i++)
            {
                if (fileNames.Position >= fileNames.Length)
                {
                    throw new EndOfStreamException();
                }

                this.Entries.Add(new Entry()
                {
                    Path   = fileNames.ReadStringZ().Replace('/', '\\'),
                    Offset = BitConverter.ToUInt32(fileData, (i * 12) + 0),
                    Size   = BitConverter.ToUInt32(fileData, (i * 12) + 4),
                });
            }
        }
Пример #23
0
 public static RawDirectoryEntry Read(Stream input, Endian endian)
 {
     RawDirectoryEntry instance;
     instance.DirectoryCount = input.ReadValueS32(endian);
     instance.DirectoryIndex = input.ReadValueS32(endian);
     instance.FileCount = input.ReadValueS32(endian);
     instance.FileIndex = input.ReadValueS32(endian);
     instance.Unknown10 = input.ReadValueU32(endian);
     instance.Unknown14 = input.ReadValueU32(endian);
     instance.Unknown18 = input.ReadValueU32(endian);
     instance.Unknown1C = input.ReadValueU32(endian);
     return instance;
 }
        public override void Read(Stream s)
        {
            _unknown1     = s.ReadValueS32(Endianness);
            _unknown2     = s.ReadValueS16(Endianness);
            _num          = s.ReadValueS16(Endianness);
            _unknown3     = s.ReadValueS32(Endianness);
            _table2Offset = s.ReadValueS32(Endianness);

            _dataList1 = new List <TFString>();
            _dataList2 = new List <ItemData>();

            var firstString = -1;

            for (var i = 0; i < 43; i++)
            {
                var str = ReadString(s);
                _dataList1.Add(str);

                if (firstString == -1)
                {
                    firstString = str.Offset;
                }
            }

            _remainder1 = s.ReadBytes(0x54);

            for (var i = 0; i < _num; i++)
            {
                var item = new ItemData();
                for (var j = 0; j < 12; j++)
                {
                    item.Unknown[j] = s.ReadValueS32(Endianness);
                }

                if (firstString == -1)
                {
                    firstString = item.Unknown[8];
                }

                item.Data = ReadString(s, item.Unknown[8]);

                _dataList2.Add(item);
            }

            var remainderSize = (int)(firstString - s.Position);

            if (remainderSize > 0)
            {
                _remainder2 = ReadRemainder(s, remainderSize);
            }
        }
Пример #25
0
        private void ReadHeader(Stream s)
        {
            s.Seek(0, SeekOrigin.Begin);

            var header = _root.Header;

            header.Signature     = s.ReadBytes(4);
            header.Size1         = s.ReadValueS32(Endianness);
            header.ContentOffset = s.ReadValueS32(Endianness);
            header.Unknown1      = s.ReadValueS32(Endianness);
            header.Unknown2      = s.ReadValueS32(Endianness);
            header.ContentSize   = s.ReadValueS32(Endianness);
            header.Unknown3      = s.ReadValueS64(Endianness);
        }
        public void Deserialize(Stream input, Endian endian)
        {
            this.FaceCount = input.ReadValueS32(endian);
            this.FaceIndex = input.ReadValueS32(endian);

            var count = input.ReadValueS32(endian);

            this.BoneIndices.Clear();
            this.BoneIndices.Capacity = count;
            for (int i = 0; i < count; i++)
            {
                this.BoneIndices.Add(input.ReadValueS16(endian));
            }
        }
Пример #27
0
        public override void Read(Stream s)
        {
            var numFiles = s.ReadValueS16(Endianness);

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

                var f = new File
                {
                    Unknown         = s.ReadValueS32(Endianness),
                    OffsetMsg       = s.ReadValueS32(Endianness),
                    OffsetRemainder = s.ReadValueS32(Endianness),
                    SizeMsg         = s.ReadValueS16(Endianness),
                    SizeRemainder   = s.ReadValueS16(Endianness)
                };

                if (f.OffsetMsg != 0)
                {
                    s.Seek(f.OffsetMsg, SeekOrigin.Begin);
                    f.MsgBytes = s.ReadBytes(f.SizeMsg);

                    var msgFile = new MsgFile(string.Empty);
                    using (var ms = new MemoryStream(f.MsgBytes))
                    {
                        msgFile.Read(ms);
                    }

                    if (msgFile.Strings.Count > 0)
                    {
                        foreach (var tfString in msgFile.Strings)
                        {
                            tfString.Section = f.OffsetMsg.ToString("X8");
                            tfString.FileId  = Id;
                        }
                    }

                    f.Msg = msgFile;
                }

                if (f.OffsetRemainder != 0)
                {
                    s.Seek(f.OffsetRemainder, SeekOrigin.Begin);
                    f.Remainder = s.ReadBytes(f.SizeRemainder);
                }

                _files.Add(f);
            }
        }
Пример #28
0
        private TFString ReadString(Stream s)
        {
            var stringOffset = s.ReadValueS32(Endianness);
            var pos          = s.Position;

            var value = new TFString {
                FileId = Id, Offset = stringOffset, Visible = false
            };

            if (stringOffset != 0)
            {
                s.Seek(stringOffset, SeekOrigin.Begin);

                var str = s.ReadStringZ(Encoding);

                if (!string.IsNullOrEmpty(str.TrimEnd('\0')))
                {
                    str = Yakuza0Project.ReadingReplacements(str);

                    value.Original    = str;
                    value.Translation = str;
                    value.Visible     = true;
                }
            }

            s.Seek(pos, SeekOrigin.Begin);

            return(value);
        }
        void PropertyContainerFile.IRawVariant.Deserialize(Stream input, Endian endian)
        {
            int count = input.ReadValueS32(endian);
            var bytes = input.ReadBytes(count);

            this._Value = bytes;
        }
Пример #30
0
        public override void Deserialize(Stream input)
        {
            var length = input.ReadValueS32();

            this.Data = new byte[length];
            input.Read(this.Data, 0, this.Data.Length);
        }
Пример #31
0
		public void Deserialize(Stream input, Endian endian) {
			this.Size = input.ReadValueU32(endian);
			this.Flags = input.ReadValueEnum<HeaderFlags>(endian);
			this.Height = input.ReadValueS32(endian);
			this.Width = input.ReadValueS32(endian);
			this.PitchOrLinearSize = input.ReadValueU32(endian);
			this.Depth = input.ReadValueU32(endian);
			this.MipMapCount = input.ReadValueU32(endian);
			if (input.Read(this.Reserved1, 0, this.Reserved1.Length) != this.Reserved1.Length) {
				throw new EndOfStreamException();
			}
			this.PixelFormat.Deserialize(input, endian);
			this.SurfaceFlags = input.ReadValueU32(endian);
			this.CubemapFlags = input.ReadValueU32(endian);
			if (input.Read(this.Reserved2, 0, this.Reserved2.Length) != this.Reserved2.Length) {
				throw new EndOfStreamException();
			}
		}
Пример #32
0
        public void Deserialize(Stream input)
        {
            var magic = input.ReadValueU32(Endian.Little);
            if (magic != 0x434F4E44 && // COND
                magic.Swap() != 0x434F4E44)
            {
                throw new FormatException();
            }
            var endian = magic == 0x434F4E44 ? Endian.Little : Endian.Big;

            var version = input.ReadValueU32(endian);
            if (version != 1)
            {
                throw new FormatException();
            }
            this.Version = version;

            var unknown08 = input.ReadValueU16(endian);
            var count = input.ReadValueU16(endian);

            var ids = new int[count];
            var offsets = new uint[count];
            for (ushort i = 0; i < count; i++)
            {
                ids[i] = input.ReadValueS32(endian);
                offsets[i] = input.ReadValueU32(endian);
            }

            for (ushort i = 0; i < count; i++)
            {
                var id = ids[i];
                var offset = offsets[i];

                input.Seek(offset, SeekOrigin.Begin);

                var flags = input.ReadValueU8();

                var valueType = (Conditionals.ValueType)((flags & 0x0F) >> 0);
                var opType = (Conditionals.OpType)((flags & 0xF0) >> 4);

                if (valueType == Conditionals.ValueType.Bool)
                {
                    switch (opType)
                    {
                        default:
                        {
                            throw new NotSupportedException();
                        }
                    }
                }
            }

            //throw new NotImplementedException();

            this.Endian = endian;
        }
Пример #33
0
        public static object Deserialize(Stream input, FieldType type, bool littleEndian)
        {
            switch (type)
            {
                case FieldType.UInt8: return input.ReadValueU8();
                case FieldType.Int8: return input.ReadValueS8();
                case FieldType.UInt16: return input.ReadValueU16(littleEndian);
                case FieldType.Int16: return input.ReadValueS16(littleEndian);
                case FieldType.UInt32: return input.ReadValueU32(littleEndian);
                case FieldType.Int32: return input.ReadValueS32(littleEndian);
                case FieldType.UInt64: return input.ReadValueU64(littleEndian);
                case FieldType.Int64: return input.ReadValueS64(littleEndian);
                case FieldType.Single: return input.ReadValueF32(littleEndian);
                case FieldType.Double: return input.ReadValueF64(littleEndian);
                case FieldType.Vector3:
                {
                    var value = new Builtins.Vector3();
                    value.Deserialize(input, littleEndian);
                    return value;
                }
                case FieldType.Vector4:
                {
                    var value = new Builtins.Vector4();
                    value.Deserialize(input, littleEndian);
                    return value;
                }
                case FieldType.Quaternion:
                {
                    var value = new Builtins.Quaternion();
                    value.Deserialize(input, littleEndian);
                    return value;
                }
                case FieldType.String:
                {
                    throw new NotSupportedException("cannot deserialize strings via Builtin");
                }
                case FieldType.Color:
                {
                    var value = new Builtins.Color();
                    value.Deserialize(input, littleEndian);
                    return value;
                }
                case FieldType.Matrix4x4:
                {
                    var value = new Builtins.Matrix4x4();
                    value.Deserialize(input, littleEndian);
                    return value;
                }
            }

            throw new NotSupportedException("unsupported builtin type");
        }
Пример #34
0
        public void Deserialize(Stream input)
        {
            var magic = input.ReadValueU32(Endian.Little);
            if (magic != 0x53464152 && // SFAR
                magic.Swap() != 0x53464152)
            {
                throw new FormatException();
            }
            var endian = magic == 0x53464152 ? Endian.Little : Endian.Big;

            var version = input.ReadValueU32(endian);
            if (version != 0x00010000)
            {
                throw new FormatException();
            }

            var dataOffset = input.ReadValueU32(endian);
            var fileTableOffset = input.ReadValueU32(endian);
            var fileTableCount = input.ReadValueU32(endian);
            var blockSizeTableOffset = input.ReadValueU32(endian);
            this.MaximumBlockSize = input.ReadValueU32(endian);
            this.CompressionScheme = input
                .ReadValueEnum<SFXArchive.CompressionScheme>(endian);

            if (fileTableOffset != 0x20)
            {
                throw new FormatException();
            }

            if (this.MaximumBlockSize != 0x010000)
            {
                throw new FormatException();
            }

            /*
            if (this.CompressionScheme != SFXArchive.CompressionScheme.None &&
                this.CompressionScheme != SFXArchive.CompressionScheme.LZMA &&
                this.CompressionScheme != SFXArchive.CompressionScheme.LZX)
            {
                throw new FormatException();
            }
            */

            input.Seek(blockSizeTableOffset, SeekOrigin.Begin);

            var blockSizeTableSize = dataOffset - fileTableOffset;
            var blockSizeTableCount = blockSizeTableSize / 2;
            this.BlockSizes.Clear();
            for (uint i = 0; i < blockSizeTableCount; i++)
            {
                this.BlockSizes.Add(input.ReadValueU16(endian));
            }

            input.Seek(fileTableOffset, SeekOrigin.Begin);
            for (uint i = 0; i < fileTableCount; i++)
            {
// ReSharper disable UseObjectOrCollectionInitializer
                var entry = new SFXArchive.Entry();
// ReSharper restore UseObjectOrCollectionInitializer
                entry.NameHash = input.ReadFileNameHash();
                entry.BlockSizeIndex = input.ReadValueS32(endian);
                entry.UncompressedSize = input.ReadValueU32(endian);
                entry.UncompressedSize |= ((long)input.ReadValueU8()) << 32;
                entry.Offset = input.ReadValueU32(endian);
                entry.Offset |= ((long)input.ReadValueU8()) << 32;
                this.Entries.Add(entry);
            }
        }
Пример #35
0
        /// <summary>
        /// Takes compressed archived image data and returns the raw image data
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public byte[] DecompressTex(Stream archiveStream, int offset, int uncSize, int cprSize)
        {
            int pos = 0;
            archiveStream.Seek(offset, SeekOrigin.Begin);
            int magicNumber = archiveStream.ReadValueS32();
            pos += 4;
            if (magicNumber != -1641380927)
            {
                throw new FormatException("Magic Number is not correct. Invalid archive data");
            }
            int blockSize = archiveStream.ReadValueS32();
            pos += 4;
            int readCprSize = archiveStream.ReadValueS32(); //Archive cprSize doesn't include header size
            pos += 4;
            int uncReadSize = archiveStream.ReadValueS32();
            if (uncReadSize != uncSize)
            {
                throw new FormatException("Uncompressed data sizes don't match. Read: " + uncReadSize + ", expected: " + uncSize);
            }
            pos += 4;
            int noChunks = (uncSize + blockSize - 1) / blockSize;

            CompressedChunkBlock[] chunks = new CompressedChunkBlock[noChunks];
            for (int i = 0; i < noChunks; i++)
            {
                CompressedChunkBlock chunk = new CompressedChunkBlock();
                chunk.cprSize = archiveStream.ReadValueS32();
                chunk.uncSize = archiveStream.ReadValueS32();
                chunk.rawData = new byte[chunk.cprSize];
                pos += 8;
                chunks[i] = chunk;
            }
            if (readCprSize + pos != cprSize)
            {
                throw new FormatException("Compressed data sizes don't match. Invalid archive data");
            }
            byte[] rawData = new byte[readCprSize];
            rawData = archiveStream.ReadBytes(readCprSize);
            archiveStream.Close();
            using (MemoryStream data = new MemoryStream(rawData))
            {
                for (int i = 0; i < noChunks; i++)
                {
                    chunks[i].rawData = data.ReadBytes(chunks[i].cprSize);
                }
            }

            byte[] imgBuffer = new byte[uncSize];
            int resultPos = 0;

            for (int i = 0; i < noChunks; i++)
            {
                CompressedChunkBlock chunk = chunks[i];
                byte[] tempResult = new byte[chunk.uncSize];
                try
                {
                    LZO1X.Decompress(chunk.rawData, tempResult);
                }
                catch
                {
                    throw new Exception("LZO decompression failed!");
                }
                Buffer.BlockCopy(tempResult, 0, imgBuffer, resultPos, chunk.uncSize);
                resultPos += chunk.uncSize;
            }

            return imgBuffer;
        }
Пример #36
0
        public MemoryStream DecompressPCC(Stream raw, IPCCObject pcc)
        {
            raw.Seek(pcc.header.Length, SeekOrigin.Begin);
            int pos = 4;
            pcc.NumChunks = raw.ReadValueS32();
            List<Chunk> Chunks = new List<Chunk>();

            //DebugOutput.PrintLn("Reading chunk headers...");
            for (int i = 0; i < pcc.NumChunks; i++)
            {
                Chunk c = new Chunk();
                c.uncompressedOffset = raw.ReadValueS32();
                c.uncompressedSize = raw.ReadValueS32();
                c.compressedOffset = raw.ReadValueS32();
                c.compressedSize = raw.ReadValueS32();
                c.Compressed = new byte[c.compressedSize];
                c.Uncompressed = new byte[c.uncompressedSize];
                //DebugOutput.PrintLn("Chunk " + i + ", compressed size = " + c.compressedSize + ", uncompressed size = " + c.uncompressedSize);
                //DebugOutput.PrintLn("Compressed offset = " + c.compressedOffset + ", uncompressed offset = " + c.uncompressedOffset);
                Chunks.Add(c);
            }

            //DebugOutput.PrintLn("\tRead Chunks...");
            int count = 0;
            for (int i = 0; i < Chunks.Count; i++)
            {
                Chunk c = Chunks[i];
                raw.Seek(c.compressedOffset, SeekOrigin.Begin);
                c.Compressed = raw.ReadBytes(c.compressedSize);

                ChunkHeader h = new ChunkHeader();
                h.magic = BitConverter.ToInt32(c.Compressed, 0);
                if (h.magic != -1641380927)
                    throw new FormatException("Chunk magic number incorrect");
                h.blocksize = BitConverter.ToInt32(c.Compressed, 4);
                h.compressedsize = BitConverter.ToInt32(c.Compressed, 8);
                h.uncompressedsize = BitConverter.ToInt32(c.Compressed, 12);
                //DebugOutput.PrintLn("Chunkheader read: Magic = " + h.magic + ", Blocksize = " + h.blocksize + ", Compressed Size = " + h.compressedsize + ", Uncompressed size = " + h.uncompressedsize);
                pos = 16;
                int blockCount = (h.uncompressedsize % h.blocksize == 0)
                    ?
                    h.uncompressedsize / h.blocksize
                    :
                    h.uncompressedsize / h.blocksize + 1;
                List<Block> BlockList = new List<Block>();
                //DebugOutput.PrintLn("\t\t" + count + " Read Blockheaders...");
                for (int j = 0; j < blockCount; j++)
                {
                    Block b = new Block();
                    b.compressedsize = BitConverter.ToInt32(c.Compressed, pos);
                    b.uncompressedsize = BitConverter.ToInt32(c.Compressed, pos + 4);
                    //DebugOutput.PrintLn("Block " + j + ", compressed size = " + b.compressedsize + ", uncompressed size = " + b.uncompressedsize);
                    pos += 8;
                    BlockList.Add(b);
                }
                int outpos = 0;
                //DebugOutput.PrintLn("\t\t" + count + " Read and decompress Blocks...");
                foreach (Block b in BlockList)
                {
                    byte[] datain = new byte[b.compressedsize];
                    byte[] dataout = new byte[b.uncompressedsize];
                    for (int j = 0; j < b.compressedsize; j++)
                        datain[j] = c.Compressed[pos + j];
                    pos += b.compressedsize;

                    try
                    {
                        LZO1X.Decompress(datain, dataout);
                    }
                    catch
                    {
                        throw new Exception("LZO decompression failed!");
                    }
                    for (int j = 0; j < b.uncompressedsize; j++)
                        c.Uncompressed[outpos + j] = dataout[j];
                    outpos += b.uncompressedsize;
                }
                c.header = h;
                c.blocks = BlockList;
                count++;
                Chunks[i] = c;
            }

            MemoryStream result = new MemoryStream();
            foreach (Chunk c in Chunks)
            {
                result.Seek(c.uncompressedOffset, SeekOrigin.Begin);
                result.WriteBytes(c.Uncompressed);
            }

            return result;
        }
Пример #37
0
        /// <summary>
        ///     compress an entire ME3 pcc into a byte array.
        /// </summary>
        /// <param name="uncompressedPcc">uncompressed pcc stream.</param>
        /// <returns>a compressed array of bytes.</returns>
        public static Stream Compress(Stream uncompressedPcc)
        {
            uncompressedPcc.Position = 0;

            var magic = uncompressedPcc.ReadValueU32(Endian.Little);
            if (magic != 0x9E2A83C1 &&
                magic.Swap() != 0x9E2A83C1)
            {
                throw new FormatException("not a pcc package");
            }
            var endian = magic == 0x9E2A83C1 ?
                Endian.Little : Endian.Big;
            var encoding = endian == Endian.Little ?
                Encoding.Unicode : Encoding.BigEndianUnicode;

            var versionLo = uncompressedPcc.ReadValueU16(endian);
            var versionHi = uncompressedPcc.ReadValueU16(endian);

            if (versionLo != 684 &&
                versionHi != 194)
            {
                throw new FormatException("unsupported version");
            }

            uncompressedPcc.Seek(4, SeekOrigin.Current);

            var folderNameLength = uncompressedPcc.ReadValueS32(endian);
            var folderNameByteLength =
                folderNameLength >= 0 ? folderNameLength : (-folderNameLength * 2);
            uncompressedPcc.Seek(folderNameByteLength, SeekOrigin.Current);

            var packageFlagsOffset = uncompressedPcc.Position;
            var packageFlags = uncompressedPcc.ReadValueU32(endian);

            if ((packageFlags & 8) != 0)
            {
                uncompressedPcc.Seek(4, SeekOrigin.Current);
            }

            var nameCount = uncompressedPcc.ReadValueU32(endian);
            var namesOffset = uncompressedPcc.ReadValueU32(endian);
            var exportCount = uncompressedPcc.ReadValueU32(endian);
            var exportInfosOffset = uncompressedPcc.ReadValueU32(endian);
            SortedDictionary<uint, uint> exportDataOffsets = new SortedDictionary<uint, uint>();

            Stream data;
            if ((packageFlags & 0x02000000) == 0)
            {
                data = uncompressedPcc;
            }
            else
            {
                throw new FormatException("pcc data is compressed");
            }

            // get info about export data, sizes and offsets
            data.Seek(exportInfosOffset, SeekOrigin.Begin);
            for (uint i = 0; i < exportCount; i++)
            {
                var classIndex = data.ReadValueS32(endian);
                data.Seek(4, SeekOrigin.Current);
                var outerIndex = data.ReadValueS32(endian);
                var objectNameIndex = data.ReadValueS32(endian);
                data.Seek(16, SeekOrigin.Current);

                uint exportDataSize = data.ReadValueU32(endian);
                uint exportDataOffset = data.ReadValueU32(endian);
                exportDataOffsets.Add(exportDataOffset, exportDataSize);

                data.Seek(4, SeekOrigin.Current);
                var count = data.ReadValueU32(endian);
                data.Seek(count * 4, SeekOrigin.Current);
                data.Seek(20, SeekOrigin.Current);
            }

            const uint maxBlockSize = 0x100000;
            Stream outputStream = new MemoryStream();
            // copying pcc header
            byte[] buffer = new byte[130];
            uncompressedPcc.Seek(0, SeekOrigin.Begin);
            uncompressedPcc.Read(buffer, 0, 130);
            outputStream.Write(buffer, 0, buffer.Length);

            //add compressed pcc flag
            uncompressedPcc.Seek(12, SeekOrigin.Begin);
            folderNameLength = uncompressedPcc.ReadValueS32();
            folderNameByteLength =
                folderNameLength >= 0 ? folderNameLength : (-folderNameLength * 2);
            uncompressedPcc.Seek(folderNameByteLength, SeekOrigin.Current);
            outputStream.Seek(uncompressedPcc.Position, SeekOrigin.Begin);

            packageFlags = uncompressedPcc.ReadValueU32();
            packageFlags |= 0x02000000; // add compression flag
            outputStream.WriteValueU32(packageFlags);

            outputStream.Seek(buffer.Length, SeekOrigin.Begin);

            long outOffsetData;
            long outOffsetBlockInfo;
            long inOffsetData = namesOffset;
            List<int> blockSizes = new List<int>();
            int countSize = (int)(exportDataOffsets.Min(obj => obj.Key) - namesOffset);

            //count the number of blocks and relative sizes
            uint lastOffset = exportDataOffsets.Min(obj => obj.Key);
            foreach (KeyValuePair<uint, uint> exportInfo in exportDataOffsets)
            {
                // part that adds empty spaces (leaved when editing export data and moved to the end of pcc) into the count
                if (exportInfo.Key != lastOffset)
                {
                    int emptySpace = (int)(exportInfo.Key - lastOffset);
                    if (countSize + emptySpace > maxBlockSize)
                    {
                        blockSizes.Add(countSize);
                        countSize = 0;
                    }
                    else
                        countSize += emptySpace;
                }

                // adds export data into the count
                if (countSize + exportInfo.Value > maxBlockSize)
                {
                    blockSizes.Add(countSize);
                    countSize = (int)exportInfo.Value;
                }
                else
                {
                    countSize += (int)exportInfo.Value;
                }

                lastOffset = exportInfo.Key + exportInfo.Value;
            }
            blockSizes.Add(countSize);

            outputStream.WriteValueS32(blockSizes.Count);
            outOffsetBlockInfo = outputStream.Position;
            outOffsetData = namesOffset + (blockSizes.Count * 16);

            uncompressedPcc.Seek(namesOffset, SeekOrigin.Begin);
            //divide the block in segments
            for (int i = 0; i < blockSizes.Count; i++)
            {
                int currentUncBlockSize = blockSizes[i];

                outputStream.Seek(outOffsetBlockInfo, SeekOrigin.Begin);
                outputStream.WriteValueU32((uint)uncompressedPcc.Position);
                outputStream.WriteValueS32(currentUncBlockSize);
                outputStream.WriteValueU32((uint)outOffsetData);

                byte[] inputBlock = new byte[currentUncBlockSize];
                uncompressedPcc.Read(inputBlock, 0, currentUncBlockSize);
                byte[] compressedBlock = ZBlock.Compress(inputBlock, 0, inputBlock.Length);

                outputStream.WriteValueS32(compressedBlock.Length);
                outOffsetBlockInfo = outputStream.Position;

                outputStream.Seek(outOffsetData, SeekOrigin.Begin);
                outputStream.Write(compressedBlock, 0, compressedBlock.Length);
                outOffsetData = outputStream.Position;
            }

            //copying some unknown values + extra names list
            int bufferSize = (int)namesOffset - 0x86;
            buffer = new byte[bufferSize];
            uncompressedPcc.Seek(0x86, SeekOrigin.Begin);
            uncompressedPcc.Read(buffer, 0, buffer.Length);
            outputStream.Seek(outOffsetBlockInfo, SeekOrigin.Begin);
            outputStream.Write(buffer, 0, buffer.Length);

            outputStream.Seek(0, SeekOrigin.Begin);

            return outputStream;
        }
Пример #38
0
        /// <summary>
        ///     decompress an entire ME3 pcc file into a new stream
        /// </summary>
        /// <param name="input">pcc file passed in stream format</param>
        /// <returns>a decompressed array of bytes</returns>
        public static MemoryStream DecompressME3(Stream input)
        {
            input.Seek(0, SeekOrigin.Begin);
            var magic = input.ReadValueU32(Endian.Little);
            if (magic != 0x9E2A83C1 &&
                magic.Swap() != 0x9E2A83C1)
            {
                throw new FormatException("not a pcc file");
            }
            var endian = magic == 0x9E2A83C1 ? Endian.Little : Endian.Big;

            var versionLo = input.ReadValueU16(endian);
            var versionHi = input.ReadValueU16(endian);

            if (versionLo != 684 &&
                versionHi != 194)
            {
                throw new FormatException("unsupported pcc version");
            }

            long headerSize = 8;

            input.Seek(4, SeekOrigin.Current);
            headerSize += 4;

            var folderNameLength = input.ReadValueS32(endian);
            headerSize += 4;

            var folderNameByteLength =
                folderNameLength >= 0 ? folderNameLength : (-folderNameLength * 2);
            input.Seek(folderNameByteLength, SeekOrigin.Current);
            headerSize += folderNameByteLength;

            var packageFlagsOffset = input.Position;
            var packageFlags = input.ReadValueU32(endian);
            headerSize += 4;

            if ((packageFlags & 0x02000000u) == 0)
            {
                throw new FormatException("pcc file is already decompressed");
            }

            if ((packageFlags & 8) != 0)
            {
                input.Seek(4, SeekOrigin.Current);
                headerSize += 4;
            }

            uint nameCount = input.ReadValueU32(endian);
            uint nameOffset = input.ReadValueU32(endian);

            input.Seek(52, SeekOrigin.Current);
            headerSize += 60;

            var generationsCount = input.ReadValueU32(endian);
            input.Seek(generationsCount * 12, SeekOrigin.Current);
            headerSize += generationsCount * 12;

            input.Seek(20, SeekOrigin.Current);
            headerSize += 24;

            var blockCount = input.ReadValueU32(endian);
            int headBlockOff = (int)input.Position;
            var afterBlockTableOffset = headBlockOff + (blockCount * 16);
            var indataOffset = afterBlockTableOffset + 8;
            byte[] buff;

            input.Seek(0, SeekOrigin.Begin);
            MemoryStream output = new MemoryStream();
            output.Seek(0, SeekOrigin.Begin);

            output.WriteFromStream(input, headerSize);
            output.WriteValueU32(0, endian); // block count

            input.Seek(afterBlockTableOffset, SeekOrigin.Begin);
            output.WriteFromStream(input, 8);

            //check if has extra name list (don't know it's usage...)
            if ((packageFlags & 0x10000000) != 0)
            {
                long curPos = output.Position;
                output.WriteFromStream(input, nameOffset - curPos);
            }

            //decompress blocks in parallel
            Task<byte[]>[] tasks = new Task<byte[]>[blockCount];
            uint[] uncompressedOffsets = new uint[blockCount];
            for (int i = 0; i < blockCount; i++)
            {
                input.Seek(headBlockOff, SeekOrigin.Begin);
                uncompressedOffsets[i] = input.ReadValueU32(endian);
                var uncompressedSize = input.ReadValueU32(endian);
                var compressedOffset = input.ReadValueU32(endian);
                var compressedSize = input.ReadValueU32(endian);
                headBlockOff = (int)input.Position;

                buff = new byte[compressedSize];
                input.Seek(compressedOffset, SeekOrigin.Begin);
                input.Read(buff, 0, buff.Length);

                tasks[i] = ZBlock.DecompressAsync(buff);
            }
            Task.WaitAll(tasks);
            for (int i = 0; i < blockCount; i++)
            {
                output.Seek(uncompressedOffsets[i], SeekOrigin.Begin);
                output.WriteBytes(tasks[i].Result);
            }

            output.Seek(packageFlagsOffset, SeekOrigin.Begin);
            output.WriteValueU32(packageFlags & ~0x02000000u, endian);
            return output;
        }
        public void Deserialize(Stream input)
        {
            var magic = input.ReadValueU32(Endian.Little);
            if (magic != 0x434F4E44 && // COND
                magic.Swap() != 0x434F4E44)
            {
                throw new FormatException();
            }
            var endian = magic == 0x434F4E44 ? Endian.Little : Endian.Big;

            var version = input.ReadValueU32(endian);
            if (version != 1)
            {
                throw new FormatException();
            }
            this.Version = version;

            var unknown08 = input.ReadValueU16(endian);
            var count = input.ReadValueU16(endian);

            var ids = new int[count];
            var offsets = new uint[count];
            for (ushort i = 0; i < count; i++)
            {
                ids[i] = input.ReadValueS32(endian);
                offsets[i] = input.ReadValueU32(endian);
            }

            var sortedOffsets = offsets
                .OrderBy(o => o)
                .Distinct()
                .ToArray();

            this._Buffers.Clear();
            for (int i = 0; i < sortedOffsets.Length; i++)
            {
                var offset = sortedOffsets[i];
                if (offset == 0)
                {
                    continue;
                }

                var nextOffset = i + 1 < sortedOffsets.Length
                                     ? sortedOffsets[i + 1]
                                     : input.Length;

                input.Seek(offset, SeekOrigin.Begin);

                var length = (int)(nextOffset - offset);

                var bytes = input.ReadBytes(length);
                this._Buffers.Add(offset, bytes);
            }

            this._Conditionals.Clear();
            for (int i = 0; i < count; i++)
            {
                this._Conditionals.Add(ids[i], offsets[i]);
            }

            this.Endian = endian;
        }
Пример #40
0
        public void Deserialize(Stream input)
        {
            if (input.ReadValueU32() != 0x57325243) // 'W2RC' -> Witcher 2 Resource?
            {
                throw new FormatException();
            }

            this.Version = input.ReadValueU32();
            if (this.Version < 83 || this.Version > 115)
            {
                throw new FormatException();
            }

            var flags = input.ReadValueU32();

            var nameDataOffset = input.ReadValueU32();
            var nameCount = input.ReadValueU32();
            var objectDataOffset = input.ReadValueU32();
            var objectCount = input.ReadValueU32();
            var linkDataOffset = input.ReadValueU32();
            var linkCount = input.ReadValueU32();
            uint dependencyDataOffset = 0;
            uint dependencyCount = 0;

            if (this.Version >= 46)
            {
                dependencyDataOffset = input.ReadValueU32();
                dependencyCount = input.ReadValueU32();
            }

            var info = new Resource.Info();
            
            info.Names = new string[nameCount];
            if (nameCount > 0)
            {
                input.Seek(nameDataOffset, SeekOrigin.Begin);
                for (uint i = 0; i < nameCount; i++)
                {
                    info.Names[i] = input.ReadEncodedString();
                }
            }

            info.Links = new Resource.LinkInfo[linkCount];
            if (linkCount > 0)
            {
                input.Seek(linkDataOffset, SeekOrigin.Begin);

                for (uint i = 0; i < linkCount; i++)
                {
                    var link = new Resource.LinkInfo();
                    link.FileName = input.ReadEncodedStringW();
                    link.Unknown1 = input.ReadValueU16();
                    link.Unknown2 = input.ReadValueU16();
                    info.Links[i] = link;
                }
            }

            this.Dependencies.Clear();
            if (dependencyCount > 1)
            {
                input.Seek(dependencyDataOffset, SeekOrigin.Begin);

                info.Dependencies = new string[dependencyCount];
                for (uint i = 1; i < dependencyCount; i++)
                {
                    var path = input.ReadEncodedString();
                    info.Dependencies[i] = path;
                    this.Dependencies.Add(path);
                }
            }

            this.Objects = new List<Resource.ObjectInfo>();
            info.Objects = new Resource.ObjectInfo[objectCount];
            if (objectCount > 0)
            {
                input.Seek(objectDataOffset, SeekOrigin.Begin);

                var offsets = new Dictionary<Resource.ObjectInfo, ObjectLocation>();

                for (uint i = 0; i < objectCount; i++)
                {
                    var typeNameIndex = input.ReadValueS16();
                    if (typeNameIndex < 1 ||
                        typeNameIndex > info.Names.Length)
                    {
                        throw new FormatException();
                    }

                    var obj = new Resource.ObjectInfo();
                    obj.TypeName = info.Names[typeNameIndex - 1];

                    var parentIndex = input.ReadValueS32();

                    var location = new ObjectLocation();
                    location.Size = input.ReadValueU32();
                    location.Offset = input.ReadValueU32();

                    obj.Flags = input.ReadValueU32();
                    obj.Unknown5 = input.ReadValueU32();
                    obj.Link = this.Version < 102 ? null : input.ReadEncodedString();

                    if (TypeCache.Supports(obj.TypeName) == false)
                    {
                        obj.Data = new GenericObject(obj.TypeName);
                    }
                    else
                    {
                        obj.Data = TypeCache.Instantiate(obj.TypeName);
                    }

                    info.Objects[i] = obj;
                    offsets.Add(obj, location);

                    if (obj.Unknown5 != 0)
                    {
                        throw new FormatException();
                    }

                    if (parentIndex > 0)
                    {
                        var parent = info.Objects[parentIndex - 1];
                        if (parent.Children == null)
                        {
                            parent.Children = new List<Resource.ObjectInfo>();
                        }
                        parent.Children.Add(obj);
                        obj.Parent = parent;
                    }
                    else
                    {
                        obj.Parent = null;
                        this.Objects.Add(obj);
                    }
                }

                foreach (var obj in info.Objects)
                {
                    var location = offsets[obj];

                    input.Seek(location.Offset, SeekOrigin.Begin);
                    
                    var data = new byte[location.Size];
                    input.Read(data, 0, data.Length);

                    using (var reader = new Resource.ResourceReader(info, data))
                    {
                        obj.Data.Serialize(reader);

                        var bytesRemaining = reader.Length - reader.Position;
                        if (bytesRemaining > 0)
                        {
                            if (obj.Data is GenericObject)
                            {
                                byte[] undecodedData = new byte[bytesRemaining];
                                Array.Copy(data, reader.Position, undecodedData, 0, bytesRemaining);
                                ((GenericObject) obj.Data).UndecodedData = undecodedData;
                            }
                            else
                            {
                                throw new FormatException();
                            }
                        }
                    }
                }
            }
        }
Пример #41
0
        public void Deserialize(Stream input)
        {
            input.Seek(0, SeekOrigin.Begin);

            var magic = input.ReadValueU32(false);
            if (magic != 0x47464620)
            {
                throw new FormatException();
            }

            var version = input.ReadValueU32(false);
            if (version != 0x56342E30 && // 4.0
                version != 0x56342E31) // 4.1
            {
                throw new FormatException("unsupported version");
            }

            this.FileVersion = (byte)(version - 0x56342E30);
            this.FilePlatform = input.ReadValueEnum<GFF.FilePlatform>(false);
            this.FormatType = input.ReadValueEnum<GFF.FormatType>(false);
            this.FormatVersion = input.ReadValueU32(false);

            var littleEndian = this.FilePlatform == GFF.FilePlatform.PC;

            var structCount = input.ReadValueU32(littleEndian);
            var stringCount = this.FileVersion < 1 ? 0 : input.ReadValueU32(littleEndian);
            var stringOffset = this.FileVersion < 1 ? 0 : input.ReadValueU32(littleEndian);
            var dataOffset = input.ReadValueU32(littleEndian);

            if (this.FileVersion < 1)
            {
                stringOffset = dataOffset;
            }
            else
            {
                if (dataOffset < stringOffset)
                {
                    throw new FormatException();
                }
            }

            this.Structures.Clear();
            for (uint i = 0; i < structCount; i++)
            {
                var structDef = new GFF.StructureDefinition();
                //structDef.Id = input.ReadValueU32(littleEndian);
                structDef.Id = input.ReadValueU32(false);
                var fieldCount = input.ReadValueU32(littleEndian);
                var fieldOffset = input.ReadValueU32(littleEndian);
                structDef.DataSize = input.ReadValueU32(littleEndian);

                long nextOffset = input.Position;

                structDef.Fields.Clear();
                input.Seek(fieldOffset, SeekOrigin.Begin);
                for (uint j = 0; j < fieldCount; j++)
                {
                    var fieldDef = new GFF.FieldDefinition();
                    fieldDef.Id = input.ReadValueS32(littleEndian);
                    var rawFlags = input.ReadValueU32(littleEndian);
                    fieldDef.Offset = input.ReadValueU32(littleEndian);

                    var type = (ushort)(rawFlags & 0xFFFF);
                    var flags = (GFF.FieldFlags)((rawFlags >> 16) & 0xFFFF);

                    if ((flags & GFF.FieldFlags.IsStructure) != 0)
                    {
                        flags &= ~GFF.FieldFlags.IsStructure;
                        fieldDef.Type = GFF.FieldType.Structure;
                        fieldDef.StructureId = type;
                    }
                    else
                    {
                        fieldDef.Type = (GFF.FieldType)type;
                    }

                    fieldDef.Flags = flags;
                    structDef.Fields.Add(fieldDef);
                }

                this.Structures.Add(structDef);
                input.Seek(nextOffset, SeekOrigin.Begin);
            }

            if (this.FileVersion >= 1)
            {
                input.Seek(stringOffset, SeekOrigin.Begin);
                this.StringTable = new List<string>();
                for (uint i = 0; i < stringCount; i++)
                {
                    this.StringTable.Add(input.ReadStringZ(Encoding.UTF8));
                }
            }

            input.Seek(dataOffset, SeekOrigin.Begin);
            this.Data = input.ReadToMemoryStream(input.Length - dataOffset);
        }
Пример #42
0
        public void Deserialize(Stream input)
        {
            var magic = input.ReadValueU32(Endian.Little);
            if (magic != 0x666D726D && // fmrm
                magic.Swap() != 0x666D726D)
            {
                throw new FormatException();
            }
            var endian = magic == 0x666D726D ? Endian.Little : Endian.Big;

            var version = input.ReadValueU32(endian);
            if (version != 1)
            {
                throw new FormatException();
            }
            this.Version = version;

            /*var maxKeyLength =*/ input.ReadValueS32(endian);
            var maxValueLength = input.ReadValueS32(endian);

            var stringTableSize = input.ReadValueU32(endian);
            var huffmanSize = input.ReadValueU32(endian);
            var indexSize = input.ReadValueU32(endian);
            var dataSize = input.ReadValueU32(endian);

            var strings = new List<KeyValuePair<uint, string>>();
            using (var data = input.ReadToMemoryStream(stringTableSize))
            {
                var localStringTableSize = data.ReadValueU32(endian);
                if (localStringTableSize != stringTableSize)
                {
                    throw new FormatException();
                }

                var count = data.ReadValueU32(endian);

                var offsets = new List<KeyValuePair<uint, uint>>();
                for (uint i = 0; i < count; i++)
                {
                    var hash = data.ReadValueU32(endian);
                    var offset = data.ReadValueU32(endian);
                    offsets.Add(new KeyValuePair<uint, uint>(hash, offset));
                }

                foreach (var kv in offsets)
                {
                    var hash = kv.Key;
                    var offset = kv.Value;

                    data.Seek(8 + offset, SeekOrigin.Begin);
                    var length = data.ReadValueU16(endian);
                    var text = data.ReadString(length, Encoding.UTF8);

                    if (text.HashCrc32() != hash)
                    {
                        throw new InvalidOperationException();
                    }

                    strings.Add(new KeyValuePair<uint, string>(hash, text));
                }
            }

            Huffman.Pair[] huffmanTree;
            using (var data = input.ReadToMemoryStream(huffmanSize))
            {
                var count = data.ReadValueU16(endian);
                huffmanTree = new Huffman.Pair[count];
                for (ushort i = 0; i < count; i++)
                {
                    var left = data.ReadValueS32(endian);
                    var right = data.ReadValueS32(endian);
                    huffmanTree[i] = new Huffman.Pair(left, right);
                }
            }

            using (var index = input.ReadToMemoryStream(indexSize))
            {
                var totalBits = input.ReadValueS32(endian);
                var data = input.ReadBytes(dataSize);
                var bitArray = new BitArray(data) { Length = totalBits };

                var files = new List<KeyValuePair<string, uint>>();
                var fileCount = index.ReadValueU16(endian);
                for (ushort i = 0; i < fileCount; i++)
                {
                    var nameIndex = index.ReadValueU16(endian);
                    var name = strings[nameIndex].Value;
                    var offset = index.ReadValueU32(endian);
                    files.Add(new KeyValuePair<string, uint>(name, offset));
                }

                foreach (var fileInfo in files.OrderBy(f => f.Key))
                {
                    var file = new Coalesced.File() { Name = fileInfo.Key };

                    index.Seek(fileInfo.Value, SeekOrigin.Begin);
                    var sectionCount = index.ReadValueU16(endian);
                    var sections = new List<KeyValuePair<string, uint>>();
                    for (ushort i = 0; i < sectionCount; i++)
                    {
                        var nameIndex = index.ReadValueU16(endian);
                        var name = strings[nameIndex].Value;
                        var offset = index.ReadValueU32(endian);
                        sections.Add(new KeyValuePair<string, uint>(name, offset));
                    }

                    foreach (var sectionInfo in sections.OrderBy(s => s.Key))
                    {
                        var section = new Dictionary<string, List<Coalesced.Entry>>();

                        index.Seek(fileInfo.Value + sectionInfo.Value, SeekOrigin.Begin);
                        var valueCount = index.ReadValueU16(endian);
                        var values = new List<KeyValuePair<string, uint>>();
                        for (ushort i = 0; i < valueCount; i++)
                        {
                            var nameIndex = index.ReadValueU16(endian);
                            var name = strings[nameIndex].Value;
                            var offset = index.ReadValueU32(endian);
                            values.Add(new KeyValuePair<string, uint>(name, offset));
                        }

                        foreach (var valueInfo in values.OrderBy(v => v.Key))
                        {
                            var value = new List<Coalesced.Entry>();

                            index.Seek(fileInfo.Value + sectionInfo.Value + valueInfo.Value, SeekOrigin.Begin);
                            var itemCount = index.ReadValueU16(endian);

                            for (ushort i = 0; i < itemCount; i++)
                            {
                                var offset = index.ReadValueS32(endian);

                                var type = (offset & 0xE0000000) >> 29;
                                if (type == 1)
                                {
                                    value.Add(new Coalesced.Entry(1, null));
                                }
                                else if (type == 0 || type == 2 || type == 3 || type == 4)
                                {
                                    offset &= 0x1FFFFFFF;
                                    var text = Huffman.Decoder.Decode(
                                        huffmanTree, bitArray, offset, maxValueLength);
                                    value.Add(new Coalesced.Entry(2, text));
                                }
                                else
                                {
                                    throw new NotImplementedException();
                                }
                            }

                            section.Add(valueInfo.Key, value);
                        }

                        file.Sections.Add(sectionInfo.Key, section);
                    }

                    this.Files.Add(file);
                }
            }

            this.Endian = endian;
        }
Пример #43
0
        private static Stream ReadPackage(Stream input)
        {
            var magic = input.ReadValueU32(Endian.Little);
            if (magic != 0x9E2A83C1 &&
                magic.Swap() != 0x9E2A83C1)
            {
                throw new FormatException("not a package");
            }
            var endian = magic == 0x9E2A83C1
                             ? Endian.Little
                             : Endian.Big;

            var versionLo = input.ReadValueU16(endian);
            var versionHi = input.ReadValueU16(endian);

            if (versionLo != 684 &&
                versionHi != 194)
            {
                throw new FormatException("unsupported version");
            }

            input.Seek(4, SeekOrigin.Current);

            var folderNameLength = input.ReadValueS32(endian);
            var folderNameByteLength =
                folderNameLength >= 0 ? folderNameLength : (-folderNameLength * 2);
            input.Seek(folderNameByteLength, SeekOrigin.Current);

            /*var packageFlagsOffset = input.Position;*/
            var packageFlags = input.ReadValueU32(endian);

            if ((packageFlags & 8) != 0)
            {
                input.Seek(4, SeekOrigin.Current);
            }

            input.Seek(24, SeekOrigin.Current);

            if ((packageFlags & 0x02000000) == 0)
            {
                return input;
            }

            input.Seek(36, SeekOrigin.Current);

            var generationsCount = input.ReadValueU32(endian);
            input.Seek(generationsCount * 12, SeekOrigin.Current);

            input.Seek(20, SeekOrigin.Current);

            var blockCount = input.ReadValueU32(endian);

            var blockStream = new BlockStream(input);
            for (int i = 0; i < blockCount; i++)
            {
                var uncompressedOffset = input.ReadValueU32(endian);
                var uncompressedSize = input.ReadValueU32(endian);
                var compressedOffset = input.ReadValueU32(endian);
                var compressedSize = input.ReadValueU32(endian);
                blockStream.AddBlock(
                    uncompressedOffset,
                    uncompressedSize,
                    compressedOffset,
                    compressedSize);
            }

            return blockStream;
        }
Пример #44
0
        public void Deserialize(Stream input)
        {
            var magic = input.ReadValueU32(Endian.Little);
            if (magic != 0x53464152 && // SFAR
                magic.Swap() != 0x53464152)
            {
                throw new FormatException();
            }
            var endian = magic == 0x53464152 ? Endian.Little : Endian.Big;

            var version = input.ReadValueU32(endian);
            if (version != 0x00010000)
            {
                throw new FormatException();
            }

            var dataOffset = input.ReadValueU32(endian);
            bool firstDataOffset = true;
            uint minDataOffset = dataOffset;
            //Console.WriteLine("Data Offset: {0:X8}",dataOffset);
            var fileTableOffset = input.ReadValueU32(endian);
            //Console.WriteLine("File Table Offset: {0:X8}",fileTableOffset);
            var fileTableCount = input.ReadValueU32(endian);
            //Console.WriteLine("File Table Count: {0:X8}",fileTableCount);
            var blockSizeTableOffset = input.ReadValueU32(endian);
            //Console.WriteLine("Block Size Table Offset: {0:X8}",blockSizeTableOffset);
            this.MaximumBlockSize = input.ReadValueU32(endian);
            this.CompressionScheme = input
                .ReadValueEnum<SFXArchive.CompressionScheme>(endian);

            if (fileTableOffset != 0x20)
            {
                throw new FormatException();
            }

            if (this.MaximumBlockSize != 0x010000)
            {
                throw new FormatException();
            }

            /*
            if (this.CompressionScheme != SFXArchive.CompressionScheme.None &&
                this.CompressionScheme != SFXArchive.CompressionScheme.LZMA &&
                this.CompressionScheme != SFXArchive.CompressionScheme.LZX)
            {
                throw new FormatException();
            }
            */
            input.Seek(fileTableOffset, SeekOrigin.Begin);
            for (uint i = 0; i < fileTableCount; i++)
            {
            // ReSharper disable UseObjectOrCollectionInitializer
                var entry = new SFXArchive.Entry();
                entry.entryOffset = input.Position;
            // ReSharper restore UseObjectOrCollectionInitializer
                entry.nameHash = input.ReadFileNameHash();
                //Console.WriteLine("FileNameHash: {0}",entry.NameHash.ToString());
                entry.blockSizeIndex = input.ReadValueS32(endian);
                //Console.WriteLine("Begin position: {0:X8}",input.Position);
                entry.uncompressedSize = input.ReadValueU32(endian);
                entry.uncompressedSize |= ((long)input.ReadValueU8()) << 32;
                //Console.WriteLine("  End position: {0:X8}",input.Position);
                entry.dataOffset = input.ReadValueU32(endian);
                entry.dataOffset |= ((long)input.ReadValueU8()) << 32;
                if(firstDataOffset)
                {
                    minDataOffset = (uint)entry.dataOffset;
                    firstDataOffset = false;
                }
                else
                {
                    if(minDataOffset > entry.dataOffset)
                        minDataOffset = (uint)entry.dataOffset;
                }
                //if(entry.NameHash.Equals (fileNameListNameHash))Console.WriteLine("Offset: {0:X10}, UncSize {1:X10}",entry.Offset,entry.UncompressedSize);
                this.Entries.Add(entry);
            }
            if(minDataOffset > dataOffset)
                dataOffset = minDataOffset;

            input.Seek(blockSizeTableOffset, SeekOrigin.Begin);

            var blockSizeTableSize = dataOffset - blockSizeTableOffset;
            var blockSizeTableCount = blockSizeTableSize / 2;
            //ushort aux;
            //Console.WriteLine("dataOffset: {0:X8}\nfileTableOffset: {1:X8}\nBlockSizeTableSize: {2:X8}\nblockSizeTableOffset: {3:X8}", dataOffset,fileTableOffset,blockSizeTableSize,blockSizeTableOffset);
            this.BlockSizes.Clear();
            //Console.WriteLine("initial position: {0:X8}",input.Position);
            //Console.WriteLine("blockSizeTableCount: {0}",blockSizeTableCount);
            for (uint i = 0; i < blockSizeTableCount; i++)
            {
                this.BlockSizes.Add(input.ReadValueU16(endian));
            }
            //Console.WriteLine("final position: {0:X8}",input.Position);
            //Console.WriteLine("number of repetitions: {0}",blockSizeTableCount);
            //var fileNameListNameHash = new FileNameHash(
            //        new byte[] { 0xB5, 0x50, 0x19, 0xCB, 0xF9, 0xD3, 0xDA, 0x65, 0xD5, 0x5B, 0x32, 0x1C, 0x00, 0x19, 0x69, 0x7C, });
        }