public static WwiseIndex Load(Stream input) { if (input == null) { throw new ArgumentNullException("input"); } var magic = input.ReadValueU32(Endian.Little); if (magic != 0x58444957 && magic.Swap() != 0x58444957) { throw new FormatException("invalid magic"); } var endian = magic == 0x58444957 ? Endian.Little : Endian.Big; var version = input.ReadValueU32(endian); if (version != 1) { throw new FormatException("unexpected version"); } var reader = new FileFormats.Unreal.FileReader(input, version, endian); var index = new WwiseIndex(); index.Serialize(reader); return index; }
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; }
public void Deserialize(Stream input) { var magic = input.ReadValueU32(this.LittleEndian); if (magic != 0x54414653) throw new NotSupportedException("Bad magic number"); this.Unknown04 = input.ReadValueU32(this.LittleEndian); this.NumberOfFiles = input.ReadValueU32(this.LittleEndian); var count = input.ReadValueU32(this.LittleEndian); this.Unknown10 = input.ReadValueU32(this.LittleEndian); this.BasePath = input.ReadString(32, true, Encoding.ASCII); this.Entries.Clear(); for (uint i = 0; i < count; i++) { var entry = new Big.EntryV2(); entry.NameHash = input.ReadValueU32(this.LittleEndian); entry.Locale = input.ReadValueU32(this.LittleEndian); entry.Size = input.ReadValueU32(this.LittleEndian); var offset = input.ReadValueU32(this.LittleEndian); entry.Offset = offset & 0xFFFFFF00; entry.File = offset & 0xFF; this.Entries.Add(entry); } }
public void Deserialize(Stream input, Endian endianness) { if (input.Length < 20) { throw new FormatException("bad section header size?"); } var count0 = input.ReadValueU32(endianness); var count1 = input.ReadValueU32(endianness); var count2 = input.ReadValueU32(endianness); var count3 = input.ReadValueU32(endianness); var count4 = input.ReadValueU32(endianness); this.LocalDataResolvers.Clear(); for (uint i = 0; i < count0; i++) { var unknown = new LocalDataResolver(); unknown.Deserialize(input); this.LocalDataResolvers.Add(unknown); } this.RemoteDataResolvers.Clear(); for (uint i = 0; i < count1; i++) { var unknown = new RemoteDataResolver(); unknown.Deserialize(input); this.RemoteDataResolvers.Add(unknown); } this.Unknown2s.Clear(); for (uint i = 0; i < count2; i++) { var unknown = new Unknown2Resolver(); unknown.Deserialize(input); this.Unknown2s.Add(unknown); } this.Unknown3s.Clear(); if (count3 > 0) throw new NotSupportedException(); //for (uint i = 0; i < count3; i++) //{ // var a = input.ReadValueU32(); // this.Unknown3s.Add(a); //} this.Unknown4s.Clear(); for (uint i = 0; i < count4; i++) { var unknown = new Unknown4Resolver(); unknown.Deserialize(input); this.Unknown4s.Add(unknown); } }
public void Deserialize(Stream input) { if (input.ReadValueU32(false) != 0x626D6174) { throw new FormatException(); } uint count = input.ReadValueU32(); this.Unknown0.Clear(); for (uint i = 0; i < count; i++) { var unknown0 = new Subtype1(); unknown0.Deserialize(input); this.Unknown0.Add(unknown0); } }
public void Deserialize(Stream input) { input.Seek(0, SeekOrigin.Begin); var header = input.ReadStructure<SimGroup.FileHeader>(); if (header.HeaderSize < Marshal.SizeOf(header) || header.HeaderSize > input.Length) { throw new FormatException("bad data size"); } uint[] unknown08s = new uint[header.Unknown14Count]; input.Seek(header.Unknown08Offset, SeekOrigin.Begin); for (ushort i = 0; i < header.Unknown14Count; i++) { unknown08s[i] = input.ReadValueU32(); } input.Seek(header.Unknown0COffset, SeekOrigin.Begin); for (ushort i = 0; i < header.Unknown16Count; i++) { } }
public void Deserialize(Stream input) { if (input.ReadValueU32() != 4) { throw new FormatException("unsupported script version"); } }
private static string ReadString(Stream input) { var length = input.ReadValueU32(); if (length >= 1024) { throw new InvalidOperationException(); } return input.ReadString(length, true, Encoding.ASCII); }
public void Deserialize(Stream input) { var fileAlignment = input.ReadValueU32(true); if (fileAlignment != 0x7FF00000 && fileAlignment != 0x0000F07F && fileAlignment != 0x62300000 && fileAlignment != 0x00003062) { throw new FormatException("unexpected file alignment (should have been 0x7FF00000)"); } this.LittleEndian = fileAlignment == 0x7FF00000 || fileAlignment == 0x62300000; this.FileAlignment = this.LittleEndian == true ? fileAlignment : fileAlignment.Swap(); this.BasePath = input.ReadString(64, true, Encoding.ASCII); var count = input.ReadValueU32(this.LittleEndian); var hashes = new uint[count]; for (uint i = 0; i < count; i++) { hashes[i] = input.ReadValueU32(this.LittleEndian); } this.Entries.Clear(); for (uint i = 0; i < count; i++) { var entry = new Big.Entry(); entry.NameHash = hashes[i]; entry.UncompressedSize = input.ReadValueU32(this.LittleEndian); entry.Offset = input.ReadValueU32(this.LittleEndian); entry.Locale = input.ReadValueU32(this.LittleEndian); entry.CompressedSize = input.ReadValueU32(this.LittleEndian); this.Entries.Add(entry); if (entry.CompressedSize != 0) { throw new NotSupportedException(); } } }
private static uint ComputeIncompleteHashOfZip(Stream input, uint hash) { hash = ComputeHashOfFile(input, hash); // get basic zip info input.Seek(-22, SeekOrigin.End); if (input.ReadValueU32() != 0x06054B50) { throw new FormatException(); } input.Seek(8, SeekOrigin.Current); var indexSize = input.ReadValueU32(); var indexOffset = input.ReadValueU32(); input.Seek(indexOffset, SeekOrigin.Begin); hash = ComputeIncompleteHashOfBlock(input, indexSize.Align(BLOCK_SIZE), hash); return(hash); }
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); }
public static void SkipSignature(Stream input) { const Endian endian = Endian.Little; var magic = input.ReadValueU32(endian); if (magic != Signature) { throw new FormatException(); } var unknown0 = input.ReadValueU32(endian); if (unknown0 != 0) { throw new FormatException(); } input.Seek(548, SeekOrigin.Current); // TODO(gibbed): figure this out }
public UInt64 ReadHash(Stream stream) { if (this.HashesArePrecalculated == true) { return(stream.ReadValueU64()); } throw new InvalidOperationException("unsure how to handle this"); // suspected that this is a uint32 + string rather than the hash return(stream.ReadString(stream.ReadValueU32(), Encoding.ASCII).Hash1003F()); }
void IChunk.Deserialize(IChunk parent, Stream input, Endian endian) { var count = input.ReadValueU32(endian); this.Unknown00 = input.ReadValueU32(endian); this.Paths.Clear(); for (uint i = 0; i < count; i++) { var length = input.ReadValueU32(endian); var value = input.ReadString(length); input.Seek(1, SeekOrigin.Current); // skip null var length2 = input.ReadValueU32(endian); var key = input.ReadString(length2); input.Seek(1, SeekOrigin.Current); // skip null this._Paths.Add(key, value); } }
public void Deserialize(ushort version, Stream input, Endian endian) { if (version == 4) { Unk0_V4 = input.ReadValueU32(endian); } this.Name = input.ReadStringU32(endian); this.Unk1 = input.ReadValueU32(endian); if (this.Unk1 != 1) { throw new InvalidOperationException(); } if (version == 4) { Unk2_V4 = input.ReadValueU32(endian); } uint size = input.ReadValueU32(endian); this.Data = input.ReadBytes((int)size); }
public override void Deserialize(Stream input) { this.Name = input.ReadStringAlignedU8(); this.Version = input.ReadValueU32(); this.PositionX = input.ReadValueU32(); this.PositionY = input.ReadValueU32(); this.DimensionX = input.ReadValueU32(); this.DimensionY = input.ReadValueU32(); this.JustificationX = input.ReadValueU32(); this.JustificationY = input.ReadValueU32(); this.Color = input.ReadValueU32(); this.Translucency = input.ReadValueU32(); this.RotationValue = input.ReadValueF32(); this.NumberOfImages = input.ReadValueU32(); this.ImageNames = new string[this.NumberOfImages]; for (uint i = 0; i < this.NumberOfImages; i++) { this.ImageNames[i] = input.ReadStringAlignedU8(); } }
public void Deserialize(Stream input) { uint length = input.ReadValueU32(); if (input.Position + length > input.Length) { throw new InvalidOperationException(); } uint count = input.ReadValueU32(); var memory = input.ReadToMemoryStream(length); this.Entries = new List <Entry>(); for (uint i = 0; i < count; i++) { var entry = new Entry(); entry.Deserialize(memory); this.Entries.Add(entry); } }
public void Deserialize(Stream input) { // ((value & 0x01FFFFFF) >> 0) * 4 = data dest // ((value & 0xFE000000) >> 25) = section type // buffer[pointer] = sections // .Where(s.id == buffer[pointer] && s.type == type) var value = input.ReadValueU32(); this.PointerOffset = (uint)(((value & 0x01FFFFFF) >> 0) * 4); this.SectionType = (byte)((value & 0xFE000000) >> 25); }
public static string ReadStringU32(this Stream stream, bool littleEndian) { var length = stream.ReadValueU32(littleEndian); if (length > 0x3FF) { return("unknown"); //throw new InvalidOperationException(); } return(stream.ReadString(length)); }
public static RawFileEntry Read(Stream input, Endian endian) { RawFileEntry instance; instance.CompressionFlags = input.ReadValueU32(endian); instance.DataUncompressedSize = input.ReadValueU32(endian); instance.DataCompressedSize = input.ReadValueU32(endian); instance.DataOffsetLo = input.ReadValueU32(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 Deserialize(Stream input) { this.Room = input.ReadStringAlignedU8(); this.Drawable = input.ReadStringAlignedU8(); this.VertexCount = input.ReadValueU32(); this.Vertices = new Vector3[this.VertexCount]; for (uint i = 0; i < this.VertexCount; i++) { this.Vertices[i] = new Vector3(input); } }
public static CompressedBlockHeader Read(Stream input, Endian endian) { CompressedBlockHeader instance; instance.UncompressedSize = input.ReadValueU32(endian); instance.Unknown04 = input.ReadValueU32(endian); instance.ChunkSize = input.ReadValueS16(endian); instance.ChunkCount = input.ReadValueS16(endian); instance.Unknown0C = input.ReadValueS16(endian); instance.Unknown0E = input.ReadValueU8(); instance.Unknown0F = input.ReadValueU8(); instance.Chunks = new short[8]; instance.CompressedSize = 0; for (int i = 0; i < 8; ++i) { instance.Chunks[i] = input.ReadValueS16(endian); instance.CompressedSize += (uint)instance.Chunks[i]; } return(instance); }
public static string ReadStringU32(this Stream stream, Endian endian) { var size = stream.ReadValueU32(endian); if (size == 0) { return(""); } return(stream.ReadString(size, true, Encoding.ASCII)); }
public override void Deserialize(Stream input) { this.PlaneAxis = input.ReadValueU8(); this.PlanePosn = input.ReadValueF32(); this.NumSEntities = input.ReadValueU32(); this.NumSPhys = input.ReadValueU32(); this.NumIntersects = input.ReadValueU32(); this.NumDPhys = input.ReadValueU32(); this.NumFences = input.ReadValueU32(); this.NumRoads = input.ReadValueU32(); this.NumPaths = input.ReadValueU32(); this.NumAnims = input.ReadValueU32(); }
public void Deserialize(Stream input) { var magic = input.ReadValueU32(Endian.Little); if (magic != Signature && magic.Swap() != Signature) { throw new FormatException(); } var endian = magic == Signature ? Endian.Little : Endian.Big; var unk04 = input.ReadValueU16(endian); var unk06 = input.ReadValueU16(endian); if (unk04 != 2 || unk06 != 1) { throw new FormatException(); } var alignment = input.ReadValueU32(endian); if (alignment != 0x800) { throw new FormatException(); } var entries = new List <EntryInfo>(); while (input.Position + 12 <= input.Length) { var nameHash = input.ReadValueU32(endian); var offset = input.ReadValueU32(endian); var size = input.ReadValueU32(endian); entries.Add(new EntryInfo(nameHash, offset, size)); } this._Endian = endian; this._Alignment = alignment; this._Entries.Clear(); this._Entries.AddRange(entries); }
public void Read(Stream r) { HashPart1 = r.ReadValueU32(); HashPart2 = r.ReadValueU32(); HashComplete = ((ulong)HashPart2 << 32 | (ulong)HashPart1); int length = r.ReadValueS32(); byte[] bytes = r.ReadBytes(length); Name = Encoding.ASCII.GetString(bytes); alpha1 = r.ReadValueU8(); alpha2 = r.ReadValueU8(); unk3 = r.ReadValueS32(); unk4 = r.ReadValueU8(); this.unk5 = r.ReadValueS32(); unk6 = r.ReadValueS32(); UnkHash = r.ReadValueS32(); // mafia 3 ShaderHash = r.ReadValueU64(); AdaptHash = r.ReadValueU32(); int count = r.ReadValueS32(); Parameters = new ShaderParameter[count]; for (int i = 0; i < count; i++) { Parameters[i] = new ShaderParameter(r); } count = r.ReadValueS32(); Samplers = new ShaderParameterSampler[count]; for (int j = 0; j < count; j++) { Samplers[j] = new ShaderParameterSampler(r); } count = r.ReadValueS32(); for (int j = 0; j < count; j++) { var fourcc = Encoding.ASCII.GetString(r.ReadBytes(4)); var unk5 = r.ReadBytes(12); } }
public void Deserialize(Stream input, Endian endian) { long basePosition = input.Position; if (input.ReadValueU32(endian) != 0) { throw new FormatException(); } var totalSize = input.ReadValueU32(endian); if (basePosition + totalSize > input.Length) { throw new FormatException(); } var unknown08 = input.ReadValueU16(endian); // probably frame count? var unknown0A = input.ReadValueU16(endian); // probably header size var unknown0C = input.ReadValueU32(endian); // probably version if (unknown08 != 1 || unknown0A != 16 || unknown0C != 3) { throw new FormatException(); } if (input.Position > basePosition + totalSize) { throw new FormatException(); } var dataSize = input.ReadValueS32(); input.Seek(-4, SeekOrigin.Current); if (dataSize < 4 || input.Position + dataSize > basePosition + totalSize) { throw new FormatException(); } this.Sprite = FileFormats.Sprite.Sprite.Read(input, endian); }
public void Deserialize(Stream input) { var version = input.ReadValueU32(Endian.Little); if (version != Version && version.Swap() != Version) { throw new FormatException("unsupported file version"); } var endian = version == Version ? Endian.Little : Endian.Big; var magic = input.ReadValueU32(endian); if (magic != Signature) { throw new FormatException("bad magic"); } this.Endian = endian; this.Header = new CustomMapGameFileHeader(); this.Header.Deserialize(input, endian); this.Snapshot = new Snapshot(); this.Snapshot.Deserialize(input, endian); /* PS3 map files have an extra snapshot which has a larger resolution, * need to figure out how to adequately detect this (and get a sample * of a 360 map file. */ if (endian == Endian.Big) { this.ExtraSnapshot = new Snapshot(); this.ExtraSnapshot.Deserialize(input, endian); } this.Data = new CustomMap.Data(); this.Data.Deserialize(input, endian); this.Archive = new CustomMap.Archive(); this.Archive.Deserialize(input, endian); }
public void Deserialize(Stream input) { // header if (input.ReadValueU8() != 0) { throw new Exception(); } input.Seek(3, SeekOrigin.Current); input.Seek(4, SeekOrigin.Current); if (input.ReadString(8, true, Encoding.ASCII) != "AnarkBGF") { throw new FormatException("invalid header tag"); } if (input.ReadValueU32() != 1) { throw new FormatException("invalid header version"); } input.Seek(4, SeekOrigin.Current); uint idSize = input.ReadValueU8(); input.Seek(7, SeekOrigin.Current); if (idSize != 4) { throw new FormatException("don't know how to handle this id size"); } // blocks uint size = input.ReadValueU32(); uint count = input.ReadValueU32(); for (uint i = 0; i < count; i++) { var block = new Block(); block.Deserialize(input); } }
public void Deserialize(Stream input, ushort version, Endian endian) { this.Name = input.ReadStringU16(0x40, Encoding.ASCII, endian); this.Type = input.ReadValueU8(); this.Flags = (ContainerFlags)input.ReadValueU16(endian); var primitiveCount = input.ReadValueU16(endian); this.DataOffset = input.ReadValueU32(endian); this.Parent = version >= 10 ? input.ReadStringU16(0x40, Encoding.ASCII, endian) : ""; var extraLength = input.ReadValueU32(endian); this.Extra = input.ReadBytes(extraLength); var oldSize = version >= 9 ? 0 : input.ReadValueU32(endian); this.CompressedSize = input.ReadValueU32(endian); this.Sizes.Clear(); if ((this.Flags & ContainerFlags.Unknown7) != 0 || version >= 11) { var sizeCount = version >= 9 ? primitiveCount : (oldSize / 4); for (uint i = 0; i < sizeCount; i++) { var size = new PrimitiveSize(); size.CPUSize = version >= 9 ? input.ReadValueS32(endian) : -1; size.GPUSize = input.ReadValueS32(endian); this.Sizes.Add(size); } } this.Primitives.Clear(); for (ushort i = 0; i < primitiveCount; i++) { var primitive = new PrimitiveEntry(); primitive.Deserialize(input, endian); this.Primitives.Add(primitive); } }
public const uint Signature = 0xFF443350; // 'P3D\xFF' public void Deserialize(Stream input) { var start = input.Position; var magic = input.ReadValueU32(Endian.Little); if (magic != Signature && magic.Swap() != Signature) { throw new FormatException("not a Pure3D file"); } var endian = magic == Signature ? Endian.Little : Endian.Big; var headerSize = input.ReadValueU32(endian); if (headerSize != 12) { throw new FormatException("invalid header size"); } var totalSize = input.ReadValueU32(endian); if (start + totalSize > input.Length) { throw new FormatException(); } var end = start + totalSize; this.Nodes.Clear(); while (input.Position < end) { this.Nodes.Add(DeserializeNode(input, endian, null)); } if (input.Position != end) { throw new FormatException(); } this.Endian = endian; }
private void Deserialize(Stream input, Endian endian) { var version = input.ReadValueU32(endian); if (version != _Version) { throw new SaveCorruptionException("bad stats version"); } var length = input.ReadValueU32(endian); var end = input.Position + length; if (end > input.Length) { throw new SaveCorruptionException("not enough data for stats"); } this.Stats.Clear(); var count = input.ReadValueU16(endian); for (int i = 0; i < count; i++) { var id = input.ReadValueU16(endian); var type1 = (DataType)input.ReadValueU8(); var value1 = ReadData(input, type1, endian); var type2 = (DataType)input.ReadValueU8(); var value2 = ReadData(input, type2, endian); this.Stats.Add(new PlayerStat() { Id = id, Value1 = value1, Value2 = value2, }); } if (input.Position != end) { throw new SaveCorruptionException("did not consume all stats data"); } }
public void Deserialize(Stream input) { input.ReadValueU32(false); input.ReadValueU32(true); input.ReadValueU32(true); input.ReadValueU32(true); input.ReadValueU32(true); input.ReadValueU32(true); input.ReadValueU32(true); }
public void Deserialize(Stream input) { this.Version = input.ReadValueU32(); if (this.Version < 1 || this.Version > 2) { throw new FormatException("unsupported blob version"); } var nameLength = this.Version == 2 ? 32u : 14u; var count = input.ReadValueU32(); this.Entries = new List<Entry>(); for (uint i = 0; i < count; i++) { var entry = new Entry(); entry.Name = input.ReadString(nameLength, true); entry.Offset = input.ReadValueU32(); entry.Size = input.ReadValueU32(); this.Entries.Add(entry); } }
public void Deserialize(IBlock parent, Stream input, Endian endian) { var count = input.ReadValueU32(endian); this.Unknown.Clear(); for (uint i = 0; i < count; i++) { var data = new byte[52]; input.Read(data, 0, data.Length); this.Unknown.Add(data); } }
public void Deserialize(DataStorage.FileHeader header, Stream input) { uint count = input.ReadValueU32(); this.Tables.Clear(); for (uint i = 0; i < count; i++) { var table = new TableData(); table.Deserialize(header, input); this.Tables.Add(table); } }
public void Deserialize(Stream input, Endian endian) { this.UndeformedDiffuseTexture = input.ReadStringU32(endian); this.UndeformedNormalMap = input.ReadStringU32(endian); this.UndeformedPropertiesMap = input.ReadStringU32(endian); this.DeformedDiffuseTexture = input.ReadStringU32(endian); this.DeformedNormalMap = input.ReadStringU32(endian); this.DeformedPropertiesMap = input.ReadStringU32(endian); this.NormalMapEx3 = input.ReadStringU32(endian); this.ShadowMapTexture = input.ReadStringU32(endian); this.Unknown8 = input.ReadValueU32(endian); }
public override void Deserialize(Stream input) { this.Name = input.ReadStringAlignedU8(); this.Version = input.ReadValueU32(); this.FOV = input.ReadValueF32(); this.AspectRatio = input.ReadValueF32(); this.NearClip = input.ReadValueF32(); this.FarClip = input.ReadValueF32(); this.Position = new Vector3(input); this.Look = new Vector3(input); this.Up = new Vector3(input); }
public void Deserialize(ushort version, Stream input, Endian endian) { uint count = input.ReadValueU32(endian); this.Tables.Clear(); for (uint i = 0; i < count; i++) { var table = new TableData(); table.Deserialize(version, input, endian); this.Tables.Add(table); } }
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"); }
public void Deserialize(Stream input) { this.Version = input.ReadValueU32(); if (this.Version < 1 || this.Version > 2) { throw new FormatException("unsupported blob version"); } var nameLength = this.Version == 2 ? 32u : 14u; var count = input.ReadValueU32(); this.Entries = new List<Entry>(); for (uint i = 0; i < count; i++) { // ReSharper disable UseObjectOrCollectionInitializer var entry = new Entry(); // ReSharper restore UseObjectOrCollectionInitializer entry.Name = input.ReadString(nameLength, true); entry.Offset = input.ReadValueU32(); entry.Size = input.ReadValueU32(); this.Entries.Add(entry); } }
void LoadME3save(Stream file) { if (file != null) { if (file.ReadValueU32(Endian.Big) == 0x434F4E20) { return; } file.Seek(-4, SeekOrigin.Current); try { me3Save = Gibbed.MassEffect3.FileFormats.SFXSaveGameFile.Read(file); } catch (Exception) { return; } } }
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(); } }
public void Deserialize(Stream input) { input.Seek(0, SeekOrigin.Begin); var magic = input.ReadValueU32(false); if (magic != 0x42494748) // BIGH { throw new FormatException("unknown magic"); } this.TotalFileSize = input.ReadValueU32(true); // :wtc: uint fileCount = input.ReadValueU32(false); uint headerSize = input.ReadValueU32(false); this.Entries.Clear(); var duplicateNames = new List<uint>(); for (uint i = 0; i < fileCount; i++) { var entry = new Entry(); entry.Offset = input.ReadValueU32(false); entry.Size = input.ReadValueU32(false); entry.Name = input.ReadValueU32(false); if (duplicateNames.Contains(entry.Name) == true) { entry.Duplicate = true; } else { entry.Duplicate = false; duplicateNames.Add(entry.Name); } this.Entries.Add(entry); } }
/// <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) { this.Unknown0 = input.ReadValueU32(); this.Unknown1 = input.ReadValueU32(); this.Unknown2 = input.ReadValueU32(); }
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, }); }
public void Deserialize(Stream input, Endian endian) { this.Size = input.ReadValueU32(endian); this.Flags = input.ReadValueEnum<PixelFormatFlags>(endian); this.FourCC = input.ReadValueU32(endian); this.RGBBitCount = input.ReadValueU32(endian); this.RedBitMask = input.ReadValueU32(endian); this.GreenBitMask = input.ReadValueU32(endian); this.BlueBitMask = input.ReadValueU32(endian); this.AlphaBitMask = input.ReadValueU32(endian); }
public void Deserialize(Stream input) { // ((value & 0xFFFFFFFF00000000) >> 32) = pointer offset // ((value & 0x00000000FFFFFFFF) >> 0) = data offset // buffer[pointer] = &buffer[data] this.PointerOffset = input.ReadValueU32(); this.DataOffset = input.ReadValueU32(); }
private void showVpxyFile(Stream vpxyStream) { showRcolHeader(vpxyStream); string vpxyString = vpxyStream.ReadStringASCII(4); uint vpxyVersion = vpxyStream.ReadValueU32(); uint tailOffset = vpxyStream.ReadValueU32(); uint tailSize = vpxyStream.ReadValueU32(); vpxyStream.Seek(tailOffset - 4, SeekOrigin.Current); uint numTGIs = vpxyStream.ReadValueU32(); for (int i = 0; i < numTGIs; i++) { ListViewItem loditem = new ListViewItem(); loditem.Text = "TGI #" + i.ToString(); uint lodTypeId = vpxyStream.ReadValueU32(); uint lodGroupId = vpxyStream.ReadValueU32(); ulong lodInstanceId = vpxyStream.ReadValueU64(); loditem.SubItems.Add("key:" + lodTypeId.ToString("X8") + ":" + lodGroupId.ToString("X8") + ":" + lodInstanceId.ToString("X16")); if (isLocalFile(new ResourceKey(lodInstanceId, lodTypeId, lodGroupId))) { loditem.SubItems.Add("*"); } listView2.Items.Add(loditem); } }
public bool Load(Stream input) { if (this._IsLoaded == true) { return true; } input.Seek(this.CompressedOffset, SeekOrigin.Begin); if (input.ReadValueU32() != 0x9E2A83C1) { throw new FormatException("bad block magic"); } this._SegmentSize = input.ReadValueU32(); /*uint compressedSize = */ input.ReadValueU32(); uint uncompressedSize = input.ReadValueU32(); if (uncompressedSize != this.UncompressedSize) { throw new InvalidOperationException(); } uint count = ((uncompressedSize + this._SegmentSize) - 1) / this._SegmentSize; uint segmentOffset = (4 * 4) + (count * 8); for (uint i = 0; i < count; i++) { // ReSharper disable UseObjectOrCollectionInitializer var segment = new Segment(); // ReSharper restore UseObjectOrCollectionInitializer segment.CompressedSize = input.ReadValueU32(); segment.UncompressedSize = input.ReadValueU32(); segment.Offset = segmentOffset; this._Segments.Add(segment); segmentOffset += segment.CompressedSize; } this._IsLoaded = true; return true; }
public void Deserialize(Stream input) { input.Seek(-4, SeekOrigin.End); // read strings var stringTableOffset = input.ReadValueU32(); input.Seek(stringTableOffset, SeekOrigin.Begin); var stringCount = input.ReadValueU32(); Strings = new Script.RawString[stringCount]; for (int i = 0; i < Strings.Length; i++) { var stringEntry = new Script.RawString(); stringEntry.Value = input.ReadEncodedString(); stringEntry.IsName = input.ReadValueB8(); Strings[i] = stringEntry; } input.Seek(0, SeekOrigin.Begin); // now the script data this.Unknown0 = input.ReadEncodedString(); this.TimeStamp = DateTime.FromFileTime(input.ReadValueS64()); this.Unknown2 = input.ReadEncodedString(); var typeDefCount = input.ReadValueU32(); var funcDefCount = input.ReadValueU32(); var rawTypeDefs = new Script.RawTypeDefinition[typeDefCount]; TypeDefs = new Script.TypeDefinition[typeDefCount]; for (uint i = 0; i < typeDefCount; i++) { var rawTypeDef = new Script.RawTypeDefinition(); rawTypeDef.Name = Strings[input.ReadValueEncodedS32()].Value; rawTypeDef.Type = (Script.NativeType)input.ReadValueEncodedS32(); rawTypeDef.NativePropertyCount = input.ReadValueEncodedS32(); rawTypeDef.ScriptedPropertyCount = input.ReadValueEncodedS32(); rawTypeDef.Flags = (Script.TypeDefinitionFlags)input.ReadValueEncodedS32(); Script.TypeDefinition typeDef = null; switch (rawTypeDef.Type) { case Script.NativeType.Simple: { if (rawTypeDef.NativePropertyCount > 0 || rawTypeDef.ScriptedPropertyCount > 0) { throw new FormatException(); } typeDef = new Script.SimpleDefinition() { Name = rawTypeDef.Name, Flags = rawTypeDef.Flags, }; break; } case Script.NativeType.Enum: { if (rawTypeDef.NativePropertyCount > 0 || rawTypeDef.ScriptedPropertyCount > 0) { throw new FormatException(); } typeDef = new Script.EnumDefinition() { Name = rawTypeDef.Name, Flags = rawTypeDef.Flags, }; break; } case Script.NativeType.Class: { typeDef = new Script.ClassDefinition() { Name = rawTypeDef.Name, Flags = rawTypeDef.Flags, }; break; } case Script.NativeType.Array: { if (rawTypeDef.NativePropertyCount > 0 || rawTypeDef.ScriptedPropertyCount > 0) { throw new FormatException(); } typeDef = new Script.ArrayDefinition() { Name = rawTypeDef.Name, Flags = rawTypeDef.Flags, }; break; } case Script.NativeType.Pointer: { if (rawTypeDef.NativePropertyCount > 0 || rawTypeDef.ScriptedPropertyCount > 0) { throw new FormatException(); } typeDef = new Script.PointerDefinition() { Name = rawTypeDef.Name, Flags = rawTypeDef.Flags, }; break; } case Script.NativeType.Handle: { if (rawTypeDef.NativePropertyCount > 0 || rawTypeDef.ScriptedPropertyCount > 0) { throw new FormatException(); } typeDef = new Script.HandleDefinition() { Name = rawTypeDef.Name, Flags = rawTypeDef.Flags, }; break; } case Script.NativeType.SoftHandle: { if (rawTypeDef.NativePropertyCount > 0 || rawTypeDef.ScriptedPropertyCount > 0) { throw new FormatException(); } typeDef = new Script.SoftHandleDefinition() { Name = rawTypeDef.Name, Flags = rawTypeDef.Flags, }; break; } case Script.NativeType.BitField: { if (rawTypeDef.NativePropertyCount > 0 || rawTypeDef.ScriptedPropertyCount > 0) { throw new FormatException(); } typeDef = new Script.BitFieldDefinition() { Name = rawTypeDef.Name, Flags = rawTypeDef.Flags, }; break; } default: { throw new FormatException(); } } rawTypeDefs[i] = rawTypeDef; if (typeDef == null) { throw new FormatException(); } TypeDefs[i] = typeDef; } _rawFuncDefs = new Script.RawFunctionDefinition[funcDefCount]; FuncDefs = new Script.FunctionDefinition[funcDefCount]; for (uint i = 0; i < funcDefCount; i++) { var rawFuncDef = new Script.RawFunctionDefinition(); rawFuncDef.Name = Strings[input.ReadValueEncodedS32()].Value; rawFuncDef.DefinedOnId = input.ReadValueEncodedS32(); rawFuncDef.Flags = input.ReadValueEncodedS32(); var funcDef = new Script.FunctionDefinition(); funcDef.Name = rawFuncDef.Name; if (rawFuncDef.DefinedOnId != 0) { var typeDef = TypeDefs[rawFuncDef.DefinedOnId] as Script.ClassDefinition; if (typeDef == null) throw new FormatException("expected ClassDefinition, found " + TypeDefs[rawFuncDef.DefinedOnId]); typeDef.Functions[funcDef.Name] = funcDef; funcDef.ContainingClass = typeDef; } _rawFuncDefs[i] = rawFuncDef; FuncDefs[i] = funcDef; } // parse enums for (int i = 0; i < rawTypeDefs.Length; i++) { var rawTypeDef = rawTypeDefs[i]; if (rawTypeDef.Type != Script.NativeType.Enum) { continue; } else if ((rawTypeDef.Flags & Script.TypeDefinitionFlags.Scripted) == 0) { continue; } var type = (Script.NativeType)input.ReadValueEncodedS32(); if (rawTypeDef.Type != type) { throw new FormatException(); } var id = input.ReadValueEncodedS32(); if (id != i) { throw new FormatException(); } var typeDef = (Script.EnumDefinition)TypeDefs[i]; typeDef.Unknown0 = input.ReadValueEncodedS32(); var constantCount = input.ReadValueEncodedS32(); typeDef.Constants.Clear(); for (int j = 0; j < constantCount; j++) { var constantName = Strings[input.ReadValueEncodedS32()].Value; var constantValue = input.ReadValueEncodedS32(); typeDef.Constants.Add(new EnumDefinition.Constant(constantName, constantValue)); } } // parse classes for (int i = 0; i < rawTypeDefs.Length; i++) { ParseClass(input, rawTypeDefs, i); } // parse class defaults for (int i = 0; i < rawTypeDefs.Length; i++) { var rawTypeDef = rawTypeDefs[i]; if (rawTypeDef.Type != Script.NativeType.Class) { continue; } else if ((rawTypeDef.Flags & Script.TypeDefinitionFlags.Scripted) == 0) { continue; } var id = input.ReadValueEncodedS32(); if (id != i) { throw new FormatException(); } var typeDef = (Script.ClassDefinition)TypeDefs[i]; var defaultCount = input.ReadValueEncodedS32(); for (int j = 0; j < defaultCount; j++) { var propName = Strings[input.ReadValueEncodedS32()].Value; var dataType = input.ReadValueEncodedS32(); if (dataType == 0 || dataType == 1) { var typeName = input.ReadEncodedString(); var typeDataSize = input.ReadValueU32(); // size + 4 var typeData = new byte[typeDataSize - 4]; input.Read(typeData, 0, typeData.Length); typeDef.Defaults.Add(propName, new Script.PropertyDefault() { TypeName = typeName, Data = typeData, }); } else { throw new FormatException(); } } } // parse functions (awww yeah) for (int i = 0; i < _rawFuncDefs.Length; i++) { ParseFunction(input, i); } }
public static SFXSaveGameFile Read(Stream input) { if (input == null) { throw new ArgumentNullException("input"); } var save = new SFXSaveGameFile() { _Version = input.ReadValueU32(Endian.Little) }; if (save._Version != 29 && save._Version.Swap() != 29 && save._Version != 59 && save._Version.Swap() != 59) { throw new FormatException("unexpected version"); } var endian = save._Version == 29 || save._Version == 59 ? Endian.Little : Endian.Big; if (endian == Endian.Big) { save._Version = save._Version.Swap(); } var reader = new Unreal.FileReader(input, save._Version, endian); save.Serialize(reader); if (save._Version >= 27) { if (input.Position != input.Length - 4) { throw new FormatException("bad checksum position"); } save._Checksum = input.ReadValueU32(); } if (input.Position != input.Length) { throw new FormatException("did not consume entire file"); } save.Endian = endian; return save; }
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; }
/// <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; }
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); } }
private List<uint> showRcolHeader(Stream input) { List<uint> chunkPositions = new List<uint>(); addListItem("Start RCOL header", ""); input.ReadValueU32(); input.ReadValueU32(); uint rcolIndex3 = input.ReadValueU32(); uint rcolIndex1 = input.ReadValueU32(); uint rcolIndex2 = input.ReadValueU32(); for (int i = 0; i < rcolIndex2; i++) { ulong instanceId = input.ReadValueU64(); uint typeId = input.ReadValueU32(); uint groupId = input.ReadValueU32(); addListItem("Internal IGT #" + (i + 1).ToString(), "key:" + typeId.ToString("X8") + ":" + groupId.ToString("X8") + ":" + instanceId.ToString("X16")); } for (int i = 0; i < rcolIndex1; i++) { ulong instanceId = input.ReadValueU64(); uint typeId = input.ReadValueU32(); uint groupId = input.ReadValueU32(); addListItem("External IGT #" + (i + 1).ToString(), "key:" + typeId.ToString("X8") + ":" + groupId.ToString("X8") + ":" + instanceId.ToString("X16")); } for (int i = 0; i < rcolIndex2; i++) { uint chunkPos = input.ReadValueU32(); uint chunkSize = input.ReadValueU32(); addListItem("Chunk " + (i + 1).ToString(), "Pos: " + chunkPos.ToString() + " Size: " + chunkSize.ToString()); chunkPositions.Add(chunkPos); } addListItem("End RCOL header", ""); return chunkPositions; }
public void Deserialize(Stream input, Endian endianness) { this.DataSize = input.ReadValueU32(endianness); var type = input.ReadValueU8(); if (ValidSectionTypes.ContainsKey(type) == false) { throw new FormatException("unknown section type"); } this.Type = (SectionType)type; this.Unknown05 = input.ReadValueU8(); this.Unknown06 = input.ReadValueU16(endianness); this.Flags = input.ReadValueU32(endianness); this.Id = input.ReadValueU32(endianness); this.Unknown10 = input.ReadValueU32(endianness); }
public void Deserialize(Stream input) { this.Unknown0 = ReadString(input); this.Unknown1 = ReadString(input); uint count = input.ReadValueU32(); this.Unknown2.Clear(); for (uint i = 0; i < count; i++) { var unknown2 = new Subtype2(); unknown2.Deserialize(input); this.Unknown2.Add(unknown2); } }