diff --git a/minitool1.sln b/minitool1.sln index 262832a..86570c4 100644 --- a/minitool1.sln +++ b/minitool1.sln @@ -1,10 +1,12 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 -VisualStudioVersion = 17.12.35506.116 d17.12 +VisualStudioVersion = 17.12.35506.116 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "minitool1", "minitool1\minitool1.csproj", "{D66AD932-3282-4BF4-9F84-E9AC9C84DE0B}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "minitool2", "minitool2\minitool2.csproj", "{0FE5458A-A3A9-4D0B-A540-BF4A7CD3F7EA}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -15,6 +17,10 @@ Global {D66AD932-3282-4BF4-9F84-E9AC9C84DE0B}.Debug|Any CPU.Build.0 = Debug|Any CPU {D66AD932-3282-4BF4-9F84-E9AC9C84DE0B}.Release|Any CPU.ActiveCfg = Release|Any CPU {D66AD932-3282-4BF4-9F84-E9AC9C84DE0B}.Release|Any CPU.Build.0 = Release|Any CPU + {0FE5458A-A3A9-4D0B-A540-BF4A7CD3F7EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0FE5458A-A3A9-4D0B-A540-BF4A7CD3F7EA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0FE5458A-A3A9-4D0B-A540-BF4A7CD3F7EA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0FE5458A-A3A9-4D0B-A540-BF4A7CD3F7EA}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/minitool2/Program.cs b/minitool2/Program.cs new file mode 100644 index 0000000..96a5149 --- /dev/null +++ b/minitool2/Program.cs @@ -0,0 +1,100 @@ +namespace minitool2 +{ + internal class Program + { + static void Main(string[] args) + { + if (args.Length == 0) + { + Console.WriteLine("Usage: minitool2 "); + return; + } + + string filePath = args[0]; + + if (!File.Exists(filePath)) + { + Console.WriteLine("文件不存在"); + Console.ReadKey(); + return; + } + + if (Path.GetExtension(filePath).ToLower() != ".arc") + { + Console.WriteLine("文件后缀不正确"); + Console.ReadKey(); + return; + } + + byte[] fileHeader = "@ARCH000"u8.ToArray(); + byte[] unityFsHeader = [0x55, 0x6E, 0x69, 0x74, 0x79, 0x46, 0x53, 0x00, 0x00, 0x00, 0x00]; + + using FileStream fs = new(filePath, FileMode.Open, FileAccess.Read); + byte[] buffer = new byte[fileHeader.Length]; + fs.Read(buffer, 0, buffer.Length); + + for (int i = 0; i < fileHeader.Length; i++) + { + if (buffer[i] != fileHeader[i]) + { + Console.WriteLine("文件头不符合规则"); + Console.ReadKey(); + return; + } + } + + List positions = []; + long position = 0; + int bytesRead; + buffer = new byte[unityFsHeader.Length]; + + while ((bytesRead = fs.Read(buffer, 0, buffer.Length)) == buffer.Length) + { + bool match = true; + for (int j = 0; j < unityFsHeader.Length; j++) + { + if (buffer[j] != unityFsHeader[j]) + { + match = false; + break; + } + } + if (match) + { + positions.Add(position); + } + position += 1; + fs.Seek(position, SeekOrigin.Begin); + } + + if (positions.Count == 0) + { + Console.WriteLine("未找到任何UnityFS块"); + Console.ReadKey(); + return; + } + + string outputDir = Path.Combine(Directory.GetCurrentDirectory(), "output"); + Directory.CreateDirectory(outputDir); + + for (int i = 0; i < positions.Count; i++) + { + long start = positions[i]; + long end = (i + 1 < positions.Count) ? positions[i + 1] : fs.Length; + long length = end - start; + + fs.Seek(start, SeekOrigin.Begin); + buffer = new byte[length]; + fs.Read(buffer, 0, buffer.Length); + + string outputFilePath = Path.Combine(outputDir, $"{(i + 1).ToString("D5")}.assets"); + File.WriteAllBytes(outputFilePath, buffer); + + Console.Write($"\r进度: {((i + 1) * 100 / positions.Count)}%"); + } + + Console.WriteLine("提取完成"); + Console.ReadKey(); + } + } +} diff --git a/minitool2/minitool2.csproj b/minitool2/minitool2.csproj new file mode 100644 index 0000000..2150e37 --- /dev/null +++ b/minitool2/minitool2.csproj @@ -0,0 +1,10 @@ + + + + Exe + net8.0 + enable + enable + + +