public Packfile(Stream stream, bool isStr2) { IsStr2 = isStr2; stream.Seek(0, SeekOrigin.Begin); FileData = stream.ReadStruct<PackfileFileData>(); m_Files = new List<IPackfileEntry>(); uint runningPosition = 0; List<PackfileEntryFileData> entryFileData = new List<PackfileEntryFileData>(); for (int i = 0; i < FileData.NumFiles; i++) { PackfileEntryFileData data = stream.ReadStruct<PackfileEntryFileData>(); if (IsCondensed && IsCompressed) { data.Flags = 0; data.Start = runningPosition; runningPosition += data.Size; } else if (IsCondensed) { data.Start = runningPosition; runningPosition += data.Size.Align(16); } entryFileData.Add(data); } for (int i = 0; i < FileData.NumFiles; i++) { stream.Align(2); string filename = stream.ReadAsciiNullTerminatedString(); stream.Seek(1, SeekOrigin.Current); m_Files.Add(new PackfileEntry(this, entryFileData[i], filename)); stream.Align(2); } if (IsCondensed && IsCompressed) { DataOffset = 0; byte[] compressedData = new byte[FileData.CompressedDataSize]; stream.Read(compressedData, 0, (int)FileData.CompressedDataSize); using (MemoryStream tempStream = new MemoryStream(compressedData)) { using (Stream s = new ZlibStream(tempStream, CompressionMode.Decompress, true)) { byte[] uncompressedData = new byte[FileData.DataSize]; s.Read(uncompressedData, 0, (int)FileData.DataSize); DataStream = new MemoryStream(uncompressedData); } } } else { DataStream = stream; DataOffset = stream.Position; } }
/// <summary> /// Copies the paths from the Index into the given stream at the current address /// note: Creates the table on an align(512) address then creates the table-index on /// an align(512) address following it. /// </summary> /// <param name="outputStream">The stream to write to</param> /// <returns>PathInfoStruct containing addresses/info of the paths table & index</returns> private PathsInfoStruct GeneratePathsTable(Stream outputStream) { var info = new PathsInfoStruct( ); // extract the paths from the index and copy them into a local list object. var paths = Index.Select(x => x.Path).ToList( ); info.PathCount = paths.Count; info.PathTableAddress = outputStream.Align(512); // pad the stream to align(512) and assign the new address to PathTableAddress. GenerateStringEntries(outputStream, paths); // Write the paths into the stream and subtract the PathTableAddress from the new stream position // to get the PathTableLength. info.PathTableLength = ( int )outputStream.Position - info.PathTableAddress; // pad the stream to align(512) and assign the new address to PathIndexAddress. info.PathIndexAddress = outputStream.Align(512); // write the index for the path table GenerateTableIndex(outputStream, paths); // finish on the next 512 alignment boundary outputStream.Align(512); Padding.AssertIsAligned(512, outputStream); // return the struct that contains the information about where in the stream this // resource was written return(info); }
private void CopyMeta(Stream outputStream, int address, out int metaDataSize) { var startAddress = outputStream.Align(512); var buffer = new VirtualStream(address); for (var i = 0; i < Index.Count; ++i) { var datum = Index[i]; if (datum.Class == TagClass.Sbsp || datum.Class == TagClass.Ltmp) { datum.Length = 0; datum.VirtualAddress = 0; Index.Update(datum.Identifier, datum); continue; } var data = Deserialize(datum.Identifier); var dataAddress = ( int )buffer.Position; Padding.AssertIsAligned(4, buffer); buffer.Write(data); buffer.Align( ); var length = ( int )buffer.Position - dataAddress; datum.Length = length; datum.VirtualAddress = dataAddress; Index.Update(datum.Identifier, datum); } buffer.Position = 0; buffer.BufferedCopyBytesTo(( int )buffer.Length, outputStream); metaDataSize = outputStream.Align(4096) - startAddress; }
public Packfile(Stream stream, bool isStr2) { IsStr2 = isStr2; stream.Seek(0, SeekOrigin.Begin); FileData = stream.ReadStruct <PackfileFileData>(); m_Files = new List <IPackfileEntry>(); uint runningPosition = 0; List <PackfileEntryFileData> entryFileData = new List <PackfileEntryFileData>(); for (int i = 0; i < FileData.NumFiles; i++) { PackfileEntryFileData data = stream.ReadStruct <PackfileEntryFileData>(); if (IsCondensed && IsCompressed) { data.Flags = 0; data.Start = runningPosition; runningPosition += data.Size; } else if (IsCondensed) { data.Start = runningPosition; runningPosition += data.Size.Align(16); } entryFileData.Add(data); } for (int i = 0; i < FileData.NumFiles; i++) { stream.Align(2); string filename = stream.ReadAsciiNullTerminatedString(); stream.Seek(1, SeekOrigin.Current); m_Files.Add(new PackfileEntry(this, entryFileData[i], filename)); stream.Align(2); } if (IsCondensed && IsCompressed) { DataOffset = 0; byte[] compressedData = new byte[FileData.CompressedDataSize]; stream.Read(compressedData, 0, (int)FileData.CompressedDataSize); using (MemoryStream tempStream = new MemoryStream(compressedData)) { using (Stream s = new ZlibStream(tempStream, CompressionMode.Decompress, true)) { byte[] uncompressedData = new byte[FileData.DataSize]; s.Read(uncompressedData, 0, (int)FileData.DataSize); DataStream = new MemoryStream(uncompressedData); } } } else { DataStream = stream; DataOffset = stream.Position; } }
public void Save(Stream outStream) { TagGroupHeader header = new TagGroupHeader { AbideTag = "atag", GroupTag = TagGroup.Tag, TagResourceCount = (uint)resources.Count, }; using (BinaryWriter writer = new BinaryWriter(outStream)) using (BinaryReader reader = new BinaryReader(outStream)) { outStream.Seek(TagGroupHeader.Size, SeekOrigin.Current); // skip header TagGroup.Write(writer); if (resources.Count > 0) { header.RawOffsetsOffset = (uint)outStream.Align(512); foreach (int offset in resources.Keys) { writer.Write(offset); } header.RawLengthsOffset = (uint)outStream.Align(512); foreach (byte[] resource in resources.Values) { writer.Write(resource.Length); } header.RawDataOffset = (uint)outStream.Align(512); foreach (byte[] datum in resources.Values) { writer.Write(datum); } } int count = (int)(outStream.Align(16) - TagGroupHeader.Size) / 4; outStream.Seek(TagGroupHeader.Size, SeekOrigin.Begin); for (int i = 0; i < count; i++) { header.Checksum ^= reader.ReadUInt32(); } outStream.Seek(0, SeekOrigin.Begin); writer.Write(header); } }
public ClaimsSetMetadata(byte[] data) : base(data) { ClaimSetSize = Stream.ReadInt(); Stream.Seek(4); CompressionFormat = (CompressionFormat)Stream.ReadInt(); UncompressedClaimSetSize = Stream.ReadInt(); ReservedType = Stream.ReadShort(); ReservedFieldSize = Stream.ReadInt(); Stream.Align(8); var size = Stream.ReadInt(); if (size != ClaimSetSize) { throw new InvalidDataException($"Data length {size} doesn't match expected ClaimSetSize {ClaimSetSize}"); } var claimSet = Stream.Read(ClaimSetSize); if (CompressionFormat != CompressionFormat.COMPRESSION_FORMAT_NONE) { claimSet = Compressions.Decompress(claimSet, UncompressedClaimSetSize, CompressionFormat); } ClaimsSet = new ClaimsSet(claimSet); ReservedField = Stream.Read(ReservedFieldSize); }
public static void Write(this Stream stream, ref POF POF, int ID) { POF.Offsets.Sort(); long CurrentPOFOffset = 0; long POFOffset = 0; byte BitShift = (byte)(2 + POF.Type); int Max1 = (0x00FF >> BitShift) << BitShift; int Max2 = (0xFFFF >> BitShift) << BitShift; POF.Length = 5 + ID; for (int i = 0; i < POF.Offsets.Count; i++) { POFOffset = POF.Offsets[i] - CurrentPOFOffset; CurrentPOFOffset = POF.Offsets[i]; if (POFOffset <= Max1) { POF.Length += 1; } else if (POFOffset <= Max2) { POF.Length += 2; } else { POF.Length += 4; } POF.Offsets[i] = POFOffset; } long POFLengthAling = POF.Length.Align(16); POF.Header = new Header { DataSize = (int)POFLengthAling, ID = ID, Format = Main.Format.F2LE, Length = 0x20, SectionSize = (int)POFLengthAling, Signature = 0x30464F50 }; POF.Header.Signature += POF.Type << 24; stream.Write(POF.Header); stream.Write(POF.Length); for (int i = 0; i < POF.Offsets.Count; i++) { POFOffset = POF.Offsets[i]; if (POFOffset <= Max1) { stream.Write(( byte)((1 << 6) | (POFOffset >> BitShift))); } else if (POFOffset <= Max2) { stream.WriteEndian((ushort)((2 << 14) | (POFOffset >> BitShift)), true); } else { stream.WriteEndian(( uint)((3 << 30) | (POFOffset >> BitShift)), true); } } stream.Write(0x00); stream.Align(16, true); stream.WriteEOFC(ID); }
private StringsInfoStruct GenerateStringsTable(Stream outputStream) { var info = new StringsInfoStruct { StringCount = Strings.Length, Strings128TableAddress = outputStream.Align(512) }; GenerateStrings128(outputStream); info.StringIndexAddress = outputStream.Align(512); GenerateTableIndex(outputStream, Strings); info.StringTableAddress = outputStream.Align(512); GenerateStringEntries(outputStream, Strings); info.StringTableLength = ( int )outputStream.Position - info.StringTableAddress; outputStream.Align(512); return(info); }
public ClaimEntry(NdrBinaryReader stream) : base(stream) { Stream.Seek(4); Type = (ClaimType)Stream.ReadShort(); Stream.Align(4); Count = Stream.ReadUnsignedInt(); Stream.Seek(4); }
public ClaimsSet(byte[] claims) : base(claims) { Count = Stream.ReadInt(); Stream.Seek(4); ReservedType = Stream.ReadShort(); ReservedFieldSize = Stream.ReadInt(); ReservedField = Stream.Read(ReservedFieldSize); Stream.Align(8); ClaimsArray = ReadClaimsArray(Stream); }
/// <summary> /// Copys all the strings from the cache into 128 byte blocks into outputStream. /// note: will pad to align(512) before and after the table /// </summary> /// <param name="outputStream">stream to copy strings into</param> private void GenerateStrings128(Stream outputStream) { outputStream.Align(512); var buffer = new byte[128]; foreach (var value in Strings) { // zero out the buffer, the convert the string into ASII encoding and get the bytes, // compute the length truncated to the length of the buffer to avoid overrunning the buffer // finally copy the string bytes into the buffer Array.Clear(buffer, 0, buffer.Length); var sourceArray = Encoding.ASCII.GetBytes(value); var length = Math.Min(sourceArray.Length, buffer.Length); Array.Copy(sourceArray, buffer, length); outputStream.Write(buffer, 0, buffer.Length); } }
public void Save(Stream s) { s.WriteStruct(Header); foreach (SimulatedNodeInfo sni in Nodes) { s.WriteStruct(sni); } foreach (SimulatedNodeLinkInfo snli in NodeLinks) { s.WriteStruct(snli); } foreach (ClothSimCollisionPrimitiveInfo cscpi in CollisionPrimitives) { s.WriteStruct(cscpi); } s.Align(8); foreach (ClothSimRopeInfo csri in Ropes) { s.WriteStruct(csri); } for (int i = 0; i < Header.NumRopes; i++) { List <UInt32> ropeNodes = RopeNodes[i]; foreach (UInt32 ropeNode in ropeNodes) { s.WriteUInt32(ropeNode); } List <UInt32> ropeLinks = RopeLinks[i]; foreach (UInt32 ropeLink in ropeLinks) { s.WriteUInt32(ropeLink); } } }
public UpnDomainInfo(byte[] data) : base(data) { UpnLength = Stream.ReadShort(); UpnOffset = Stream.ReadShort(); DnsDomainNameLength = Stream.ReadShort(); DnsDomainNameOffset = Stream.ReadShort(); Flags = (UpnDomainFlags)Stream.ReadInt(); Stream.Align(8); Upn = Encoding.Unicode.GetString(Stream.Read(UpnLength)); Stream.Align(8); Domain = Encoding.Unicode.GetString(Stream.Read(DnsDomainNameLength)); }
public void Save(Stream s) { using (MemoryStream referenceStream = new MemoryStream()) { foreach (string reference in References) { referenceStream.WriteAsciiNullTerminatedString(reference); } Header.ReferenceCount = (uint)References.Count; Header.ReferenceDataSize = (uint)referenceStream.Length; s.WriteStruct(Header); long position = s.Position; s.Seek(position + Header.ReferenceDataStart, SeekOrigin.Begin); referenceStream.Seek(0, SeekOrigin.Begin); referenceStream.CopyTo(s); s.Seek(position + Header.ReferenceDataSize + 1, SeekOrigin.Begin); s.Align(16); } }
public VFile(Stream s) { References = new List <string>(); Header = s.ReadStruct <VFileHeader>(); long position = s.Position; s.Seek(position + Header.ReferenceDataStart, SeekOrigin.Begin); for (int i = 0; i < Header.ReferenceCount; i++) { string reference = s.ReadAsciiNullTerminatedString(); References.Add(reference); } s.Seek(position + Header.ReferenceDataSize + 1, SeekOrigin.Begin); if (Header.Version >= 2) { s.Align(16); } }
private void ProcessDataTable(Chunk chunk) { Progress?.Report("Processing data table"); Stream.Align(0x10); var table = new AaronDataTable(); table.Name = HashResolver.Resolve(Reader.ReadUInt32()); table.Entries = new List <AaronDataTableEntry>(); while (Stream.Position < chunk.EndOffset) { var entry = new AaronDataTableEntry(); entry.Name = HashResolver.Resolve(Reader.ReadUInt32()); entry.Unknown = Reader.ReadUInt32(); entry.Unknown2 = Reader.ReadSingle(); table.Entries.Add(entry); } _dataTableService.AddDataTable(table); }
static void CreateDummyClothSim(string path) { Console.WriteLine("Creating dummy cloth sim: {0}", path); string name = Path.GetFileNameWithoutExtension(path); if (name.Length >= 28) // the field in the struct is only 28 bytes long, and needs to include a null { name = name.Substring(0, 27); } using (Stream stream = File.Create(path)) { stream.WriteUInt32(0x02); // version stream.WriteUInt32(0); // data size stream.WriteAsciiNullTerminatedString(name); stream.Align(0x24); stream.WriteUInt32(0); // num passes stream.WriteUInt32(1); // air resistance stream.WriteUInt32(1); // wind multiplier stream.WriteUInt32(1); // wind constant stream.WriteUInt32(1); // gravity multiplier stream.WriteUInt32(0); // object velocity inheritance stream.WriteUInt32(0); // object position inheritance stream.WriteUInt32(0); // object rotation inheritance stream.WriteUInt32(0); // wind type stream.WriteUInt32(0); // num nodes stream.WriteUInt32(0); // num anchor nodes stream.WriteUInt32(0); // num node links stream.WriteUInt32(0); // num ropes stream.WriteUInt32(0); // num colliders //stream.WriteUInt32(0); // bounding sphere radius stream.WriteUInt32(0); // *nodes stream.WriteUInt32(0); // *node_links stream.WriteUInt32(0); // *ropes stream.WriteUInt32(0); // *colliders } }
public void Save(Stream stream) { long dataStart = CalculateDataStartOffset(); stream.Seek(dataStart, SeekOrigin.Begin); long fileStart = 0; long compressedSize = 0; long uncompressedSize = 0; // Output file data ZlibStream dataStream = null; if (IsCompressed && IsCondensed) { dataStream = new ZlibStream(stream, CompressionMode.Compress, CompressionLevel.BestCompression, true); dataStream.FlushMode = FlushType.Sync; } long compressedStart = 0; for (int i = 0; i < Files.Count; i++) { IPackfileEntry entry = Files[i]; Stream fs = m_Streams[entry.Name]; bool isLast = (i == (Files.Count - 1)); PackfileEntry pfE = (PackfileEntry)entry; var data = pfE.Data; data.Start = (uint)fileStart; data.Size = (uint)fs.Length; data.Alignment = (IsCondensed) ? (ushort)16 : (ushort)1; if (this.IsCompressed) { data.Flags = PackfileEntryFlags.Compressed; } if (IsCompressed && IsCondensed) { fs.CopyTo(dataStream); dataStream.Flush(); long afterData = dataStream.TotalOut; data.CompressedSize = (uint)(afterData - compressedStart); compressedStart = afterData; if (IsStr2) { fileStart += data.Size.Align(16); uncompressedSize += data.Size.Align(16); compressedSize += data.CompressedSize; } else { fileStart += data.Size; //.Align(16); if (!isLast) { uncompressedSize += data.Size; //.Align(16); //uint toSkip = data.Size.Align(16) - data.Size; // for (int j = 0; j < toSkip; j++) //dataStream.WriteByte(0); } else { uncompressedSize += data.Size; } compressedSize += data.CompressedSize; } } else if (IsCondensed) { fs.CopyTo(stream); data.CompressedSize = 0xFFFFFFFF; fileStart += data.Size.Align(16); if (isLast) { uncompressedSize += data.Size; } else { uint toSkip = data.Size.Align(16) - data.Size; uncompressedSize += data.Size.Align(16); stream.Seek(toSkip, SeekOrigin.Current); } } else if (IsCompressed) { long beforeData = stream.Position; using (dataStream = new ZlibStream(stream, CompressionMode.Compress, CompressionLevel.BestCompression, true)) { dataStream.FlushMode = FlushType.Sync; fs.CopyTo(dataStream); dataStream.Flush(); } long afterData = stream.Position; data.CompressedSize = (uint)(afterData - beforeData); fileStart += data.CompressedSize; uncompressedSize += data.Size; compressedSize += data.CompressedSize; } else { fs.CopyTo(stream); data.CompressedSize = 0xFFFFFFFF; fileStart += data.Size; uncompressedSize += data.Size; } fs.Close(); pfE.Data = data; } if (IsCompressed && IsCondensed) { dataStream.Close(); } // Output file names stream.Seek(CalculateEntryNamesOffset(), SeekOrigin.Begin); long startOffset = CalculateEntryNamesOffset(); foreach (IPackfileEntry entry in Files) { PackfileEntry pfE = (PackfileEntry)entry; stream.Align(2); pfE.Data.FilenameOffset = (UInt32)(stream.Position - startOffset); stream.WriteAsciiNullTerminatedString(entry.Name); stream.Seek(1, SeekOrigin.Current); stream.Align(2); } long nameSize = stream.Position - CalculateEntryNamesOffset(); // Output file info stream.Seek(GetEntryDataOffset(), SeekOrigin.Begin); foreach (IPackfileEntry entry in Files) { PackfileEntry pfE = (PackfileEntry)entry; stream.WriteStruct(pfE.Data); } long dirSize = stream.Position - GetEntryDataOffset(); // Output header stream.Seek(0, SeekOrigin.Begin); FileData.Descriptor = 0x51890ACE; FileData.Version = 0x0A; FileData.HeaderChecksum = 0; FileData.FileSize = (uint)stream.Length; FileData.NumFiles = (uint)Files.Count; FileData.DirSize = (uint)dirSize; FileData.FilenameSize = (uint)nameSize; FileData.DataSize = (uint)uncompressedSize; if (IsCompressed) { FileData.CompressedDataSize = (uint)compressedSize; } else { FileData.CompressedDataSize = 0xFFFFFFFF; } stream.WriteStruct(FileData); uint checksum = 0; byte[] checksumBuffer = new byte[0x1C]; stream.Seek(0x0C, SeekOrigin.Begin); stream.Read(checksumBuffer, 0, checksumBuffer.Length); checksum = Hashes.CrcVolition(checksumBuffer); stream.Seek(0x08, SeekOrigin.Begin); stream.WriteUInt32(checksum); stream.Flush(); }
public void STRWriter(string filepath) { uint Offset = 0; uint CurrentOffset = 0; Stream writer = File.OpenWriter(filepath + (Header. Format > Main.Format.FT ? ".str" : ".bin"), true); writer.Format = Header.Format; POF = new POF(); writer.IsBE = writer.Format == Main.Format.F2BE; long Count = STRs.LongLength; if (writer.Format > Main.Format.FT) { writer.Position = 0x40; writer.WriteEndian(Count); writer.GetOffset(ref POF).WriteEndian(0x80); writer.Position = 0x80; for (int i = 0; i < Count; i++) { writer.GetOffset(ref POF).Write(0x00); writer.WriteEndian(STRs[i].ID); } writer.Align(16); } else { for (int i = 0; i < Count; i++) { writer.Write(0x00); } writer.Align(32); } List <string> UsedSTR = new List <string>(); List <int> UsedSTRPos = new List <int>(); int[] STRPos = new int[Count]; for (int i1 = 0; i1 < Count; i1++) { if (UsedSTR.Contains(STRs[i1].Str)) { for (int i2 = 0; i2 < Count; i2++) { if (UsedSTR[i2] == STRs[i1].Str) { STRPos[i1] = UsedSTRPos[i2]; break; } } } else { STRPos[i1] = writer.Position; UsedSTRPos.Add(STRPos[i1]); UsedSTR.Add(STRs[i1].Str); writer.Write(STRs[i1].Str); writer.WriteByte(0); } } if (writer.Format > Main.Format.FT) { writer.Align(16); Offset = writer.UIntPosition; writer.Position = 0x80; } else { writer.Position = 0; } for (int i1 = 0; i1 < Count; i1++) { writer.WriteEndian(STRPos[i1]); if (writer.Format > Main.Format.FT) { writer.Position += 4; } } if (writer.Format > Main.Format.FT) { writer.UIntPosition = Offset; writer.Write(ref POF, 1); CurrentOffset = writer.UIntPosition; writer.WriteEOFC(0); Header.Lenght = 0x40; Header.DataSize = (int)(CurrentOffset - Header.Lenght); Header.Signature = 0x41525453; Header.SectionSize = (int)(Offset - Header.Lenght); writer.Position = 0; writer.Write(Header); } writer.Close(); }
public void DEXWriter(string filepath, Main.Format Format) { Header = new PDHead() { Format = Format }; IO = File.OpenWriter(filepath + (Header.Format > Main.Format.F ? ".Dex" : ".bin"), true); IO.Format = Header.Format; if (IO.Format > Main.Format.F) { Header.Lenght = 0x20; Header.DataSize = 0x00; Header.Signature = 0x43505845; Header.SectionSize = 0x00; IO.Write(Header); } IO.Write(0x64); IO.Write(Dex.Length); if (Header.IsX) { IO.Write((long)0x28); } else { IO.Write(0x20); } if (Header.IsX) { IO.Write((long)0x00); } else { IO.Write(0x00); } int Position0 = IO.Position; IO.Write((long)0x00); IO.Write((long)0x00); for (int i = 0; i < Dex.Length * 3; i++) { if (Header.IsX) { IO.Write((long)0x00); } else { IO.Write(0x00); } } IO.Align(0x20, true); for (int i0 = 0; i0 < Dex.Length; i0++) { Dex[i0].MainOffset = IO.Position - Header.Lenght; for (int i1 = 0; i1 < Dex[i0].Main.Count; i1++) { IO.Write(Dex[i0].Main[i1].Frame); IO.Write(Dex[i0].Main[i1].Both); IO.Write(Dex[i0].Main[i1].ID); IO.Write(Dex[i0].Main[i1].Value); IO.Write(Dex[i0].Main[i1].Trans); } IO.Align(0x20, true); Dex[i0].EyesOffset = IO.Position - Header.Lenght; for (int i1 = 0; i1 < Dex[i0].Eyes.Count; i1++) { IO.Write(Dex[i0].Eyes[i1].Frame); IO.Write(Dex[i0].Eyes[i1].Both); IO.Write(Dex[i0].Eyes[i1].ID); IO.Write(Dex[i0].Eyes[i1].Value); IO.Write(Dex[i0].Eyes[i1].Trans); } IO.Align(0x20, true); } for (int i0 = 0; i0 < Dex.Length; i0++) { Dex[i0].NameOffset = IO.Position - Header.Lenght; IO.Write(Dex[i0].Name + "\0"); } IO.Align(0x10, true); if (Header.IsX) { IO.Seek(Header.Lenght + 0x28, 0); } else { IO.Seek(Header.Lenght + 0x20, 0); } for (int i0 = 0; i0 < Dex.Length; i0++) { IO.Write(Dex[i0].MainOffset); if (Header.IsX) { IO.Write(0x00); } IO.Write(Dex[i0].EyesOffset); if (Header.IsX) { IO.Write(0x00); } } int Position1 = IO.Position - Header.Lenght; for (int i0 = 0; i0 < Dex.Length; i0++) { IO.Write(Dex[i0].NameOffset); if (Header.IsX) { IO.Write(0x00); } } if (Header.IsX) { IO.Seek(Position0 - 8, 0); } else { IO.Seek(Position0 - 4, 0); } IO.Write(Position1); if (IO.Format > Main.Format.F) { Offset = IO.Length - Header.Lenght; IO.Seek(IO.Length, 0); IO.WriteEOFC(0); IO.Seek(0, 0); Header.DataSize = Offset; Header.SectionSize = Offset; IO.Write(Header); } IO.Close(); }
public void Save(Stream stream) { // Calculate IndexSize FileData.IndexCount = (uint)Files.Count; FileData.IndexSize = (FileData.IndexCount * 0x1C); // Write Names & calculate NamesSize Dictionary <string, uint> filenames = new Dictionary <string, uint>(StringComparer.InvariantCultureIgnoreCase); stream.Seek(CalculateEntryNamesOffset(), SeekOrigin.Begin); uint filenameOffset = 0; foreach (PackfileEntry entry in Files) { string filename = Path.GetFileNameWithoutExtension(entry.Name); if (filenames.ContainsKey(filename)) { entry.Data.FilenameOffset = filenames[filename]; } else { entry.Data.FilenameOffset = filenameOffset; int length = stream.WriteAsciiNullTerminatedString(filename); filenames.Add(filename, filenameOffset); filenameOffset += (uint)length; } } FileData.NamesSize = filenameOffset; // Write Extensions & calculate ExtensionsSize Dictionary <string, uint> extensions = new Dictionary <string, uint>(StringComparer.InvariantCultureIgnoreCase); uint extensionOffset = 0; stream.Seek(CalculateExtensionsOffset(), SeekOrigin.Begin); foreach (PackfileEntry entry in Files) { string extension = Path.GetExtension(entry.Name); if (extension.StartsWith(".")) { extension = extension.Remove(0, 1); } if (extensions.ContainsKey(extension)) { entry.Data.ExtensionOffset = extensions[extension]; } else { entry.Data.ExtensionOffset = extensionOffset; int length = stream.WriteAsciiNullTerminatedString(extension); extensions.Add(extension, extensionOffset); extensionOffset += (uint)length; } } FileData.ExtensionsSize = extensionOffset; // Write data uint dataOffset = 0; stream.Seek(CalculateDataStartOffset(), SeekOrigin.Begin); foreach (PackfileEntry entry in Files) { Stream inStream = m_Streams[entry.Name]; entry.Data.Size = (uint)inStream.Length; entry.Data.Start = dataOffset; entry.Data.CompressedSize = (uint)0xFFFFFFFF; inStream.CopyTo(stream); dataOffset += entry.Data.Size; stream.Align(16); dataOffset = dataOffset.Align(16); } // Write Header stream.Seek(0, SeekOrigin.Begin); FileData.Descriptor = 0x51890ACE; FileData.Version = 0x04; FileData.CompressedDataSize = 0xFFFFFFFF; FileData.UncompressedDataSize = dataOffset; FileData.PackageSize = (uint)stream.Length; stream.WriteStruct(FileData); // Write file index stream.Seek(GetEntryDataOffset(), SeekOrigin.Begin); foreach (PackfileEntry entry in Files) { stream.WriteStruct(entry.Data); } }
public ClothSimulationFile(Stream s) { Header = s.ReadStruct <ClothSimulationHeader>(); Nodes = new List <SimulatedNodeInfo>(); NodeLinks = new List <SimulatedNodeLinkInfo>(); Ropes = new List <ClothSimRopeInfo>(); RopeNodes = new List <List <uint> >(); RopeLinks = new List <List <uint> >(); CollisionPrimitives = new List <ClothSimCollisionPrimitiveInfo>(); for (int i = 0; i < Header.NumNodes; i++) { SimulatedNodeInfo sni = s.ReadStruct <SimulatedNodeInfo>(); Nodes.Add(sni); } for (int i = 0; i < Header.NumNodeLinks; i++) { SimulatedNodeLinkInfo snli = s.ReadStruct <SimulatedNodeLinkInfo>(); NodeLinks.Add(snli); } for (int i = 0; i < Header.NumColliders; i++) { ClothSimCollisionPrimitiveInfo cscpi = s.ReadStruct <ClothSimCollisionPrimitiveInfo>(); CollisionPrimitives.Add(cscpi); } s.Align(8); for (int i = 0; i < Header.NumRopes; i++) { ClothSimRopeInfo csri = s.ReadStruct <ClothSimRopeInfo>(); Ropes.Add(csri); } for (int i = 0; i < Header.NumRopes; i++) { ClothSimRopeInfo csri = Ropes[i]; List <UInt32> ropeNodes = new List <uint>(); for (int j = 0; j < csri.NumNodes; j++) { uint ropeNode = s.ReadUInt32(); ropeNodes.Add(ropeNode); } RopeNodes.Add(ropeNodes); List <UInt32> ropeLinks = new List <uint>(); for (int j = 0; j < csri.NumLinks; j++) { uint ropeLink = s.ReadUInt32(); ropeLinks.Add(ropeLink); } RopeLinks.Add(ropeLinks); } }
public static void Write(this Stream IO, ref Pointer <Aif> Aif) { if (Aif.Value.Unk0.Count > 0) { Aif.Value.Unk0.Offset = IO.Position; for (int i = 0; i < Aif.Value.Unk0.Count; i++) { IO.Write(Aif.Value.Unk0.Entries[i]); } } if (Aif.Value.Unk1.Count > 0) { Aif.Value.Unk1.Offset = IO.Position; for (int i = 0; i < Aif.Value.Unk1.Count; i++) { IO.Write(Aif.Value.Unk1.Entries[i]); } } if (Aif.Value.Unk2.Count > 0) { Aif.Value.Unk2.Offset = IO.Position; for (int i = 0; i < Aif.Value.Unk2.Count; i++) { IO.Write(Aif.Value.Unk2.Entries[i]); } } if (Aif.Value.Unk3.Count > 0) { Aif.Value.Unk3.Offset = IO.Position; for (int i = 0; i < Aif.Value.Unk3.Count; i++) { IO.Write(Aif.Value.Unk3.Entries[i]); } } IO.Align(0x10); Aif.Value.Value.Offset = IO.Position; IO.Write(Aif.Value.Value.Value); IO.Align(0x10); Aif.Value.Pointer = IO.Position; if (Aif.Value.Unk0.Count > 0) { IO.Write(Aif.Value.Unk0.Count); IO.Write(Aif.Value.Unk0.Offset); } else { IO.Write(0L); } if (Aif.Value.Unk1.Count > 0) { IO.Write(Aif.Value.Unk1.Count); IO.Write(Aif.Value.Unk1.Offset); } else { IO.Write(0L); } if (Aif.Value.Unk2.Count > 0) { IO.Write(Aif.Value.Unk2.Count); IO.Write(Aif.Value.Unk2.Offset); } else { IO.Write(0L); } if (Aif.Value.Unk3.Count > 0) { IO.Write(Aif.Value.Unk3.Count); IO.Write(Aif.Value.Unk3.Offset); } else { IO.Write(0L); } }
public void Save(Stream stream) { long dataStart = CalculateDataStartOffset(); stream.Seek(dataStart, SeekOrigin.Begin); long fileStart = 0; long compressedSize = 0; long uncompressedSize = 0; // Output file data ZlibStream dataStream = null; if (IsCompressed && IsCondensed) { dataStream = new ZlibStream(stream, CompressionMode.Compress, CompressionLevel.BestCompression, true); dataStream.FlushMode = FlushType.Sync; } long compressedStart = 0; for (int i = 0; i < Files.Count; i++) { IPackfileEntry entry = Files[i]; Stream fs = m_Streams[entry.Name]; bool isLast = (i == (Files.Count - 1)); PackfileEntry pfE = (PackfileEntry)entry; var data = pfE.Data; data.Start = (uint)fileStart; data.Size = (uint)fs.Length; data.Alignment = (IsCondensed) ? (ushort)16 : (ushort)1; if (this.IsCompressed) data.Flags = PackfileEntryFlags.Compressed; if (IsCompressed && IsCondensed) { fs.CopyTo(dataStream); dataStream.Flush(); long afterData = dataStream.TotalOut; data.CompressedSize = (uint)(afterData - compressedStart); compressedStart = afterData; if (IsStr2) { fileStart += data.Size.Align(16); uncompressedSize += data.Size.Align(16); compressedSize += data.CompressedSize; } else { fileStart += data.Size; //.Align(16); if (!isLast) { uncompressedSize += data.Size; //.Align(16); //uint toSkip = data.Size.Align(16) - data.Size; // for (int j = 0; j < toSkip; j++) //dataStream.WriteByte(0); } else { uncompressedSize += data.Size; } compressedSize += data.CompressedSize; } } else if (IsCondensed) { fs.CopyTo(stream); data.CompressedSize = 0xFFFFFFFF; fileStart += data.Size.Align(16); if (isLast) uncompressedSize += data.Size; else { uint toSkip = data.Size.Align(16) - data.Size; uncompressedSize += data.Size.Align(16); stream.Seek(toSkip, SeekOrigin.Current); } } else if (IsCompressed) { long beforeData = stream.Position; using (dataStream = new ZlibStream(stream, CompressionMode.Compress, CompressionLevel.BestCompression, true)) { dataStream.FlushMode = FlushType.Sync; fs.CopyTo(dataStream); dataStream.Flush(); } long afterData = stream.Position; data.CompressedSize = (uint)(afterData - beforeData); fileStart += data.CompressedSize; uncompressedSize += data.Size; compressedSize += data.CompressedSize; } else { fs.CopyTo(stream); data.CompressedSize = 0xFFFFFFFF; fileStart += data.Size; uncompressedSize += data.Size; } fs.Close(); pfE.Data = data; } if (IsCompressed && IsCondensed) { dataStream.Close(); } // Output file names stream.Seek(CalculateEntryNamesOffset(), SeekOrigin.Begin); long startOffset = CalculateEntryNamesOffset(); foreach (IPackfileEntry entry in Files) { PackfileEntry pfE = (PackfileEntry)entry; stream.Align(2); pfE.Data.FilenameOffset = (UInt32)(stream.Position - startOffset); stream.WriteAsciiNullTerminatedString(entry.Name); stream.Seek(1, SeekOrigin.Current); stream.Align(2); } long nameSize = stream.Position - CalculateEntryNamesOffset(); // Output file info stream.Seek(GetEntryDataOffset(), SeekOrigin.Begin); foreach (IPackfileEntry entry in Files) { PackfileEntry pfE = (PackfileEntry)entry; stream.WriteStruct(pfE.Data); } long dirSize = stream.Position - GetEntryDataOffset(); // Output header stream.Seek(0, SeekOrigin.Begin); FileData.Descriptor = 0x51890ACE; FileData.Version = 0x0A; FileData.HeaderChecksum = 0; FileData.FileSize = (uint)stream.Length; FileData.NumFiles = (uint)Files.Count; FileData.DirSize = (uint)dirSize; FileData.FilenameSize = (uint)nameSize; FileData.DataSize = (uint)uncompressedSize; if (IsCompressed) FileData.CompressedDataSize = (uint)compressedSize; else FileData.CompressedDataSize = 0xFFFFFFFF; stream.WriteStruct(FileData); uint checksum = 0; byte[] checksumBuffer = new byte[0x1C]; stream.Seek(0x0C, SeekOrigin.Begin); stream.Read(checksumBuffer, 0, checksumBuffer.Length); checksum = Hashes.CrcVolition(checksumBuffer); stream.Seek(0x08, SeekOrigin.Begin); stream.WriteUInt32(checksum); stream.Flush(); }
private void ProcessBoundsPack(Chunk chunk) { Progress?.Report("Processing car bounds pack"); Stream.Align(0x10); var boundsHeader = BinaryHelpers.ReadStruct <BoundsHeader>(Reader); var car = _carService.FindCarByCollisionHash(boundsHeader.NameHash); if (car.BoundsPack != null) { throw new InvalidDataException("Duplicate bounds pack for " + car.CarTypeName); } var bp = new AaronBoundsPack { Entries = new List <AaronBoundsEntry>(boundsHeader.NumBounds), NameHash = boundsHeader.NameHash, PointClouds = new List <AaronBoundsPointCloud>() }; for (var i = 0; i < boundsHeader.NumBounds; i++) { var boundsStruct = BinaryHelpers.ReadStruct <Bounds>(Reader); Debug.Assert(boundsStruct.CollectionPtr == 0); var boundsEntry = new AaronBoundsEntry { Position = boundsStruct.Position, AttributeName = boundsStruct.AttributeName, ChildIndex = boundsStruct.ChildIndex, Flags = (AaronBoundsFlags)boundsStruct.Flags, HalfDimensions = boundsStruct.HalfDimensions, NameHash = boundsStruct.NameHash, NumChildren = boundsStruct.NumChildren, Orientation = boundsStruct.Orientation, PCloudIndex = boundsStruct.PCloudIndex, Pivot = boundsStruct.Pivot, Surface = boundsStruct.Surface }; bp.Entries.Add(boundsEntry); } var pointCloudHeader = BinaryHelpers.ReadStruct <PCloudHeader>(Reader); bp.PointClouds = new List <AaronBoundsPointCloud>(pointCloudHeader.NumPClouds); for (var i = 0; i < pointCloudHeader.NumPClouds; i++) { int numPoints = Reader.ReadInt32(); Reader.ReadInt64(); // fPad Reader.ReadUInt32(); // fPList var pointCloud = new AaronBoundsPointCloud { Vertices = new List <Vector4>(numPoints) }; for (var j = 0; j < numPoints; j++) { var vertex = BinaryHelpers.ReadStruct <Vector4>(Reader); pointCloud.Vertices.Add(vertex); } bp.PointClouds.Add(pointCloud); } car.BoundsPack = bp; }
public void STRWriter(string filepath) { if (STRs == null || STRs.Length == 0 || Header.Format > Main.Format.F2BE) { return; } uint Offset = 0; uint CurrentOffset = 0; IO = File.OpenWriter(filepath + (Header.Format > Main.Format.FT ? ".str" : ".bin"), true); IO.Format = Header.Format; POF = new POF(); IO.IsBE = IO.Format == Main.Format.F2BE; long Count = STRs.LongLength; if (IO.Format > Main.Format.FT) { IO.Position = 0x40; IO.WriteX(Count); IO.GetOffset(ref POF); IO.WriteX(0x80); IO.Position = 0x80; for (int i = 0; i < Count; i++) { IO.Write(0x00L); } IO.Align(0x10); } else { for (int i = 0; i < Count; i++) { IO.Write(0x00); } IO.Align(0x20); } KKdList <string> UsedSTR = KKdList <string> .New; KKdList <int> UsedSTRPos = KKdList <int> .New; int[] STRPos = new int[Count]; for (int i = 0; i < Count; i++) { if (!UsedSTR.Contains(STRs[i].Str.Value)) { STRPos[i] = IO.Position; UsedSTRPos.Add(STRPos[i]); UsedSTR.Add(STRs[i].Str.Value); IO.Write(STRs[i].Str.Value + "\0"); } else { for (int i2 = 0; i2 < Count; i2++) { if (UsedSTR[i2] == STRs[i].Str.Value) { STRPos[i] = UsedSTRPos[i2]; break; } } } } if (IO.Format > Main.Format.FT) { IO.Align(0x10); Offset = IO.UIntPosition; IO.Position = 0x80; for (int i = 0; i < Count; i++) { IO.GetOffset(ref POF); IO.WriteEndian(STRPos[i]); IO.WriteEndian(STRs[i].ID); } IO.UIntPosition = Offset; IO.Write(ref POF, 1); CurrentOffset = IO.UIntPosition; IO.WriteEOFC(0); Header.DataSize = (int)(CurrentOffset - 0x40); Header.Signature = 0x41525453; Header.SectionSize = (int)(Offset - 0x40); IO.Position = 0; IO.Write(Header); } else { IO.Position = 0; for (int i = 0; i < Count; i++) { IO.Write(STRPos[i]); } } IO.Close(); }
public void Save(Stream s) { s.Align(4); s.Align(8); Header.NumNavpoints = (short)Navpoints.Count; Header.NumRigBones = (short)RigBones.Count; // Header.NumMaterials // Header.NumMaterialMaps // Header.NumLODsPerSubmesh // Header.NumSubmeshVIDs Header.NumCSpheres = (ushort)CSpheres.Count; Header.NumCCylinders = (ushort)CCylinders.Count; // NumLogicalSubmeshes s.WriteStruct(Header); using (MemoryStream textureNameStream = new MemoryStream()) { string[] textureNames = new string[TextureNames.Count]; TextureNames.Keys.CopyTo(textureNames, 0); foreach (var textureName in textureNames) { textureNameStream.Align(2); TextureNames[textureName] = (int)textureNameStream.Position; textureNameStream.WriteAsciiNullTerminatedString(textureName); textureNameStream.WriteUInt8(0); // padding byte? textureNameStream.Align(2); } s.WriteInt32((int)textureNameStream.Length); s.Align(16); s.WriteUInt8(0); textureNameStream.Seek(0, SeekOrigin.Begin); textureNameStream.CopyTo(s); } if (Header.NumNavpoints > 0) { s.Align(16); foreach (StaticMeshNavpoint navpoint in Navpoints) { s.WriteStruct(navpoint); } } if (Header.NumCSpheres > 0) { s.Align(16); foreach (CMeshCSphere csphere in CSpheres) { s.WriteStruct(csphere); } } if (Header.NumCCylinders > 0) { s.Align(16); foreach (CMeshCCylinder ccylinder in CCylinders) { s.WriteStruct(ccylinder); } } if (Header.NumRigBones > 0) { s.Align(16); foreach (uint rigBone in RigBones) { s.WriteUInt32(rigBone); } } s.Align(8); s.WriteUInt16(MeshVersion); s.Align(4); s.WriteUInt32(MeshGpuDataCrc); s.WriteUInt32(MeshCpuDataSize); s.Write(MiscData, 0, MiscData.Length); if (Header.NumMaterialMaps > 0) { s.Align(8); // Skip pointer tables? s.Seek(8 * Header.NumMaterialMaps, SeekOrigin.Current); for (int i = 0; i < Header.NumMaterialMaps; i++) { s.WriteUInt32(MaterialMapCrcs[i]); } } if (Header.NumMaterials > 0) { s.Align(8); // Skip more pointers s.Seek(8 * Header.NumMaterials, SeekOrigin.Current); for (int i = 0; i < Header.NumMaterials; i++) { StaticMeshMaterial material = Materials[i]; s.WriteUInt32(material.DataSize); s.Align(8); s.WriteStruct(material.Data); for (int j = 0; j < material.Data.NumTextures; j++) { string textureName = material.TextureNames[j]; RenderLibMaterialTextureDesc textureDesc = material.TextureDescriptions[j]; int textureNameOffset = TextureNames[textureName]; textureDesc.TextureHandle = textureNameOffset; s.WriteStruct(textureDesc); } for (int j = 0; j < material.Data.NumConstants; j++) { uint constantNameChecksum = material.NameChecksums[j]; s.WriteUInt32(constantNameChecksum); } s.Align(16); for (int j = 0; j < material.Data.NumConstants; j++) { RenderLibMaterialConstants constant = material.Constants[j]; s.WriteStruct(constant); } } } s.Write(MaterialMapData, 0, MaterialMapData.Length); }
public StaticMesh(Stream s) { s.Align(4); s.Align(8); Header = s.ReadStruct <StaticMeshHeader>(); // Read texture names int textureNameSize = s.ReadInt32(); s.Align(16); s.ReadByte(); byte[] textureNameData = new byte[textureNameSize]; s.Read(textureNameData, 0, textureNameSize); MemoryStream textureNameStream = new MemoryStream(textureNameData); while (textureNameStream.Position < textureNameData.Length) { textureNameStream.Align(2); int position = (int)textureNameStream.Position; string textureName = textureNameStream.ReadAsciiNullTerminatedString(); byte paddingByte = textureNameStream.ReadUInt8(); TextureNames.Add(textureName, position); if (paddingByte != 0) { throw new Exception(); } textureNameStream.Align(2); } if (Header.Version < 0x2A) { Header.NumSubmeshVIDs = (ushort)Header.NumLogicalSubmeshes; } if (Header.NumNavpoints > 0) { s.Align(16); for (int i = 0; i < Header.NumNavpoints; i++) { StaticMeshNavpoint navpoint = s.ReadStruct <StaticMeshNavpoint>(); Navpoints.Add(navpoint); } } if (Header.NumCSpheres > 0) { s.Align(16); for (int i = 0; i < Header.NumCSpheres; i++) { CMeshCSphere cmeshCSphere = s.ReadStruct <CMeshCSphere>(); CSpheres.Add(cmeshCSphere); } } if (Header.NumCCylinders > 0) { s.Align(16); for (int i = 0; i < Header.NumCCylinders; i++) { CMeshCCylinder cylinder = s.ReadStruct <CMeshCCylinder>(); CCylinders.Add(cylinder); } } if (Header.NumRigBones > 0) { s.Align(16); for (int i = 0; i < Header.NumRigBones; i++) { UInt32 rigBone = s.ReadUInt32(); RigBones.Add(rigBone); } } s.Align(8); long originalOffset = s.Position; MeshVersion = s.ReadUInt16(); s.Align(4); MeshGpuDataCrc = s.ReadUInt32(); MeshCpuDataSize = s.ReadUInt32(); MiscData = new byte[(originalOffset + MeshCpuDataSize) - s.Position]; s.Read(MiscData, 0, MiscData.Length); if (Header.NumMaterialMaps > 0) { s.Align(8); // Skip pointer tables? s.Seek(8 * Header.NumMaterialMaps, SeekOrigin.Current); MaterialMapCrcs = new uint[Header.NumMaterialMaps]; for (int i = 0; i < Header.NumMaterialMaps; i++) { MaterialMapCrcs[i] = s.ReadUInt32(); } } if (Header.NumMaterials > 0) { s.Align(8); // Skip more pointers s.Seek(8 * Header.NumMaterials, SeekOrigin.Current); for (int i = 0; i < Header.NumMaterials; i++) { StaticMeshMaterial material = new StaticMeshMaterial(); Materials.Add(material); long materialStart = s.Position; material.DataSize = s.ReadUInt32(); s.Align(8); material.Data = s.ReadStruct <RenderLibMaterialData>(); s.Align(4); for (int j = 0; j < material.Data.NumTextures; j++) { RenderLibMaterialTextureDesc textureDesc = s.ReadStruct <RenderLibMaterialTextureDesc>(); material.TextureDescriptions.Add(textureDesc); } s.Align(4); for (int j = 0; j < material.Data.NumConstants; j++) { uint constantNameChecksum = s.ReadUInt32(); material.NameChecksums.Add(constantNameChecksum); } s.Align(16); for (int j = 0; j < material.Data.NumConstants; j++) { RenderLibMaterialConstants constant = s.ReadStruct <RenderLibMaterialConstants>(); material.Constants.Add(constant); } uint materialSize = (uint)(s.Position - materialStart); if (materialSize != material.DataSize) { throw new Exception(String.Format("materialSize != material.DataSize - {0} != {1}", materialSize, material.DataSize)); } if (material.Data.NumTextures > 0) { for (int j = 0; j < material.Data.NumTextures; j++) { RenderLibMaterialTextureDesc textureDesc = material.TextureDescriptions[j]; textureNameStream.Seek(textureDesc.TextureHandle, SeekOrigin.Begin); string textureName = textureNameStream.ReadAsciiNullTerminatedString(); material.TextureNames.Add(textureName); } } } } MaterialMapData = new byte[s.Length - s.Position]; s.Read(MaterialMapData, 0, MaterialMapData.Length); }
public void Save(Stream stream) { // Calculate IndexSize FileData.IndexCount = (uint)Files.Count; FileData.IndexSize = (FileData.IndexCount * 0x1C); // Write Names & calculate NamesSize Dictionary<string, uint> filenames = new Dictionary<string, uint>(StringComparer.InvariantCultureIgnoreCase); stream.Seek(CalculateEntryNamesOffset(), SeekOrigin.Begin); uint filenameOffset = 0; foreach (PackfileEntry entry in Files) { string filename = Path.GetFileNameWithoutExtension(entry.Name); if (filenames.ContainsKey(filename)) { entry.Data.FilenameOffset = filenames[filename]; } else { entry.Data.FilenameOffset = filenameOffset; int length = stream.WriteAsciiNullTerminatedString(filename); filenames.Add(filename, filenameOffset); filenameOffset += (uint)length; } } FileData.NamesSize = filenameOffset; // Write Extensions & calculate ExtensionsSize Dictionary<string, uint> extensions = new Dictionary<string, uint>(StringComparer.InvariantCultureIgnoreCase); uint extensionOffset = 0; stream.Seek(CalculateExtensionsOffset(), SeekOrigin.Begin); foreach (PackfileEntry entry in Files) { string extension = Path.GetExtension(entry.Name); if (extension.StartsWith(".")) extension = extension.Remove(0, 1); if (extensions.ContainsKey(extension)) { entry.Data.ExtensionOffset = extensions[extension]; } else { entry.Data.ExtensionOffset = extensionOffset; int length = stream.WriteAsciiNullTerminatedString(extension); extensions.Add(extension, extensionOffset); extensionOffset += (uint)length; } } FileData.ExtensionsSize = extensionOffset; // Write data uint dataOffset = 0; stream.Seek(CalculateDataStartOffset(), SeekOrigin.Begin); foreach (PackfileEntry entry in Files) { Stream inStream = m_Streams[entry.Name]; entry.Data.Size = (uint)inStream.Length; entry.Data.Start = dataOffset; entry.Data.CompressedSize = (uint)0xFFFFFFFF; inStream.CopyTo(stream); dataOffset += entry.Data.Size; stream.Align(16); dataOffset = dataOffset.Align(16); } // Write Header stream.Seek(0, SeekOrigin.Begin); FileData.Descriptor = 0x51890ACE; FileData.Version = 0x04; FileData.CompressedDataSize = 0xFFFFFFFF; FileData.UncompressedDataSize = dataOffset; FileData.PackageSize = (uint)stream.Length; stream.WriteStruct(FileData); // Write file index stream.Seek(GetEntryDataOffset(), SeekOrigin.Begin); foreach (PackfileEntry entry in Files) { stream.WriteStruct(entry.Data); } }
public void BINWriter(string file) { if (AetSets == null) { return; } if (AetSets.Length == 0) { return; } List <string> SetName = new List <string>(); List <string> SetFileName = new List <string>(); List <int> Ids = new List <int>(); List <int> SetIds = new List <int>(); List <int> NotAdd = new List <int>(); AET temp; AetSet set; for (i = 0; i < AetSets.Length; i++) { set = AetSets[i]; if (set.Name != null) { if (SetName.Contains(set.Name)) { NotAdd.Add(i); continue; } else { SetName.Add(set.Name); } } if (set.FileName != null) { if (SetFileName.Contains(set.FileName)) { NotAdd.Add(i); continue; } else { SetFileName.Add(set.FileName); } } if (set.NewId) { AetSets[i].Id = null; for (i0 = 0; i0 < set.Aets.Length; i0++) { AetSets[i].Aets[i0].Id = null; } continue; } if (set.Id != null) { if (SetIds.Contains((int)set.Id)) { NotAdd.Add(i); continue; } else { SetIds.Add((int)set.Id); } } for (i0 = 0; i0 < set.Aets.Length; i0++) { temp = set.Aets[i0]; if (temp.Id != null) { if (Ids.Contains((int)temp.Id)) { NotAdd.Add(i); break; } else { Ids.Add((int)temp.Id); } } } } SetName = null; SetFileName = null; for (i = 0; i < AetSets.Length; i++) { set = AetSets[i]; if (NotAdd.Contains(i)) { continue; } if (!set.NewId) { continue; } i1 = 0; if (set.Id == null) { while (true) { if (!SetIds.Contains(i1)) { AetSets[i].Id = i1; SetIds.Add(i1); break; } i1++; } } for (i0 = 0, i1 = 0; i0 < set.Aets.Length; i0++) { if (set.Aets[i0].Id == null) { while (true) { if (!Ids.Contains(i1)) { AetSets[i].Aets[i0].Id = i1; Ids.Add(i1); break; } i1++; } } } } Ids = null; SetIds = null; for (i = 0, i0 = 0, i2 = 0; i < AetSets.Length; i++) { if (!NotAdd.Contains(i)) { i0 += AetSets[i].Aets.Length; i2++; } } i1 = i0 * 12; i1 = i1.Align(0x20) + 0x20; IO = File.OpenWriter(file + ".bin", true); IO.Write(i2); IO.Write(i1); IO.Write(i0); IO.Write(0x20); IO.Write(0x9066906690669066); IO.Write(0x9066906690669066); IO.Position = (i1 + i2 * 0x14).Align(0x20); for (i = 0; i < AetSets.Length; i++) { if (NotAdd.Contains(i)) { continue; } AetSets[i].NameOffset = IO.Position; IO.Write(AetSets[i].Name + "\0"); AetSets[i].FileNameOffset = IO.Position; IO.Write(AetSets[i].FileName + "\0"); } for (i = 0; i < AetSets.Length; i++) { if (NotAdd.Contains(i)) { continue; } for (i0 = 0; i0 < AetSets[i].Aets.Length; i0++) { AetSets[i].Aets[i0].NameOffset = IO.Position; IO.Write(AetSets[i].Aets[i0].Name + "\0"); } } IO.Align(0x08, true); IO.Position = 0x20; for (i = 0, i2 = 0; i < AetSets.Length; i++) { if (NotAdd.Contains(i)) { i2++; continue; } for (i0 = 0; i0 < AetSets[i].Aets.Length; i0++) { IO.Write(AetSets[i].Aets[i0].Id); IO.Write(AetSets[i].Aets[i0].NameOffset); IO.Write((ushort)i0); IO.Write((ushort)(i - i2)); } } IO.Align(0x20); for (i = 0, i2 = 0; i < AetSets.Length; i++) { if (NotAdd.Contains(i)) { i2++; continue; } IO.Write(AetSets[i].Id); IO.Write(AetSets[i].NameOffset); IO.Write(AetSets[i].FileNameOffset); IO.Write(i - i2); IO.Write(AetSets[i].SpriteSetId); } IO.Close(); }
public void DEXWriter(string filepath, Main.Format Format) { Header = new Header(); IO = File.OpenWriter(filepath + (Format > Main.Format.F ? ".dex" : ".bin"), true); Header.Format = IO.Format = Format; IO.Offset = Format > Main.Format.F ? 0x20 : 0; IO.Write(0x64); IO.Write(Dex.Length); IO.WriteX(Header.IsX ? 0x28 : 0x20); IO.WriteX(0x00); int Position0 = IO.Position; IO.Write(0x00L); IO.Write(0x00L); for (int i = 0; i < Dex.Length * 3; i++) { IO.WriteX(0x00); } IO.Align(0x20, true); for (int i0 = 0; i0 < Dex.Length; i0++) { Dex[i0].MainOffset = IO.Position; for (int i1 = 0; i1 < Dex[i0].Main.Count; i1++) { IO.Write(Dex[i0].Main[i1].Frame); IO.Write(Dex[i0].Main[i1].Both); IO.Write(Dex[i0].Main[i1].ID); IO.Write(Dex[i0].Main[i1].Value); IO.Write(Dex[i0].Main[i1].Trans); } IO.Align(0x20, true); Dex[i0].EyesOffset = IO.Position; for (int i1 = 0; i1 < Dex[i0].Eyes.Count; i1++) { IO.Write(Dex[i0].Eyes[i1].Frame); IO.Write(Dex[i0].Eyes[i1].Both); IO.Write(Dex[i0].Eyes[i1].ID); IO.Write(Dex[i0].Eyes[i1].Value); IO.Write(Dex[i0].Eyes[i1].Trans); } IO.Align(0x20, true); } for (int i0 = 0; i0 < Dex.Length; i0++) { Dex[i0].NameOffset = IO.Position; IO.Write(Dex[i0].Name + "\0"); } IO.Align(0x10, true); IO.Position = Header.IsX ? 0x28 : 0x20; for (int i0 = 0; i0 < Dex.Length; i0++) { IO.WriteX(Dex[i0].MainOffset); IO.WriteX(Dex[i0].EyesOffset); } int Position1 = IO.Position; for (int i0 = 0; i0 < Dex.Length; i0++) { IO.WriteX(Dex[i0].NameOffset); } IO.Position = Position0 - (Header.IsX ? 8 : 4); IO.Write(Position1); if (Format > Main.Format.F) { Offset = IO.Length; IO.Offset = 0; IO.Position = IO.Length; IO.WriteEOFC(0); IO.Position = 0; Header.DataSize = Offset; Header.SectionSize = Offset; Header.Signature = 0x43505845; IO.Write(Header, true); } IO.Close(); }