static void RecursiveFTP(Arc arc, DirectoryInfo directory, string ftpRoot, string relativePath) { foreach (var folder in directory.EnumerateDirectories()) { string thisRelPath = Path.Combine(relativePath, folder.Name); var req = (FtpWebRequest)WebRequest.Create(ftpRoot + thisRelPath.Replace('\\', '/')); req.Method = "MKD"; req.KeepAlive = true; req.Timeout = 10000; Console.WriteLine($"Requesting folder creation: {thisRelPath}"); using (var res = (FtpWebResponse)req.GetResponse()) Console.WriteLine(res.StatusDescription); RecursiveFTP(arc, folder, ftpRoot, thisRelPath); } foreach (var file in directory.EnumerateFiles()) { GetFileRegionInfo(file.Name, out string arcFileName, out int region); string arcPath = Path.Combine(relativePath, arcFileName).Replace('\\', '/'); Console.ForegroundColor = ConsoleColor.Yellow; Console.Write(arcPath); if (region > 0) { Console.Write($" region={region}"); } Console.ForegroundColor = ConsoleColor.White; Console.Write(" -> "); try { arc.GetFileInformation(arcPath, out long offset, out uint compSize, out uint decompSize, out bool regional, region); if (offset == 0) { throw new Exception("File path does not return valid data. See if the path is correct"); } if (InjectedOffsets.Contains(offset)) { throw new Exception("File path points to address where data is already handled"); } if (file.Length > decompSize) { throw new Exception($"Decompiled size ({file.Length}) exceeds its limit: ({decompSize})"); } if (InjectedOffsets.Contains(offset)) { throw new Exception($"Another file already has this offset ({offset.ToString("x")})"); } byte[] compFile = Compress(file, compSize); var filepath = Path.Combine(relativePath, $"{offset.ToString("x")}_{file.Name}"); var ftpPath = ftpRoot + filepath.Replace('\\', '/'); var req = (FtpWebRequest)WebRequest.Create(ftpPath); req.Method = "STOR"; req.KeepAlive = true; req.UseBinary = true; req.Timeout = 10000; req.UsePassive = false; req.ContentLength = compFile.Length; using (var str = req.GetRequestStream()) str.Write(compFile, 0, compFile.Length); using (var res = (FtpWebResponse)req.GetResponse()) { Console.ForegroundColor = ConsoleColor.Green; Console.Write("Transferred!"); Console.ForegroundColor = ConsoleColor.White; Console.Write($" (FTP status: {res.StatusDescription})"); } InjectedOffsets.Add(offset); } catch (Exception e) { Console.ForegroundColor = ConsoleColor.Red; Console.Write("Failed: "); Console.ForegroundColor = ConsoleColor.White; Console.Write(e.Message); } Console.WriteLine(); } }
static void RecursiveInject(Arc arc, DirectoryInfo directory, BinaryWriter writer, string relativePath) { foreach (var folder in directory.EnumerateDirectories()) { RecursiveInject(arc, folder, writer, Path.Combine(relativePath, folder.Name)); } foreach (var file in directory.EnumerateFiles()) { GetFileRegionInfo(file.Name, out string arcFileName, out int region); string arcPath = Path.Combine(relativePath, arcFileName).Replace('\\', '/'); Console.ForegroundColor = ConsoleColor.Yellow; Console.Write(arcPath); if (region > 0) { Console.Write($" region={region}"); } Console.ForegroundColor = ConsoleColor.White; Console.Write(" -> "); try { arc.GetFileInformation(arcPath, out long offset, out uint compSize, out uint decompSize, out bool regional, region); if (offset == 0) { throw new Exception("File path does not return valid data. See if the path is correct"); } if (InjectedOffsets.Contains(offset)) { throw new Exception($"Another file already has this offset ({offset.ToString("x")})"); } if (InjectUndo) { writer.BaseStream.Position = offset; writer.Write(arc.GetFileCompressed(arcPath)); InjectedOffsets.Add(offset); Console.ForegroundColor = ConsoleColor.Yellow; Console.Write("Restored"); Console.ForegroundColor = ConsoleColor.White; } else if (InjectDump) { if (file.Length > decompSize) { throw new Exception($"Decompiled size ({file.Length}) exceeds its limit: ({decompSize})"); } InjectedOffsets.Add(offset); var compFile = Compress(file, compSize); var dumpFolderPath = Path.Combine(InjectDumpPath, relativePath); var newName = $"{offset.ToString("x")}_{file.Name}"; Directory.CreateDirectory(dumpFolderPath); File.WriteAllBytes(Path.Combine(dumpFolderPath, newName), compFile); } else { if (file.Length > decompSize) { throw new Exception($"Decompiled size ({file.Length}) exceeds its limit: ({decompSize})"); } writer.BaseStream.Position = offset; writer.Write(Compress(file, compSize)); InjectedOffsets.Add(offset); Console.ForegroundColor = ConsoleColor.Green; Console.Write("Injected"); Console.ForegroundColor = ConsoleColor.White; } } catch (Exception e) { Console.ForegroundColor = ConsoleColor.Red; Console.Write("Failed: "); Console.ForegroundColor = ConsoleColor.White; Console.Write(e.Message); } Console.WriteLine(); } }