├── .gitattributes ├── .gitignore ├── AMUSE ├── ArcPAC.cs ├── Binary.cs ├── Entry.cs ├── Program.cs └── Softpal.csproj ├── AVG_Engine ├── AVG_GPX.csproj ├── ArcGPX.cs ├── LittleEndian.cs ├── PackEntry.cs ├── Package.cs └── Program.cs ├── Ai6Win ├── Ai6Win.csproj ├── ArcAI6Win.cs ├── Entry.cs ├── LzssStream.cs ├── Program.cs └── Utility.cs ├── EAGLS ├── ArcPak.cs ├── CRuntimeRandomGenerator.cs ├── CgEncryption.cs ├── EaglsEncryption.cs ├── EaglsPak.csproj ├── IEntryEncryption.cs ├── IRandomGenerator.cs ├── LehmerRandomGenerator.cs ├── Note.txt ├── PackEntry.cs ├── Package.cs └── Program.cs ├── Escude ├── ArcBIN.cs ├── Binary.cs ├── BitStream.cs ├── Entry.cs ├── EscudeBin.csproj ├── LittleEndian.cs ├── LzwDecoder.cs ├── LzwEncoder.cs ├── MsbBitStream.cs └── Program.cs ├── Lilim ├── ArcAOS2.cs ├── BitStream.cs ├── Entry.cs ├── File.cs ├── Huffman.cs ├── HuffmanCompressor │ ├── HeapNode.cs │ ├── HuffmanEncoder.cs │ ├── MinHeap.cs │ └── TreeNode.cs ├── LilimAos.csproj ├── LilimAos.sln ├── MsbBitStream.cs ├── Program.cs └── build.cmd ├── NEJII ├── ArcCDT.cs ├── Entry.cs ├── LzssStream.cs ├── NejiiCDT.csproj └── Program.cs ├── NEKOSDK ├── ArcPAK.cs ├── ComponentAce │ └── Compression │ │ └── Libs │ │ └── zlib │ │ ├── Adler32.cs │ │ ├── Deflate.cs │ │ ├── InfBlocks.cs │ │ ├── InfCodes.cs │ │ ├── InfTree.cs │ │ ├── Inflate.cs │ │ ├── MyZlib.cs │ │ ├── StaticTree.cs │ │ ├── SupportClass.cs │ │ ├── Tree.cs │ │ ├── ZInputStream.cs │ │ ├── ZOutputStream.cs │ │ ├── ZStream.cs │ │ ├── ZStreamException.cs │ │ └── zlibConst.cs ├── Entry.cs ├── GameRes │ ├── Compression │ │ ├── BitStream.cs │ │ ├── CompressionLevel.cs │ │ ├── CompressionMode.cs │ │ ├── MsbBitStream.cs │ │ └── ZLibStream.cs │ └── Utility │ │ ├── Adler32.cs │ │ ├── CheckedStream.cs │ │ └── ICheckSum.cs ├── NEKOSDK.csproj └── Program.cs ├── Nexas ├── ArcPAC.cs ├── Compression.cs ├── Entry.cs ├── GameRes │ ├── Compression │ │ ├── BitStream.cs │ │ ├── CompressionLevel.cs │ │ ├── CompressionMode.cs │ │ ├── Huffman.cs │ │ ├── MsbBitStream.cs │ │ └── ZLibStream.cs │ └── Utility │ │ ├── Adler32.cs │ │ ├── CheckedStream.cs │ │ └── ICheckSum.cs ├── LzssStream.cs ├── Nexas.csproj └── Program.cs ├── README.md ├── Silky ├── ArcSilky.cs ├── Entry.cs ├── LzssStream.cs ├── Program.cs ├── SilkyArc.csproj └── Utility.cs ├── TmrHiro ├── ArcPac.cs ├── Binary.cs ├── Entry.cs ├── Program.cs ├── TmrHiro.csproj └── Utility.cs ├── Unity ├── ArcBIN.cs ├── BinDeserializer.cs ├── Binary.cs ├── Entry.cs ├── InputCryptoStream.cs ├── Note.txt ├── OutputCryptoStream.cs ├── Program.cs ├── UnityBin.csproj └── Utility.cs ├── Valkyria ├── ArcDat.cs ├── Entry.cs ├── Program.cs └── ValkyriaDat.csproj ├── Visual novel archive tools.sln ├── build.cmd └── codeX RScript ├── ArcXFL.cs ├── Entry.cs ├── Program.cs └── codeX RScript.csproj /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /AMUSE/ArcPAC.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Text; 5 | 6 | namespace AMUSE 7 | { 8 | internal class ArcPAC 9 | { 10 | private string GetStringLiteral(BinaryReader reader, uint index_offset, uint name_length) 11 | { 12 | List list = new List(); 13 | reader.BaseStream.Position = (long)((ulong)index_offset); 14 | byte[] array = reader.ReadBytes((int)name_length); 15 | int num = 0; 16 | while (num < array.Length && array[num] != 0) 17 | { 18 | list.Add(array[num]); 19 | num++; 20 | } 21 | return Encoding.GetEncoding(932).GetString(list.ToArray()); 22 | } 23 | protected List ReadIndex(BinaryReader reader, int count, uint index_offset, uint name_length) 24 | { 25 | for (int i = 0; i < count; i++) 26 | { 27 | string stringLiteral = this.GetStringLiteral(reader, index_offset, name_length); 28 | index_offset += name_length; 29 | Entry entry = new Entry(); 30 | reader.BaseStream.Position = (long)((ulong)index_offset); 31 | entry.Size = reader.ReadInt32(); 32 | entry.Offset = reader.ReadInt32(); 33 | entry.Name = stringLiteral; 34 | if ((long)(entry.Offset + entry.Size) > reader.BaseStream.Length) 35 | { 36 | throw new Exception("Unsupported file format!"); 37 | } 38 | this.dir.Add(entry); 39 | index_offset += 8U; 40 | } 41 | return this.dir; 42 | } 43 | public List TryOpen(string filePath) 44 | { 45 | this.buffer = File.ReadAllBytes(filePath); 46 | using (BinaryReader binaryReader = new BinaryReader(new MemoryStream(this.buffer))) 47 | { 48 | byte[] bytes = binaryReader.ReadBytes(4); 49 | if (!Encoding.ASCII.GetString(bytes).Equals("PAC ")) 50 | { 51 | throw new Exception("Unsupported file format!"); 52 | } 53 | binaryReader.ReadInt32(); 54 | int num = binaryReader.ReadInt32(); 55 | if (num > 4000) 56 | { 57 | throw new Exception("Unsupported file format!"); 58 | } 59 | uint num2 = 2052U; 60 | uint num3 = 32U; 61 | binaryReader.BaseStream.Position = (long)((ulong)(num2 + num3 + 4U)); 62 | if (binaryReader.ReadUInt32() != num2 + (uint)(num * (int)(num3 + 8U))) 63 | { 64 | throw new Exception("Unsupported file format!"); 65 | } 66 | this.ReadIndex(binaryReader, num, num2, num3); 67 | binaryReader.BaseStream.Position = 12L; 68 | this.blockBuffer = binaryReader.ReadBytes(2040); 69 | } 70 | return this.dir; 71 | } 72 | public unsafe byte[] Unpack(Entry entry) 73 | { 74 | byte[] array; 75 | using (BinaryReader binaryReader = new BinaryReader(new MemoryStream(this.buffer))) 76 | { 77 | binaryReader.BaseStream.Position = (long)entry.Offset; 78 | if (this.buffer[entry.Offset] != 36 || entry.Size <= 16) 79 | { 80 | array = binaryReader.ReadBytes(entry.Size); 81 | } 82 | else 83 | { 84 | array = binaryReader.ReadBytes(entry.Size); 85 | int num = (array.Length - 16) / 4; 86 | if (num > 0) 87 | { 88 | try 89 | { 90 | fixed (byte* ptr = &array[16]) 91 | { 92 | uint* ptr2 = (uint*)ptr; 93 | int num2 = 4; 94 | uint* ptr3 = ptr2 + num; 95 | while (ptr2 != ptr3) 96 | { 97 | byte* ptr4 = (byte*)ptr2; 98 | *ptr4 = Binary.RotByteL(*ptr4, num2++); 99 | *ptr2 ^= 4157965725U; 100 | ptr2++; 101 | } 102 | } 103 | } 104 | finally 105 | { 106 | byte* ptr = null; 107 | } 108 | } 109 | } 110 | } 111 | return array; 112 | } 113 | public unsafe void Pack(string packPath, string outputFile) 114 | { 115 | bool flag = false; 116 | byte[] array = new byte[2040]; 117 | List list = new List(); 118 | string[] files = Directory.GetFiles(packPath); 119 | for (int i = 0; i < files.Length; i++) 120 | { 121 | Entry entry = new Entry(); 122 | byte[] array2 = File.ReadAllBytes(files[i]); 123 | entry.fileBuffer = array2; 124 | entry.Name = Path.GetFileName(files[i]); 125 | if (entry.Name.Equals("block.tmp") && entry.fileBuffer.Length == 2040) 126 | { 127 | flag = true; 128 | array = array2; 129 | } 130 | else 131 | { 132 | list.Add(entry); 133 | } 134 | } 135 | if (!flag) 136 | { 137 | throw new Exception("Can't find block.tmp, please use this tool to unpack PAC to generate block.tmp!"); 138 | } 139 | string directoryName = Path.GetDirectoryName(packPath); 140 | using (BinaryWriter binaryWriter = new BinaryWriter(new FileStream(outputFile, FileMode.Create))) 141 | { 142 | int value = 541278544; 143 | binaryWriter.Write(value); 144 | binaryWriter.Flush(); 145 | int value2 = 0; 146 | binaryWriter.Write(value2); 147 | binaryWriter.Flush(); 148 | int count = list.Count; 149 | binaryWriter.Write(count); 150 | binaryWriter.Flush(); 151 | binaryWriter.Write(array); 152 | binaryWriter.Flush(); 153 | ulong num = 2052UL; 154 | uint num2 = 32U; 155 | uint num3 = (uint)(num + (ulong)((long)list.Count * (long)((ulong)(num2 + 8U)))); 156 | for (int j = 0; j < list.Count; j++) 157 | { 158 | byte[] bytes = Encoding.GetEncoding(932).GetBytes(list[j].Name); 159 | if (bytes.Length > 32) 160 | { 161 | throw new Exception("File's name is too long!"); 162 | } 163 | byte[] dst = new byte[32]; 164 | Buffer.BlockCopy(bytes, 0, dst, 0, bytes.Length); 165 | binaryWriter.Write(dst); 166 | binaryWriter.Flush(); 167 | binaryWriter.Write(list[j].fileBuffer.Length); 168 | binaryWriter.Flush(); 169 | binaryWriter.Write(num3); 170 | num3 += (uint)list[j].fileBuffer.Length; 171 | } 172 | for (int k = 0; k < list.Count; k++) 173 | { 174 | if (list[k].fileBuffer[0] != 36 || list[k].fileBuffer.Length <= 16) 175 | { 176 | binaryWriter.Write(list[k].fileBuffer); 177 | } 178 | else 179 | { 180 | int num4 = (list[k].fileBuffer.Length - 16) / 4; 181 | if (num4 > 0) 182 | { 183 | try 184 | { 185 | fixed (byte* ptr = &list[k].fileBuffer[16]) 186 | { 187 | uint* ptr2 = (uint*)ptr; 188 | int num5 = 4; 189 | uint* ptr3 = ptr2 + num4; 190 | while (ptr2 != ptr3) 191 | { 192 | byte* ptr4 = (byte*)ptr2; 193 | *ptr2 ^= 4157965725U; 194 | *ptr4 = Binary.RotByteR(*ptr4, num5++); 195 | ptr2++; 196 | } 197 | } 198 | } 199 | finally 200 | { 201 | byte* ptr = null; 202 | } 203 | } 204 | binaryWriter.Write(list[k].fileBuffer); 205 | } 206 | } 207 | } 208 | } 209 | private byte[] buffer; 210 | public byte[] blockBuffer; 211 | private List dir = new List(); 212 | } 213 | } 214 | -------------------------------------------------------------------------------- /AMUSE/Binary.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | 4 | namespace AMUSE 5 | { 6 | public static class Binary 7 | { 8 | public static byte RotByteR(byte v, int count) 9 | { 10 | count &= 7; 11 | return (byte)(v >> count | (int)v << 8 - count); 12 | } 13 | public static byte RotByteL(byte v, int count) 14 | { 15 | count &= 7; 16 | return (byte)((int)v << count | v >> 8 - count); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /AMUSE/Entry.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace AMUSE 4 | { 5 | public class Entry 6 | { 7 | public virtual string Name { get; set; } 8 | 9 | public virtual string SubName { get; set; } 10 | 11 | public virtual string Type { get; set; } 12 | 13 | public int filename_offset { get; set; } 14 | 15 | public int filename_length { get; set; } 16 | 17 | public int Offset { get; set; } 18 | 19 | public int Size { get; set; } 20 | 21 | public bool IsPacked { get; set; } 22 | 23 | public int UnpackedSize { get; set; } 24 | 25 | public long StructPosition { get; set; } 26 | 27 | public byte[] fileBuffer { get; set; } 28 | 29 | public Entry() 30 | { 31 | this.Type = ""; 32 | this.Offset = -1; 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /AMUSE/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Text; 5 | 6 | namespace AMUSE 7 | { 8 | class Program 9 | { 10 | static void Main(string[] args) 11 | { 12 | Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); 13 | if (args.Length < 2) 14 | { 15 | Console.WriteLine("Usage: "); 16 | Console.WriteLine(" Unpack: Pac.exe -u "); 17 | Console.WriteLine(" Pack: Pac.exe -p "); 18 | return; 19 | } 20 | 21 | string operation = args[0]; 22 | string inputFile = args[1]; 23 | string outputFile = args[2]; 24 | 25 | if (operation == "-u") 26 | { 27 | Unpack(inputFile, outputFile); 28 | } 29 | else if (operation == "-p") 30 | { 31 | Pack(inputFile, outputFile); 32 | } 33 | else 34 | { 35 | Console.WriteLine("Invalid operation. Valid operations are 'unpack' and 'pack'."); 36 | } 37 | } 38 | 39 | static void Unpack(string inputFile, string outputFile) 40 | { 41 | ArcPAC arcPAC = new ArcPAC(); 42 | try 43 | { 44 | Directory.CreateDirectory(outputFile); 45 | 46 | foreach (Entry entry in arcPAC.TryOpen(inputFile)) 47 | { 48 | byte[] bytes = arcPAC.Unpack(entry); 49 | System.IO.File.WriteAllBytes(Path.Combine(outputFile, entry.Name), bytes); 50 | } 51 | 52 | System.IO.File.WriteAllBytes(Path.Combine(outputFile, "block.tmp"), arcPAC.blockBuffer); 53 | } 54 | catch (Exception ex) 55 | { 56 | Console.WriteLine(ex.Message); 57 | return; 58 | } 59 | Console.WriteLine("Unpacked successfully!"); 60 | } 61 | 62 | static void Pack(string inputFile, string outputFile) 63 | { 64 | ArcPAC ArcPAC = new ArcPAC(); 65 | try 66 | { 67 | ArcPAC.Pack(inputFile, outputFile); 68 | } 69 | catch (Exception ex) 70 | { 71 | Console.WriteLine(ex.Message); 72 | return; 73 | } 74 | Console.WriteLine("Pack successfully!"); 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /AMUSE/Softpal.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net6.0 6 | enable 7 | enable 8 | true 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /AVG_Engine/AVG_GPX.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net6.0 6 | enable 7 | enable 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /AVG_Engine/LittleEndian.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace GPX 5 | { 6 | public static class LittleEndian 7 | { 8 | public static ushort ToUInt16(TArray value, int index) where TArray : IList 9 | { 10 | return (ushort)((int)value[index] | (int)value[index + 1] << 8); 11 | } 12 | public static short ToInt16(TArray value, int index) where TArray : IList 13 | { 14 | return (short)((int)value[index] | (int)value[index + 1] << 8); 15 | } 16 | public static uint ToUInt32(TArray value, int index) where TArray : IList 17 | { 18 | return (uint)((int)value[index] | (int)value[index + 1] << 8 | (int)value[index + 2] << 16 | (int)value[index + 3] << 24); 19 | } 20 | public static int ToInt32(TArray value, int index) where TArray : IList 21 | { 22 | return (int)LittleEndian.ToUInt32(value, index); 23 | } 24 | public static ulong ToUInt64(TArray value, int index) where TArray : IList 25 | { 26 | return (ulong)LittleEndian.ToUInt32(value, index) | (ulong)LittleEndian.ToUInt32(value, index + 4) << 32; 27 | } 28 | public static long ToInt64(TArray value, int index) where TArray : IList 29 | { 30 | return (long)LittleEndian.ToUInt64(value, index); 31 | } 32 | public static void Pack(ushort value, byte[] buf, int index) 33 | { 34 | buf[index] = (byte)value; 35 | buf[index + 1] = (byte)(value >> 8); 36 | } 37 | public static void Pack(uint value, byte[] buf, int index) 38 | { 39 | buf[index] = (byte)value; 40 | buf[index + 1] = (byte)(value >> 8); 41 | buf[index + 2] = (byte)(value >> 16); 42 | buf[index + 3] = (byte)(value >> 24); 43 | } 44 | public static void Pack(ulong value, byte[] buf, int index) 45 | { 46 | LittleEndian.Pack((uint)value, buf, index); 47 | LittleEndian.Pack((uint)(value >> 32), buf, index + 4); 48 | } 49 | public static void Pack(short value, byte[] buf, int index) 50 | { 51 | LittleEndian.Pack((ushort)value, buf, index); 52 | } 53 | public static void Pack(int value, byte[] buf, int index) 54 | { 55 | LittleEndian.Pack((uint)value, buf, index); 56 | } 57 | public static void Pack(long value, byte[] buf, int index) 58 | { 59 | LittleEndian.Pack((ulong)value, buf, index); 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /AVG_Engine/PackEntry.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace GPX 4 | { 5 | public class PackEntry 6 | { 7 | public virtual string Name { get; set; } 8 | public virtual string Type { get; set; } 9 | public long Offset { get; set; } 10 | public uint Size { get; set; } 11 | public bool IsPacked { get; set; } 12 | public int UnpackedSize { get; set; } 13 | public long StructPosition { get; set; } 14 | public int c1 { get; set; } 15 | public int c2 { get; set; } 16 | public byte[] fileBuffer { get; set; } 17 | public PackEntry() 18 | { 19 | this.Type = ""; 20 | this.Offset = -1L; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /AVG_Engine/Package.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace GPX 5 | { 6 | internal class Package 7 | { 8 | public byte[] buffer; 9 | 10 | public List dir = new List(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /AVG_Engine/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Text; 5 | 6 | namespace GPX 7 | { 8 | class Program 9 | { 10 | static void Main(string[] args) 11 | { 12 | if (args.Length < 3) 13 | { 14 | Console.WriteLine("Usage: "); 15 | Console.WriteLine(" Unpack: GPX.exe -u "); 16 | Console.WriteLine(" Pack: GPX.exe -p "); 17 | return; 18 | } 19 | 20 | string operation = args[0]; 21 | string inputFile = args[1]; 22 | string outputFile = args[2]; 23 | 24 | if (operation == "-u") 25 | { 26 | Unpack(inputFile, outputFile); 27 | } 28 | else if (operation == "-p") 29 | { 30 | Pack(inputFile, outputFile); 31 | } 32 | else 33 | { 34 | Console.WriteLine("Invalid operation. Valid operations are 'unpack' and 'pack'."); 35 | } 36 | } 37 | 38 | static void Unpack(string inputFile, string outputFolder) 39 | { 40 | ArcGPX arcGPX = new ArcGPX(); 41 | try 42 | { 43 | Directory.CreateDirectory(outputFolder); 44 | 45 | List entries = arcGPX.TryOpen(inputFile); 46 | foreach (PackEntry entry in entries) 47 | { 48 | byte[] bytes = arcGPX.Unpack(entry); 49 | string filePath = Path.Combine(outputFolder, entry.Name); 50 | string directory = Path.GetDirectoryName(filePath); 51 | if (!Directory.Exists(directory)) 52 | { 53 | Directory.CreateDirectory(directory); 54 | } 55 | File.WriteAllBytes(filePath, bytes); 56 | } 57 | 58 | // Create block.tmp 59 | File.WriteAllBytes(Path.Combine(outputFolder, "block.tmp"), arcGPX.fileHead); 60 | 61 | // Create FileList.txt 62 | using (StreamWriter writer = new StreamWriter(new FileStream(Path.Combine(outputFolder, "FileList.txt"), FileMode.Create), Encoding.UTF8)) 63 | { 64 | for (int i = 0; i < entries.Count; i++) 65 | { 66 | writer.WriteLine(entries[i].Name); 67 | writer.Flush(); 68 | writer.WriteLine(entries[i].c1.ToString()); 69 | writer.Flush(); 70 | writer.WriteLine(entries[i].c2.ToString()); 71 | writer.Flush(); 72 | } 73 | } 74 | } 75 | catch (Exception ex) 76 | { 77 | Console.WriteLine(ex.Message); 78 | return; 79 | } 80 | Console.WriteLine("Unpacked successfully!"); 81 | } 82 | 83 | static void Pack(string inputFolder, string outputFile) 84 | { 85 | ArcGPX arcGPX = new ArcGPX(); 86 | try 87 | { 88 | arcGPX.Pack(inputFolder, outputFile); 89 | } 90 | catch (Exception ex) 91 | { 92 | Console.WriteLine(ex.Message); 93 | return; 94 | } 95 | Console.WriteLine("Packed successfully!"); 96 | } 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /Ai6Win/Ai6Win.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net6.0 6 | enable 7 | enable 8 | true 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Ai6Win/ArcAI6Win.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.IO.Compression; 5 | using System.Text; 6 | 7 | namespace Ai6Win 8 | { 9 | internal class ArcAI6Win 10 | { 11 | public List TryOpen(string filePath) 12 | { 13 | this.buffer = File.ReadAllBytes(filePath); 14 | using (BinaryReader binaryReader = new BinaryReader(new MemoryStream(this.buffer))) 15 | { 16 | int num = binaryReader.ReadInt32(); 17 | if (num > 16384) 18 | { 19 | throw new Exception("Unsupported file format!"); 20 | } 21 | if ((ulong)(num * 272) > (ulong)binaryReader.BaseStream.Length) 22 | { 23 | throw new Exception("Unsupported file format!"); 24 | } 25 | for (int i = 0; i < num; i++) 26 | { 27 | byte[] array = binaryReader.ReadBytes(260); 28 | int num2 = Array.IndexOf(array, 0); 29 | if (num2 == 0) 30 | { 31 | throw new Exception("Unsupported file format!"); 32 | } 33 | if (-1 == num2) 34 | { 35 | num2 = array.Length; 36 | } 37 | byte b = (byte)(num2 + 1); 38 | for (int j = 0; j < num2; j++) 39 | { 40 | byte[] array2 = array; 41 | int num3 = j; 42 | byte b2 = array2[num3]; 43 | byte b3 = b; 44 | b = (byte)(b3 - 1); 45 | array2[num3] = (byte)(b2 - b3); 46 | } 47 | string @string = Encoding.GetEncoding(932).GetString(array, 0, num2); 48 | Entry entry = new Entry(); 49 | if (@string.Equals("sis4__scene000.mes")) 50 | { 51 | string.Format("", new object[0]); 52 | } 53 | entry.Name = @string; 54 | entry.Size = Binary.BigEndian(binaryReader.ReadUInt32()); 55 | entry.UnpackedSize = (int)Binary.BigEndian(binaryReader.ReadUInt32()); 56 | entry.Offset = (long)((ulong)Binary.BigEndian(binaryReader.ReadUInt32())); 57 | if (entry.Offset + (long)((ulong)entry.Size) > binaryReader.BaseStream.Length) 58 | { 59 | throw new Exception("Unsupported file format!"); 60 | } 61 | entry.IsPacked = ((ulong)entry.Size != (ulong)((long)entry.UnpackedSize)); 62 | this.dir.Add(entry); 63 | } 64 | } 65 | return this.dir; 66 | } 67 | public byte[] Unpack(Entry entry) 68 | { 69 | byte[] result; 70 | using (BinaryReader binaryReader = new BinaryReader(new MemoryStream(this.buffer))) 71 | { 72 | binaryReader.BaseStream.Position = entry.Offset; 73 | result = binaryReader.ReadBytes((int)entry.Size); 74 | } 75 | if (entry.IsPacked) 76 | { 77 | byte[] result2; 78 | using (LzssStream lzssStream = new LzssStream(new MemoryStream(result), CompressionMode.Decompress)) 79 | { 80 | result2 = new byte[entry.UnpackedSize]; 81 | lzssStream.Read(result2, 0, entry.UnpackedSize); 82 | } 83 | return result2; 84 | } 85 | return result; 86 | } 87 | public void Pack(string packPath, string outputFile) 88 | { 89 | List list = new List(); 90 | bool flag = true; 91 | string[] files = Directory.GetFiles(packPath); 92 | if (Path.GetFileName(packPath).Equals("layer")) 93 | { 94 | flag = false; 95 | } 96 | for (int i = 0; i < files.Length; i++) 97 | { 98 | Entry entry = new Entry(); 99 | byte[] array = File.ReadAllBytes(files[i]); 100 | if (flag) 101 | { 102 | byte[] src = new byte[array.Length * 2]; 103 | byte[] array2; 104 | int lastCodeLength; 105 | using (LzssStream lzssStream = new LzssStream(new MemoryStream(src), CompressionMode.Compress)) 106 | { 107 | lzssStream.Write(array, 0, array.Length); 108 | if (lzssStream.LastCodeLength == 0) 109 | { 110 | throw new Exception("Failed to compress!"); 111 | } 112 | array2 = new byte[lzssStream.LastCodeLength]; 113 | lastCodeLength = lzssStream.LastCodeLength; 114 | } 115 | Buffer.BlockCopy(src, 0, array2, 0, lastCodeLength); 116 | entry.fileBuffer = array2; 117 | entry.UnpackedSize = array.Length; 118 | entry.IsPacked = true; 119 | entry.Name = Path.GetFileName(files[i]); 120 | list.Add(entry); 121 | } 122 | else 123 | { 124 | entry.fileBuffer = array; 125 | entry.UnpackedSize = array.Length; 126 | entry.IsPacked = false; 127 | entry.Name = Path.GetFileName(files[i]); 128 | list.Add(entry); 129 | } 130 | } 131 | string directoryName = Path.GetDirectoryName(packPath); 132 | uint num = (uint)(list.Count * 260 + list.Count * 12 + 4); 133 | using (BinaryWriter binaryWriter = new BinaryWriter(new FileStream(outputFile, FileMode.Create))) 134 | { 135 | int count = list.Count; 136 | binaryWriter.Write(count); 137 | binaryWriter.Flush(); 138 | for (int j = 0; j < list.Count; j++) 139 | { 140 | byte[] bytes = Encoding.GetEncoding(932).GetBytes(list[j].Name); 141 | if (bytes.Length > 259) 142 | { 143 | throw new Exception("File's name is too long!"); 144 | } 145 | byte b = (byte)(bytes.Length + 1); 146 | for (int k = 0; k < bytes.Length; k++) 147 | { 148 | byte[] array3 = bytes; 149 | int num2 = k; 150 | byte b2 = array3[num2]; 151 | byte b3 = b; 152 | b = (byte)(b3 - 1); 153 | array3[num2] = (byte)(b2 + b3); 154 | } 155 | byte[] dst = new byte[260]; 156 | Buffer.BlockCopy(bytes, 0, dst, 0, bytes.Length); 157 | binaryWriter.Write(dst); 158 | binaryWriter.Flush(); 159 | uint value = Binary.ToBigEndian((uint)list[j].fileBuffer.Length); 160 | uint value2 = Binary.ToBigEndian((uint)list[j].UnpackedSize); 161 | uint value3 = Binary.ToBigEndian(num); 162 | num += (uint)list[j].fileBuffer.Length; 163 | binaryWriter.Write(value); 164 | binaryWriter.Flush(); 165 | binaryWriter.Write(value2); 166 | binaryWriter.Flush(); 167 | binaryWriter.Write(value3); 168 | binaryWriter.Flush(); 169 | } 170 | for (int l = 0; l < list.Count; l++) 171 | { 172 | binaryWriter.Write(list[l].fileBuffer); 173 | binaryWriter.Flush(); 174 | } 175 | } 176 | } 177 | private byte[] buffer; 178 | private List dir = new List(); 179 | } 180 | } 181 | -------------------------------------------------------------------------------- /Ai6Win/Entry.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Ai6Win 4 | { 5 | public class Entry 6 | { 7 | public virtual string Name { get; set; } 8 | 9 | public virtual string Type { get; set; } 10 | 11 | public long Offset { get; set; } 12 | 13 | public uint Size { get; set; } 14 | 15 | public bool IsPacked { get; set; } 16 | 17 | public int UnpackedSize { get; set; } 18 | 19 | public long StructPosition { get; set; } 20 | 21 | public byte[] fileBuffer { get; set; } 22 | 23 | public Entry() 24 | { 25 | this.Type = ""; 26 | this.Offset = -1L; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Ai6Win/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Text; 5 | 6 | namespace Ai6Win 7 | { 8 | class Program 9 | { 10 | static void Main(string[] args) 11 | { 12 | Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); 13 | if (args.Length < 2) 14 | { 15 | Console.WriteLine("Usage: "); 16 | Console.WriteLine(" Unpack: Arc.exe -u "); 17 | Console.WriteLine(" Pack: Arc.exe -p "); 18 | return; 19 | } 20 | 21 | string operation = args[0]; 22 | string inputFile = args[1]; 23 | string outputFile = args[2]; 24 | 25 | if (operation == "-u") 26 | { 27 | Unpack(inputFile, outputFile); 28 | } 29 | else if (operation == "-p") 30 | { 31 | Pack(inputFile, outputFile); 32 | } 33 | else 34 | { 35 | Console.WriteLine("Invalid operation. Valid operations are 'unpack' and 'pack'."); 36 | } 37 | } 38 | 39 | static void Unpack(string inputFile, string outputFile) 40 | { 41 | ArcAI6Win ArcAI6Win = new ArcAI6Win(); 42 | try 43 | { 44 | Directory.CreateDirectory(outputFile); 45 | 46 | foreach (Entry entry in ArcAI6Win.TryOpen(inputFile)) 47 | { 48 | byte[] bytes = ArcAI6Win.Unpack(entry); 49 | System.IO.File.WriteAllBytes(Path.Combine(outputFile, entry.Name), bytes); 50 | } 51 | } 52 | catch (Exception ex) 53 | { 54 | Console.WriteLine(ex.Message); 55 | return; 56 | } 57 | Console.WriteLine("Unpacked successfully!"); 58 | } 59 | 60 | static void Pack(string inputFile, string outputFile) 61 | { 62 | ArcAI6Win ArcAI6Win = new ArcAI6Win(); 63 | try 64 | { 65 | ArcAI6Win.Pack(inputFile, outputFile); 66 | } 67 | catch (Exception ex) 68 | { 69 | Console.WriteLine(ex.Message); 70 | return; 71 | } 72 | Console.WriteLine("Pack successfully!"); 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /Ai6Win/Utility.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | 4 | namespace Ai6Win 5 | { 6 | public static class Binary 7 | { 8 | public static uint BigEndian(uint u) 9 | { 10 | return u << 24 | (u & 65280U) << 8 | (u & 16711680U) >> 8 | u >> 24; 11 | } 12 | 13 | public static uint ToBigEndian(uint u) 14 | { 15 | return u >> 24 | (u & 16711680U) >> 8 | (u & 65280U) << 8 | u << 24; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /EAGLS/ArcPak.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Text; 5 | 6 | namespace EAGLS 7 | { 8 | internal class ArcPak 9 | { 10 | public byte[] CrypteIndex(byte[] index, int indexSize) 11 | { 12 | CRuntimeRandomGenerator cruntimeRandomGenerator = new CRuntimeRandomGenerator(); 13 | cruntimeRandomGenerator.SRand(indexSize); 14 | byte[] array = new byte[indexSize]; 15 | for (int i = 0; i < indexSize; i++) 16 | { 17 | int num = (int)ArcPak.IndexKey[cruntimeRandomGenerator.Rand() % ArcPak.IndexKey.Length]; 18 | array[i] = (byte)((int)index[i] ^ num); 19 | } 20 | return array; 21 | } 22 | public void EnCrypteIndex(byte[] index, int indexSize, int seed) 23 | { 24 | CRuntimeRandomGenerator cruntimeRandomGenerator = new CRuntimeRandomGenerator(); 25 | cruntimeRandomGenerator.SRand(seed); 26 | for (int i = 0; i < indexSize; i++) 27 | { 28 | if (i + 1 == indexSize) 29 | { 30 | string.Format("sd", new object[0]); 31 | } 32 | int num = (int)ArcPak.IndexKey[cruntimeRandomGenerator.Rand() % ArcPak.IndexKey.Length]; 33 | index[i] = (byte)((int)index[i] ^ num); 34 | } 35 | } 36 | public void Pack(string packPath) 37 | { 38 | List list = new List(); 39 | string[] files = Directory.GetFiles(packPath); 40 | for (int i = 0; i < files.Length; i++) 41 | { 42 | PackEntry packEntry = new PackEntry(); 43 | byte[] fileBuffer = File.ReadAllBytes(files[i]); 44 | packEntry.fileBuffer = fileBuffer; 45 | packEntry.Name = Path.GetFileName(files[i]); 46 | list.Add(packEntry); 47 | } 48 | string directoryName = Path.GetDirectoryName(packPath); 49 | string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(packPath); 50 | string path = Path.Combine(directoryName, fileNameWithoutExtension + ".pak"); 51 | string path2 = Path.Combine(directoryName, fileNameWithoutExtension + ".idx"); 52 | long num = 0L; 53 | MemoryStream memoryStream = new MemoryStream(new byte[400004]); 54 | byte[] array; 55 | using (BinaryWriter binaryWriter = new BinaryWriter(memoryStream)) 56 | { 57 | for (int j = 0; j < list.Count; j++) 58 | { 59 | byte[] bytes = Encoding.GetEncoding(932).GetBytes(list[j].Name); 60 | if (bytes.Length > 24) 61 | { 62 | throw new Exception("Files' name are too long!"); 63 | } 64 | byte[] dst = new byte[24]; 65 | Buffer.BlockCopy(bytes, 0, dst, 0, bytes.Length); 66 | binaryWriter.Write(dst); 67 | binaryWriter.Flush(); 68 | binaryWriter.Write(num); 69 | num += (long)list[j].fileBuffer.Length; 70 | binaryWriter.Write(list[j].fileBuffer.Length); 71 | binaryWriter.Flush(); 72 | int value = 0; 73 | binaryWriter.Write(value); 74 | binaryWriter.Flush(); 75 | } 76 | int num2 = (int)binaryWriter.BaseStream.Length; 77 | binaryWriter.BaseStream.Position = binaryWriter.BaseStream.Length - 4L; 78 | binaryWriter.Write(num2); 79 | binaryWriter.Flush(); 80 | array = memoryStream.ToArray(); 81 | this.EnCrypteIndex(array, 400000, num2); 82 | } 83 | File.WriteAllBytes(path2, array); 84 | EaglsEncryption eaglsEncryption = new EaglsEncryption(); 85 | LehmerRandomGenerator lehmerRandomGenerator = new LehmerRandomGenerator(); 86 | lehmerRandomGenerator.setSeed(2039843147); 87 | CgEncryption cgEncryption = new CgEncryption(lehmerRandomGenerator); 88 | using (BinaryWriter binaryWriter2 = new BinaryWriter(new FileStream(path, FileMode.Create))) 89 | { 90 | for (int k = 0; k < list.Count; k++) 91 | { 92 | byte[] bytes2 = new byte[1]; 93 | string extension = Path.GetExtension(list[k].Name); 94 | if (extension.Equals(".dat")) 95 | { 96 | bytes2 = eaglsEncryption.Decrypt(list[k].fileBuffer); 97 | File.WriteAllBytes(Path.Combine(directoryName, list[k].Name), bytes2); 98 | } 99 | else if (extension.Equals("gr")) 100 | { 101 | bytes2 = cgEncryption.Decrypt(list[k].fileBuffer); 102 | } 103 | else 104 | { 105 | bytes2 = list[k].fileBuffer; 106 | } 107 | binaryWriter2.Write(bytes2); 108 | } 109 | } 110 | } 111 | internal static readonly string IndexKey = "1qaz2wsx3edc4rfv5tgb6yhn7ujm8ik,9ol.0p;/-@:^[]"; 112 | internal static readonly byte[] EaglsKey = Encoding.ASCII.GetBytes("EAGLS_SYSTEM"); 113 | internal static readonly byte[] AdvSysKey = Encoding.ASCII.GetBytes("ADVSYS"); 114 | private byte[] buffer; 115 | private List dir = new List(); 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /EAGLS/CRuntimeRandomGenerator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace EAGLS 4 | { 5 | public class CRuntimeRandomGenerator : IRandomGenerator 6 | { 7 | public void SRand(int seed) 8 | { 9 | this.m_seed = (uint)seed; 10 | } 11 | public int Rand() 12 | { 13 | this.m_seed = this.m_seed * 214013U + 2531011U; 14 | return (int)(this.m_seed >> 16 & 32767U); 15 | } 16 | public uint m_seed; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /EAGLS/CgEncryption.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace EAGLS 4 | { 5 | public class CgEncryption 6 | { 7 | public CgEncryption(IRandomGenerator rng) 8 | { 9 | this.m_rng = rng; 10 | } 11 | public byte[] Decrypt(byte[] data) 12 | { 13 | this.m_rng.SRand((int)data[data.Length - 1]); 14 | int num = Math.Min(data.Length - 1, 5963); 15 | for (int i = 0; i < num; i++) 16 | { 17 | int num2 = i; 18 | data[num2] ^= this.Key[this.m_rng.Rand() % this.Key.Length]; 19 | } 20 | return data; 21 | } 22 | private readonly byte[] Key = ArcPak.EaglsKey; 23 | private readonly IRandomGenerator m_rng; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /EAGLS/EaglsEncryption.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace EAGLS 4 | { 5 | public class EaglsEncryption 6 | { 7 | public EaglsEncryption() 8 | { 9 | this.m_rng = new CRuntimeRandomGenerator(); 10 | } 11 | public byte[] Decrypt(byte[] data) 12 | { 13 | int num = 3600; 14 | int num2 = data.Length - num - 2; 15 | this.m_rng.SRand((int)((sbyte)data[data.Length - 1])); 16 | for (int i = 0; i < num2; i += 2) 17 | { 18 | int num3 = num + i; 19 | data[num3] ^= this.Key[this.m_rng.Rand() % this.Key.Length]; 20 | } 21 | return data; 22 | } 23 | private readonly byte[] Key = ArcPak.EaglsKey; 24 | private readonly CRuntimeRandomGenerator m_rng; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /EAGLS/EaglsPak.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net6.0 6 | enable 7 | enable 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /EAGLS/IEntryEncryption.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace EAGLS 4 | { 5 | public interface IEntryEncryption 6 | { 7 | void Decrypt(byte[] data); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /EAGLS/IRandomGenerator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace EAGLS 4 | { 5 | public interface IRandomGenerator 6 | { 7 | void SRand(int seed); 8 | int Rand(); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /EAGLS/LehmerRandomGenerator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace EAGLS 4 | { 5 | public class LehmerRandomGenerator : IRandomGenerator 6 | { 7 | public void SRand(int seed) 8 | { 9 | this.m_seed = (seed ^ 123459876); 10 | } 11 | public void setSeed(int seed) 12 | { 13 | this.m_seed = seed; 14 | } 15 | public int Rand() 16 | { 17 | this.m_seed = 48271 * (this.m_seed % 44488) - 3399 * (this.m_seed / 44488); 18 | if (this.m_seed < 0) 19 | { 20 | this.m_seed += int.MaxValue; 21 | } 22 | return (int)((double)this.m_seed * 4.656612875245797E-10 * 256.0); 23 | } 24 | private int m_seed; 25 | private const int A = 48271; 26 | private const int Q = 44488; 27 | private const int R = 3399; 28 | private const int M = 2147483647; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /EAGLS/Note.txt: -------------------------------------------------------------------------------- 1 | Use GARbro to unpack 2 | 3 | Just drag&drop folder to the exe to pack -------------------------------------------------------------------------------- /EAGLS/PackEntry.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace EAGLS 4 | { 5 | public class PackEntry 6 | { 7 | public virtual string Name { get; set; } 8 | public virtual string Type { get; set; } 9 | public long Offset { get; set; } 10 | public uint Size { get; set; } 11 | public bool IsPacked { get; set; } 12 | public int UnpackedSize { get; set; } 13 | public long StructPosition { get; set; } 14 | public int c1 { get; set; } 15 | public int c2 { get; set; } 16 | public byte[] fileBuffer { get; set; } 17 | public PackEntry() 18 | { 19 | this.Type = ""; 20 | this.Offset = -1L; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /EAGLS/Package.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace EAGLS 5 | { 6 | internal class Package 7 | { 8 | public byte[] buffer; 9 | public List dir = new List(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /EAGLS/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Text; 5 | using System.Linq; 6 | 7 | namespace EAGLS 8 | { 9 | class Program 10 | { 11 | static void Main(string[] args) 12 | { 13 | Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); 14 | string packPath; 15 | if (args.Length > 0) 16 | { 17 | packPath = args[0]; 18 | } 19 | else 20 | { 21 | Console.WriteLine("Please input the pack path in the command line or drag a folder onto the executable."); 22 | return; 23 | } 24 | 25 | ArcPak ArcPak = new ArcPak(); 26 | try 27 | { 28 | ArcPak.Pack(packPath); 29 | } 30 | catch (Exception ex) 31 | { 32 | Console.WriteLine(ex.Message); 33 | return; 34 | } 35 | Console.WriteLine("Pack successfully!"); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Escude/Binary.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | 4 | namespace Escu 5 | { 6 | public static class Binary 7 | { 8 | public static uint BigEndian(uint u) 9 | { 10 | return u << 24 | (u & 65280U) << 8 | (u & 16711680U) >> 8 | u >> 24; 11 | } 12 | public static uint ToBigEndian(uint u) 13 | { 14 | return u >> 24 | (u & 16711680U) >> 8 | (u & 65280U) << 8 | u << 24; 15 | } 16 | public static short ToBigEndianUint16(short u) 17 | { 18 | return (short)(u >> 8 | (int)u << 8); 19 | } 20 | public static int BigEndian(int i) 21 | { 22 | return (int)Binary.BigEndian((uint)i); 23 | } 24 | public static ushort BigEndian(ushort u) 25 | { 26 | return (ushort)((int)u << 8 | u >> 8); 27 | } 28 | public static short BigEndian(short i) 29 | { 30 | return (short)Binary.BigEndian((ushort)i); 31 | } 32 | public static ulong BigEndian(ulong u) 33 | { 34 | return (ulong)Binary.BigEndian((uint)(u & (ulong)uint.MaxValue)) << 32 | (ulong)Binary.BigEndian((uint)(u >> 32)); 35 | } 36 | public static long BigEndian(long i) 37 | { 38 | return (long)Binary.BigEndian((ulong)i); 39 | } 40 | public static void CopyOverlapped(byte[] data, int src, int dst, int count) 41 | { 42 | if (dst > src) 43 | { 44 | while (count > 0) 45 | { 46 | int num = Math.Min(dst - src, count); 47 | Buffer.BlockCopy(data, src, data, dst, num); 48 | dst += num; 49 | count -= num; 50 | } 51 | return; 52 | } 53 | Buffer.BlockCopy(data, src, data, dst, count); 54 | } 55 | public static string GetCString(byte[] data, int index, int length_limit, Encoding enc) 56 | { 57 | int num = 0; 58 | while (num < length_limit && data[index + num] != 0) 59 | { 60 | num++; 61 | } 62 | return enc.GetString(data, index, num); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /Escude/BitStream.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace Escu 5 | { 6 | public class BitStream : IDisposable 7 | { 8 | public Stream Input 9 | { 10 | get 11 | { 12 | return this.m_input; 13 | } 14 | } 15 | public int CacheSize 16 | { 17 | get 18 | { 19 | return this.m_cached_bits; 20 | } 21 | } 22 | protected BitStream(Stream file, bool leave_open) 23 | { 24 | this.m_input = file; 25 | this.m_should_dispose = !leave_open; 26 | } 27 | public void Reset() 28 | { 29 | this.m_cached_bits = 0; 30 | } 31 | public void Dispose() 32 | { 33 | this.Dispose(true); 34 | GC.SuppressFinalize(this); 35 | } 36 | protected virtual void Dispose(bool disposing) 37 | { 38 | if (!this.m_disposed) 39 | { 40 | if (disposing && this.m_should_dispose && this.m_input != null) 41 | { 42 | this.m_input.Dispose(); 43 | } 44 | this.m_disposed = true; 45 | } 46 | } 47 | protected Stream m_input; 48 | private bool m_should_dispose; 49 | protected int m_bits; 50 | protected int m_cached_bits; 51 | private bool m_disposed; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Escude/Entry.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Escu 4 | { 5 | public class Entry 6 | { 7 | public virtual string Name { get; set; } 8 | public virtual string SubName { get; set; } 9 | public virtual string Type { get; set; } 10 | public int filename_offset { get; set; } 11 | public int filename_length { get; set; } 12 | public int Offset { get; set; } 13 | public uint Size { get; set; } 14 | public bool IsPacked { get; set; } 15 | public int UnpackedSize { get; set; } 16 | public long StructPosition { get; set; } 17 | public byte[] fileBuffer { get; set; } 18 | public Entry() 19 | { 20 | this.Type = ""; 21 | this.Offset = -1; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Escude/EscudeBin.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net6.0 6 | enable 7 | enable 8 | true 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Escude/LittleEndian.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Escu 5 | { 6 | public static class LittleEndian 7 | { 8 | public static ushort ToUInt16(TArray value, int index) where TArray : IList 9 | { 10 | return (ushort)((int)value[index] | (int)value[index + 1] << 8); 11 | } 12 | public static short ToInt16(TArray value, int index) where TArray : IList 13 | { 14 | return (short)((int)value[index] | (int)value[index + 1] << 8); 15 | } 16 | public static uint ToUInt32(TArray value, int index) where TArray : IList 17 | { 18 | return (uint)((int)value[index] | (int)value[index + 1] << 8 | (int)value[index + 2] << 16 | (int)value[index + 3] << 24); 19 | } 20 | public static int ToInt32(TArray value, int index) where TArray : IList 21 | { 22 | return (int)LittleEndian.ToUInt32(value, index); 23 | } 24 | public static ulong ToUInt64(TArray value, int index) where TArray : IList 25 | { 26 | return (ulong)LittleEndian.ToUInt32(value, index) | (ulong)LittleEndian.ToUInt32(value, index + 4) << 32; 27 | } 28 | public static long ToInt64(TArray value, int index) where TArray : IList 29 | { 30 | return (long)LittleEndian.ToUInt64(value, index); 31 | } 32 | public static void Pack(ushort value, byte[] buf, int index) 33 | { 34 | buf[index] = (byte)value; 35 | buf[index + 1] = (byte)(value >> 8); 36 | } 37 | public static void Pack(uint value, byte[] buf, int index) 38 | { 39 | buf[index] = (byte)value; 40 | buf[index + 1] = (byte)(value >> 8); 41 | buf[index + 2] = (byte)(value >> 16); 42 | buf[index + 3] = (byte)(value >> 24); 43 | } 44 | public static void Pack(ulong value, byte[] buf, int index) 45 | { 46 | LittleEndian.Pack((uint)value, buf, index); 47 | LittleEndian.Pack((uint)(value >> 32), buf, index + 4); 48 | } 49 | public static void Pack(short value, byte[] buf, int index) 50 | { 51 | LittleEndian.Pack((ushort)value, buf, index); 52 | } 53 | public static void Pack(int value, byte[] buf, int index) 54 | { 55 | LittleEndian.Pack((uint)value, buf, index); 56 | } 57 | public static void Pack(long value, byte[] buf, int index) 58 | { 59 | LittleEndian.Pack((ulong)value, buf, index); 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /Escude/LzwDecoder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace Escu 5 | { 6 | internal sealed class LzwDecoder : IDisposable 7 | { 8 | public byte[] Output 9 | { 10 | get 11 | { 12 | return this.m_output; 13 | } 14 | } 15 | public LzwDecoder(Stream input, int unpacked_size) 16 | { 17 | this.m_input = new MsbBitStream(input, true); 18 | this.m_output = new byte[unpacked_size]; 19 | } 20 | public void Unpack() 21 | { 22 | int i = 0; 23 | int[] array = new int[35072]; 24 | int num = 9; 25 | int num2 = 0; 26 | while (i < this.m_output.Length) 27 | { 28 | int num3 = this.m_input.GetBits(num); 29 | if (-1 == num3) 30 | { 31 | throw new EndOfStreamException("Invalid compressed stream"); 32 | } 33 | if (256 == num3) 34 | { 35 | break; 36 | } 37 | if (257 == num3) 38 | { 39 | num++; 40 | if (num > 24) 41 | { 42 | throw new Exception("Invalid comressed stream"); 43 | } 44 | } 45 | else if (258 == num3) 46 | { 47 | num = 9; 48 | num2 = 0; 49 | } 50 | else 51 | { 52 | if (num2 >= array.Length) 53 | { 54 | throw new Exception("Invalid comressed stream"); 55 | } 56 | array[num2++] = i; 57 | if (num3 < 256) 58 | { 59 | this.m_output[i++] = (byte)num3; 60 | } 61 | else 62 | { 63 | num3 -= 259; 64 | if (num3 >= num2) 65 | { 66 | throw new Exception("Invalid comressed stream"); 67 | } 68 | int num4 = array[num3]; 69 | int num5 = Math.Min(this.m_output.Length - i, array[num3 + 1] - num4 + 1); 70 | if (num5 < 0) 71 | { 72 | throw new Exception("Invalid comressed stream"); 73 | } 74 | Binary.CopyOverlapped(this.m_output, num4, i, num5); 75 | i += num5; 76 | } 77 | } 78 | } 79 | } 80 | public void Dispose() 81 | { 82 | if (!this._disposed) 83 | { 84 | this.m_input.Dispose(); 85 | this._disposed = true; 86 | } 87 | GC.SuppressFinalize(this); 88 | } 89 | private MsbBitStream m_input; 90 | private byte[] m_output; 91 | private bool _disposed; 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /Escude/LzwEncoder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace Escu 5 | { 6 | internal sealed class LzwEncoder 7 | { 8 | public LzwEncoder(byte[] output) 9 | { 10 | this.m_output = output; 11 | } 12 | private byte MakeByte(int pos, int src) 13 | { 14 | byte b = 0; 15 | int num; 16 | if (pos < 8) 17 | { 18 | num = pos; 19 | } 20 | else 21 | { 22 | num = 8; 23 | } 24 | for (int i = 0; i < num; i--) 25 | { 26 | int num2 = src >> pos; 27 | pos--; 28 | if ((num2 & 1) == 1) 29 | { 30 | b |= 1; 31 | } 32 | else 33 | { 34 | b |= 0; 35 | } 36 | b = (byte)(b << 1); 37 | } 38 | return b; 39 | } 40 | public void EncodeBit(int token, int token_width, BinaryWriter wrter) 41 | { 42 | int num = (1 << token_width) - 1; 43 | if (this.cache_bits < 24) 44 | { 45 | this.mm_bits <<= token_width; 46 | this.mm_bits |= (token & num); 47 | this.cache_bits += token_width; 48 | } 49 | while (this.cache_bits >= token_width) 50 | { 51 | int num2 = this.cache_bits - 8; 52 | byte b = (byte)(this.mm_bits >> num2 & 255); 53 | this.cache_bits -= 8; 54 | int num3 = (1 << this.cache_bits) - 1; 55 | this.mm_bits &= num3; 56 | byte value = b; 57 | wrter.Write(value); 58 | wrter.Flush(); 59 | } 60 | } 61 | public byte[] Pack(byte[] buffer) 62 | { 63 | using (BinaryWriter binaryWriter = new BinaryWriter(new MemoryStream(this.m_output))) 64 | { 65 | int value = 7365473; 66 | binaryWriter.Write(value); 67 | binaryWriter.Flush(); 68 | int value2 = (int)Binary.ToBigEndian((uint)buffer.Length); 69 | binaryWriter.Write(value2); 70 | binaryWriter.Flush(); 71 | int num = 0; 72 | for (int i = 0; i < buffer.Length; i++) 73 | { 74 | num++; 75 | if (num > 32768) 76 | { 77 | this.EncodeBit(258, 9, binaryWriter); 78 | num = 0; 79 | } 80 | int token = (int)buffer[i]; 81 | this.EncodeBit(token, 9, binaryWriter); 82 | } 83 | this.EncodeBit(256, 9, binaryWriter); 84 | this.EncodeBit(256, 9, binaryWriter); 85 | this.last_size = (int)binaryWriter.BaseStream.Position; 86 | } 87 | this.m_paked = new byte[this.last_size]; 88 | Buffer.BlockCopy(this.m_output, 0, this.m_paked, 0, this.last_size); 89 | return this.m_paked; 90 | } 91 | private byte[] m_output; 92 | private byte[] m_inbuffer; 93 | public int cache_bits; 94 | public int mm_bits; 95 | public int src; 96 | public byte[] m_paked; 97 | public int last_size; 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /Escude/MsbBitStream.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace Escu 5 | { 6 | public class MsbBitStream : BitStream 7 | { 8 | public MsbBitStream(Stream file, bool leave_open = false) : base(file, leave_open) 9 | { 10 | } 11 | public int GetBits(int count) 12 | { 13 | while (this.m_cached_bits < count) 14 | { 15 | int num = this.m_input.ReadByte(); 16 | if (-1 == num) 17 | { 18 | return -1; 19 | } 20 | this.m_bits = (this.m_bits << 8 | num); 21 | this.m_cached_bits += 8; 22 | } 23 | int num2 = (1 << count) - 1; 24 | this.m_cached_bits -= count; 25 | return this.m_bits >> this.m_cached_bits & num2; 26 | } 27 | public int GetNextBit() 28 | { 29 | return this.GetBits(1); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Escude/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Text; 5 | 6 | namespace Escu 7 | { 8 | class Program 9 | { 10 | static void Main(string[] args) 11 | { 12 | Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); 13 | if (args.Length < 2) 14 | { 15 | Console.WriteLine("Usage: "); 16 | Console.WriteLine(" Unpack: Bin.exe -u "); 17 | Console.WriteLine(" Pack: Bin.exe -p "); 18 | return; 19 | } 20 | 21 | string operation = args[0]; 22 | string inputFile = args[1]; 23 | string outputFile = args[2]; 24 | 25 | if (operation == "-u") 26 | { 27 | Unpack(inputFile, outputFile); 28 | } 29 | else if (operation == "-p") 30 | { 31 | Pack(inputFile, outputFile); 32 | } 33 | else 34 | { 35 | Console.WriteLine("Invalid operation. Valid operations are 'unpack' and 'pack'."); 36 | } 37 | } 38 | 39 | static void Unpack(string inputFile, string outputFile) 40 | { 41 | ArcBIN ArcBIN = new ArcBIN(); 42 | try 43 | { 44 | Directory.CreateDirectory(outputFile); 45 | 46 | List entries = ArcBIN.TryOpen(inputFile); 47 | foreach (Entry entry in entries) 48 | { 49 | byte[] bytes = ArcBIN.Unpack(entry); 50 | System.IO.File.WriteAllBytes(Path.Combine(outputFile, entry.Name), bytes); 51 | } 52 | 53 | using (StreamWriter streamWriter = new StreamWriter(new FileStream(Path.Combine(outputFile, "FileList.txt"), FileMode.Create), Encoding.UTF8)) 54 | { 55 | for (int i = 0; i < entries.Count; i++) 56 | { 57 | streamWriter.WriteLine(entries[i].Name); 58 | streamWriter.Flush(); 59 | } 60 | } 61 | } 62 | catch (Exception ex) 63 | { 64 | Console.WriteLine(ex.Message); 65 | return; 66 | } 67 | Console.WriteLine("Unpacked successfully!"); 68 | } 69 | 70 | static void Pack(string inputFile, string outputFile) 71 | { 72 | ArcBIN ArcBIN = new ArcBIN(); 73 | try 74 | { 75 | ArcBIN.Pack(inputFile, outputFile); 76 | } 77 | catch (Exception ex) 78 | { 79 | Console.WriteLine(ex.Message); 80 | return; 81 | } 82 | Console.WriteLine("Pack successfully!"); 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /Lilim/ArcAOS2.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Text; 5 | using HuffmanCompressor; 6 | 7 | namespace Lilim 8 | { 9 | internal class ArcAOS2 10 | { 11 | private string GetStringLiteral(BinaryReader reader, uint index_offset, uint name_length) 12 | { 13 | List list = new List(); 14 | reader.BaseStream.Position = (long)((ulong)index_offset); 15 | byte[] array = reader.ReadBytes((int)name_length); 16 | int num = 0; 17 | while (num < array.Length && array[num] != 0) 18 | { 19 | list.Add(array[num]); 20 | num++; 21 | } 22 | return Encoding.GetEncoding(932).GetString(list.ToArray()); 23 | } 24 | 25 | public List TryOpen(string filePath) 26 | { 27 | this.buffer = File.ReadAllBytes(filePath); 28 | using (BinaryReader binaryReader = new BinaryReader(new MemoryStream(this.buffer))) 29 | { 30 | if (binaryReader.ReadInt32() != 0) 31 | { 32 | throw new Exception("Unsupported file format!"); 33 | } 34 | long num = (long)((ulong)binaryReader.ReadUInt32()); 35 | uint num2 = 273U; 36 | int num3 = binaryReader.ReadInt32(); 37 | if (num >= (long)this.buffer.Length || (ulong)num2 + (ulong)((long)num3) >= (ulong)((long)this.buffer.Length) || num < (long)((ulong)num2 + (ulong)((long)num3))) 38 | { 39 | throw new Exception("Unsupported file format!"); 40 | } 41 | this.blockBuffer = binaryReader.ReadBytes(261); 42 | int num4 = num3 / 40; 43 | if (num4 > 16384) 44 | { 45 | throw new Exception("Unsupported file format!"); 46 | } 47 | for (int i = 0; i < num4; i++) 48 | { 49 | string stringLiteral = this.GetStringLiteral(binaryReader, num2, 32U); 50 | if (stringLiteral.Length == 0) 51 | { 52 | throw new Exception("Unsupported file format!"); 53 | } 54 | num2 += 32U; 55 | Entry entry = new Entry(); 56 | binaryReader.BaseStream.Position = (long)((ulong)num2); 57 | entry.Offset = binaryReader.ReadInt32() + (int)num; 58 | entry.Size = binaryReader.ReadInt32(); 59 | string extension = Path.GetExtension(stringLiteral); 60 | entry.IsPacked = (extension.Equals(".scr") || extension.Equals(".cmp")); 61 | entry.Name = stringLiteral; 62 | if ((long)(entry.Offset + entry.Size) > binaryReader.BaseStream.Length) 63 | { 64 | throw new Exception("Unsupported file format!"); 65 | } 66 | this.dir.Add(entry); 67 | num2 += 8U; 68 | } 69 | } 70 | return this.dir; 71 | } 72 | 73 | public byte[] Unpack(Entry entry) 74 | { 75 | byte[] result; 76 | using (BinaryReader binaryReader = new BinaryReader(new MemoryStream(this.buffer))) 77 | { 78 | if (entry.IsPacked) 79 | { 80 | binaryReader.BaseStream.Position = (long)entry.Offset; 81 | int unpakedSize = binaryReader.ReadInt32(); 82 | byte[] input = binaryReader.ReadBytes(entry.Size); 83 | result = new Huffman().Decoder(input, unpakedSize); 84 | } 85 | else 86 | { 87 | binaryReader.BaseStream.Position = (long)entry.Offset; 88 | result = binaryReader.ReadBytes(entry.Size); 89 | } 90 | } 91 | return result; 92 | } 93 | 94 | public void Pack(string packPath, string outputFile) 95 | { 96 | bool flag = false; 97 | List list = new List(); 98 | List fileList = Files.GetFileList(packPath); 99 | for (int i = 0; i < fileList.Count; i++) 100 | { 101 | Entry entry = new Entry(); 102 | byte[] array = File.ReadAllBytes(fileList[i]); 103 | entry.Name = Files.GetSubFileName(packPath, fileList[i]); 104 | if (entry.Name.Equals("block.tmp") && array.Length == 261) 105 | { 106 | flag = true; 107 | this.blockBuffer = array; 108 | } 109 | else 110 | { 111 | byte[] fileBuffer = HuffmanEncoder.HuffmanEncoding(array); 112 | entry.fileBuffer = fileBuffer; 113 | entry.UnpackedSize = array.Length; 114 | list.Add(entry); 115 | } 116 | } 117 | if (!flag) 118 | { 119 | throw new Exception("Can't find block.tmp, please use this tool to unpack AOS archive to generate block.tmp!"); 120 | } 121 | string directoryName = Path.GetDirectoryName(packPath); 122 | using (BinaryWriter binaryWriter = new BinaryWriter(new FileStream(outputFile, FileMode.Create))) 123 | { 124 | int num = list.Count * 40; 125 | int value = num + 273; 126 | int value2 = 0; 127 | binaryWriter.Write(value2); 128 | binaryWriter.Flush(); 129 | binaryWriter.Write(value); 130 | binaryWriter.Flush(); 131 | binaryWriter.Write(num); 132 | binaryWriter.Flush(); 133 | binaryWriter.Write(this.blockBuffer); 134 | binaryWriter.Flush(); 135 | int num2 = 0; 136 | for (int j = 0; j < list.Count; j++) 137 | { 138 | byte[] bytes = Encoding.GetEncoding(932).GetBytes(list[j].Name); 139 | if (bytes.Length > 32) 140 | { 141 | throw new Exception("File's name is too long!"); 142 | } 143 | byte[] dst = new byte[32]; 144 | Buffer.BlockCopy(bytes, 0, dst, 0, bytes.Length); 145 | binaryWriter.Write(dst); 146 | binaryWriter.Flush(); 147 | binaryWriter.Write(num2); 148 | binaryWriter.Flush(); 149 | num2 += list[j].fileBuffer.Length; 150 | num2 += 4; 151 | binaryWriter.Write(list[j].fileBuffer.Length); 152 | binaryWriter.Flush(); 153 | } 154 | for (int k = 0; k < list.Count; k++) 155 | { 156 | binaryWriter.Write(list[k].UnpackedSize); 157 | binaryWriter.Flush(); 158 | binaryWriter.Write(list[k].fileBuffer); 159 | binaryWriter.Flush(); 160 | } 161 | } 162 | } 163 | private byte[] buffer; 164 | public byte[] blockBuffer; 165 | private List dir = new List(); 166 | } 167 | } 168 | -------------------------------------------------------------------------------- /Lilim/BitStream.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace Lilim 5 | { 6 | public class BitStream : IDisposable 7 | { 8 | public Stream Input 9 | { 10 | get 11 | { 12 | return this.m_input; 13 | } 14 | } 15 | public int CacheSize 16 | { 17 | get 18 | { 19 | return this.m_cached_bits; 20 | } 21 | } 22 | protected BitStream(Stream file, bool leave_open) 23 | { 24 | this.m_input = file; 25 | this.m_should_dispose = !leave_open; 26 | } 27 | public void Reset() 28 | { 29 | this.m_cached_bits = 0; 30 | } 31 | public void Dispose() 32 | { 33 | this.Dispose(true); 34 | GC.SuppressFinalize(this); 35 | } 36 | protected virtual void Dispose(bool disposing) 37 | { 38 | if (!this.m_disposed) 39 | { 40 | if (disposing && this.m_should_dispose && this.m_input != null) 41 | { 42 | this.m_input.Dispose(); 43 | } 44 | this.m_disposed = true; 45 | } 46 | } 47 | protected Stream m_input; 48 | private bool m_should_dispose; 49 | protected int m_bits; 50 | protected int m_cached_bits; 51 | private bool m_disposed; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Lilim/Entry.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Lilim 4 | { 5 | public class Entry 6 | { 7 | public virtual string Name { get; set; } 8 | public virtual string SubName { get; set; } 9 | public virtual string Type { get; set; } 10 | public int filename_offset { get; set; } 11 | public int filename_length { get; set; } 12 | public int Offset { get; set; } 13 | public int Size { get; set; } 14 | public bool IsPacked { get; set; } 15 | public int UnpackedSize { get; set; } 16 | public long StructPosition { get; set; } 17 | public byte[] fileBuffer { get; set; } 18 | public Entry() 19 | { 20 | this.Type = ""; 21 | this.Offset = -1; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Lilim/File.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | 5 | namespace Lilim 6 | { 7 | public static class Files 8 | { 9 | public static List GetFileList(string path) 10 | { 11 | List list = new List(); 12 | if (Directory.Exists(path)) 13 | { 14 | foreach (string item in Directory.GetFiles(path)) 15 | { 16 | list.Add(item); 17 | } 18 | foreach (string path2 in Directory.GetDirectories(path)) 19 | { 20 | list.AddRange(Files.GetFileList(path2)); 21 | } 22 | } 23 | return list; 24 | } 25 | public static string GetSubFileName(string rootPath, string filePath) 26 | { 27 | return filePath.Substring(rootPath.Length + 1, filePath.Length - (rootPath.Length + 1)); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Lilim/Huffman.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace Lilim 5 | { 6 | internal class Huffman 7 | { 8 | public void Initialize(Stream input) 9 | { 10 | this.m_input = new MsbBitStream(input, true); 11 | } 12 | public void EncodeBit(int token, int token_width, BinaryWriter wrter) 13 | { 14 | int num = (1 << token_width) - 1; 15 | if (this.cache_bits < 24) 16 | { 17 | this.mm_bits <<= token_width; 18 | this.mm_bits |= (token & num); 19 | this.cache_bits += token_width; 20 | } 21 | if (this.cache_bits >= 8) 22 | { 23 | while (this.cache_bits >= token_width) 24 | { 25 | int num2 = this.cache_bits - 8; 26 | byte b = (byte)(this.mm_bits >> num2 & 255); 27 | this.cache_bits -= 8; 28 | int num3 = (1 << this.cache_bits) - 1; 29 | this.mm_bits &= num3; 30 | byte value = b; 31 | wrter.Write(value); 32 | wrter.Flush(); 33 | } 34 | } 35 | } 36 | public byte[] Decoder(byte[] input, int unpakedSize) 37 | { 38 | this.Initialize(new MemoryStream(input)); 39 | byte[] array = new byte[unpakedSize]; 40 | this.m_token = 256; 41 | ushort num = this.CreateTree(); 42 | int num2 = unpakedSize; 43 | do 44 | { 45 | ushort num3 = num; 46 | int num4 = 0; 47 | while (num3 >= 256) 48 | { 49 | num4++; 50 | int bits = this.m_input.GetBits(1); 51 | if (-1 == bits) 52 | { 53 | break; 54 | } 55 | if (bits != 0) 56 | { 57 | num3 = this.rhs[(int)num3]; 58 | } 59 | else 60 | { 61 | num3 = this.lhs[(int)num3]; 62 | } 63 | } 64 | byte[] array2 = array; 65 | int pos = this.m_pos; 66 | this.m_pos = pos + 1; 67 | array2[pos] = (byte)num3; 68 | } 69 | while (--num2 != 0); 70 | return array; 71 | } 72 | public byte[] Encoder(byte[] input) 73 | { 74 | byte[] array = new byte[input.Length * 255]; 75 | byte[] array2 = new byte[1]; 76 | int num = 0; 77 | for (ushort num2 = 256; num2 < 512; num2 += 1) 78 | { 79 | this.lhs[(int)num2] = num2; 80 | } 81 | ushort num3 = 256; 82 | ushort num4 = 0; 83 | while (num3 < 512) 84 | { 85 | this.rhs[(int)num3] = num4; 86 | num3 += 1; 87 | num4 += 1; 88 | } 89 | this.rhs[257] = 0; 90 | using (BinaryWriter binaryWriter = new BinaryWriter(new MemoryStream(array))) 91 | { 92 | int num5 = 9; 93 | this.WriteTree(binaryWriter); 94 | for (int i = 0; i < input.Length; i++) 95 | { 96 | if (input[i] == 0) 97 | { 98 | this.EncodeBit(1, 1, binaryWriter); 99 | } 100 | else if (input[i] == 1) 101 | { 102 | for (int j = 0; j < 255; j++) 103 | { 104 | this.EncodeBit(0, 1, binaryWriter); 105 | } 106 | } 107 | else 108 | { 109 | for (int k = 0; k < (int)(input[i] - 1); k++) 110 | { 111 | if (num5 == 0) 112 | { 113 | this.EncodeBit(0, 1, binaryWriter); 114 | } 115 | else 116 | { 117 | num5--; 118 | } 119 | } 120 | this.EncodeBit(1, 1, binaryWriter); 121 | } 122 | } 123 | this.EncodeBit(255, 8, binaryWriter); 124 | this.EncodeBit(255, 8, binaryWriter); 125 | num = (int)binaryWriter.BaseStream.Position; 126 | } 127 | if (num != 0) 128 | { 129 | array2 = new byte[num]; 130 | Buffer.BlockCopy(array, 0, array2, 0, num); 131 | } 132 | return array2; 133 | } 134 | private void WriteTree(BinaryWriter writer) 135 | { 136 | for (int i = 256; i < 512; i++) 137 | { 138 | if (i == 511) 139 | { 140 | this.EncodeBit(0, 1, writer); 141 | this.EncodeBit(1, 8, writer); 142 | } 143 | else 144 | { 145 | this.EncodeBit(1, 1, writer); 146 | } 147 | } 148 | for (int j = 511; j > 255; j--) 149 | { 150 | this.EncodeBit(0, 1, writer); 151 | this.EncodeBit((int)this.rhs[j], 8, writer); 152 | } 153 | } 154 | private ushort CreateTree() 155 | { 156 | int bits = this.m_input.GetBits(1); 157 | if (-1 == bits) 158 | { 159 | throw new Exception("Unexpected end of the Huffman-compressed stream."); 160 | } 161 | if (bits == 0) 162 | { 163 | return (ushort)this.m_input.GetBits(8); 164 | } 165 | ushort token = this.m_token; 166 | this.m_token = (ushort)(token + 1); 167 | ushort num = token; 168 | if (num >= 512) 169 | { 170 | throw new Exception("Invalid Huffman-compressed stream."); 171 | } 172 | this.lhs[(int)num] = this.CreateTree(); 173 | this.rhs[(int)num] = this.CreateTree(); 174 | return num; 175 | } 176 | private MsbBitStream m_input; 177 | private const int TreeSize = 512; 178 | private ushort[] lhs = new ushort[512]; 179 | private ushort[] rhs = new ushort[512]; 180 | private int m_pos; 181 | private ushort m_token = 256; 182 | public int cache_bits; 183 | public int mm_bits; 184 | } 185 | } 186 | -------------------------------------------------------------------------------- /Lilim/HuffmanCompressor/HeapNode.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HuffmanCompressor 4 | { 5 | internal struct HeapNode 6 | { 7 | public uint elem; 8 | public uint weight; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Lilim/HuffmanCompressor/HuffmanEncoder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace HuffmanCompressor 5 | { 6 | internal class HuffmanEncoder 7 | { 8 | private static uint parent(uint index) 9 | { 10 | return index - 1U >> 1; 11 | } 12 | private static void swap(MinHeap[] heap, uint ia, uint ib) 13 | { 14 | HeapNode data = heap[(int)ia].data; 15 | heap[(int)ia].data = heap[(int)ib].data; 16 | heap[(int)ib].data = data; 17 | } 18 | private static void bubbleUp(MinHeap[] heap, uint index) 19 | { 20 | while (index > 0U && heap[(int)HuffmanEncoder.parent(index)].data.weight > heap[(int)index].data.weight) 21 | { 22 | HuffmanEncoder.swap(heap, HuffmanEncoder.parent(index), index); 23 | index = HuffmanEncoder.parent(index); 24 | } 25 | } 26 | private static bool heapInsert(MinHeap[] heap, uint elem, uint weight, uint index) 27 | { 28 | heap[(int)index].data.elem = elem; 29 | heap[(int)index].data.weight = weight; 30 | HuffmanEncoder.bubbleUp(heap, index); 31 | return true; 32 | } 33 | private static uint lchild(uint index) 34 | { 35 | return (index << 1) + 1U; 36 | } 37 | private static uint rchild(uint index) 38 | { 39 | return (index << 1) + 2U; 40 | } 41 | private static void bubbleDown(MinHeap[] heap, uint index, uint currentIndex) 42 | { 43 | for (;;) 44 | { 45 | uint num = HuffmanEncoder.lchild(index); 46 | uint num2 = HuffmanEncoder.rchild(index); 47 | uint num3 = (num < currentIndex) ? heap[(int)num].data.weight : uint.MaxValue; 48 | uint num4 = (num2 < currentIndex) ? heap[(int)num2].data.weight : uint.MaxValue; 49 | uint num5 = (num3 < num4) ? num : num2; 50 | uint num6 = (num3 < num4) ? num3 : num4; 51 | if (heap[(int)index].data.weight <= num6) 52 | { 53 | break; 54 | } 55 | HuffmanEncoder.swap(heap, index, num5); 56 | index = num5; 57 | } 58 | } 59 | private static bool heapPopMin(MinHeap[] heap, out uint elem, out uint weight, uint currentIndex) 60 | { 61 | elem = heap[0].data.elem; 62 | weight = heap[0].data.weight; 63 | HuffmanEncoder.swap(heap, 0U, currentIndex - 1U); 64 | currentIndex = (currentIndex -= 1U); 65 | HuffmanEncoder.bubbleDown(heap, 0U, currentIndex); 66 | return true; 67 | } 68 | private static uint BuildTree(TreeNode[] tree, byte[] orginal) 69 | { 70 | uint num = 0U; 71 | while ((ulong)num < (ulong)((long)orginal.Length)) 72 | { 73 | byte b = orginal[(int)num]; 74 | tree[(int)b].weight = tree[(int)b].weight + 1U; 75 | num += 1U; 76 | } 77 | MinHeap[] heap = new MinHeap[256]; 78 | uint num2 = 0U; 79 | for (ushort num3 = 0; num3 < 256; num3 += 1) 80 | { 81 | if (tree[(int)num3].weight > 0U) 82 | { 83 | HuffmanEncoder.heapInsert(heap, (uint)num3, tree[(int)num3].weight, num2); 84 | num2 += 1U; 85 | } 86 | } 87 | ushort num4 = 256; 88 | while (num2 > 1U) 89 | { 90 | uint num5; 91 | uint num6; 92 | HuffmanEncoder.heapPopMin(heap, out num5, out num6, num2); 93 | num2 -= 1U; 94 | uint num7; 95 | uint num8; 96 | HuffmanEncoder.heapPopMin(heap, out num7, out num8, num2); 97 | num2 -= 1U; 98 | tree[(int)num4].lchild = (ushort)num5; 99 | tree[(int)num4].rchild = (ushort)num7; 100 | tree[(int)num4].weight = num6 + num8; 101 | tree[(int)num5].parent = num4; 102 | tree[(int)num5].isrchild = 0; 103 | tree[(int)num7].parent = num4; 104 | tree[(int)num7].isrchild = 1; 105 | HuffmanEncoder.heapInsert(heap, (uint)num4, num6 + num8, num2); 106 | num2 += 1U; 107 | num4 += 1; 108 | } 109 | uint result; 110 | uint num9; 111 | HuffmanEncoder.heapPopMin(heap, out result, out num9, num2); 112 | num2 -= 1U; 113 | return result; 114 | } 115 | private static void EncodeBit2(int token, int token_width, BinaryWriter wrter) 116 | { 117 | int num = (1 << token_width) - 1; 118 | if (HuffmanEncoder.cache_bits < 24) 119 | { 120 | HuffmanEncoder.mm_bits <<= token_width; 121 | HuffmanEncoder.mm_bits |= (token & num); 122 | HuffmanEncoder.cache_bits += token_width; 123 | } 124 | if (HuffmanEncoder.cache_bits >= 8) 125 | { 126 | while (HuffmanEncoder.cache_bits >= token_width) 127 | { 128 | int num2 = HuffmanEncoder.cache_bits - 8; 129 | byte b = (byte)(HuffmanEncoder.mm_bits >> num2 & 255); 130 | HuffmanEncoder.cache_bits -= 8; 131 | int num3 = (1 << HuffmanEncoder.cache_bits) - 1; 132 | HuffmanEncoder.mm_bits &= num3; 133 | byte value = b; 134 | wrter.Write(value); 135 | wrter.Flush(); 136 | } 137 | } 138 | } 139 | private static void subtreeEncodingWorker(TreeNode[] tree, int rootIndex, BinaryWriter bs) 140 | { 141 | if (rootIndex < 256) 142 | { 143 | HuffmanEncoder.EncodeBit2(0, 1, bs); 144 | HuffmanEncoder.EncodeBit2(rootIndex, 8, bs); 145 | return; 146 | } 147 | HuffmanEncoder.EncodeBit2(1, 1, bs); 148 | HuffmanEncoder.subtreeEncodingWorker(tree, (int)tree[rootIndex].lchild, bs); 149 | HuffmanEncoder.subtreeEncodingWorker(tree, (int)tree[rootIndex].rchild, bs); 150 | } 151 | private static void encodeTree(TreeNode[] tree, uint rootIndex, BinaryWriter bs) 152 | { 153 | HuffmanEncoder.subtreeEncodingWorker(tree, (int)rootIndex, bs); 154 | } 155 | private static void encodeData(TreeNode[] tree, uint rootIndex, byte[] data, uint oriLen, BinaryWriter bs) 156 | { 157 | byte[,] array = new byte[256, 256]; 158 | byte[] array2 = new byte[256]; 159 | for (ushort num = 0; num < 256; num += 1) 160 | { 161 | if (tree[(int)num].weight != 0U) 162 | { 163 | ushort num2 = num; 164 | while ((uint)num2 != rootIndex) 165 | { 166 | byte[,] array3 = array; 167 | int num3 = (int)num; 168 | byte[] array4 = array2; 169 | ushort num4 = num; 170 | byte b = array4[(int)num4]; 171 | array4[(int)num4] = (byte)(b + 1); 172 | array3[num3, (int)b] = (byte)tree[(int)num2].isrchild; 173 | num2 = tree[(int)num2].parent; 174 | } 175 | } 176 | } 177 | for (uint num5 = 0U; num5 < oriLen; num5 += 1U) 178 | { 179 | for (int i = (int)(array2[(int)data[(int)num5]] - 1); i >= 0; i--) 180 | { 181 | HuffmanEncoder.EncodeBit2((int)array[(int)data[(int)num5], i], 1, bs); 182 | } 183 | } 184 | } 185 | public static byte[] HuffmanEncoding(byte[] orginal) 186 | { 187 | HuffmanEncoder.cache_bits = 0; 188 | HuffmanEncoder.mm_bits = 0; 189 | TreeNode[] tree = new TreeNode[512]; 190 | uint rootIndex = HuffmanEncoder.BuildTree(tree, orginal); 191 | byte[] array = new byte[orginal.Length * 4]; 192 | int num = 0; 193 | using (BinaryWriter binaryWriter = new BinaryWriter(new MemoryStream(array))) 194 | { 195 | HuffmanEncoder.encodeTree(tree, rootIndex, binaryWriter); 196 | HuffmanEncoder.encodeData(tree, rootIndex, orginal, (uint)orginal.Length, binaryWriter); 197 | for (int i = 0; i < 255; i++) 198 | { 199 | HuffmanEncoder.EncodeBit2(255, 8, binaryWriter); 200 | } 201 | num = (int)binaryWriter.BaseStream.Position; 202 | } 203 | byte[] array2 = new byte[num]; 204 | Buffer.BlockCopy(array, 0, array2, 0, num); 205 | return array2; 206 | } 207 | public static int cache_bits; 208 | public static int mm_bits; 209 | } 210 | } 211 | -------------------------------------------------------------------------------- /Lilim/HuffmanCompressor/MinHeap.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HuffmanCompressor 4 | { 5 | internal struct MinHeap 6 | { 7 | public HeapNode data; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Lilim/HuffmanCompressor/TreeNode.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HuffmanCompressor 4 | { 5 | internal struct TreeNode 6 | { 7 | public ushort parent; 8 | public ushort isrchild; 9 | public ushort lchild; 10 | public ushort rchild; 11 | public uint weight; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Lilim/LilimAos.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net6.0 6 | enable 7 | enable 8 | true 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Lilim/LilimAos.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.1.32228.430 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aos", "LilimAos.csproj", "{1B134B33-DEBB-49AE-B17A-8D98F19AABD5}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {1B134B33-DEBB-49AE-B17A-8D98F19AABD5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {1B134B33-DEBB-49AE-B17A-8D98F19AABD5}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {1B134B33-DEBB-49AE-B17A-8D98F19AABD5}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {1B134B33-DEBB-49AE-B17A-8D98F19AABD5}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {A78C3A15-FA8F-4A48-AEDB-BDC7D3A9C33A} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /Lilim/MsbBitStream.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace Lilim 5 | { 6 | public class MsbBitStream : BitStream 7 | { 8 | public MsbBitStream(Stream file, bool leave_open = false) : base(file, leave_open) 9 | { 10 | } 11 | public int GetBits(int count) 12 | { 13 | while (this.m_cached_bits < count) 14 | { 15 | int num = this.m_input.ReadByte(); 16 | if (-1 == num) 17 | { 18 | return -1; 19 | } 20 | this.m_bits = (this.m_bits << 8 | num); 21 | this.m_cached_bits += 8; 22 | } 23 | int num2 = (1 << count) - 1; 24 | this.m_cached_bits -= count; 25 | return this.m_bits >> this.m_cached_bits & num2; 26 | } 27 | public int GetNextBit() 28 | { 29 | return this.GetBits(1); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Lilim/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Text; 5 | 6 | namespace Lilim 7 | { 8 | class Program 9 | { 10 | static void Main(string[] args) 11 | { 12 | Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); 13 | if (args.Length < 2) 14 | { 15 | Console.WriteLine("Usage: "); 16 | Console.WriteLine(" Unpack: Aos.exe -u "); 17 | Console.WriteLine(" Pack: Aos.exe -p "); 18 | return; 19 | } 20 | 21 | string operation = args[0]; 22 | string inputFile = args[1]; 23 | string outputFile = args[2]; 24 | 25 | if (operation == "-u") 26 | { 27 | Unpack(inputFile, outputFile); 28 | } 29 | else if (operation == "-p") 30 | { 31 | Pack(inputFile, outputFile); 32 | } 33 | else 34 | { 35 | Console.WriteLine("Invalid operation. Valid operations are 'unpack' and 'pack'."); 36 | } 37 | } 38 | 39 | static void Unpack(string inputFile, string outputFile) 40 | { 41 | ArcAOS2 ArcAOS2 = new ArcAOS2(); 42 | try 43 | { 44 | Directory.CreateDirectory(outputFile); 45 | 46 | foreach (Entry entry in ArcAOS2.TryOpen(inputFile)) 47 | { 48 | byte[] bytes = ArcAOS2.Unpack(entry); 49 | System.IO.File.WriteAllBytes(Path.Combine(outputFile, entry.Name), bytes); 50 | } 51 | 52 | System.IO.File.WriteAllBytes(Path.Combine(outputFile, "block.tmp"), ArcAOS2.blockBuffer); 53 | } 54 | catch (Exception ex) 55 | { 56 | Console.WriteLine(ex.Message); 57 | return; 58 | } 59 | Console.WriteLine("Unpacked successfully!"); 60 | } 61 | 62 | static void Pack(string inputFile, string outputFile) 63 | { 64 | ArcAOS2 ArcAOS2 = new ArcAOS2(); 65 | try 66 | { 67 | ArcAOS2.Pack(inputFile, outputFile); 68 | } 69 | catch (Exception ex) 70 | { 71 | Console.WriteLine(ex.Message); 72 | return; 73 | } 74 | Console.WriteLine("Pack successfully!"); 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /Lilim/build.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | dotnet build -c release 3 | pause -------------------------------------------------------------------------------- /NEJII/ArcCDT.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.IO.Compression; 5 | using System.Text; 6 | 7 | namespace NEJII 8 | { 9 | internal class ArcCDT 10 | { 11 | private int strlen(BinaryReader reader) 12 | { 13 | bool flag = false; 14 | long position = reader.BaseStream.Position; 15 | while (reader.BaseStream.Position != reader.BaseStream.Length) 16 | { 17 | if (reader.ReadByte() == 0) 18 | { 19 | flag = true; 20 | break; 21 | } 22 | } 23 | int result; 24 | if (flag) 25 | { 26 | result = (int)(reader.BaseStream.Position - position - 1L); 27 | } 28 | else 29 | { 30 | result = (int)(reader.BaseStream.Position - position); 31 | } 32 | reader.BaseStream.Position = position; 33 | return result; 34 | } 35 | public List TryOpen(string filePath) 36 | { 37 | this.fileFullPath = filePath; 38 | this.buffer = File.ReadAllBytes(filePath); 39 | long num = (long)this.buffer.Length; 40 | if (num <= 12L) 41 | { 42 | throw new Exception("Unsupported file format!"); 43 | } 44 | using (BinaryReader binaryReader = new BinaryReader(new MemoryStream(this.buffer))) 45 | { 46 | binaryReader.BaseStream.Position = binaryReader.BaseStream.Length - 12L; 47 | if (binaryReader.ReadInt32() != 3230546) 48 | { 49 | throw new Exception("Unsupported file format!"); 50 | } 51 | int num2 = binaryReader.ReadInt32(); 52 | if (num2 > 16384) 53 | { 54 | throw new Exception("Unsupported file format!"); 55 | } 56 | int num3 = binaryReader.ReadInt32(); 57 | if ((long)num3 > num) 58 | { 59 | throw new Exception("Unsupported file format!"); 60 | } 61 | binaryReader.BaseStream.Position = (long)num3; 62 | for (int i = 0; i < num2; i++) 63 | { 64 | int num4 = this.strlen(binaryReader); 65 | if (num4 > 16) 66 | { 67 | throw new Exception("File's name is too long"); 68 | } 69 | byte[] bytes = binaryReader.ReadBytes(16); 70 | string @string = Encoding.GetEncoding(932).GetString(bytes, 0, num4); 71 | Entry entry = new Entry(); 72 | entry.Name = @string; 73 | entry.Size = binaryReader.ReadUInt32(); 74 | entry.UnpackedSize = binaryReader.ReadInt32(); 75 | entry.IsPacked = (binaryReader.ReadInt32() != 0); 76 | entry.Offset = binaryReader.ReadInt32(); 77 | if ((long)entry.Offset + (long)((ulong)entry.Size) > num) 78 | { 79 | throw new Exception("Unsupported file format!"); 80 | } 81 | this.dir.Add(entry); 82 | } 83 | } 84 | return this.dir; 85 | } 86 | public static bool LzssCompress(byte[] m_input, byte[] m_output, int unpakedSize) 87 | { 88 | byte[] array = new byte[4112]; 89 | short num = 4078; 90 | ushort num2 = 0; 91 | int num3 = 0; 92 | int i = 0; 93 | while (i < m_input.Length) 94 | { 95 | num2 = (ushort)(num2 >> 1); 96 | if (((num2 = (ushort)(num2 >> 1)) & 256) == 0) 97 | { 98 | num2 = (ushort)m_input[i++]; 99 | num2 |= 65280; 100 | } 101 | if ((num2 & 1) == 0) 102 | { 103 | int num4 = (int)m_input[i++]; 104 | byte b = m_input[i++]; 105 | int num5 = (int)(b & 15); 106 | num5 += 2; 107 | int num6 = num4 | (int)(b & 240) << 4; 108 | for (int j = 0; j < num5; j++) 109 | { 110 | byte b2 = array[num6 + j & 4095]; 111 | m_output[num3++] = b2; 112 | unpakedSize--; 113 | if (unpakedSize == 0) 114 | { 115 | return true; 116 | } 117 | byte[] array2 = array; 118 | short num7 = num; 119 | num = (byte)(num7 + 1); 120 | array2[(int)num7] = b2; 121 | } 122 | } 123 | else 124 | { 125 | byte b3 = m_input[i++]; 126 | m_output[num3++] = b3; 127 | unpakedSize--; 128 | if (unpakedSize == 0) 129 | { 130 | return true; 131 | } 132 | byte[] array3 = array; 133 | short num8 = num; 134 | num = (byte)(num8 + 1); 135 | array3[(int)num8] = b3; 136 | } 137 | } 138 | return unpakedSize == 0; 139 | } 140 | public byte[] Unpack(Entry entry) 141 | { 142 | byte[] result; 143 | using (BinaryReader binaryReader = new BinaryReader(new MemoryStream(this.buffer))) 144 | { 145 | binaryReader.BaseStream.Position = (long)entry.Offset; 146 | result = binaryReader.ReadBytes((int)entry.Size); 147 | } 148 | if (entry.IsPacked) 149 | { 150 | byte[] result2; 151 | using (LzssStream lzssStream = new LzssStream(new MemoryStream(result), CompressionMode.Decompress)) 152 | { 153 | result2 = new byte[entry.UnpackedSize]; 154 | lzssStream.Read(result2, 0, entry.UnpackedSize); 155 | } 156 | return result2; 157 | } 158 | return result; 159 | } 160 | public void Pack(string packPath, string outputFile) 161 | { 162 | List list = new List(); 163 | string[] files = Directory.GetFiles(packPath); 164 | for (int i = 0; i < files.Length; i++) 165 | { 166 | Entry entry = new Entry(); 167 | byte[] array = File.ReadAllBytes(files[i]); 168 | byte[] src = new byte[array.Length * 2]; 169 | byte[] array2; 170 | int lastCodeLength; 171 | using (LzssStream lzssStream = new LzssStream(new MemoryStream(src), CompressionMode.Compress)) 172 | { 173 | lzssStream.Write(array, 0, array.Length); 174 | if (lzssStream.LastCodeLength == 0) 175 | { 176 | throw new Exception("Failed to compress!"); 177 | } 178 | array2 = new byte[lzssStream.LastCodeLength]; 179 | lastCodeLength = lzssStream.LastCodeLength; 180 | } 181 | Buffer.BlockCopy(src, 0, array2, 0, lastCodeLength); 182 | entry.fileBuffer = array2; 183 | entry.UnpackedSize = array.Length; 184 | entry.IsPacked = true; 185 | entry.Name = Path.GetFileName(files[i]); 186 | list.Add(entry); 187 | } 188 | string directoryName = Path.GetDirectoryName(packPath); 189 | using (BinaryWriter binaryWriter = new BinaryWriter(new FileStream(outputFile, FileMode.Create))) 190 | { 191 | uint num = (uint)(list.Count * 32); 192 | for (int j = 0; j < list.Count; j++) 193 | { 194 | byte[] bytes = Encoding.GetEncoding(932).GetBytes(list[j].Name); 195 | if (bytes.Length > 16) 196 | { 197 | throw new Exception("Files' name are too long!"); 198 | } 199 | byte[] dst = new byte[16]; 200 | Buffer.BlockCopy(bytes, 0, dst, 0, bytes.Length); 201 | binaryWriter.Write(dst); 202 | binaryWriter.Flush(); 203 | binaryWriter.Write(list[j].fileBuffer.Length); 204 | binaryWriter.Flush(); 205 | binaryWriter.Write(list[j].UnpackedSize); 206 | binaryWriter.Flush(); 207 | int value = 1; 208 | binaryWriter.Write(value); 209 | binaryWriter.Flush(); 210 | binaryWriter.Write(num); 211 | binaryWriter.Flush(); 212 | num += (uint)list[j].fileBuffer.Length; 213 | } 214 | for (int k = 0; k < list.Count; k++) 215 | { 216 | binaryWriter.Write(list[k].fileBuffer); 217 | binaryWriter.Flush(); 218 | } 219 | int value2 = 3230546; 220 | binaryWriter.Write(value2); 221 | binaryWriter.Flush(); 222 | binaryWriter.Write(list.Count); 223 | binaryWriter.Flush(); 224 | int value3 = 0; 225 | binaryWriter.Write(value3); 226 | binaryWriter.Flush(); 227 | } 228 | } 229 | private byte[] buffer; 230 | private List dir = new List(); 231 | private string fileFullPath = ""; 232 | private bool isScript; 233 | private byte[] key; 234 | } 235 | } 236 | -------------------------------------------------------------------------------- /NEJII/Entry.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace NEJII 4 | { 5 | public class Entry 6 | { 7 | public virtual string Name { get; set; } 8 | public virtual string Type { get; set; } 9 | public int Offset { get; set; } 10 | public uint Size { get; set; } 11 | public bool IsPacked { get; set; } 12 | public int UnpackedSize { get; set; } 13 | public long StructPosition { get; set; } 14 | public byte[] fileBuffer { get; set; } 15 | public Entry() 16 | { 17 | this.Type = ""; 18 | this.Offset = -1; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /NEJII/NejiiCDT.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net6.0 6 | enable 7 | enable 8 | true 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /NEJII/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Text; 5 | 6 | namespace NEJII 7 | { 8 | class Program 9 | { 10 | static void Main(string[] args) 11 | { 12 | Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); 13 | if (args.Length < 2) 14 | { 15 | Console.WriteLine("Usage: "); 16 | Console.WriteLine(" Unpack: CDT.exe -u "); 17 | Console.WriteLine(" Pack: CDT.exe -p "); 18 | return; 19 | } 20 | 21 | string operation = args[0]; 22 | string inputFile = args[1]; 23 | string outputFile = args[2]; 24 | 25 | if (operation == "-u") 26 | { 27 | Unpack(inputFile, outputFile); 28 | } 29 | else if (operation == "-p") 30 | { 31 | Pack(inputFile, outputFile); 32 | } 33 | else 34 | { 35 | Console.WriteLine("Invalid operation. Valid operations are 'unpack' and 'pack'."); 36 | } 37 | } 38 | 39 | static void Unpack(string inputFile, string outputFile) 40 | { 41 | ArcCDT ArcCDT = new ArcCDT(); 42 | try 43 | { 44 | Directory.CreateDirectory(outputFile); 45 | 46 | foreach (Entry entry in ArcCDT.TryOpen(inputFile)) 47 | { 48 | byte[] bytes = ArcCDT.Unpack(entry); 49 | System.IO.File.WriteAllBytes(Path.Combine(outputFile, entry.Name), bytes); 50 | } 51 | } 52 | catch (Exception ex) 53 | { 54 | Console.WriteLine(ex.Message); 55 | return; 56 | } 57 | Console.WriteLine("Unpacked successfully!"); 58 | } 59 | 60 | static void Pack(string inputFile, string outputFile) 61 | { 62 | ArcCDT ArcCDT = new ArcCDT(); 63 | try 64 | { 65 | ArcCDT.Pack(inputFile, outputFile); 66 | } 67 | catch (Exception ex) 68 | { 69 | Console.WriteLine(ex.Message); 70 | return; 71 | } 72 | Console.WriteLine("Pack successfully!"); 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /NEKOSDK/ComponentAce/Compression/Libs/zlib/Adler32.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2006, ComponentAce 2 | // http://www.componentace.com 3 | // All rights reserved. 4 | 5 | // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 6 | 7 | // Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | // Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 9 | // Neither the name of ComponentAce nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 10 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 11 | 12 | 13 | 14 | /* 15 | Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. 16 | 17 | Redistribution and use in source and binary forms, with or without 18 | modification, are permitted provided that the following conditions are met: 19 | 20 | 1. Redistributions of source code must retain the above copyright notice, 21 | this list of conditions and the following disclaimer. 22 | 23 | 2. Redistributions in binary form must reproduce the above copyright 24 | notice, this list of conditions and the following disclaimer in 25 | the documentation and/or other materials provided with the distribution. 26 | 27 | 3. The names of the authors may not be used to endorse or promote products 28 | derived from this software without specific prior written permission. 29 | 30 | THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, 31 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 32 | FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, 33 | INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, 34 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 35 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 36 | OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 37 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 38 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 39 | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 40 | */ 41 | /* 42 | * This program is based on zlib-1.1.3, so all credit should go authors 43 | * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) 44 | * and contributors of zlib. 45 | */ 46 | using System; 47 | namespace ComponentAce.Compression.Libs.zlib 48 | { 49 | 50 | sealed class Adler32 51 | { 52 | 53 | // largest prime smaller than 65536 54 | private const int BASE = 65521; 55 | // NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 56 | private const int NMAX = 5552; 57 | 58 | internal long adler32(long adler, byte[] buf, int index, int len) 59 | { 60 | if (buf == null) 61 | { 62 | return 1L; 63 | } 64 | 65 | long s1 = adler & 0xffff; 66 | long s2 = (adler >> 16) & 0xffff; 67 | int k; 68 | 69 | while (len > 0) 70 | { 71 | k = len < NMAX?len:NMAX; 72 | len -= k; 73 | while (k >= 16) 74 | { 75 | s1 += (buf[index++] & 0xff); s2 += s1; 76 | s1 += (buf[index++] & 0xff); s2 += s1; 77 | s1 += (buf[index++] & 0xff); s2 += s1; 78 | s1 += (buf[index++] & 0xff); s2 += s1; 79 | s1 += (buf[index++] & 0xff); s2 += s1; 80 | s1 += (buf[index++] & 0xff); s2 += s1; 81 | s1 += (buf[index++] & 0xff); s2 += s1; 82 | s1 += (buf[index++] & 0xff); s2 += s1; 83 | s1 += (buf[index++] & 0xff); s2 += s1; 84 | s1 += (buf[index++] & 0xff); s2 += s1; 85 | s1 += (buf[index++] & 0xff); s2 += s1; 86 | s1 += (buf[index++] & 0xff); s2 += s1; 87 | s1 += (buf[index++] & 0xff); s2 += s1; 88 | s1 += (buf[index++] & 0xff); s2 += s1; 89 | s1 += (buf[index++] & 0xff); s2 += s1; 90 | s1 += (buf[index++] & 0xff); s2 += s1; 91 | k -= 16; 92 | } 93 | if (k != 0) 94 | { 95 | do 96 | { 97 | s1 += (buf[index++] & 0xff); s2 += s1; 98 | } 99 | while (--k != 0); 100 | } 101 | s1 %= BASE; 102 | s2 %= BASE; 103 | } 104 | return (s2 << 16) | s1; 105 | } 106 | 107 | } 108 | } -------------------------------------------------------------------------------- /NEKOSDK/ComponentAce/Compression/Libs/zlib/MyZlib.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace ComponentAce.Compression.Libs.zlib 5 | { 6 | internal class MyZlib 7 | { 8 | public static void CopyStream(Stream input, Stream output) 9 | { 10 | byte[] buffer = new byte[2000]; 11 | int count; 12 | while ((count = input.Read(buffer, 0, 2000)) > 0) 13 | { 14 | output.Write(buffer, 0, count); 15 | output.Flush(); 16 | } 17 | } 18 | public static byte[] compressBytes(byte[] sourceByte) 19 | { 20 | MemoryStream memoryStream = new MemoryStream(sourceByte); 21 | Stream stream = MyZlib.compressStream(memoryStream); 22 | byte[] array = new byte[stream.Length]; 23 | stream.Position = 0L; 24 | stream.Read(array, 0, array.Length); 25 | stream.Close(); 26 | memoryStream.Close(); 27 | return array; 28 | } 29 | public static byte[] deCompressBytes(byte[] sourceByte) 30 | { 31 | MemoryStream memoryStream = new MemoryStream(sourceByte); 32 | Stream stream = MyZlib.deCompressStream(memoryStream); 33 | byte[] array = new byte[stream.Length]; 34 | stream.Position = 0L; 35 | stream.Read(array, 0, array.Length); 36 | stream.Close(); 37 | memoryStream.Close(); 38 | return array; 39 | } 40 | public static Stream compressStream(Stream sourceStream) 41 | { 42 | MemoryStream memoryStream = new MemoryStream(); 43 | ZOutputStream zoutputStream = new ZOutputStream(memoryStream, -1); 44 | MyZlib.CopyStream(sourceStream, zoutputStream); 45 | zoutputStream.finish(); 46 | return memoryStream; 47 | } 48 | public static Stream deCompressStream(Stream sourceStream) 49 | { 50 | MemoryStream memoryStream = new MemoryStream(); 51 | ZOutputStream zoutputStream = new ZOutputStream(memoryStream); 52 | MyZlib.CopyStream(sourceStream, zoutputStream); 53 | zoutputStream.finish(); 54 | return memoryStream; 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /NEKOSDK/ComponentAce/Compression/Libs/zlib/StaticTree.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2006, ComponentAce 2 | // http://www.componentace.com 3 | // All rights reserved. 4 | 5 | // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 6 | 7 | // Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | // Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 9 | // Neither the name of ComponentAce nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 10 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 11 | 12 | /* 13 | Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. 14 | 15 | Redistribution and use in source and binary forms, with or without 16 | modification, are permitted provided that the following conditions are met: 17 | 18 | 1. Redistributions of source code must retain the above copyright notice, 19 | this list of conditions and the following disclaimer. 20 | 21 | 2. Redistributions in binary form must reproduce the above copyright 22 | notice, this list of conditions and the following disclaimer in 23 | the documentation and/or other materials provided with the distribution. 24 | 25 | 3. The names of the authors may not be used to endorse or promote products 26 | derived from this software without specific prior written permission. 27 | 28 | THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, 29 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 30 | FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, 31 | INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, 32 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 33 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 34 | OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 35 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 36 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 37 | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 38 | */ 39 | /* 40 | * This program is based on zlib-1.1.3, so all credit should go authors 41 | * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) 42 | * and contributors of zlib. 43 | */ 44 | using System; 45 | namespace ComponentAce.Compression.Libs.zlib 46 | { 47 | 48 | sealed class StaticTree 49 | { 50 | private const int MAX_BITS = 15; 51 | 52 | private const int BL_CODES = 19; 53 | private const int D_CODES = 30; 54 | private const int LITERALS = 256; 55 | private const int LENGTH_CODES = 29; 56 | private static readonly int L_CODES = (LITERALS + 1 + LENGTH_CODES); 57 | 58 | // Bit length codes must not exceed MAX_BL_BITS bits 59 | internal const int MAX_BL_BITS = 7; 60 | 61 | internal static readonly short[] static_ltree = new short[]{12, 8, 140, 8, 76, 8, 204, 8, 44, 8, 172, 8, 108, 8, 236, 8, 28, 8, 156, 8, 92, 8, 220, 8, 60, 8, 188, 8, 124, 8, 252, 8, 2, 8, 130, 8, 66, 8, 194, 8, 34, 8, 162, 8, 98, 8, 226, 8, 18, 8, 146, 8, 82, 8, 210, 8, 50, 8, 178, 8, 114, 8, 242, 8, 10, 8, 138, 8, 74, 8, 202, 8, 42, 8, 170, 8, 106, 8, 234, 8, 26, 8, 154, 8, 90, 8, 218, 8, 58, 8, 186, 8, 122, 8, 250, 8, 6, 8, 134, 8, 70, 8, 198, 8, 38, 8, 166, 8, 102, 8, 230, 8, 22, 8, 150, 8, 86, 8, 214, 8, 54, 8, 182, 8, 118, 8, 246, 8, 14, 8, 142, 8, 78, 8, 206, 8, 46, 8, 174, 8, 110, 8, 238, 8, 30, 8, 158, 8, 94, 8, 222, 8, 62, 8, 190, 8, 126, 8, 254, 8, 1, 8, 129, 8, 65, 8, 193, 8, 33, 8, 161, 8, 97, 8, 225, 8, 17, 8, 145, 8, 81, 8, 209, 8, 49, 8, 177, 8, 113, 8, 241, 8, 9, 8, 137, 8, 73, 8, 201, 8, 41, 8, 169, 8, 105, 8, 233, 8, 25, 8, 153, 8, 89, 8, 217, 8, 57, 8, 185, 8, 121, 8, 249, 8, 5, 8, 133, 8, 69, 8, 197, 8, 37, 8, 165, 8, 101, 8, 229, 8, 21, 8, 149, 8, 85, 8, 213, 8, 53, 8, 181, 8, 117, 8, 245, 8, 13, 8, 141, 8, 77, 8, 205, 8, 45, 8, 173, 8, 109, 8, 237, 8, 29, 8, 157, 8, 93, 8, 221, 8, 61, 8, 189, 8, 125, 8, 253, 8, 19, 9, 275, 9, 147, 9, 403, 9, 83, 9, 339, 9, 211, 9, 467, 9, 51, 9, 307, 9, 179, 9, 435, 9, 115, 9, 371, 9, 243, 9, 499, 9, 11, 9, 267, 9, 139, 9, 395, 9, 75, 9, 331, 9, 203, 9, 459, 9, 43, 9, 299, 9, 171, 9, 427, 9, 107, 9, 363, 9, 235, 9, 491, 9, 27, 9, 283, 9, 155, 9, 411, 9, 91, 9, 347, 9, 219, 9, 475, 9, 59, 9, 315, 9, 187, 9, 443, 9, 123, 9, 379, 9, 251, 9, 507, 9, 7, 9, 263, 9, 135, 9, 391, 9, 71, 9, 327, 9, 199, 9, 455, 9, 39, 9, 295, 9, 167, 9, 423, 9, 103, 9, 359, 9, 231, 9, 487, 9, 23, 9, 279, 9, 151, 9, 407, 9, 87, 9, 343, 9, 215, 9, 471, 9, 55, 9, 311, 9, 183, 9, 439, 9, 119, 9, 375, 9, 247, 9, 503, 9, 15, 9, 271, 9, 143, 9, 399, 9, 79, 9, 335, 9, 207, 9, 463, 9, 47, 9, 303, 9, 175, 9, 431, 9, 111, 9, 367, 9, 239, 9, 495, 9, 31, 9, 287, 9, 159, 9, 415, 9, 95, 9, 351, 9, 223, 9, 479, 9, 63, 9, 319, 9, 191, 9, 447, 9, 127, 9, 383, 9, 255, 9, 511, 9, 0, 7, 64, 7 62 | , 32, 7, 96, 7, 16, 7, 80, 7, 48, 7, 112, 7, 8, 7, 72, 7, 40, 7, 104, 7, 24, 7, 88, 7, 56, 7, 120, 7, 4, 7, 68, 7, 36, 7, 100, 7, 20, 7, 84, 7, 52, 7, 116, 7, 3, 8, 131, 8, 67, 8, 195, 8, 35, 8, 163, 8, 99, 8, 227, 8}; 63 | 64 | internal static readonly short[] static_dtree = new short[]{0, 5, 16, 5, 8, 5, 24, 5, 4, 5, 20, 5, 12, 5, 28, 5, 2, 5, 18, 5, 10, 5, 26, 5, 6, 5, 22, 5, 14, 5, 30, 5, 1, 5, 17, 5, 9, 5, 25, 5, 5, 5, 21, 5, 13, 5, 29, 5, 3, 5, 19, 5, 11, 5, 27, 5, 7, 5, 23, 5}; 65 | 66 | internal static StaticTree static_l_desc; 67 | 68 | internal static StaticTree static_d_desc; 69 | 70 | internal static StaticTree static_bl_desc; 71 | 72 | internal short[] static_tree; // static tree or null 73 | internal int[] extra_bits; // extra bits for each code or null 74 | internal int extra_base; // base index for extra_bits 75 | internal int elems; // max number of elements in the tree 76 | internal int max_length; // max bit length for the codes 77 | 78 | internal StaticTree(short[] static_tree, int[] extra_bits, int extra_base, int elems, int max_length) 79 | { 80 | this.static_tree = static_tree; 81 | this.extra_bits = extra_bits; 82 | this.extra_base = extra_base; 83 | this.elems = elems; 84 | this.max_length = max_length; 85 | } 86 | static StaticTree() 87 | { 88 | static_l_desc = new StaticTree(static_ltree, Tree.extra_lbits, LITERALS + 1, L_CODES, MAX_BITS); 89 | static_d_desc = new StaticTree(static_dtree, Tree.extra_dbits, 0, D_CODES, MAX_BITS); 90 | static_bl_desc = new StaticTree(null, Tree.extra_blbits, 0, BL_CODES, MAX_BL_BITS); 91 | } 92 | } 93 | } -------------------------------------------------------------------------------- /NEKOSDK/ComponentAce/Compression/Libs/zlib/SupportClass.cs: -------------------------------------------------------------------------------- 1 | 2 | using System; 3 | 4 | 5 | namespace ComponentAce.Compression.Libs.zlib 6 | { 7 | public class SupportClass 8 | { 9 | /// 10 | /// This method returns the literal value received 11 | /// 12 | /// The literal to return 13 | /// The received value 14 | public static long Identity(long literal) 15 | { 16 | return literal; 17 | } 18 | 19 | /// 20 | /// This method returns the literal value received 21 | /// 22 | /// The literal to return 23 | /// The received value 24 | public static ulong Identity(ulong literal) 25 | { 26 | return literal; 27 | } 28 | 29 | /// 30 | /// This method returns the literal value received 31 | /// 32 | /// The literal to return 33 | /// The received value 34 | public static float Identity(float literal) 35 | { 36 | return literal; 37 | } 38 | 39 | /// 40 | /// This method returns the literal value received 41 | /// 42 | /// The literal to return 43 | /// The received value 44 | public static double Identity(double literal) 45 | { 46 | return literal; 47 | } 48 | 49 | /*******************************/ 50 | /// 51 | /// Performs an unsigned bitwise right shift with the specified number 52 | /// 53 | /// Number to operate on 54 | /// Ammount of bits to shift 55 | /// The resulting number from the shift operation 56 | public static int URShift(int number, int bits) 57 | { 58 | if ( number >= 0) 59 | return number >> bits; 60 | else 61 | return (number >> bits) + (2 << ~bits); 62 | } 63 | 64 | /// 65 | /// Performs an unsigned bitwise right shift with the specified number 66 | /// 67 | /// Number to operate on 68 | /// Ammount of bits to shift 69 | /// The resulting number from the shift operation 70 | public static int URShift(int number, long bits) 71 | { 72 | return URShift(number, (int)bits); 73 | } 74 | 75 | /// 76 | /// Performs an unsigned bitwise right shift with the specified number 77 | /// 78 | /// Number to operate on 79 | /// Ammount of bits to shift 80 | /// The resulting number from the shift operation 81 | public static long URShift(long number, int bits) 82 | { 83 | if ( number >= 0) 84 | return number >> bits; 85 | else 86 | return (number >> bits) + (2L << ~bits); 87 | } 88 | 89 | /// 90 | /// Performs an unsigned bitwise right shift with the specified number 91 | /// 92 | /// Number to operate on 93 | /// Ammount of bits to shift 94 | /// The resulting number from the shift operation 95 | public static long URShift(long number, long bits) 96 | { 97 | return URShift(number, (int)bits); 98 | } 99 | 100 | /*******************************/ 101 | /// Reads a number of characters from the current source Stream and writes the data to the target array at the specified index. 102 | /// The source Stream to read from. 103 | /// Contains the array of characteres read from the source Stream. 104 | /// The starting index of the target array. 105 | /// The maximum number of characters to read from the source Stream. 106 | /// The number of characters read. The number will be less than or equal to count depending on the data available in the source Stream. Returns -1 if the end of the stream is reached. 107 | public static System.Int32 ReadInput(System.IO.Stream sourceStream, byte[] target, int start, int count) 108 | { 109 | // Returns 0 bytes if not enough space in target 110 | if (target.Length == 0) 111 | return 0; 112 | 113 | byte[] receiver = new byte[target.Length]; 114 | int bytesRead = sourceStream.Read(receiver, start, count); 115 | 116 | // Returns -1 if EOF 117 | if (bytesRead == 0) 118 | return -1; 119 | 120 | for(int i = start; i < start + bytesRead; i++) 121 | target[i] = (byte)receiver[i]; 122 | 123 | return bytesRead; 124 | } 125 | 126 | /// Reads a number of characters from the current source TextReader and writes the data to the target array at the specified index. 127 | /// The source TextReader to read from 128 | /// Contains the array of characteres read from the source TextReader. 129 | /// The starting index of the target array. 130 | /// The maximum number of characters to read from the source TextReader. 131 | /// The number of characters read. The number will be less than or equal to count depending on the data available in the source TextReader. Returns -1 if the end of the stream is reached. 132 | public static System.Int32 ReadInput(System.IO.TextReader sourceTextReader, byte[] target, int start, int count) 133 | { 134 | // Returns 0 bytes if not enough space in target 135 | if (target.Length == 0) return 0; 136 | 137 | char[] charArray = new char[target.Length]; 138 | int bytesRead = sourceTextReader.Read(charArray, start, count); 139 | 140 | // Returns -1 if EOF 141 | if (bytesRead == 0) return -1; 142 | 143 | for(int index=start; index 150 | /// Converts a string to an array of bytes 151 | /// 152 | /// The string to be converted 153 | /// The new array of bytes 154 | public static byte[] ToByteArray(System.String sourceString) 155 | { 156 | return System.Text.UTF8Encoding.UTF8.GetBytes(sourceString); 157 | } 158 | 159 | /// 160 | /// Converts an array of bytes to an array of chars 161 | /// 162 | /// The array of bytes to convert 163 | /// The new array of chars 164 | public static char[] ToCharArray(byte[] byteArray) 165 | { 166 | return System.Text.UTF8Encoding.UTF8.GetChars(byteArray); 167 | } 168 | 169 | 170 | } 171 | } -------------------------------------------------------------------------------- /NEKOSDK/ComponentAce/Compression/Libs/zlib/ZInputStream.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2006, ComponentAce 2 | // http://www.componentace.com 3 | // All rights reserved. 4 | 5 | // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 6 | 7 | // Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | // Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 9 | // Neither the name of ComponentAce nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 10 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 11 | 12 | /* 13 | Copyright (c) 2001 Lapo Luchini. 14 | 15 | Redistribution and use in source and binary forms, with or without 16 | modification, are permitted provided that the following conditions are met: 17 | 18 | 1. Redistributions of source code must retain the above copyright notice, 19 | this list of conditions and the following disclaimer. 20 | 21 | 2. Redistributions in binary form must reproduce the above copyright 22 | notice, this list of conditions and the following disclaimer in 23 | the documentation and/or other materials provided with the distribution. 24 | 25 | 3. The names of the authors may not be used to endorse or promote products 26 | derived from this software without specific prior written permission. 27 | 28 | THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, 29 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 30 | FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS 31 | OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, 32 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 33 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 34 | OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 35 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 36 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 37 | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 38 | */ 39 | /* 40 | * This program is based on zlib-1.1.3, so all credit should go authors 41 | * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) 42 | * and contributors of zlib. 43 | */ 44 | using System; 45 | namespace ComponentAce.Compression.Libs.zlib 46 | { 47 | 48 | public class ZInputStream:System.IO.BinaryReader 49 | { 50 | internal void InitBlock() 51 | { 52 | flush = zlibConst.Z_NO_FLUSH; 53 | buf = new byte[bufsize]; 54 | } 55 | virtual public int FlushMode 56 | { 57 | get 58 | { 59 | return (flush); 60 | } 61 | 62 | set 63 | { 64 | this.flush = value; 65 | } 66 | 67 | } 68 | /// Returns the total number of bytes input so far. 69 | virtual public long TotalIn 70 | { 71 | get 72 | { 73 | return z.total_in; 74 | } 75 | 76 | } 77 | /// Returns the total number of bytes output so far. 78 | virtual public long TotalOut 79 | { 80 | get 81 | { 82 | return z.total_out; 83 | } 84 | 85 | } 86 | 87 | protected ZStream z = new ZStream(); 88 | protected int bufsize = 512; 89 | protected int flush; 90 | protected byte[] buf, buf1 = new byte[1]; 91 | protected bool compress; 92 | 93 | internal System.IO.Stream in_Renamed = null; 94 | 95 | public ZInputStream(System.IO.Stream in_Renamed):base(in_Renamed) 96 | { 97 | InitBlock(); 98 | this.in_Renamed = in_Renamed; 99 | z.inflateInit(); 100 | compress = false; 101 | z.next_in = buf; 102 | z.next_in_index = 0; 103 | z.avail_in = 0; 104 | } 105 | 106 | public ZInputStream(System.IO.Stream in_Renamed, int level):base(in_Renamed) 107 | { 108 | InitBlock(); 109 | this.in_Renamed = in_Renamed; 110 | z.deflateInit(level); 111 | compress = true; 112 | z.next_in = buf; 113 | z.next_in_index = 0; 114 | z.avail_in = 0; 115 | } 116 | 117 | /*public int available() throws IOException { 118 | return inf.finished() ? 0 : 1; 119 | }*/ 120 | 121 | public override int Read() 122 | { 123 | if (read(buf1, 0, 1) == - 1) 124 | return (- 1); 125 | return (buf1[0] & 0xFF); 126 | } 127 | 128 | internal bool nomoreinput = false; 129 | 130 | public int read(byte[] b, int off, int len) 131 | { 132 | if (len == 0) 133 | return (0); 134 | int err; 135 | z.next_out = b; 136 | z.next_out_index = off; 137 | z.avail_out = len; 138 | do 139 | { 140 | if ((z.avail_in == 0) && (!nomoreinput)) 141 | { 142 | // if buffer is empty and more input is avaiable, refill it 143 | z.next_in_index = 0; 144 | z.avail_in = SupportClass.ReadInput(in_Renamed, buf, 0, bufsize); //(bufsize> this.m_cached_bits & num2; 26 | } 27 | public int GetNextBit() 28 | { 29 | return this.GetBits(1); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /NEKOSDK/GameRes/Compression/ZLibStream.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.IO.Compression; 4 | using GameRes.Utility; 5 | 6 | namespace GameRes.Compression 7 | { 8 | public class ZLibStream : Stream 9 | { 10 | public Stream BaseStream 11 | { 12 | get 13 | { 14 | return this.m_stream.BaseStream; 15 | } 16 | } 17 | public int TotalIn 18 | { 19 | get 20 | { 21 | return this.m_total_in; 22 | } 23 | } 24 | public ZLibStream(Stream stream, CompressionMode mode, bool leave_open = false) : this(stream, mode, CompressionLevel.Default, leave_open) 25 | { 26 | } 27 | public ZLibStream(Stream stream, CompressionMode mode, CompressionLevel level, bool leave_open = false) 28 | { 29 | try 30 | { 31 | if (CompressionMode.Decompress == mode) 32 | { 33 | this.InitDecompress(stream); 34 | } 35 | else 36 | { 37 | this.InitCompress(stream, level); 38 | } 39 | this.m_should_dispose_base = !leave_open; 40 | } 41 | catch 42 | { 43 | if (!leave_open) 44 | { 45 | stream.Dispose(); 46 | } 47 | throw; 48 | } 49 | } 50 | private void InitDecompress(Stream stream) 51 | { 52 | int num = stream.ReadByte(); 53 | int num2 = stream.ReadByte(); 54 | if ((120 != num && 88 != num) || (num << 8 | num2) % 31 != 0) 55 | { 56 | throw new InvalidDataException("Data not recoginzed as zlib-compressed stream"); 57 | } 58 | this.m_stream = new DeflateStream(stream, System.IO.Compression.CompressionMode.Decompress, true); 59 | this.m_writing = false; 60 | } 61 | private void InitCompress(Stream stream, GameRes.Compression.CompressionLevel level) 62 | { 63 | int num = (int)level; 64 | System.IO.Compression.CompressionLevel compressionLevel; 65 | if (num == 0) 66 | { 67 | compressionLevel = System.IO.Compression.CompressionLevel.NoCompression; 68 | } 69 | else if (num > 5) 70 | { 71 | compressionLevel = System.IO.Compression.CompressionLevel.Optimal; 72 | num = 3; 73 | } 74 | else 75 | { 76 | compressionLevel = System.IO.Compression.CompressionLevel.Fastest; 77 | num = 1; 78 | } 79 | int num2 = 30720 | num << 6; 80 | num2 = (num2 + 30) / 31 * 31; 81 | stream.WriteByte((byte)(num2 >> 8)); 82 | stream.WriteByte((byte)num2); 83 | this.m_stream = new DeflateStream(stream, compressionLevel, true); 84 | this.m_adler = new CheckedStream(this.m_stream, new Adler32()); 85 | this.m_writing = true; 86 | } 87 | private void WriteCheckSum(Stream output) 88 | { 89 | uint checkSumValue = this.m_adler.CheckSumValue; 90 | output.WriteByte((byte)(checkSumValue >> 24)); 91 | output.WriteByte((byte)(checkSumValue >> 16)); 92 | output.WriteByte((byte)(checkSumValue >> 8)); 93 | output.WriteByte((byte)checkSumValue); 94 | } 95 | public override bool CanRead 96 | { 97 | get 98 | { 99 | return !this.m_writing; 100 | } 101 | } 102 | public override bool CanSeek 103 | { 104 | get 105 | { 106 | return false; 107 | } 108 | } 109 | public override bool CanWrite 110 | { 111 | get 112 | { 113 | return this.m_writing; 114 | } 115 | } 116 | public override long Length 117 | { 118 | get 119 | { 120 | return this.m_stream.Length; 121 | } 122 | } 123 | public override long Position 124 | { 125 | get 126 | { 127 | return this.m_stream.Position; 128 | } 129 | set 130 | { 131 | this.m_stream.Position = value; 132 | } 133 | } 134 | public override int Read(byte[] buffer, int offset, int count) 135 | { 136 | return this.m_stream.Read(buffer, offset, count); 137 | } 138 | public override int ReadByte() 139 | { 140 | return this.m_stream.ReadByte(); 141 | } 142 | public override void Flush() 143 | { 144 | this.m_stream.Flush(); 145 | } 146 | public override long Seek(long offset, SeekOrigin origin) 147 | { 148 | throw new NotSupportedException("ZLibStream.Seek method not supported"); 149 | } 150 | public override void SetLength(long length) 151 | { 152 | throw new NotSupportedException("ZLibStream.SetLength method not supported"); 153 | } 154 | public override void Write(byte[] buffer, int offset, int count) 155 | { 156 | if (count > 0) 157 | { 158 | this.m_adler.Write(buffer, offset, count); 159 | this.m_total_in += count; 160 | } 161 | } 162 | public override void WriteByte(byte value) 163 | { 164 | this.m_adler.WriteByte(value); 165 | this.m_total_in++; 166 | } 167 | protected override void Dispose(bool disposing) 168 | { 169 | if (!this.m_disposed) 170 | { 171 | try 172 | { 173 | if (disposing) 174 | { 175 | Stream baseStream = this.m_stream.BaseStream; 176 | this.m_stream.Dispose(); 177 | if (this.m_writing) 178 | { 179 | this.WriteCheckSum(baseStream); 180 | this.m_adler.Dispose(); 181 | } 182 | if (this.m_should_dispose_base) 183 | { 184 | baseStream.Dispose(); 185 | } 186 | } 187 | this.m_disposed = true; 188 | } 189 | finally 190 | { 191 | base.Dispose(disposing); 192 | } 193 | } 194 | } 195 | private DeflateStream m_stream; 196 | private CheckedStream m_adler; 197 | private bool m_should_dispose_base; 198 | private bool m_writing; 199 | public int m_total_in; 200 | private bool m_disposed; 201 | } 202 | } 203 | -------------------------------------------------------------------------------- /NEKOSDK/GameRes/Utility/Adler32.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace GameRes.Utility 4 | { 5 | public sealed class Adler32 : ICheckSum 6 | { 7 | public unsafe static uint Compute(byte[] buf, int pos, int len) 8 | { 9 | if (len == 0) 10 | { 11 | return 1U; 12 | } 13 | fixed (byte* ptr = &buf[pos]) 14 | { 15 | byte* buf2 = ptr; 16 | return Adler32.Update(1U, buf2, len); 17 | } 18 | } 19 | public unsafe static uint Compute(byte* buf, int len) 20 | { 21 | return Adler32.Update(1U, buf, len); 22 | } 23 | private unsafe static uint Update(uint adler, byte* buf, int len) 24 | { 25 | uint num = adler >> 16 & 65535U; 26 | adler &= 65535U; 27 | if (1 == len) 28 | { 29 | adler += (uint)(*buf); 30 | if (adler >= 65521U) 31 | { 32 | adler -= 65521U; 33 | } 34 | num += adler; 35 | if (num >= 65521U) 36 | { 37 | num -= 65521U; 38 | } 39 | return adler | num << 16; 40 | } 41 | if (len < 16) 42 | { 43 | while (len-- != 0) 44 | { 45 | adler += (uint)(*(buf++)); 46 | num += adler; 47 | } 48 | if (adler >= 65521U) 49 | { 50 | adler -= 65521U; 51 | } 52 | num %= 65521U; 53 | return adler | num << 16; 54 | } 55 | while (len >= 5552) 56 | { 57 | len -= 5552; 58 | int num2 = 347; 59 | do 60 | { 61 | adler += (uint)(*buf); 62 | num += adler; 63 | adler += (uint)buf[1]; 64 | num += adler; 65 | adler += (uint)buf[2]; 66 | num += adler; 67 | adler += (uint)buf[3]; 68 | num += adler; 69 | adler += (uint)buf[4]; 70 | num += adler; 71 | adler += (uint)buf[5]; 72 | num += adler; 73 | adler += (uint)buf[6]; 74 | num += adler; 75 | adler += (uint)buf[7]; 76 | num += adler; 77 | adler += (uint)buf[8]; 78 | num += adler; 79 | adler += (uint)buf[9]; 80 | num += adler; 81 | adler += (uint)buf[10]; 82 | num += adler; 83 | adler += (uint)buf[11]; 84 | num += adler; 85 | adler += (uint)buf[12]; 86 | num += adler; 87 | adler += (uint)buf[13]; 88 | num += adler; 89 | adler += (uint)buf[14]; 90 | num += adler; 91 | adler += (uint)buf[15]; 92 | num += adler; 93 | buf += 16; 94 | } 95 | while (--num2 != 0); 96 | adler %= 65521U; 97 | num %= 65521U; 98 | } 99 | if (len != 0) 100 | { 101 | while (len >= 16) 102 | { 103 | len -= 16; 104 | adler += (uint)(*buf); 105 | num += adler; 106 | adler += (uint)buf[1]; 107 | num += adler; 108 | adler += (uint)buf[2]; 109 | num += adler; 110 | adler += (uint)buf[3]; 111 | num += adler; 112 | adler += (uint)buf[4]; 113 | num += adler; 114 | adler += (uint)buf[5]; 115 | num += adler; 116 | adler += (uint)buf[6]; 117 | num += adler; 118 | adler += (uint)buf[7]; 119 | num += adler; 120 | adler += (uint)buf[8]; 121 | num += adler; 122 | adler += (uint)buf[9]; 123 | num += adler; 124 | adler += (uint)buf[10]; 125 | num += adler; 126 | adler += (uint)buf[11]; 127 | num += adler; 128 | adler += (uint)buf[12]; 129 | num += adler; 130 | adler += (uint)buf[13]; 131 | num += adler; 132 | adler += (uint)buf[14]; 133 | num += adler; 134 | adler += (uint)buf[15]; 135 | num += adler; 136 | buf += 16; 137 | } 138 | while (len-- != 0) 139 | { 140 | adler += (uint)(*(buf++)); 141 | num += adler; 142 | } 143 | adler %= 65521U; 144 | num %= 65521U; 145 | } 146 | return adler | num << 16; 147 | } 148 | public uint Value 149 | { 150 | get 151 | { 152 | return this.m_adler; 153 | } 154 | } 155 | public unsafe void Update(byte[] buf, int pos, int len) 156 | { 157 | if (len == 0) 158 | { 159 | return; 160 | } 161 | fixed (byte* ptr = &buf[pos]) 162 | { 163 | byte* buf2 = ptr; 164 | this.m_adler = Adler32.Update(this.m_adler, buf2, len); 165 | } 166 | } 167 | public unsafe uint Update(byte* buf, int len) 168 | { 169 | this.m_adler = Adler32.Update(this.m_adler, buf, len); 170 | return this.m_adler; 171 | } 172 | private const uint BASE = 65521U; 173 | private const int NMAX = 5552; 174 | private uint m_adler = 1U; 175 | } 176 | } 177 | -------------------------------------------------------------------------------- /NEKOSDK/GameRes/Utility/CheckedStream.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace GameRes.Utility 5 | { 6 | public class CheckedStream : Stream 7 | { 8 | public override bool CanRead 9 | { 10 | get 11 | { 12 | return this.m_stream.CanRead; 13 | } 14 | } 15 | public override bool CanWrite 16 | { 17 | get 18 | { 19 | return this.m_stream.CanWrite; 20 | } 21 | } 22 | public override bool CanSeek 23 | { 24 | get 25 | { 26 | return this.m_stream.CanSeek; 27 | } 28 | } 29 | public override long Length 30 | { 31 | get 32 | { 33 | return this.m_stream.Length; 34 | } 35 | } 36 | public Stream BaseStream 37 | { 38 | get 39 | { 40 | return this.m_stream; 41 | } 42 | } 43 | public uint CheckSumValue 44 | { 45 | get 46 | { 47 | return this.m_checksum.Value; 48 | } 49 | } 50 | public CheckedStream(Stream stream, ICheckSum algorithm) 51 | { 52 | this.m_stream = stream; 53 | this.m_checksum = algorithm; 54 | } 55 | public override int Read(byte[] buffer, int offset, int count) 56 | { 57 | int num = this.m_stream.Read(buffer, offset, count); 58 | if (num > 0) 59 | { 60 | this.m_checksum.Update(buffer, offset, num); 61 | } 62 | return num; 63 | } 64 | public override void Write(byte[] buffer, int offset, int count) 65 | { 66 | this.m_stream.Write(buffer, offset, count); 67 | this.m_checksum.Update(buffer, offset, count); 68 | } 69 | public override long Position 70 | { 71 | get 72 | { 73 | return this.m_stream.Position; 74 | } 75 | set 76 | { 77 | this.m_stream.Position = value; 78 | } 79 | } 80 | public override void SetLength(long value) 81 | { 82 | this.m_stream.SetLength(value); 83 | } 84 | public override long Seek(long offset, SeekOrigin origin) 85 | { 86 | return this.m_stream.Seek(offset, origin); 87 | } 88 | public override void Flush() 89 | { 90 | this.m_stream.Flush(); 91 | } 92 | private Stream m_stream; 93 | private ICheckSum m_checksum; 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /NEKOSDK/GameRes/Utility/ICheckSum.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace GameRes.Utility 4 | { 5 | public interface ICheckSum 6 | { 7 | uint Value { get; } 8 | void Update(byte[] buf, int pos, int len); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /NEKOSDK/NEKOSDK.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net6.0 6 | enable 7 | enable 8 | true 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /NEKOSDK/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Text; 5 | 6 | namespace NEKOSDK 7 | { 8 | class Program 9 | { 10 | static void Main(string[] args) 11 | { 12 | Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); 13 | if (args.Length < 2) 14 | { 15 | Console.WriteLine("Usage: "); 16 | Console.WriteLine(" Unpack: Pak.exe -u "); 17 | Console.WriteLine(" Pack: Pak.exe -p "); 18 | return; 19 | } 20 | 21 | string operation = args[0]; 22 | string inputFile = args[1]; 23 | string outputFile = args[2]; 24 | 25 | if (operation == "-u") 26 | { 27 | Unpack(inputFile, outputFile); 28 | } 29 | else if (operation == "-p") 30 | { 31 | Pack(inputFile, outputFile); 32 | } 33 | else 34 | { 35 | Console.WriteLine("Invalid operation. Valid operations are 'unpack' and 'pack'."); 36 | } 37 | } 38 | 39 | static void Unpack(string inputFile, string outputFile) 40 | { 41 | ArcPAK ArcPAK = new ArcPAK(); 42 | try 43 | { 44 | Directory.CreateDirectory(outputFile); 45 | 46 | foreach (Entry entry in ArcPAK.TryOpen(inputFile)) 47 | { 48 | byte[] bytes = ArcPAK.Unpack(entry); 49 | System.IO.File.WriteAllBytes(Path.Combine(outputFile, entry.Name), bytes); 50 | } 51 | } 52 | catch (Exception ex) 53 | { 54 | Console.WriteLine(ex.Message); 55 | return; 56 | } 57 | Console.WriteLine("Unpacked successfully!"); 58 | } 59 | 60 | static void Pack(string inputFile, string outputFile) 61 | { 62 | ArcPAK ArcPAK = new ArcPAK(); 63 | try 64 | { 65 | ArcPAK.Pack(inputFile, outputFile); 66 | } 67 | catch (Exception ex) 68 | { 69 | Console.WriteLine(ex.Message); 70 | return; 71 | } 72 | Console.WriteLine("Pack successfully!"); 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /Nexas/ArcPAC.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.IO.Compression; 5 | using System.Text; 6 | using GameRes.Utility; 7 | using GameRes.Compression; 8 | using ZstdNet; 9 | 10 | namespace Nexas 11 | { 12 | internal class ArcPAC 13 | { 14 | private string GetStringLiteral(BinaryReader reader, long index_offset, uint name_length) 15 | { 16 | List list = new List(); 17 | reader.BaseStream.Position = index_offset; 18 | byte[] array = reader.ReadBytes((int)name_length); 19 | int num = 0; 20 | while (num < array.Length && array[num] != 0) 21 | { 22 | list.Add(array[num]); 23 | num++; 24 | } 25 | return Encoding.GetEncoding(932).GetString(list.ToArray()); 26 | } 27 | public List TryOpen(string filePath) 28 | { 29 | this.buffer = File.ReadAllBytes(filePath); 30 | List result; 31 | using (BinaryReader binaryReader = new BinaryReader(new MemoryStream(this.buffer))) 32 | { 33 | byte[] array = binaryReader.ReadBytes(4); 34 | if (array[0] != 80 || array[1] != 65 || array[2] != 67) 35 | { 36 | throw new Exception("Unsupported file format!"); 37 | } 38 | int num = binaryReader.ReadInt32(); 39 | this.pack_type = binaryReader.ReadInt32(); 40 | if (num > 40000) 41 | { 42 | throw new Exception("Unsupported file format!"); 43 | } 44 | binaryReader.BaseStream.Position = binaryReader.BaseStream.Length - 4L; 45 | int num2 = binaryReader.ReadInt32(); 46 | int num3 = num * 76; 47 | if ((long)num2 >= binaryReader.BaseStream.Length) 48 | { 49 | throw new Exception("Unsupported file format!"); 50 | } 51 | binaryReader.BaseStream.Position = binaryReader.BaseStream.Length - 4L - (long)num2; 52 | byte[] array2 = binaryReader.ReadBytes(num2); 53 | for (int i = 0; i < array2.Length; i++) 54 | { 55 | array2[i] = (byte)(~array2[i]); 56 | } 57 | byte[] array3 = new byte[num3]; 58 | using (BinaryReader binaryReader2 = new BinaryReader(new MemoryStream(new Huffman().Decoder(array2, num3)))) 59 | { 60 | uint name_length = 64U; 61 | for (int j = 0; j < num; j++) 62 | { 63 | string stringLiteral = this.GetStringLiteral(binaryReader2, binaryReader2.BaseStream.Position, name_length); 64 | if (string.IsNullOrEmpty(stringLiteral)) 65 | { 66 | throw new Exception("Unsupported file format!"); 67 | } 68 | Entry entry = new Entry(); 69 | entry.Name = stringLiteral; 70 | entry.Offset = binaryReader2.ReadInt32(); 71 | entry.UnpackedSize = binaryReader2.ReadInt32(); 72 | entry.Size = binaryReader2.ReadInt32(); 73 | if ((long)(entry.Offset + entry.Size) > binaryReader.BaseStream.Length) 74 | { 75 | throw new Exception("Unsupported file format!"); 76 | } 77 | entry.IsPacked = (this.pack_type != 0 && (this.pack_type != 4 || entry.Size != entry.UnpackedSize)); 78 | if (Path.GetExtension(entry.Name).Equals(".png")) 79 | { 80 | entry.IsPacked = false; 81 | } 82 | if (Path.GetExtension(entry.Name).Equals(".ogg")) 83 | { 84 | entry.IsPacked = false; 85 | } 86 | if (Path.GetExtension(entry.Name).Equals(".wav")) 87 | { 88 | entry.IsPacked = false; 89 | } 90 | this.dir.Add(entry); 91 | } 92 | } 93 | result = this.dir; 94 | } 95 | return result; 96 | } 97 | public byte[] Unpack(Entry entry) 98 | { 99 | byte[] array = new byte[1]; 100 | using (BinaryReader binaryReader = new BinaryReader(new MemoryStream(this.buffer))) 101 | { 102 | binaryReader.BaseStream.Position = (long)entry.Offset; 103 | byte[] array2 = binaryReader.ReadBytes(entry.Size); 104 | if (!entry.IsPacked) 105 | { 106 | array = array2; 107 | } 108 | else 109 | { 110 | Compression compression = (Compression)this.pack_type; 111 | if (compression != Compression.Lzss) 112 | { 113 | if (compression != Compression.Huffman) 114 | { 115 | if (compression == Compression.zstd) 116 | { 117 | return new Decompressor().Unwrap(array2, int.MaxValue); 118 | } 119 | array = new byte[entry.UnpackedSize]; 120 | using (GameRes.Compression.ZLibStream zlibStream = new GameRes.Compression.ZLibStream(new MemoryStream(array2, 0, array2.Length), GameRes.Compression.CompressionMode.Decompress, true)) 121 | { 122 | if (zlibStream.Read(array, 0, array.Length) != entry.UnpackedSize) 123 | { 124 | throw new Exception("Failed to decompress!"); 125 | } 126 | return array; 127 | } 128 | } 129 | } 130 | else 131 | { 132 | using (LzssStream lzssStream = new LzssStream(new MemoryStream(array2), System.IO.Compression.CompressionMode.Decompress)) 133 | { 134 | array = new byte[entry.UnpackedSize]; 135 | lzssStream.Read(array, 0, entry.UnpackedSize); 136 | return array; 137 | } 138 | } 139 | array = new Huffman().Decoder(array2, entry.UnpackedSize); 140 | } 141 | } 142 | return array; 143 | } 144 | public void Pack(string packPath, string outputFile) 145 | { 146 | List list = new List(); 147 | string[] files = Directory.GetFiles(packPath); 148 | for (int i = 0; i < files.Length; i++) 149 | { 150 | Entry entry = new Entry(); 151 | byte[] array = File.ReadAllBytes(files[i]); 152 | entry.UnpackedSize = array.Length; 153 | entry.fileBuffer = array; 154 | entry.Name = Path.GetFileName(files[i]); 155 | list.Add(entry); 156 | } 157 | string directoryName = Path.GetDirectoryName(packPath); 158 | using (BinaryWriter binaryWriter = new BinaryWriter(new FileStream(outputFile, FileMode.Create))) 159 | { 160 | uint value = 4407632U; 161 | binaryWriter.Write(value); 162 | binaryWriter.Flush(); 163 | int count = list.Count; 164 | binaryWriter.Write(count); 165 | binaryWriter.Flush(); 166 | int value2 = 0; 167 | binaryWriter.Write(value2); 168 | binaryWriter.Flush(); 169 | for (int j = 0; j < list.Count; j++) 170 | { 171 | binaryWriter.Write(list[j].fileBuffer); 172 | binaryWriter.Flush(); 173 | } 174 | byte[] input = new byte[count * 76]; 175 | using (BinaryWriter binaryWriter2 = new BinaryWriter(new MemoryStream(input))) 176 | { 177 | int num = 12; 178 | for (int k = 0; k < list.Count; k++) 179 | { 180 | byte[] bytes = Encoding.GetEncoding(932).GetBytes(list[k].Name); 181 | if (bytes.Length > 64) 182 | { 183 | throw new Exception("File's name is too long!"); 184 | } 185 | byte[] dst = new byte[64]; 186 | Buffer.BlockCopy(bytes, 0, dst, 0, bytes.Length); 187 | binaryWriter2.Write(dst); 188 | binaryWriter2.Flush(); 189 | binaryWriter2.Write(num); 190 | binaryWriter2.Flush(); 191 | num += list[k].fileBuffer.Length; 192 | int unpackedSize = list[k].UnpackedSize; 193 | int value3 = list[k].fileBuffer.Length; 194 | binaryWriter2.Write(unpackedSize); 195 | binaryWriter2.Flush(); 196 | binaryWriter2.Write(value3); 197 | binaryWriter2.Flush(); 198 | } 199 | } 200 | byte[] array2 = new Huffman().Encoder(input); 201 | for (int l = 0; l < array2.Length; l++) 202 | { 203 | array2[l] = (byte)(~array2[l]); 204 | } 205 | binaryWriter.Write(array2); 206 | binaryWriter.Flush(); 207 | int value4 = array2.Length; 208 | binaryWriter.Write(value4); 209 | binaryWriter.Flush(); 210 | } 211 | } 212 | private byte[] buffer; 213 | public byte[] blockBuffer; 214 | private List dir = new List(); 215 | private int pack_type; 216 | } 217 | } 218 | -------------------------------------------------------------------------------- /Nexas/Compression.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Nexas 4 | { 5 | public enum Compression 6 | { 7 | None, 8 | Lzss, 9 | Huffman, 10 | Deflate, 11 | DeflateOrNone, 12 | zstd = 7 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Nexas/Entry.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Nexas 4 | { 5 | public class Entry 6 | { 7 | public virtual string Name { get; set; } 8 | public virtual string SubName { get; set; } 9 | public virtual string Type { get; set; } 10 | public int filename_offset { get; set; } 11 | public int filename_length { get; set; } 12 | public int Offset { get; set; } 13 | public int Size { get; set; } 14 | public bool IsPacked { get; set; } 15 | public int UnpackedSize { get; set; } 16 | public long StructPosition { get; set; } 17 | public byte[] fileBuffer { get; set; } 18 | public Entry() 19 | { 20 | this.Type = ""; 21 | this.Offset = -1; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Nexas/GameRes/Compression/BitStream.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace GameRes.Compression 5 | { 6 | public class BitStream : IDisposable 7 | { 8 | public Stream Input 9 | { 10 | get 11 | { 12 | return this.m_input; 13 | } 14 | } 15 | public int CacheSize 16 | { 17 | get 18 | { 19 | return this.m_cached_bits; 20 | } 21 | } 22 | protected BitStream(Stream file, bool leave_open) 23 | { 24 | this.m_input = file; 25 | this.m_should_dispose = !leave_open; 26 | } 27 | public void Reset() 28 | { 29 | this.m_cached_bits = 0; 30 | } 31 | public void Dispose() 32 | { 33 | this.Dispose(true); 34 | GC.SuppressFinalize(this); 35 | } 36 | protected virtual void Dispose(bool disposing) 37 | { 38 | if (!this.m_disposed) 39 | { 40 | if (disposing && this.m_should_dispose && this.m_input != null) 41 | { 42 | this.m_input.Dispose(); 43 | } 44 | this.m_disposed = true; 45 | } 46 | } 47 | protected Stream m_input; 48 | private bool m_should_dispose; 49 | protected int m_bits; 50 | protected int m_cached_bits; 51 | private bool m_disposed; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Nexas/GameRes/Compression/CompressionLevel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace GameRes.Compression 4 | { 5 | public enum CompressionLevel 6 | { 7 | NoCompression, 8 | BestSpeed, 9 | BestCompression = 9, 10 | Default = 6, 11 | Level0 = 0, 12 | Level1, 13 | Level2, 14 | Level3, 15 | Level4, 16 | Level5, 17 | Level6, 18 | Level7, 19 | Level8, 20 | Level9 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Nexas/GameRes/Compression/CompressionMode.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace GameRes.Compression 4 | { 5 | public enum CompressionMode 6 | { 7 | Compress, 8 | Decompress 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Nexas/GameRes/Compression/Huffman.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace GameRes.Compression 5 | { 6 | internal class Huffman 7 | { 8 | public void Initialize(Stream input) 9 | { 10 | this.m_input = new MsbBitStream(input, true); 11 | } 12 | public void EncodeBit(int token, int token_width, BinaryWriter wrter) 13 | { 14 | int num = (1 << token_width) - 1; 15 | if (this.cache_bits < 24) 16 | { 17 | this.mm_bits <<= token_width; 18 | this.mm_bits |= (token & num); 19 | this.cache_bits += token_width; 20 | } 21 | if (this.cache_bits >= 8) 22 | { 23 | while (this.cache_bits >= token_width) 24 | { 25 | int num2 = this.cache_bits - 8; 26 | byte b = (byte)(this.mm_bits >> num2 & 255); 27 | this.cache_bits -= 8; 28 | int num3 = (1 << this.cache_bits) - 1; 29 | this.mm_bits &= num3; 30 | byte value = b; 31 | wrter.Write(value); 32 | wrter.Flush(); 33 | } 34 | } 35 | } 36 | public byte[] Decoder(byte[] input, int unpakedSize) 37 | { 38 | this.Initialize(new MemoryStream(input)); 39 | byte[] array = new byte[unpakedSize]; 40 | this.m_token = 256; 41 | ushort num = this.CreateTree(); 42 | int num2 = unpakedSize; 43 | do 44 | { 45 | ushort num3 = num; 46 | int num4 = 0; 47 | while (num3 >= 256) 48 | { 49 | num4++; 50 | int bits = this.m_input.GetBits(1); 51 | if (-1 == bits) 52 | { 53 | break; 54 | } 55 | if (bits != 0) 56 | { 57 | num3 = this.rhs[(int)num3]; 58 | } 59 | else 60 | { 61 | num3 = this.lhs[(int)num3]; 62 | } 63 | } 64 | byte[] array2 = array; 65 | int pos = this.m_pos; 66 | this.m_pos = pos + 1; 67 | array2[pos] = (byte)num3; 68 | } 69 | while (--num2 != 0); 70 | return array; 71 | } 72 | public byte[] Encoder(byte[] input) 73 | { 74 | byte[] array = new byte[input.Length * 255]; 75 | byte[] array2 = new byte[1]; 76 | int num = 0; 77 | for (ushort num2 = 256; num2 < 512; num2 += 1) 78 | { 79 | this.lhs[(int)num2] = num2; 80 | } 81 | ushort num3 = 256; 82 | ushort num4 = 0; 83 | while (num3 < 512) 84 | { 85 | this.rhs[(int)num3] = num4; 86 | num3 += 1; 87 | num4 += 1; 88 | } 89 | this.rhs[257] = 0; 90 | using (BinaryWriter binaryWriter = new BinaryWriter(new MemoryStream(array))) 91 | { 92 | int num5 = 9; 93 | this.WriteTree(binaryWriter); 94 | for (int i = 0; i < input.Length; i++) 95 | { 96 | if (input[i] == 0) 97 | { 98 | this.EncodeBit(1, 1, binaryWriter); 99 | } 100 | else if (input[i] == 1) 101 | { 102 | for (int j = 0; j < 255; j++) 103 | { 104 | this.EncodeBit(0, 1, binaryWriter); 105 | } 106 | } 107 | else 108 | { 109 | for (int k = 0; k < (int)(input[i] - 1); k++) 110 | { 111 | if (num5 == 0) 112 | { 113 | this.EncodeBit(0, 1, binaryWriter); 114 | } 115 | else 116 | { 117 | num5--; 118 | } 119 | } 120 | this.EncodeBit(1, 1, binaryWriter); 121 | } 122 | } 123 | this.EncodeBit(255, 8, binaryWriter); 124 | this.EncodeBit(255, 8, binaryWriter); 125 | num = (int)binaryWriter.BaseStream.Position; 126 | } 127 | if (num != 0) 128 | { 129 | array2 = new byte[num]; 130 | Buffer.BlockCopy(array, 0, array2, 0, num); 131 | } 132 | return array2; 133 | } 134 | private void WriteTree(BinaryWriter writer) 135 | { 136 | for (int i = 256; i < 512; i++) 137 | { 138 | if (i == 511) 139 | { 140 | this.EncodeBit(0, 1, writer); 141 | this.EncodeBit(1, 8, writer); 142 | } 143 | else 144 | { 145 | this.EncodeBit(1, 1, writer); 146 | } 147 | } 148 | for (int j = 511; j > 255; j--) 149 | { 150 | this.EncodeBit(0, 1, writer); 151 | this.EncodeBit((int)this.rhs[j], 8, writer); 152 | } 153 | } 154 | private ushort CreateTree() 155 | { 156 | int bits = this.m_input.GetBits(1); 157 | if (-1 == bits) 158 | { 159 | throw new Exception("Unexpected end of the Huffman-compressed stream."); 160 | } 161 | if (bits == 0) 162 | { 163 | return (ushort)this.m_input.GetBits(8); 164 | } 165 | ushort token = this.m_token; 166 | this.m_token = (ushort)(token + 1); 167 | ushort num = token; 168 | if (num >= 512) 169 | { 170 | throw new Exception("Invalid Huffman-compressed stream."); 171 | } 172 | this.lhs[(int)num] = this.CreateTree(); 173 | this.rhs[(int)num] = this.CreateTree(); 174 | return num; 175 | } 176 | private MsbBitStream m_input; 177 | private const int TreeSize = 512; 178 | private ushort[] lhs = new ushort[512]; 179 | private ushort[] rhs = new ushort[512]; 180 | private int m_pos; 181 | private ushort m_token = 256; 182 | public int cache_bits; 183 | public int mm_bits; 184 | } 185 | } 186 | -------------------------------------------------------------------------------- /Nexas/GameRes/Compression/MsbBitStream.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace GameRes.Compression 5 | { 6 | public class MsbBitStream : BitStream 7 | { 8 | public MsbBitStream(Stream file, bool leave_open = false) : base(file, leave_open) 9 | { 10 | } 11 | public int GetBits(int count) 12 | { 13 | while (this.m_cached_bits < count) 14 | { 15 | int num = this.m_input.ReadByte(); 16 | if (-1 == num) 17 | { 18 | return -1; 19 | } 20 | this.m_bits = (this.m_bits << 8 | num); 21 | this.m_cached_bits += 8; 22 | } 23 | int num2 = (1 << count) - 1; 24 | this.m_cached_bits -= count; 25 | return this.m_bits >> this.m_cached_bits & num2; 26 | } 27 | public int GetNextBit() 28 | { 29 | return this.GetBits(1); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Nexas/GameRes/Compression/ZLibStream.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.IO.Compression; 4 | using GameRes.Utility; 5 | 6 | namespace GameRes.Compression 7 | { 8 | public class ZLibStream : Stream 9 | { 10 | public Stream BaseStream 11 | { 12 | get 13 | { 14 | return this.m_stream.BaseStream; 15 | } 16 | } 17 | public int TotalIn 18 | { 19 | get 20 | { 21 | return this.m_total_in; 22 | } 23 | } 24 | public ZLibStream(Stream stream, CompressionMode mode, bool leave_open = false) : this(stream, mode, CompressionLevel.Default, leave_open) 25 | { 26 | } 27 | public ZLibStream(Stream stream, CompressionMode mode, CompressionLevel level, bool leave_open = false) 28 | { 29 | try 30 | { 31 | if (CompressionMode.Decompress == mode) 32 | { 33 | this.InitDecompress(stream); 34 | } 35 | else 36 | { 37 | this.InitCompress(stream, level); 38 | } 39 | this.m_should_dispose_base = !leave_open; 40 | } 41 | catch 42 | { 43 | if (!leave_open) 44 | { 45 | stream.Dispose(); 46 | } 47 | throw; 48 | } 49 | } 50 | private void InitDecompress(Stream stream) 51 | { 52 | int num = stream.ReadByte(); 53 | int num2 = stream.ReadByte(); 54 | if ((120 != num && 88 != num) || (num << 8 | num2) % 31 != 0) 55 | { 56 | throw new InvalidDataException("Data not recoginzed as zlib-compressed stream"); 57 | } 58 | this.m_stream = new DeflateStream(stream, System.IO.Compression.CompressionMode.Decompress, true); 59 | this.m_writing = false; 60 | } 61 | private void InitCompress(Stream stream, GameRes.Compression.CompressionLevel level) 62 | { 63 | int num = (int)level; 64 | System.IO.Compression.CompressionLevel compressionLevel; 65 | if (num == 0) 66 | { 67 | compressionLevel = System.IO.Compression.CompressionLevel.NoCompression; 68 | } 69 | else if (num > 5) 70 | { 71 | compressionLevel = System.IO.Compression.CompressionLevel.Optimal; 72 | num = 3; 73 | } 74 | else 75 | { 76 | compressionLevel = System.IO.Compression.CompressionLevel.Fastest; 77 | num = 1; 78 | } 79 | int num2 = 30720 | num << 6; 80 | num2 = (num2 + 30) / 31 * 31; 81 | stream.WriteByte((byte)(num2 >> 8)); 82 | stream.WriteByte((byte)num2); 83 | this.m_stream = new DeflateStream(stream, compressionLevel, true); 84 | this.m_adler = new CheckedStream(this.m_stream, new Adler32()); 85 | this.m_writing = true; 86 | } 87 | private void WriteCheckSum(Stream output) 88 | { 89 | uint checkSumValue = this.m_adler.CheckSumValue; 90 | output.WriteByte((byte)(checkSumValue >> 24)); 91 | output.WriteByte((byte)(checkSumValue >> 16)); 92 | output.WriteByte((byte)(checkSumValue >> 8)); 93 | output.WriteByte((byte)checkSumValue); 94 | } 95 | public override bool CanRead 96 | { 97 | get 98 | { 99 | return !this.m_writing; 100 | } 101 | } 102 | public override bool CanSeek 103 | { 104 | get 105 | { 106 | return false; 107 | } 108 | } 109 | public override bool CanWrite 110 | { 111 | get 112 | { 113 | return this.m_writing; 114 | } 115 | } 116 | public override long Length 117 | { 118 | get 119 | { 120 | return this.m_stream.Length; 121 | } 122 | } 123 | public override long Position 124 | { 125 | get 126 | { 127 | return this.m_stream.Position; 128 | } 129 | set 130 | { 131 | this.m_stream.Position = value; 132 | } 133 | } 134 | public override int Read(byte[] buffer, int offset, int count) 135 | { 136 | return this.m_stream.Read(buffer, offset, count); 137 | } 138 | public override int ReadByte() 139 | { 140 | return this.m_stream.ReadByte(); 141 | } 142 | public override void Flush() 143 | { 144 | this.m_stream.Flush(); 145 | } 146 | public override long Seek(long offset, SeekOrigin origin) 147 | { 148 | throw new NotSupportedException("ZLibStream.Seek method not supported"); 149 | } 150 | public override void SetLength(long length) 151 | { 152 | throw new NotSupportedException("ZLibStream.SetLength method not supported"); 153 | } 154 | public override void Write(byte[] buffer, int offset, int count) 155 | { 156 | if (count > 0) 157 | { 158 | this.m_adler.Write(buffer, offset, count); 159 | this.m_total_in += count; 160 | } 161 | } 162 | public override void WriteByte(byte value) 163 | { 164 | this.m_adler.WriteByte(value); 165 | this.m_total_in++; 166 | } 167 | protected override void Dispose(bool disposing) 168 | { 169 | if (!this.m_disposed) 170 | { 171 | try 172 | { 173 | if (disposing) 174 | { 175 | Stream baseStream = this.m_stream.BaseStream; 176 | this.m_stream.Dispose(); 177 | if (this.m_writing) 178 | { 179 | this.WriteCheckSum(baseStream); 180 | this.m_adler.Dispose(); 181 | } 182 | if (this.m_should_dispose_base) 183 | { 184 | baseStream.Dispose(); 185 | } 186 | } 187 | this.m_disposed = true; 188 | } 189 | finally 190 | { 191 | base.Dispose(disposing); 192 | } 193 | } 194 | } 195 | private DeflateStream m_stream; 196 | private CheckedStream m_adler; 197 | private bool m_should_dispose_base; 198 | private bool m_writing; 199 | public int m_total_in; 200 | private bool m_disposed; 201 | } 202 | } 203 | -------------------------------------------------------------------------------- /Nexas/GameRes/Utility/Adler32.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace GameRes.Utility 4 | { 5 | public sealed class Adler32 : ICheckSum 6 | { 7 | public unsafe static uint Compute(byte[] buf, int pos, int len) 8 | { 9 | if (len == 0) 10 | { 11 | return 1U; 12 | } 13 | fixed (byte* ptr = &buf[pos]) 14 | { 15 | byte* buf2 = ptr; 16 | return Adler32.Update(1U, buf2, len); 17 | } 18 | } 19 | public unsafe static uint Compute(byte* buf, int len) 20 | { 21 | return Adler32.Update(1U, buf, len); 22 | } 23 | private unsafe static uint Update(uint adler, byte* buf, int len) 24 | { 25 | uint num = adler >> 16 & 65535U; 26 | adler &= 65535U; 27 | if (1 == len) 28 | { 29 | adler += (uint)(*buf); 30 | if (adler >= 65521U) 31 | { 32 | adler -= 65521U; 33 | } 34 | num += adler; 35 | if (num >= 65521U) 36 | { 37 | num -= 65521U; 38 | } 39 | return adler | num << 16; 40 | } 41 | if (len < 16) 42 | { 43 | while (len-- != 0) 44 | { 45 | adler += (uint)(*(buf++)); 46 | num += adler; 47 | } 48 | if (adler >= 65521U) 49 | { 50 | adler -= 65521U; 51 | } 52 | num %= 65521U; 53 | return adler | num << 16; 54 | } 55 | while (len >= 5552) 56 | { 57 | len -= 5552; 58 | int num2 = 347; 59 | do 60 | { 61 | adler += (uint)(*buf); 62 | num += adler; 63 | adler += (uint)buf[1]; 64 | num += adler; 65 | adler += (uint)buf[2]; 66 | num += adler; 67 | adler += (uint)buf[3]; 68 | num += adler; 69 | adler += (uint)buf[4]; 70 | num += adler; 71 | adler += (uint)buf[5]; 72 | num += adler; 73 | adler += (uint)buf[6]; 74 | num += adler; 75 | adler += (uint)buf[7]; 76 | num += adler; 77 | adler += (uint)buf[8]; 78 | num += adler; 79 | adler += (uint)buf[9]; 80 | num += adler; 81 | adler += (uint)buf[10]; 82 | num += adler; 83 | adler += (uint)buf[11]; 84 | num += adler; 85 | adler += (uint)buf[12]; 86 | num += adler; 87 | adler += (uint)buf[13]; 88 | num += adler; 89 | adler += (uint)buf[14]; 90 | num += adler; 91 | adler += (uint)buf[15]; 92 | num += adler; 93 | buf += 16; 94 | } 95 | while (--num2 != 0); 96 | adler %= 65521U; 97 | num %= 65521U; 98 | } 99 | if (len != 0) 100 | { 101 | while (len >= 16) 102 | { 103 | len -= 16; 104 | adler += (uint)(*buf); 105 | num += adler; 106 | adler += (uint)buf[1]; 107 | num += adler; 108 | adler += (uint)buf[2]; 109 | num += adler; 110 | adler += (uint)buf[3]; 111 | num += adler; 112 | adler += (uint)buf[4]; 113 | num += adler; 114 | adler += (uint)buf[5]; 115 | num += adler; 116 | adler += (uint)buf[6]; 117 | num += adler; 118 | adler += (uint)buf[7]; 119 | num += adler; 120 | adler += (uint)buf[8]; 121 | num += adler; 122 | adler += (uint)buf[9]; 123 | num += adler; 124 | adler += (uint)buf[10]; 125 | num += adler; 126 | adler += (uint)buf[11]; 127 | num += adler; 128 | adler += (uint)buf[12]; 129 | num += adler; 130 | adler += (uint)buf[13]; 131 | num += adler; 132 | adler += (uint)buf[14]; 133 | num += adler; 134 | adler += (uint)buf[15]; 135 | num += adler; 136 | buf += 16; 137 | } 138 | while (len-- != 0) 139 | { 140 | adler += (uint)(*(buf++)); 141 | num += adler; 142 | } 143 | adler %= 65521U; 144 | num %= 65521U; 145 | } 146 | return adler | num << 16; 147 | } 148 | public uint Value 149 | { 150 | get 151 | { 152 | return this.m_adler; 153 | } 154 | } 155 | public unsafe void Update(byte[] buf, int pos, int len) 156 | { 157 | if (len == 0) 158 | { 159 | return; 160 | } 161 | fixed (byte* ptr = &buf[pos]) 162 | { 163 | byte* buf2 = ptr; 164 | this.m_adler = Adler32.Update(this.m_adler, buf2, len); 165 | } 166 | } 167 | public unsafe uint Update(byte* buf, int len) 168 | { 169 | this.m_adler = Adler32.Update(this.m_adler, buf, len); 170 | return this.m_adler; 171 | } 172 | private const uint BASE = 65521U; 173 | private const int NMAX = 5552; 174 | private uint m_adler = 1U; 175 | } 176 | } 177 | -------------------------------------------------------------------------------- /Nexas/GameRes/Utility/CheckedStream.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace GameRes.Utility 5 | { 6 | public class CheckedStream : Stream 7 | { 8 | public override bool CanRead 9 | { 10 | get 11 | { 12 | return this.m_stream.CanRead; 13 | } 14 | } 15 | public override bool CanWrite 16 | { 17 | get 18 | { 19 | return this.m_stream.CanWrite; 20 | } 21 | } 22 | public override bool CanSeek 23 | { 24 | get 25 | { 26 | return this.m_stream.CanSeek; 27 | } 28 | } 29 | public override long Length 30 | { 31 | get 32 | { 33 | return this.m_stream.Length; 34 | } 35 | } 36 | public Stream BaseStream 37 | { 38 | get 39 | { 40 | return this.m_stream; 41 | } 42 | } 43 | public uint CheckSumValue 44 | { 45 | get 46 | { 47 | return this.m_checksum.Value; 48 | } 49 | } 50 | public CheckedStream(Stream stream, ICheckSum algorithm) 51 | { 52 | this.m_stream = stream; 53 | this.m_checksum = algorithm; 54 | } 55 | public override int Read(byte[] buffer, int offset, int count) 56 | { 57 | int num = this.m_stream.Read(buffer, offset, count); 58 | if (num > 0) 59 | { 60 | this.m_checksum.Update(buffer, offset, num); 61 | } 62 | return num; 63 | } 64 | public override void Write(byte[] buffer, int offset, int count) 65 | { 66 | this.m_stream.Write(buffer, offset, count); 67 | this.m_checksum.Update(buffer, offset, count); 68 | } 69 | public override long Position 70 | { 71 | get 72 | { 73 | return this.m_stream.Position; 74 | } 75 | set 76 | { 77 | this.m_stream.Position = value; 78 | } 79 | } 80 | public override void SetLength(long value) 81 | { 82 | this.m_stream.SetLength(value); 83 | } 84 | public override long Seek(long offset, SeekOrigin origin) 85 | { 86 | return this.m_stream.Seek(offset, origin); 87 | } 88 | public override void Flush() 89 | { 90 | this.m_stream.Flush(); 91 | } 92 | private Stream m_stream; 93 | private ICheckSum m_checksum; 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /Nexas/GameRes/Utility/ICheckSum.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace GameRes.Utility 4 | { 5 | public interface ICheckSum 6 | { 7 | uint Value { get; } 8 | void Update(byte[] buf, int pos, int len); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Nexas/Nexas.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net6.0 6 | enable 7 | enable 8 | true 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /Nexas/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Text; 5 | 6 | namespace Nexas 7 | { 8 | class Program 9 | { 10 | static void Main(string[] args) 11 | { 12 | Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); 13 | if (args.Length < 2) 14 | { 15 | Console.WriteLine("Usage: "); 16 | Console.WriteLine(" Unpack: Pac.exe -u "); 17 | Console.WriteLine(" Pack: Pac.exe -p "); 18 | return; 19 | } 20 | 21 | string operation = args[0]; 22 | string inputFile = args[1]; 23 | string outputFile = args[2]; 24 | 25 | if (operation == "-u") 26 | { 27 | Unpack(inputFile, outputFile); 28 | } 29 | else if (operation == "-p") 30 | { 31 | Pack(inputFile, outputFile); 32 | } 33 | else 34 | { 35 | Console.WriteLine("Invalid operation. Valid operations are 'unpack' and 'pack'."); 36 | } 37 | } 38 | 39 | static void Unpack(string inputFile, string outputFile) 40 | { 41 | ArcPAC arcPAC = new ArcPAC(); 42 | try 43 | { 44 | Directory.CreateDirectory(outputFile); 45 | 46 | foreach (Entry entry in arcPAC.TryOpen(inputFile)) 47 | { 48 | byte[] bytes = arcPAC.Unpack(entry); 49 | System.IO.File.WriteAllBytes(Path.Combine(outputFile, entry.Name), bytes); 50 | } 51 | } 52 | catch (Exception ex) 53 | { 54 | Console.WriteLine(ex.Message); 55 | return; 56 | } 57 | Console.WriteLine("Unpacked successfully!"); 58 | } 59 | 60 | static void Pack(string inputFile, string outputFile) 61 | { 62 | ArcPAC ArcPAC = new ArcPAC(); 63 | try 64 | { 65 | ArcPAC.Pack(inputFile, outputFile); 66 | } 67 | catch (Exception ex) 68 | { 69 | Console.WriteLine(ex.Message); 70 | return; 71 | } 72 | Console.WriteLine("Pack successfully!"); 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Install ZstdNet to build Nexas tool 2 | -------------------------------------------------------------------------------- /Silky/Entry.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Silky 4 | { 5 | public class Entry 6 | { 7 | public virtual string Name { get; set; } 8 | 9 | public virtual string Type { get; set; } 10 | 11 | public long Offset { get; set; } 12 | 13 | public uint Size { get; set; } 14 | 15 | public bool IsPacked { get; set; } 16 | 17 | public int UnpackedSize { get; set; } 18 | 19 | public long StructPosition { get; set; } 20 | 21 | public byte[] fileBuffer { get; set; } 22 | 23 | public Entry() 24 | { 25 | this.Type = ""; 26 | this.Offset = -1L; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Silky/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Text; 5 | 6 | namespace Silky 7 | { 8 | class Program 9 | { 10 | static void Main(string[] args) 11 | { 12 | Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); 13 | if (args.Length < 2) 14 | { 15 | Console.WriteLine("Usage: "); 16 | Console.WriteLine(" Unpack: Arc.exe -u "); 17 | Console.WriteLine(" Pack: Arc.exe -p "); 18 | return; 19 | } 20 | 21 | string operation = args[0]; 22 | string inputFile = args[1]; 23 | string outputFile = args[2]; 24 | 25 | if (operation == "-u") 26 | { 27 | Unpack(inputFile, outputFile); 28 | } 29 | else if (operation == "-p") 30 | { 31 | Pack(inputFile, outputFile); 32 | } 33 | else 34 | { 35 | Console.WriteLine("Invalid operation. Valid operations are 'unpack' and 'pack'."); 36 | } 37 | } 38 | 39 | static void Unpack(string inputFile, string outputFile) 40 | { 41 | ArcARC ArcARC = new ArcARC(); 42 | try 43 | { 44 | Directory.CreateDirectory(outputFile); 45 | 46 | List entries = ArcARC.TryOpen(inputFile); 47 | if (entries == null || entries.Count == 0) 48 | { 49 | entries = ArcARC.TryOpenOLD(inputFile); 50 | } 51 | 52 | if (entries == null || entries.Count == 0) 53 | { 54 | throw new Exception("Unsupported file format or file is empty."); 55 | } 56 | 57 | foreach (Entry entry in ArcARC.TryOpen(inputFile)) 58 | { 59 | byte[] bytes = ArcARC.Unpack(entry); 60 | System.IO.File.WriteAllBytes(Path.Combine(outputFile, entry.Name), bytes); 61 | } 62 | } 63 | catch (Exception ex) 64 | { 65 | Console.WriteLine(ex.Message); 66 | return; 67 | } 68 | Console.WriteLine("Unpacked successfully!"); 69 | } 70 | 71 | static void Pack(string inputFile, string outputFile) 72 | { 73 | ArcARC ArcARC = new ArcARC(); 74 | try 75 | { 76 | ArcARC.Pack(inputFile, outputFile); 77 | } 78 | catch (Exception ex) 79 | { 80 | Console.WriteLine(ex.Message); 81 | return; 82 | } 83 | Console.WriteLine("Pack successfully!"); 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /Silky/SilkyArc.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net6.0 6 | enable 7 | enable 8 | true 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Silky/Utility.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | 4 | namespace Silky 5 | { 6 | public static class Binary 7 | { 8 | public static uint BigEndian(uint u) 9 | { 10 | return u << 24 | (u & 65280U) << 8 | (u & 16711680U) >> 8 | u >> 24; 11 | } 12 | 13 | public static uint ToBigEndian(uint u) 14 | { 15 | return u >> 24 | (u & 16711680U) >> 8 | (u & 65280U) << 8 | u << 24; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /TmrHiro/Binary.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | 4 | namespace PAC 5 | { 6 | public static class Binary 7 | { 8 | public static byte RotByteR(byte v, int count) 9 | { 10 | count &= 7; 11 | return (byte)(v >> count | (int)v << 8 - count); 12 | } 13 | public static byte RotByteL(byte v, int count) 14 | { 15 | count &= 7; 16 | return (byte)((int)v << count | v >> 8 - count); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /TmrHiro/Entry.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace PAC 4 | { 5 | public class Entry 6 | { 7 | public virtual string Name { get; set; } 8 | public virtual string Type { get; set; } 9 | public long Offset { get; set; } 10 | public uint Size { get; set; } 11 | public bool IsPacked { get; set; } 12 | public int UnpackedSize { get; set; } 13 | public long StructPosition { get; set; } 14 | public byte[] fileBuffer { get; set; } 15 | public Entry() 16 | { 17 | this.Type = ""; 18 | this.Offset = -1L; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /TmrHiro/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Text; 5 | 6 | namespace PAC 7 | { 8 | class Program 9 | { 10 | static void Main(string[] args) 11 | { 12 | Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); 13 | if (args.Length < 2) 14 | { 15 | Console.WriteLine("Usage: "); 16 | Console.WriteLine(" Unpack: Pac.exe -u "); 17 | Console.WriteLine(" Pack: Pac.exe -p "); 18 | return; 19 | } 20 | 21 | string operation = args[0]; 22 | string inputFile = args[1]; 23 | string outputFile = args[2]; 24 | 25 | if (operation == "-u") 26 | { 27 | Unpack(inputFile, outputFile); 28 | } 29 | else if (operation == "-p") 30 | { 31 | Pack(inputFile, outputFile); 32 | } 33 | else 34 | { 35 | Console.WriteLine("Invalid operation. Valid operations are 'unpack' and 'pack'."); 36 | } 37 | } 38 | 39 | static void Unpack(string inputFile, string outputFile) 40 | { 41 | ArcPAC arcPAC = new ArcPAC(); 42 | try 43 | { 44 | Directory.CreateDirectory(outputFile); 45 | 46 | foreach (Entry entry in arcPAC.TryOpen(inputFile)) 47 | { 48 | byte[] bytes = arcPAC.Unpack(entry); 49 | System.IO.File.WriteAllBytes(Path.Combine(outputFile, entry.Name), bytes); 50 | } 51 | } 52 | catch (Exception ex) 53 | { 54 | Console.WriteLine(ex.Message); 55 | return; 56 | } 57 | Console.WriteLine("Unpacked successfully!"); 58 | } 59 | 60 | static void Pack(string inputFile, string outputFile) 61 | { 62 | ArcPAC ArcPAC = new ArcPAC(); 63 | try 64 | { 65 | ArcPAC.Pack(inputFile, outputFile); 66 | } 67 | catch (Exception ex) 68 | { 69 | Console.WriteLine(ex.Message); 70 | return; 71 | } 72 | Console.WriteLine("Pack successfully!"); 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /TmrHiro/TmrHiro.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net6.0 6 | enable 7 | enable 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /TmrHiro/Utility.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace PAC 5 | { 6 | public static class LittleEndian 7 | { 8 | public static ushort ToUInt16(TArray value, int index) where TArray : IList 9 | { 10 | return (ushort)((int)value[index] | (int)value[index + 1] << 8); 11 | } 12 | public static short ToInt16(TArray value, int index) where TArray : IList 13 | { 14 | return (short)((int)value[index] | (int)value[index + 1] << 8); 15 | } 16 | public static uint ToUInt32(TArray value, int index) where TArray : IList 17 | { 18 | return (uint)((int)value[index] | (int)value[index + 1] << 8 | (int)value[index + 2] << 16 | (int)value[index + 3] << 24); 19 | } 20 | public static int ToInt32(TArray value, int index) where TArray : IList 21 | { 22 | return (int)LittleEndian.ToUInt32(value, index); 23 | } 24 | public static ulong ToUInt64(TArray value, int index) where TArray : IList 25 | { 26 | return (ulong)LittleEndian.ToUInt32(value, index) | (ulong)LittleEndian.ToUInt32(value, index + 4) << 32; 27 | } 28 | public static long ToInt64(TArray value, int index) where TArray : IList 29 | { 30 | return (long)LittleEndian.ToUInt64(value, index); 31 | } 32 | public static void Pack(ushort value, byte[] buf, int index) 33 | { 34 | buf[index] = (byte)value; 35 | buf[index + 1] = (byte)(value >> 8); 36 | } 37 | public static void Pack(uint value, byte[] buf, int index) 38 | { 39 | buf[index] = (byte)value; 40 | buf[index + 1] = (byte)(value >> 8); 41 | buf[index + 2] = (byte)(value >> 16); 42 | buf[index + 3] = (byte)(value >> 24); 43 | } 44 | public static void Pack(ulong value, byte[] buf, int index) 45 | { 46 | LittleEndian.Pack((uint)value, buf, index); 47 | LittleEndian.Pack((uint)(value >> 32), buf, index + 4); 48 | } 49 | public static void Pack(short value, byte[] buf, int index) 50 | { 51 | LittleEndian.Pack((ushort)value, buf, index); 52 | } 53 | public static void Pack(int value, byte[] buf, int index) 54 | { 55 | LittleEndian.Pack((uint)value, buf, index); 56 | } 57 | public static void Pack(long value, byte[] buf, int index) 58 | { 59 | LittleEndian.Pack((ulong)value, buf, index); 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /Unity/BinDeserializer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.IO; 5 | using System.Text; 6 | 7 | namespace Unity 8 | { 9 | internal class BinDeserializer 10 | { 11 | public IDictionary DeserializeEntry(Stream input) 12 | { 13 | int num = input.ReadByte(); 14 | if (num < 128 || num > 143) 15 | { 16 | throw new FormatException(); 17 | } 18 | int num2 = num & 15; 19 | Hashtable hashtable = new Hashtable(num2); 20 | for (int i = 0; i < num2; i++) 21 | { 22 | num = input.ReadByte(); 23 | if (num < 160 || num > 191) 24 | { 25 | throw new FormatException(); 26 | } 27 | int num3 = num & 31; 28 | if (input.Read(this.m_buffer, 0, num3) < num3) 29 | { 30 | throw new FormatException(); 31 | } 32 | string @string = Encoding.UTF8.GetString(this.m_buffer, 0, num3); 33 | object value = this.ReadField(input); 34 | hashtable[@string] = value; 35 | } 36 | return hashtable; 37 | } 38 | public void SerializeEntryBinary(BinaryWriter writer, Dictionary map) 39 | { 40 | new Dictionary(); 41 | int count = map.Count; 42 | if (count > 15) 43 | { 44 | throw new Exception("Too many attributes!"); 45 | } 46 | int num = count | 128; 47 | writer.Write((byte)num); 48 | Dictionary.Enumerator enumerator = map.GetEnumerator(); 49 | for (int i = 0; i < count; i++) 50 | { 51 | enumerator.MoveNext(); 52 | KeyValuePair keyValuePair = enumerator.Current; 53 | string key = keyValuePair.Key; 54 | byte[] bytes = Encoding.UTF8.GetBytes(key); 55 | if (key.Length > 31) 56 | { 57 | throw new Exception("The key is too long!"); 58 | } 59 | num = (bytes.Length | 160); 60 | writer.Write((byte)num); 61 | writer.Write(bytes); 62 | object obj; 63 | if (!map.TryGetValue(key, out obj)) 64 | { 65 | throw new Exception("Failed to get value!"); 66 | } 67 | if (key.Equals("fileName")) 68 | { 69 | this.WriteFieldBinary(writer, 0, true, obj.ToString()); 70 | } 71 | else 72 | { 73 | this.WriteFieldBinary(writer, Convert.ToInt32(obj), false, ""); 74 | } 75 | } 76 | } 77 | private void WriteFieldBinary(BinaryWriter writer, int data, bool isString, string str) 78 | { 79 | if (!isString) 80 | { 81 | byte value = 210; 82 | writer.Write(value); 83 | uint value2 = Binary.ToBigEndian((uint)data); 84 | writer.Write((int)value2); 85 | return; 86 | } 87 | byte[] bytes = Encoding.UTF8.GetBytes(str); 88 | if (bytes.Length > 4095) 89 | { 90 | throw new Exception("The string is too long!"); 91 | } 92 | short value3 = Binary.ToBigEndianUint16((short)bytes.Length); 93 | byte value4 = 218; 94 | writer.Write(value4); 95 | writer.Write(value3); 96 | writer.Write(bytes); 97 | } 98 | public void SerializeEntry(OutputCryptoStream writer, Dictionary map) 99 | { 100 | new Dictionary(); 101 | int count = map.Count; 102 | if (count > 15) 103 | { 104 | throw new Exception("Too many attributes!"); 105 | } 106 | int num = count | 128; 107 | writer.Write((byte)num); 108 | Dictionary.Enumerator enumerator = map.GetEnumerator(); 109 | for (int i = 0; i < count; i++) 110 | { 111 | enumerator.MoveNext(); 112 | KeyValuePair keyValuePair = enumerator.Current; 113 | string key = keyValuePair.Key; 114 | byte[] bytes = Encoding.UTF8.GetBytes(key); 115 | if (key.Length > 31) 116 | { 117 | throw new Exception("The key is too long!"); 118 | } 119 | num = (bytes.Length | 160); 120 | writer.Write((byte)num); 121 | writer.Write(bytes); 122 | object obj; 123 | if (!map.TryGetValue(key, out obj)) 124 | { 125 | throw new Exception("Failed to get value!"); 126 | } 127 | if (key.Equals("fileName")) 128 | { 129 | this.WriteField(writer, 0, true, obj.ToString()); 130 | } 131 | else 132 | { 133 | this.WriteField(writer, Convert.ToInt32(obj), false, ""); 134 | } 135 | } 136 | } 137 | private void WriteField(OutputCryptoStream writer, int data, bool isString, string str) 138 | { 139 | if (!isString) 140 | { 141 | byte data2 = 210; 142 | writer.Write(data2); 143 | uint data3 = Binary.ToBigEndian((uint)data); 144 | writer.Write((int)data3); 145 | return; 146 | } 147 | byte[] bytes = Encoding.UTF8.GetBytes(str); 148 | if (bytes.Length > 4095) 149 | { 150 | throw new Exception("The string is too long!"); 151 | } 152 | short data4 = Binary.ToBigEndianUint16((short)bytes.Length); 153 | byte data5 = 218; 154 | writer.Write(data5); 155 | writer.Write(data4); 156 | writer.Write(bytes); 157 | } 158 | private object ReadField(Stream input) 159 | { 160 | int num = input.ReadByte(); 161 | if (num >= 0 && num < 128) 162 | { 163 | return num; 164 | } 165 | if (num >= 160 && num < 192) 166 | { 167 | int length = num & 31; 168 | return this.ReadString(input, length); 169 | } 170 | switch (num) 171 | { 172 | case 208: 173 | { 174 | int num2 = input.ReadByte(); 175 | if (-1 == num2) 176 | { 177 | throw new FormatException(); 178 | } 179 | return (sbyte)num2; 180 | } 181 | case 209: 182 | if (input.Read(this.m_buffer, 0, 2) < 2) 183 | { 184 | throw new FormatException(); 185 | } 186 | return BigEndian.ToInt16(this.m_buffer, 0); 187 | case 210: 188 | if (input.Read(this.m_buffer, 0, 4) < 4) 189 | { 190 | throw new FormatException(); 191 | } 192 | return BigEndian.ToInt32(this.m_buffer, 0); 193 | default: 194 | { 195 | if (num != 218) 196 | { 197 | throw new FormatException(); 198 | } 199 | if (input.Read(this.m_buffer, 0, 2) < 2) 200 | { 201 | throw new FormatException(); 202 | } 203 | int length2 = (int)BigEndian.ToUInt16(this.m_buffer, 0); 204 | return this.ReadString(input, length2); 205 | } 206 | } 207 | } 208 | private string ReadString(Stream input, int length) 209 | { 210 | if (length > this.m_buffer.Length) 211 | { 212 | this.m_buffer = new byte[length + 15 & -16]; 213 | } 214 | input.Read(this.m_buffer, 0, length); 215 | return Encoding.UTF8.GetString(this.m_buffer, 0, length); 216 | } 217 | private byte[] m_buffer = new byte[32]; 218 | private int Total_Byte; 219 | } 220 | } 221 | -------------------------------------------------------------------------------- /Unity/Binary.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | 4 | namespace Unity 5 | { 6 | public static class Binary 7 | { 8 | public static short ToBigEndianUint16(short u) 9 | { 10 | return (short)(u >> 8 | (int)u << 8); 11 | } 12 | 13 | public static uint BigEndian(uint u) 14 | { 15 | return u << 24 | (u & 65280U) << 8 | (u & 16711680U) >> 8 | u >> 24; 16 | } 17 | 18 | public static uint ToBigEndian(uint u) 19 | { 20 | return u >> 24 | (u & 16711680U) >> 8 | (u & 65280U) << 8 | u << 24; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Unity/Entry.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Unity 4 | { 5 | public class Entry 6 | { 7 | public virtual string Name { get; set; } 8 | public virtual string SubName { get; set; } 9 | public virtual string Type { get; set; } 10 | public int filename_offset { get; set; } 11 | public int filename_length { get; set; } 12 | public int Offset { get; set; } 13 | public int Size { get; set; } 14 | public bool IsPacked { get; set; } 15 | public int UnpackedSize { get; set; } 16 | public long StructPosition { get; set; } 17 | public byte[] fileBuffer { get; set; } 18 | public Entry() 19 | { 20 | this.Type = ""; 21 | this.Offset = -1; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Unity/InputCryptoStream.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Security.Cryptography; 4 | 5 | namespace Unity 6 | { 7 | internal class InputCryptoStream : CryptoStream 8 | { 9 | public InputCryptoStream(Stream input, ICryptoTransform transform) : base(input, transform, CryptoStreamMode.Read) 10 | { 11 | this.m_transform = transform; 12 | } 13 | protected override void Dispose(bool disposing) 14 | { 15 | base.Dispose(disposing); 16 | if (disposing && this.m_transform != null) 17 | { 18 | this.m_transform.Dispose(); 19 | this.m_transform = null; 20 | } 21 | } 22 | private ICryptoTransform m_transform; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Unity/Note.txt: -------------------------------------------------------------------------------- 1 | Use GARbro to unpack 2 | 3 | Just drag&drop folder to the exe to pack -------------------------------------------------------------------------------- /Unity/OutputCryptoStream.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Security.Cryptography; 5 | 6 | namespace Unity 7 | { 8 | internal class OutputCryptoStream : CryptoStream 9 | { 10 | public OutputCryptoStream(Stream input, ICryptoTransform transform) : base(input, transform, CryptoStreamMode.Write) 11 | { 12 | this.m_transform = transform; 13 | } 14 | protected override void Dispose(bool disposing) 15 | { 16 | base.Dispose(disposing); 17 | if (disposing && this.m_transform != null) 18 | { 19 | this.m_transform.Dispose(); 20 | this.m_transform = null; 21 | } 22 | } 23 | public void Write(int data) 24 | { 25 | byte[] array = new List 26 | { 27 | (byte)data, 28 | (byte)(data >> 8), 29 | (byte)(data >> 16), 30 | (byte)(data >> 24) 31 | }.ToArray(); 32 | this.Write(array, 0, array.Length); 33 | this.Flush(); 34 | this.Total_byte += 4; 35 | } 36 | public void Write(short data) 37 | { 38 | byte[] array = new List 39 | { 40 | (byte)data, 41 | (byte)(data >> 8) 42 | }.ToArray(); 43 | this.Write(array, 0, array.Length); 44 | this.Flush(); 45 | this.Total_byte += 2; 46 | } 47 | public void Write(byte data) 48 | { 49 | byte[] array = new List 50 | { 51 | data 52 | }.ToArray(); 53 | this.Write(array, 0, array.Length); 54 | this.Flush(); 55 | this.Total_byte++; 56 | } 57 | public void Write(byte[] buffer) 58 | { 59 | this.Write(buffer, 0, buffer.Length); 60 | this.Flush(); 61 | this.Total_byte += buffer.Length; 62 | } 63 | private ICryptoTransform m_transform; 64 | public int Total_byte; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /Unity/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | 6 | namespace Unity 7 | { 8 | class Program 9 | { 10 | static void Main(string[] args) 11 | { 12 | string packPath; 13 | if (args.Length > 0) 14 | { 15 | packPath = args[0]; 16 | } 17 | else 18 | { 19 | Console.WriteLine("Please input the pack path in the command line or drag a folder onto the executable."); 20 | return; 21 | } 22 | 23 | ArcBIN ArcBIN = new ArcBIN(); 24 | try 25 | { 26 | ArcBIN.Pack(packPath); 27 | } 28 | catch (Exception ex) 29 | { 30 | Console.WriteLine(ex.Message); 31 | return; 32 | } 33 | Console.WriteLine("Pack successfully!"); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Unity/UnityBin.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net6.0 6 | enable 7 | enable 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Unity/Utility.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Unity 5 | { 6 | public static class BigEndian 7 | { 8 | public static ushort ToUInt16(TArray value, int index) where TArray : IList 9 | { 10 | return (ushort)((int)value[index] << 8 | (int)value[index + 1]); 11 | } 12 | public static short ToInt16(TArray value, int index) where TArray : IList 13 | { 14 | return (short)((int)value[index] << 8 | (int)value[index + 1]); 15 | } 16 | public static uint ToUInt32(TArray value, int index) where TArray : IList 17 | { 18 | return (uint)((int)value[index] << 24 | (int)value[index + 1] << 16 | (int)value[index + 2] << 8 | (int)value[index + 3]); 19 | } 20 | public static int ToInt32(TArray value, int index) where TArray : IList 21 | { 22 | return (int)BigEndian.ToUInt32(value, index); 23 | } 24 | public static void Pack(ushort value, byte[] buf, int index) 25 | { 26 | buf[index] = (byte)(value >> 8); 27 | buf[index + 1] = (byte)value; 28 | } 29 | public static void Pack(uint value, byte[] buf, int index) 30 | { 31 | buf[index] = (byte)(value >> 24); 32 | buf[index + 1] = (byte)(value >> 16); 33 | buf[index + 2] = (byte)(value >> 8); 34 | buf[index + 3] = (byte)value; 35 | } 36 | public static void Pack(ulong value, byte[] buf, int index) 37 | { 38 | BigEndian.Pack((uint)(value >> 32), buf, index); 39 | BigEndian.Pack((uint)value, buf, index + 4); 40 | } 41 | public static void Pack(short value, byte[] buf, int index) 42 | { 43 | BigEndian.Pack((ushort)value, buf, index); 44 | } 45 | public static void Pack(int value, byte[] buf, int index) 46 | { 47 | BigEndian.Pack((uint)value, buf, index); 48 | } 49 | public static void Pack(long value, byte[] buf, int index) 50 | { 51 | BigEndian.Pack((ulong)value, buf, index); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Valkyria/ArcDat.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Text; 5 | 6 | namespace VALKYRIA 7 | { 8 | internal class ArcDAT 9 | { 10 | public List TryOpen(string filePath) 11 | { 12 | this.buffer = File.ReadAllBytes(filePath); 13 | using (BinaryReader binaryReader = new BinaryReader(new MemoryStream(this.buffer))) 14 | { 15 | uint num = binaryReader.ReadUInt32(); 16 | if (num == 0U || (ulong)num >= (ulong)binaryReader.BaseStream.Length) 17 | { 18 | return this.dir; 19 | } 20 | int num2 = (int)(num / 268U); 21 | if (num != (uint)(num2 * 268) || num2 > 4000) 22 | { 23 | return this.dir; 24 | } 25 | uint num3 = 4U; 26 | long num4 = (long)((ulong)(num3 + num)); 27 | for (int i = 0; i < num2; i++) 28 | { 29 | byte[] array = new byte[260]; 30 | Buffer.BlockCopy(this.buffer, (int)num3, array, 0, 260); 31 | int count = Array.IndexOf(array, 0); 32 | string @string = Encoding.GetEncoding(932).GetString(array, 0, count); 33 | num3 += 260U; 34 | Entry entry = new Entry(); 35 | entry.Name = @string; 36 | binaryReader.BaseStream.Position = (long)((ulong)num3); 37 | entry.Offset = (long)((ulong)binaryReader.ReadUInt32() + (ulong)num4); 38 | entry.Size = binaryReader.ReadUInt32(); 39 | if (entry.Offset + (long)((ulong)entry.Size) > binaryReader.BaseStream.Length) 40 | { 41 | throw new Exception("Unsupported file format!"); 42 | } 43 | num3 += 8U; 44 | this.dir.Add(entry); 45 | } 46 | } 47 | return this.dir; 48 | } 49 | public byte[] Unpack(Entry entry) 50 | { 51 | byte[] result; 52 | using (BinaryReader binaryReader = new BinaryReader(new MemoryStream(this.buffer))) 53 | { 54 | binaryReader.BaseStream.Position = entry.Offset; 55 | result = binaryReader.ReadBytes((int)entry.Size); 56 | } 57 | return result; 58 | } 59 | 60 | public void Pack(string packPath, string outputFile) 61 | { 62 | List list = new List(); 63 | string[] files = Directory.GetFiles(packPath); 64 | for (int i = 0; i < files.Length; i++) 65 | { 66 | Entry entry = new Entry(); 67 | byte[] fileBuffer = File.ReadAllBytes(files[i]); 68 | entry.fileBuffer = fileBuffer; 69 | entry.Name = Path.GetFileName(files[i]); 70 | list.Add(entry); 71 | } 72 | string directoryName = Path.GetDirectoryName(packPath); 73 | using (BinaryWriter binaryWriter = new BinaryWriter(new FileStream(outputFile, FileMode.Create))) 74 | { 75 | uint value = (uint)((long)list.Count * 268L); 76 | binaryWriter.Write(value); 77 | binaryWriter.Flush(); 78 | uint num = 0U; 79 | for (int j = 0; j < list.Count; j++) 80 | { 81 | byte[] bytes = Encoding.GetEncoding(932).GetBytes(list[j].Name); 82 | if (bytes.Length > 102) 83 | { 84 | throw new Exception("File's name is too long!"); 85 | } 86 | byte[] dst = new byte[260]; 87 | Buffer.BlockCopy(bytes, 0, dst, 0, bytes.Length); 88 | binaryWriter.Write(dst); 89 | binaryWriter.Flush(); 90 | binaryWriter.Write(num); 91 | binaryWriter.Flush(); 92 | num += (uint)list[j].fileBuffer.Length; 93 | binaryWriter.Write(list[j].fileBuffer.Length); 94 | binaryWriter.Flush(); 95 | } 96 | for (int k = 0; k < list.Count; k++) 97 | { 98 | binaryWriter.Write(list[k].fileBuffer); 99 | } 100 | } 101 | } 102 | private byte[] buffer; 103 | private List dir = new List(); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /Valkyria/Entry.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace VALKYRIA 4 | { 5 | public class Entry 6 | { 7 | public virtual string Name { get; set; } 8 | public virtual string Type { get; set; } 9 | public long Offset { get; set; } 10 | public uint Size { get; set; } 11 | public bool IsPacked { get; set; } 12 | public int UnpackedSize { get; set; } 13 | public long StructPosition { get; set; } 14 | public byte[] fileBuffer { get; set; } 15 | public Entry() 16 | { 17 | this.Type = ""; 18 | this.Offset = -1L; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Valkyria/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Text; 5 | 6 | namespace VALKYRIA 7 | { 8 | class Program 9 | { 10 | static void Main(string[] args) 11 | { 12 | Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); 13 | if (args.Length < 2) 14 | { 15 | Console.WriteLine("Usage: "); 16 | Console.WriteLine(" Unpack: Dat.exe -u "); 17 | Console.WriteLine(" Pack: Dat.exe -p "); 18 | return; 19 | } 20 | 21 | string operation = args[0]; 22 | string inputFile = args[1]; 23 | string outputFile = args[2]; 24 | 25 | if (operation == "-u") 26 | { 27 | Unpack(inputFile, outputFile); 28 | } 29 | else if (operation == "-p") 30 | { 31 | Pack(inputFile, outputFile); 32 | } 33 | else 34 | { 35 | Console.WriteLine("Invalid operation. Valid operations are 'unpack' and 'pack'."); 36 | } 37 | } 38 | 39 | static void Unpack(string inputFile, string outputFile) 40 | { 41 | ArcDAT ArcDAT = new ArcDAT(); 42 | try 43 | { 44 | Directory.CreateDirectory(outputFile); 45 | 46 | foreach (Entry entry in ArcDAT.TryOpen(inputFile)) 47 | { 48 | byte[] bytes = ArcDAT.Unpack(entry); 49 | System.IO.File.WriteAllBytes(Path.Combine(outputFile, entry.Name), bytes); 50 | } 51 | } 52 | catch (Exception ex) 53 | { 54 | Console.WriteLine(ex.Message); 55 | return; 56 | } 57 | Console.WriteLine("Unpacked successfully!"); 58 | } 59 | 60 | static void Pack(string inputFile, string outputFile) 61 | { 62 | ArcDAT ArcDAT = new ArcDAT(); 63 | try 64 | { 65 | ArcDAT.Pack(inputFile, outputFile); 66 | } 67 | catch (Exception ex) 68 | { 69 | Console.WriteLine(ex.Message); 70 | return; 71 | } 72 | Console.WriteLine("Pack successfully!"); 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /Valkyria/ValkyriaDat.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net6.0 6 | enable 7 | enable 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Visual novel archive tools.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.1.32228.430 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EscudeBin", "Escude\EscudeBin.csproj", "{00A432F4-51A2-4CEB-A24F-2C1A937589E6}" 7 | EndProject 8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Softpal", "AMUSE\Softpal.csproj", "{B2C53295-A2B3-4257-8333-50270775B529}" 9 | EndProject 10 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ValkyriaDat", "Valkyria\ValkyriaDat.csproj", "{E23ECE70-5B89-454B-A87C-5438DBA90002}" 11 | EndProject 12 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnityBin", "Unity\UnityBin.csproj", "{613FC0E6-1DA4-4DA8-B811-BDC0CACA9112}" 13 | EndProject 14 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TmrHiro", "TmrHiro\TmrHiro.csproj", "{2443A93C-1D89-4DC1-AEF3-73C35E06370B}" 15 | EndProject 16 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SilkyArc", "Silky\SilkyArc.csproj", "{1558FF84-865E-4989-99BD-9F0B3F525AF6}" 17 | EndProject 18 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NejiiCDT", "NEJII\NejiiCDT.csproj", "{D2DEFD28-9666-446B-9BC1-7CE9182E39E9}" 19 | EndProject 20 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LilimAos", "Lilim\LilimAos.csproj", "{FA9CCF36-ECDD-453C-9E3D-596964AB9AB6}" 21 | EndProject 22 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EaglsPak", "EAGLS\EaglsPak.csproj", "{BBC5D18D-4EE0-4E65-BC8A-511FA1C3AD1B}" 23 | EndProject 24 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AVG_GPX", "AVG_Engine\AVG_GPX.csproj", "{BC95CFF9-6C9A-4B55-860B-0FC2E715CB48}" 25 | EndProject 26 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ai6Win", "Ai6Win\Ai6Win.csproj", "{985696E3-5EBC-4652-BACB-DE0742EDE526}" 27 | EndProject 28 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nexas", "Nexas\Nexas.csproj", "{CF0C7295-1553-49BA-86E0-2EF75325CDBB}" 29 | EndProject 30 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "codeX RScript", "codeX RScript\codeX RScript.csproj", "{2E0BC123-0765-41D8-AB2F-0976E6CA7A70}" 31 | EndProject 32 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NEKOSDK", "NEKOSDK\NEKOSDK.csproj", "{2ADF0BB2-3C7C-4FF9-8622-D9FEB8FB83AF}" 33 | EndProject 34 | Global 35 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 36 | Debug|Any CPU = Debug|Any CPU 37 | Release|Any CPU = Release|Any CPU 38 | EndGlobalSection 39 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 40 | {00A432F4-51A2-4CEB-A24F-2C1A937589E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 41 | {00A432F4-51A2-4CEB-A24F-2C1A937589E6}.Debug|Any CPU.Build.0 = Debug|Any CPU 42 | {00A432F4-51A2-4CEB-A24F-2C1A937589E6}.Release|Any CPU.ActiveCfg = Release|Any CPU 43 | {00A432F4-51A2-4CEB-A24F-2C1A937589E6}.Release|Any CPU.Build.0 = Release|Any CPU 44 | {B2C53295-A2B3-4257-8333-50270775B529}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 45 | {B2C53295-A2B3-4257-8333-50270775B529}.Debug|Any CPU.Build.0 = Debug|Any CPU 46 | {B2C53295-A2B3-4257-8333-50270775B529}.Release|Any CPU.ActiveCfg = Release|Any CPU 47 | {B2C53295-A2B3-4257-8333-50270775B529}.Release|Any CPU.Build.0 = Release|Any CPU 48 | {E23ECE70-5B89-454B-A87C-5438DBA90002}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 49 | {E23ECE70-5B89-454B-A87C-5438DBA90002}.Debug|Any CPU.Build.0 = Debug|Any CPU 50 | {E23ECE70-5B89-454B-A87C-5438DBA90002}.Release|Any CPU.ActiveCfg = Release|Any CPU 51 | {E23ECE70-5B89-454B-A87C-5438DBA90002}.Release|Any CPU.Build.0 = Release|Any CPU 52 | {613FC0E6-1DA4-4DA8-B811-BDC0CACA9112}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 53 | {613FC0E6-1DA4-4DA8-B811-BDC0CACA9112}.Debug|Any CPU.Build.0 = Debug|Any CPU 54 | {613FC0E6-1DA4-4DA8-B811-BDC0CACA9112}.Release|Any CPU.ActiveCfg = Release|Any CPU 55 | {613FC0E6-1DA4-4DA8-B811-BDC0CACA9112}.Release|Any CPU.Build.0 = Release|Any CPU 56 | {2443A93C-1D89-4DC1-AEF3-73C35E06370B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 57 | {2443A93C-1D89-4DC1-AEF3-73C35E06370B}.Debug|Any CPU.Build.0 = Debug|Any CPU 58 | {2443A93C-1D89-4DC1-AEF3-73C35E06370B}.Release|Any CPU.ActiveCfg = Release|Any CPU 59 | {2443A93C-1D89-4DC1-AEF3-73C35E06370B}.Release|Any CPU.Build.0 = Release|Any CPU 60 | {1558FF84-865E-4989-99BD-9F0B3F525AF6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 61 | {1558FF84-865E-4989-99BD-9F0B3F525AF6}.Debug|Any CPU.Build.0 = Debug|Any CPU 62 | {1558FF84-865E-4989-99BD-9F0B3F525AF6}.Release|Any CPU.ActiveCfg = Release|Any CPU 63 | {1558FF84-865E-4989-99BD-9F0B3F525AF6}.Release|Any CPU.Build.0 = Release|Any CPU 64 | {D2DEFD28-9666-446B-9BC1-7CE9182E39E9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 65 | {D2DEFD28-9666-446B-9BC1-7CE9182E39E9}.Debug|Any CPU.Build.0 = Debug|Any CPU 66 | {D2DEFD28-9666-446B-9BC1-7CE9182E39E9}.Release|Any CPU.ActiveCfg = Release|Any CPU 67 | {D2DEFD28-9666-446B-9BC1-7CE9182E39E9}.Release|Any CPU.Build.0 = Release|Any CPU 68 | {FA9CCF36-ECDD-453C-9E3D-596964AB9AB6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 69 | {FA9CCF36-ECDD-453C-9E3D-596964AB9AB6}.Debug|Any CPU.Build.0 = Debug|Any CPU 70 | {FA9CCF36-ECDD-453C-9E3D-596964AB9AB6}.Release|Any CPU.ActiveCfg = Release|Any CPU 71 | {FA9CCF36-ECDD-453C-9E3D-596964AB9AB6}.Release|Any CPU.Build.0 = Release|Any CPU 72 | {BBC5D18D-4EE0-4E65-BC8A-511FA1C3AD1B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 73 | {BBC5D18D-4EE0-4E65-BC8A-511FA1C3AD1B}.Debug|Any CPU.Build.0 = Debug|Any CPU 74 | {BBC5D18D-4EE0-4E65-BC8A-511FA1C3AD1B}.Release|Any CPU.ActiveCfg = Release|Any CPU 75 | {BBC5D18D-4EE0-4E65-BC8A-511FA1C3AD1B}.Release|Any CPU.Build.0 = Release|Any CPU 76 | {BC95CFF9-6C9A-4B55-860B-0FC2E715CB48}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 77 | {BC95CFF9-6C9A-4B55-860B-0FC2E715CB48}.Debug|Any CPU.Build.0 = Debug|Any CPU 78 | {BC95CFF9-6C9A-4B55-860B-0FC2E715CB48}.Release|Any CPU.ActiveCfg = Release|Any CPU 79 | {BC95CFF9-6C9A-4B55-860B-0FC2E715CB48}.Release|Any CPU.Build.0 = Release|Any CPU 80 | {985696E3-5EBC-4652-BACB-DE0742EDE526}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 81 | {985696E3-5EBC-4652-BACB-DE0742EDE526}.Debug|Any CPU.Build.0 = Debug|Any CPU 82 | {985696E3-5EBC-4652-BACB-DE0742EDE526}.Release|Any CPU.ActiveCfg = Release|Any CPU 83 | {985696E3-5EBC-4652-BACB-DE0742EDE526}.Release|Any CPU.Build.0 = Release|Any CPU 84 | {CF0C7295-1553-49BA-86E0-2EF75325CDBB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 85 | {CF0C7295-1553-49BA-86E0-2EF75325CDBB}.Debug|Any CPU.Build.0 = Debug|Any CPU 86 | {CF0C7295-1553-49BA-86E0-2EF75325CDBB}.Release|Any CPU.ActiveCfg = Release|Any CPU 87 | {CF0C7295-1553-49BA-86E0-2EF75325CDBB}.Release|Any CPU.Build.0 = Release|Any CPU 88 | {2E0BC123-0765-41D8-AB2F-0976E6CA7A70}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 89 | {2E0BC123-0765-41D8-AB2F-0976E6CA7A70}.Debug|Any CPU.Build.0 = Debug|Any CPU 90 | {2E0BC123-0765-41D8-AB2F-0976E6CA7A70}.Release|Any CPU.ActiveCfg = Release|Any CPU 91 | {2E0BC123-0765-41D8-AB2F-0976E6CA7A70}.Release|Any CPU.Build.0 = Release|Any CPU 92 | {2ADF0BB2-3C7C-4FF9-8622-D9FEB8FB83AF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 93 | {2ADF0BB2-3C7C-4FF9-8622-D9FEB8FB83AF}.Debug|Any CPU.Build.0 = Debug|Any CPU 94 | {2ADF0BB2-3C7C-4FF9-8622-D9FEB8FB83AF}.Release|Any CPU.ActiveCfg = Release|Any CPU 95 | {2ADF0BB2-3C7C-4FF9-8622-D9FEB8FB83AF}.Release|Any CPU.Build.0 = Release|Any CPU 96 | EndGlobalSection 97 | GlobalSection(SolutionProperties) = preSolution 98 | HideSolutionNode = FALSE 99 | EndGlobalSection 100 | GlobalSection(ExtensibilityGlobals) = postSolution 101 | SolutionGuid = {DC49A339-CE3F-498A-B066-E631E0CF6700} 102 | EndGlobalSection 103 | EndGlobal 104 | -------------------------------------------------------------------------------- /build.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | dotnet build -c release 3 | pause -------------------------------------------------------------------------------- /codeX RScript/ArcXFL.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Text; 5 | 6 | namespace XFL 7 | { 8 | internal class ArcXFL 9 | { 10 | public int strlen(BinaryReader reader) 11 | { 12 | bool flag = false; 13 | long position = reader.BaseStream.Position; 14 | while (reader.BaseStream.Position != reader.BaseStream.Length) 15 | { 16 | if (reader.ReadByte() == 0) 17 | { 18 | flag = true; 19 | break; 20 | } 21 | } 22 | int result; 23 | if (flag) 24 | { 25 | result = (int)(reader.BaseStream.Position - position - 1L); 26 | } 27 | else 28 | { 29 | result = (int)(reader.BaseStream.Position - position); 30 | } 31 | reader.BaseStream.Position = position; 32 | return result; 33 | } 34 | public List TryOpen(string filePath) 35 | { 36 | this.buffer = File.ReadAllBytes(filePath); 37 | using (BinaryReader binaryReader = new BinaryReader(new MemoryStream(this.buffer))) 38 | { 39 | if (binaryReader.ReadInt32() != 82508) 40 | { 41 | throw new Exception("Unsupported file format!"); 42 | } 43 | uint num = binaryReader.ReadUInt32(); 44 | int num2 = binaryReader.ReadInt32(); 45 | if (num2 <= 0) 46 | { 47 | throw new Exception("Unsupported file format!"); 48 | } 49 | long num3 = (long)this.buffer.Length; 50 | uint num4 = num + 12U; 51 | if ((ulong)num >= (ulong)num3 || (ulong)num4 >= (ulong)num3) 52 | { 53 | throw new Exception("Unsupported file format!"); 54 | } 55 | long num5 = 12L; 56 | for (int i = 0; i < num2; i++) 57 | { 58 | if (num5 + 40L > (long)((ulong)num4)) 59 | { 60 | throw new Exception("Unsupported file format!"); 61 | } 62 | binaryReader.BaseStream.Position = num5; 63 | int count = this.strlen(binaryReader); 64 | byte[] bytes = binaryReader.ReadBytes(count); 65 | string @string = Encoding.GetEncoding(932).GetString(bytes); 66 | binaryReader.BaseStream.Position = num5 + 32L; 67 | long num6 = (long)((ulong)binaryReader.ReadUInt32()); 68 | uint size = binaryReader.ReadUInt32(); 69 | if (num6 > num3) 70 | { 71 | throw new Exception("Unsupported file format!"); 72 | } 73 | Entry entry = new Entry(); 74 | entry.Name = @string; 75 | entry.Offset = num6 + (long)((ulong)num4); 76 | entry.Size = size; 77 | this.dir.Add(entry); 78 | num5 += 40L; 79 | } 80 | } 81 | return this.dir; 82 | } 83 | public byte[] Unpack(Entry entry) 84 | { 85 | byte[] result; 86 | using (BinaryReader binaryReader = new BinaryReader(new MemoryStream(this.buffer))) 87 | { 88 | binaryReader.BaseStream.Position = entry.Offset; 89 | result = binaryReader.ReadBytes((int)entry.Size); 90 | } 91 | return result; 92 | } 93 | public void Pack(string packPath, string outputFile) 94 | { 95 | List list = new List(); 96 | string[] files = Directory.GetFiles(packPath); 97 | for (int i = 0; i < files.Length; i++) 98 | { 99 | Entry entry = new Entry(); 100 | byte[] fileBuffer = File.ReadAllBytes(files[i]); 101 | entry.fileBuffer = fileBuffer; 102 | entry.Name = Path.GetFileName(files[i]); 103 | list.Add(entry); 104 | } 105 | string directoryName = Path.GetDirectoryName(packPath); 106 | using (BinaryWriter binaryWriter = new BinaryWriter(new FileStream(outputFile, FileMode.Create))) 107 | { 108 | int value = 82508; 109 | binaryWriter.Write(value); 110 | binaryWriter.Flush(); 111 | uint value2 = (uint)(list.Count * 40); 112 | binaryWriter.Write(value2); 113 | binaryWriter.Flush(); 114 | binaryWriter.Write(list.Count); 115 | binaryWriter.Flush(); 116 | uint num = 0U; 117 | for (int j = 0; j < list.Count; j++) 118 | { 119 | byte[] bytes = Encoding.GetEncoding(932).GetBytes(list[j].Name); 120 | if (bytes.Length > 32) 121 | { 122 | throw new Exception("Files' name is too long!"); 123 | } 124 | byte[] dst = new byte[32]; 125 | Buffer.BlockCopy(bytes, 0, dst, 0, bytes.Length); 126 | binaryWriter.Write(dst); 127 | binaryWriter.Flush(); 128 | binaryWriter.Write(num); 129 | num += (uint)list[j].fileBuffer.Length; 130 | binaryWriter.Write(list[j].fileBuffer.Length); 131 | binaryWriter.Flush(); 132 | } 133 | for (int k = 0; k < list.Count; k++) 134 | { 135 | binaryWriter.Write(list[k].fileBuffer); 136 | } 137 | } 138 | } 139 | private byte[] buffer; 140 | private List dir = new List(); 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /codeX RScript/Entry.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace XFL 4 | { 5 | public class Entry 6 | { 7 | public virtual string Name { get; set; } 8 | public virtual string Type { get; set; } 9 | public long Offset { get; set; } 10 | public uint Size { get; set; } 11 | public bool IsPacked { get; set; } 12 | public int UnpackedSize { get; set; } 13 | public long StructPosition { get; set; } 14 | public byte[] fileBuffer { get; set; } 15 | public Entry() 16 | { 17 | this.Type = ""; 18 | this.Offset = -1L; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /codeX RScript/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Text; 5 | 6 | namespace XFL 7 | { 8 | class Program 9 | { 10 | static void Main(string[] args) 11 | { 12 | Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); 13 | if (args.Length < 2) 14 | { 15 | Console.WriteLine("Usage: "); 16 | Console.WriteLine(" Unpack: XFL.exe -u "); 17 | Console.WriteLine(" Pack: XFL.exe -p "); 18 | return; 19 | } 20 | 21 | string operation = args[0]; 22 | string inputFile = args[1]; 23 | string outputFile = args[2]; 24 | 25 | if (operation == "-u") 26 | { 27 | Unpack(inputFile, outputFile); 28 | } 29 | else if (operation == "-p") 30 | { 31 | Pack(inputFile, outputFile); 32 | } 33 | else 34 | { 35 | Console.WriteLine("Invalid operation. Valid operations are 'unpack' and 'pack'."); 36 | } 37 | } 38 | 39 | static void Unpack(string inputFile, string outputFile) 40 | { 41 | ArcXFL ArcXFL = new ArcXFL(); 42 | try 43 | { 44 | Directory.CreateDirectory(outputFile); 45 | 46 | foreach (Entry entry in ArcXFL.TryOpen(inputFile)) 47 | { 48 | byte[] bytes = ArcXFL.Unpack(entry); 49 | System.IO.File.WriteAllBytes(Path.Combine(outputFile, entry.Name), bytes); 50 | } 51 | } 52 | catch (Exception ex) 53 | { 54 | Console.WriteLine(ex.Message); 55 | return; 56 | } 57 | Console.WriteLine("Unpacked successfully!"); 58 | } 59 | 60 | static void Pack(string inputFile, string outputFile) 61 | { 62 | ArcXFL ArcXFL = new ArcXFL(); 63 | try 64 | { 65 | ArcXFL.Pack(inputFile, outputFile); 66 | } 67 | catch (Exception ex) 68 | { 69 | Console.WriteLine(ex.Message); 70 | return; 71 | } 72 | Console.WriteLine("Pack successfully!"); 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /codeX RScript/codeX RScript.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net6.0 6 | enable 7 | enable 8 | 9 | 10 | 11 | --------------------------------------------------------------------------------