diff --git a/Islet Online Unpacker.csproj b/Islet Online Unpacker.csproj new file mode 100644 index 0000000..3d4d2a1 --- /dev/null +++ b/Islet Online Unpacker.csproj @@ -0,0 +1,9 @@ + + + + Exe + net5.0 + Islet_Online_Unpacker + + + diff --git a/Islet Online Unpacker.sln b/Islet Online Unpacker.sln new file mode 100644 index 0000000..f7bab22 --- /dev/null +++ b/Islet Online Unpacker.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.34407.143 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Islet Online Unpacker", "Islet Online Unpacker.csproj", "{4B9BADD3-EE27-4AC6-8D4E-E5CAA2D2FAA1}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4B9BADD3-EE27-4AC6-8D4E-E5CAA2D2FAA1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4B9BADD3-EE27-4AC6-8D4E-E5CAA2D2FAA1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4B9BADD3-EE27-4AC6-8D4E-E5CAA2D2FAA1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4B9BADD3-EE27-4AC6-8D4E-E5CAA2D2FAA1}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {0969BADB-BDC0-4879-9427-A89BCF47474B} + EndGlobalSection +EndGlobal diff --git a/Program.cs b/Program.cs new file mode 100644 index 0000000..b4e4b07 --- /dev/null +++ b/Program.cs @@ -0,0 +1,76 @@ +using System.IO; +using System.IO.Compression; + +namespace Islet_Online_Unpacker +{ + static class Program + { + static void Main(string[] args) + { + using FileStream source = File.OpenRead(args[0]); + BinaryReader br = new(source); + Directory.CreateDirectory(Path.GetDirectoryName(source.Name) + "//" + Path.GetFileNameWithoutExtension(source.Name)); + while (br.BaseStream.Position < br.BaseStream.Length) + { + int size = br.ReadInt32(); + if (size == 0x100) + { + br.BaseStream.Position -= 4; + break; + }; + br.BaseStream.Position += size; + } + + System.Collections.Generic.List subfiles = new(); + while (br.BaseStream.Position < br.BaseStream.Length - 0x28) + { + SUBFILE subfile = new() + { + isCompressed = br.ReadInt32(), + sizeUncompressed = br.ReadInt32(), + sizeCompressed = br.ReadInt32(), + offset = br.ReadInt32() + }; + br.ReadBytes(20); + subfile.name = new(br.ReadChars(br.ReadInt16())); + subfiles.Add(subfile); + } + foreach (SUBFILE sub in subfiles) + { + br.BaseStream.Position = sub.offset; + int size = br.ReadInt32(); + if ((sub.isCompressed == 0 && size != sub.sizeUncompressed) || (sub.isCompressed == 0x100 && size != sub.sizeCompressed)) + throw new System.Exception("Fuck."); + + if (sub.name.Contains(@"\")) + Directory.CreateDirectory(Path.GetDirectoryName(source.Name) + "//" + Path.GetDirectoryName(sub.name)); + + using FileStream FS = File.Create(Path.GetDirectoryName(source.Name) + "//" + sub.name); + BinaryWriter bw = new(FS); + if (sub.isCompressed == 0x100) + { + MemoryStream ms = new(); + br.ReadInt16(); + using (var ds = new DeflateStream(new MemoryStream(br.ReadBytes(size)), CompressionMode.Decompress)) + ds.CopyTo(ms); + br = new(ms); + br.BaseStream.Position = 0; + bw.Write(br.ReadBytes(sub.sizeUncompressed)); + br = new(source); + continue; + } + + bw.Write(br.ReadBytes(size)); + bw.Close(); + } + } + struct SUBFILE + { + public int isCompressed; + public int sizeUncompressed; + public int sizeCompressed; + public int offset; + public string name; + } + } +} \ No newline at end of file diff --git a/ZstdNet.dll b/ZstdNet.dll new file mode 100644 index 0000000..6c3e86f Binary files /dev/null and b/ZstdNet.dll differ