public byte[] Export(string[] Content) { using (var Strm = new MemoryStream()) using (StructWriter Writer = new StructWriter(Strm, Encoding: Encoding)) { var File = new TextDataFormat(); File.Content = Content; File.Count = Content.Length; File.Offsets = new TextDataEntryOffset[File.Count]; var Offset = 16 + (16 * File.Count); for (int i = 0; i < Content.Length; i++) { File.Offsets[i] = new TextDataEntryOffset() { Offset = Offset }; Offset += Encoding.GetByteCount(Content[i] + '\x0'); } Writer.WriteStruct(ref File); Writer.Flush(); foreach (var String in Content) { Writer.WriteString(String, StringStyle.CString); } return(Strm.ToArray()); } }
public byte[] Export(string[] Content) { var NewHeader = new HeaderFooter(); Tools.CopyStruct(Header, ref NewHeader); using (MemoryStream OriScript = new MemoryStream(Script)) using (MemoryStream Stream = new MemoryStream()) using (StructWriter Writer = new StructWriter(Stream, Header.Endian == 'B', Encoding)) { NewHeader.StructOffset = 0; OriScript.Position = Header.StructOffset; byte[] StructData = new byte[Align(Header.StructCount * Header.StructSize)]; OriScript.Read(StructData, 0, StructData.Length); NewHeader.TypesOffset = (uint)StructData.Length; OriScript.Position = Header.TypesOffset; byte[] TypeData = new byte[Align(Header.TypesCount * Tools.GetStructLength(new TypeDescriptor()))]; OriScript.Read(TypeData, 0, TypeData.Length); NewHeader.StringOffset = (uint)(NewHeader.TypesOffset + TypeData.Length); byte[] StrData; using (MemoryStream StrStream = new MemoryStream()) using (StructWriter StrWriter = new StructWriter(StrStream, Writer.BigEndian, Encoding)) { Dictionary <string, uint> OffsetMap = new Dictionary <string, uint>(); for (int i = 0; i < Content.Length; i++) { if (OffsetMap.ContainsKey(Content[i])) { var Offset = OffsetMap[Content[i]]; BitConverter.GetBytes(Offset).CopyTo(StructData, OffsetPos[i]); } else { BitConverter.GetBytes((uint)StrWriter.Position).CopyTo(StructData, OffsetPos[i]); OffsetMap[Content[i]] = (uint)StrWriter.Position; StrWriter.Write(Content[i], StringStyle.CString); } } StrWriter.Flush(); StrData = new byte[Align(StrStream.Length)]; StrStream.ToArray().CopyTo(StrData, 0); } Writer.Write(StructData); Writer.Write(TypeData); Writer.Write(StrData); Writer.WriteStruct(ref NewHeader); Writer.Flush(); return(Stream.ToArray()); } }
public static void Repack(File[] Files, Stream Output, bool CloseStreams = true) { if ((from x in Files where x.FileName == HeaderInfo select x).Count() != 1) { throw new Exception("Header Info Not Found"); } byte[] HInfo = new byte[0x7F8]; File tmp = (from x in Files where x.FileName == HeaderInfo select x).First(); tmp.Content.Read(HInfo, 0, HInfo.Length); tmp.Content.Close(); Files = (from x in Files where x.FileName != HeaderInfo select x).ToArray(); StructWriter Writer = new StructWriter(Output, Encoding: Encoding.ASCII); PACHeader Header = new PACHeader() { Signature = "PAC ", FileCount = (uint)Files.Length, Dummy = HInfo }; Writer.WriteStruct(ref Header); uint TotalHeaderLen = (uint)((Tools.GetStructLength(new File()) * Files.Length) + Tools.GetStructLength(Header)); for (uint i = 0, x = 0; i < Files.Length; i++) { tmp = new File() { FileName = Files[i].FileName, Length = (uint)Files[i].Content.Length, Offset = x + TotalHeaderLen }; Writer.WriteStruct(ref tmp); x += tmp.Length; } for (uint i = 0; i < Files.Length; i++) { Files[i].Content.CopyTo(Writer.BaseStream); if (CloseStreams) { Files[i].Content.Close(); } } Writer.Flush(); if (CloseStreams) { Writer.Close(); } }
public byte[] Export(string[] Strings) { if (Resource.Localizations.Length != Strings.Length) { throw new Exception("You can't add/remove strings from a locres file"); } for (int i = 0; i < Resource.Localizations.Length; i++) { Resource.Localizations[i].Content = Strings[i]; } using (var Stream = new MemoryStream()) using (var Writer = new StructWriter(Stream, Encoding: Encoding.Unicode)) { Writer.WriteStruct(ref Resource); Writer.Flush(); return(Stream.ToArray()); } }
public byte[] Export(string[] Content) { if (Content.Length != Data.Count) { throw new Exception("You Can't Modify The Count of Strings."); } using (MemoryStream Buffer = new MemoryStream()) using (StructWriter Writer = new StructWriter(Buffer, Encoding: Encoding)) { for (int i = 0; i < Content.Length; i++) { Entry Entry = Data[i]; Entry.Content = Content[i]; Writer.WriteStruct(ref Entry); } Writer.Flush(); return(Encrypt(Buffer.ToArray())); } }
public byte[] Export(string[] Text) { MemoryStream Script = new MemoryStream(Data); long StrIndex = 0; long LastPos = 0; byte[] Buffer = new byte[0]; using (MemoryStream Output = new MemoryStream()) using (StructReader Reader = new StructReader(Script, Encoding: Encoding)) using (StructWriter Writer = new StructWriter(Output, Encoding: Encoding)) { foreach (long BasePos in BlockPos) { Buffer = new byte[BasePos - LastPos]; Reader.Read(Buffer, 0, Buffer.Length); Writer.Write(Buffer, 0, Buffer.Length); BINv2Struct Struct = new BINv2Struct(); Reader.ReadStruct(ref Struct); LastPos = Reader.BaseStream.Position; for (uint i = 0; i < Struct.Strings.LongLength; i++) { Struct.Strings[i] = Text[i + StrIndex]; } StrIndex += Struct.Strings.LongLength; Writer.WriteStruct(ref Struct); } if (Reader.BaseStream.Position != Reader.BaseStream.Length) { Reader.BaseStream.CopyTo(Writer.BaseStream); } Writer.Flush(); return(Output.ToArray()); } }
public static void Save(Stream Output, Entry[] Content, bool BigEndian, bool SteamVer, bool CloseStreams = true) { uint HeaderSize = (SteamVer ? ExNameSize : NameSize) + 4; StructWriter Writer = new StructWriter(Output, BigEndian); object Section = SteamVer ? (object)new SteamSection() : new Section(); ((dynamic)Section).Name = SteamVer ? "Filename " : "Filename"; ((dynamic)Section).Event = new FieldInvoke(SectionEvent); long BasePos = (uint)(Content.LongLength * 4); List <byte> OffsetBuffer = new List <byte>((int)BasePos); List <byte> NameBuffer = new List <byte>(); foreach (Entry Entry in Content) { OffsetBuffer.Add((uint)(NameBuffer.Count + BasePos), BigEndian); NameBuffer.AddRange(Encoding.UTF8.GetBytes(Entry.Filename + "\x0")); } ((dynamic)Section).Data = OffsetBuffer.Concat(NameBuffer).ToArray(); Writer.WriteStruct(SteamVer ? typeof(SteamSection) : typeof(Section), ref Section); while (Writer.BaseStream.Position % (SteamVer ? 8 : 4) != 0) { Writer.Write((byte)0x00); } long PackStart = Writer.BaseStream.Position; ((dynamic)Section).Name = SteamVer ? "Pack " : "Pack "; List <byte> OffsetTable = new List <byte>(); OffsetTable.Add(Content.Length, BigEndian); BasePos = PackStart + HeaderSize + 4 + (Content.Length * 8); while (BasePos % (SteamVer ? 8 : 0x100) != 0) { BasePos++; } foreach (Entry Entry in Content) { OffsetTable.Add((uint)BasePos, BigEndian); OffsetTable.Add((uint)Entry.Content.Length, BigEndian); BasePos += Entry.Content.Length; while (!SteamVer && BasePos % 0x100 != 0) { BasePos++; } } ((dynamic)Section).Data = OffsetTable.ToArray(); Writer.WriteStruct(SteamVer ? typeof(SteamSection) : typeof(Section), ref Section); while (Writer.BaseStream.Position % (SteamVer ? 8 : 0x100) != 0) { Writer.Write((byte)0); } Writer.Flush(); foreach (Entry Entry in Content) { Entry.Content.Position = 0; Entry.Content.CopyTo(Output); while (!SteamVer && Output.Position % 0x100 != 0) { Output.WriteByte(0); } } while (SteamVer && Output.Position % 0x10 != 0) { Output.WriteByte(0); } Writer.Close(); Output?.Close(); }
public byte[] Export(string[] Strings) { uint[] Offsets = new uint[Strings.LongLength]; Database Header = new Database(); Tools.ReadStruct(Script, ref Header); byte[] Data; using (MemoryStream Output = new MemoryStream()) { Output.Write(Script, 0, (int)Header.StringTable); using (StructWriter Writer = new StructWriter(Output, Encoding: GetEncoding())) { //Write Strings and Generate Offset Table for (uint i = 0; i < Strings.LongLength; i++) { Offsets[i] = (uint)(Writer.BaseStream.Position) - Header.StringTable; Writer.Write(Strings[i], GetStrEnd()); Writer.Flush(); } //Update StrEnd Entry of the Header uint StrEnd = 0; while ((StrEnd = (uint)Output.Position) % 4 != Header.StringEnd % 4) { Output.WriteByte(0x00); } //Copy Content After the String Table Output.Write(Script, (int)Header.StringEnd, (int)(Script.LongLength - Header.StringEnd)); Header.StringEnd = StrEnd; Data = Output.ToArray(); //Update Offsets for (uint i = Header.ValueList, OID = 0, DFID = 0; i < Header.StringTable; i += 4) { if (DataFormat[(int)DFID]) { BitConverter.GetBytes(Offsets[OID++]).CopyTo(Data, i); } DFID++; if (DFID >= DataFormat.Count) { DFID = 0; } } } } Tools.BuildStruct(ref Header).CopyTo(Data, 0); Data = Encrypt(Data); #if !MAX && !COMP1 && !COMP2 && !COMP3 && !COMP4 && !COMP5 && !COMP6 && !COMP7 && !COMP8 FakeCompress(ref Data); #else Compress(ref Data); #endif XOR(ref Data, Begin: 1); return(Data); }
public void Encode(Bitmap Texture, Stream Output, bool CloseStreams = true) { StructWriter Writer = new StructWriter(Output, (bool)IsBigEnddian); Writer.Write(0x2065727574786554); if (SteamVersion.Value) { Writer.Write(0x20202020); Writer.Write(0); //0xC, section length Writer.WriteRawType(Const.UINT64, SteamUnk); Writer.Write(0); //0x18, pnglen Writer.WriteRawType(Const.UINT16, (ushort)TexSize.Width); Writer.WriteRawType(Const.UINT16, (ushort)TexSize.Height); } else { Writer.Write(0); //0x8, blocklen Writer.WriteRawType(Const.UINT32, Flags); Writer.Write(0); //0x10, pnglen Writer.WriteRawType(Const.UINT32, (uint)TexSize.Width); Writer.WriteRawType(Const.UINT32, (uint)TexSize.Height); } if (Tiled) { Texture = Retile(Texture); } uint SectionLength; if (SteamVersion.Value) { byte[] Buffer = new byte[Texture.Width * Texture.Height * 4]; fixed(void *pBuff = &Buffer[0]) { int Stride = Texture.Width; uint *pPixel = (uint *)pBuff; unchecked { for (int i = 0; i < Buffer.Length / 4; i++) { int X = i % Stride; int Y = i / Stride; uint ARGB = (uint)Texture.GetPixel(X, Y).ToArgb(); //ARGB => ABGR *pPixel++ = (ARGB & 0xFF00FF00) | ((ARGB & 0x00FF0000) >> 8 * 2) | ((ARGB & 0x000000FF) << 8 * 2); } } } if (Compressed) { Buffer = LZSSCompress(Buffer); } Writer.Write(Buffer); SectionLength = (uint)Writer.BaseStream.Position; uint TexLen = SectionLength - 0x20; Writer.Seek(0xC, 0); Writer.WriteRawType(Const.UINT32, SectionLength); Writer.Seek(0x18, 0); Writer.WriteRawType(Const.UINT32, TexLen); } else { Texture.Save(Writer.BaseStream, ImageFormat.Png); SectionLength = (uint)Writer.BaseStream.Position; uint PngLen = SectionLength - 0x1C; Writer.Seek(0x8, 0); Writer.WriteRawType(Const.UINT32, SectionLength); Writer.Seek(0x10, 0); Writer.WriteRawType(Const.UINT32, PngLen); } Writer.Seek(SectionLength, 0); while (Writer.BaseStream.Position % (SteamVersion.Value ? 8 : 4) != 0) { Writer.Write((byte)0x0); } StructReader Reader = new StructReader(this.Texture, (bool)IsBigEnddian); Reader.Seek(SteamVersion.Value ? 0x0C : 0x08, 0); Reader.Seek(Reader.ReadRawType(Const.UINT32), 0); while (Reader.BaseStream.Position % (SteamVersion.Value ? 8 : 4) != 0) { Reader.ReadByte(); } Reader.BaseStream.CopyTo(Writer.BaseStream); Writer.Flush(); if (CloseStreams) { Writer.Close(); Output?.Close(); } }
public void Save(Entry[] Entries, Stream Output) { if (this.Entries == null) { Open(); } if (this.Entries.LongLength != Entries.LongLength) { throw new Exception("You can't add or remove files from the packget."); } Packget.BaseStream.Position = 0x00; byte[] Buffer = new byte[DataBegin]; if (Packget.Read(Buffer, 0, Buffer.Length) != Buffer.Length) { throw new Exception("Failed to Copy the Static Header Data."); } StructWriter Writer = new StructWriter(Output, false, Encoding); Writer.Write(Buffer, 0, Buffer.Length); //Recovery File Order if (PackgetHeader.Flags != 0x3) { Entries = Entries.OrderBy(x => Convert.ToUInt32(Path.GetFileNameWithoutExtension(x.FileName).Trim(), 16)).ToArray(); } uint ContentBegin = Header.Offsets.First() + PackgetHeader.HeaderLen; uint BufferPos = ContentBegin; for (uint i = 0; i < Header.Offsets.Length; i++) { uint Length = (uint)Entries[i].Content.Length; Header.Offsets[i] = BufferPos - PackgetHeader.HeaderLen; Header.Lengths[i] = Length; BufferPos += Length + (uint)AsserionRequired(Length); if (PackgetHeader.Flags == 0x3) { Header.NamesOffset[i] = BufferPos - PackgetHeader.HeaderLen; uint StrLen = (uint)Encoding.GetByteCount(Entries[i].FileName + "\x0"); StrLen += (uint)AsserionRequired(StrLen); BufferPos += StrLen; } } Writer.WriteStruct(ref Header); if (Writer.BaseStream.Position < ContentBegin) { Buffer = new byte[ContentBegin - Writer.BaseStream.Position]; Packget.BaseStream.Position = Writer.BaseStream.Position; if (Packget.Read(Buffer, 0, Buffer.Length) != Buffer.Length) { throw new Exception("Failed to copy unk data"); } Writer.Write(Buffer, 0, Buffer.Length); } Writer.BaseStream.Position = ContentBegin; for (uint i = 0; i < Header.Offsets.Length; i++) { Entries[i].Content.CopyTo(Writer.BaseStream); byte[] Assertion = new byte[AsserionRequired(Writer.BaseStream.Position)]; Writer.Write(Assertion); if (PackgetHeader.Flags == 0x3) { byte[] Data = Encoding.GetBytes(Entries[i].FileName + "\x0"); Assertion = new byte[AsserionRequired(Data.Length)]; Writer.Write(Data); Writer.Write(Assertion); } } Writer.Flush(); }