private static void RunSingleThread(IEnumerable <string> args) { List <string> validEntries = new List <string>(); foreach (string arcFile in args) { if (!File.Exists(arcFile)) { Logger.Warn($"{arcFile} is not a file"); continue; } if (!ArcFileSystem.DetectMagic(arcFile)) { Logger.Warn($"{arcFile} is not a valid ARC file."); continue; } validEntries.Add(arcFile); } DumpWorker worker = new DumpWorker(null, validEntries); worker.StartWork(null); if (MergeType == MergeType.SingleFile) { WriteAllSubtitles(worker); } }
private static void DumpSubtitles(IReadOnlyCollection <string> arcFiles) { int filesPerThread = arcFiles.Count / MaxThreads; if (MaxThreads == 1 || filesPerThread <= 1) { RunSingleThread(arcFiles); return; } DumpWorker[] workers = new DumpWorker[MaxThreads]; WaitHandle[] doneEvents = new WaitHandle[MaxThreads]; int workerid = 0; List <string> workList = new List <string>(); foreach (string arcFile in arcFiles) { if (!File.Exists(arcFile)) { Logger.Warn($"{arcFile} is not a file"); continue; } if (!ArcFileSystem.DetectMagic(arcFile)) { Logger.Warn($"{arcFile} is not a valid ARC file."); continue; } workList.Add(arcFile); if (workList.Count >= filesPerThread) { ManualResetEvent doneEvent = new ManualResetEvent(false); doneEvents[workerid] = doneEvent; workers[workerid++] = new DumpWorker(doneEvent, workList); workList = new List <string>(); } } if (workList.Count != 0) { ManualResetEvent doneEvent = new ManualResetEvent(false); doneEvents[workerid] = doneEvent; workers[workerid] = new DumpWorker(doneEvent, workList); } foreach (DumpWorker dumpWorker in workers) { ThreadPool.QueueUserWorkItem(dumpWorker.StartWork, null); } WaitHandle.WaitAll(doneEvents); if (MergeType == MergeType.SingleFile) { WriteAllSubtitles(workers); } }
public static void ExtractFromArcs(string[] arcFiles) { ArcFileSystem fileSystem = new ArcFileSystem(); foreach (string f in arcFiles) { fileSystem.LoadArc(f); } ExtractFilesFromFileSystem(fileSystem); }
public static void Install() { // get gamepath and Mod folder string gamepath = Path.GetFullPath(".\\"); string ModFolder = Path.Combine(gamepath, "Mod"); ArcFileSystem fs = new ArcFileSystem(); // Iterate through each file in Mod folder and add it to the proxy ARC file foreach (string file in Directory.GetFiles(ModFolder, "*.ks", SearchOption.AllDirectories)) { string name = Path.GetFileName(file); ArcFileEntry arcFile = !fs.FileExists(file) ? fs.CreateFile(name) : fs.GetFile(file); arcFile.Pointer = new WindowsFilePointer(file); } foreach (string file in Directory.GetFiles(ModFolder, "*.ogg", SearchOption.AllDirectories)) { string name = Path.GetFileName(file); ArcFileEntry arcFile = !fs.FileExists(file) ? fs.CreateFile(name) : fs.GetFile(file); arcFile.Pointer = new WindowsFilePointer(file); } // Save the ARC file on disk because the game does not support loading ARC from meory easily // the temp ARC is saved in ML_temp folder in game's folder, so as to not get in the way of general mods if (!Directory.Exists(Path.Combine(gamepath, "ML_temp"))) { Directory.CreateDirectory(Path.Combine(gamepath, "ML_temp")); } using (FileStream fStream = File.Create(Path.Combine(gamepath, "ML_temp\\ML_temp.arc"))) { fs.Save(fStream); } // Get the game's file system and add our custom ARC file FileSystemArchive gameFileSystem = GameUty.FileSystem as FileSystemArchive; gameFileSystem.AddArchive(Path.Combine(gamepath, "ML_temp\\ML_temp.arc")); // load custom arcs, cuz yolo foreach (string arc in Directory.GetFiles(ModFolder, "*.arc", SearchOption.AllDirectories)) { gameFileSystem.AddArchive(arc); } }
private static void ExtractFilesFromFileSystem(ArcFileSystem fileSystem) { if (fileSystem.Files.Count() == 0) { return; } var filesToExport = fileSystem.Files.Where(x => Extensions.Any(t => x.Name.Contains(t))).ToList(); if (filesToExport.Count == 0) { MessageBox.Show("No files to export..."); return; } using (var fbd = new FolderBrowserDialog()) { if (filesToExport.Count == 0) { return; } MessageBox.Show("We found files to export! Select a destination directory now for files to be placed into."); fbd.ShowDialog(); if (!String.IsNullOrEmpty(fbd.SelectedPath)) { foreach (ArcFileEntry f in filesToExport) { if (f.Name.Contains(".anm") && !f.FullName.Contains("dress")) { continue; } var decompressed = f.Pointer.Decompress(); if (!Directory.Exists(fbd.SelectedPath + "\\" + f.Parent.Name)) { Directory.CreateDirectory(fbd.SelectedPath + "\\" + f.Parent.Name); } File.WriteAllBytesAsync(fbd.SelectedPath + "\\" + f.Parent.Name + "\\" + f.Name, decompressed.Data); } MessageBox.Show($"Pulled {filesToExport.Count} files."); } } }
public static List <string> GetFiles(string arc) { var files = new List <String>(); var afs = new ArcFileSystem(); afs.LoadArc(arc); foreach (ArcFileEntry f in afs.Files) { files.Add(f.Name.ToLower()); } afs.Clear(); return(files); }
public static bool Read(string path, out List <ArcXWriterFile> files) { files = new List <ArcXWriterFile>(); ArcFileSystem fs = new ArcFileSystem(); if (!fs.LoadArc(path)) { return(false); } foreach (var file in fs.Files) { files.Add(new ArcXWriterFile(file.FullName.Replace("CM3D2ToolKit:\\\\", ""), () => new MemoryStream(file.Pointer.Compressed ? file.Pointer.Decompress().Data : file.Pointer.Data))); } return(true); }
public static List <String> GetArcFiles(string path) { int count = 0; int mcount = 0; String[] arcFiles = new String[0]; ConcurrentBag <string> tempbag = new ConcurrentBag <string>(); //Scans arc folders and lists down arc files within if (Directory.Exists(@path + @"\GameData")) { arcFiles = Directory.GetFiles(@path + @"\GameData", "*.arc", SearchOption.AllDirectories); //Arc file loading and file name saving Parallel.ForEach(arcFiles, a => //foreach (String a in arcFiles) { ++count; if (mcount >= 100 || mcount >= arcFiles.Count()) { Console.Write("\r" + Program.rm.GetString("LArc") + " " + count + "/" + arcFiles.Count()); mcount = 0; } else { ++mcount; } foreach (string s in Arc.GetFiles(a)) { tempbag.Add(s); } }); } mcount = 0; count = 0; if (Directory.Exists(@path + @"\GameData_20")) { arcFiles = Directory.GetFiles(@path + @"\GameData_20", "*.arc", SearchOption.AllDirectories); //Loads arc files from GameData_20 and extracts the names of all the files within. Parallel.ForEach(arcFiles, a => //foreach (String a in arcFiles2) { var afs = new ArcFileSystem(); //progress bar function ++count; if (mcount >= 100 || mcount >= arcFiles.Count()) { Console.Write("\r" + Program.rm.GetString("LMArc") + " " + count + "/" + arcFiles.Count()); mcount = 0; } else { ++mcount; } foreach (string s in Arc.GetFiles(a)) { tempbag.Add(s); } }); } //Checks if the game is COM, and checks if CM is linked and tries to load those arc files if so and saves the names to a list. if (File.Exists(path + @"\COM3D2.exe")) { Console.Write("\r" + Program.rm.GetString("CMCheck") + " "); if (File.Exists(path + @"\update.cfg")) { StreamReader fs = new StreamReader(path + @"\update.cfg"); while (!fs.EndOfStream) { string line = fs.ReadLine(); if (line.Contains("m_strCM3D2Path=")) { line = line.Replace("m_strCM3D2Path=", ""); if (!line.Equals("")) { if (Directory.Exists(@line + @"\GameData")) { arcFiles = Directory.GetFiles(@line + @"\GameData", "*.arc", SearchOption.AllDirectories); Parallel.ForEach(arcFiles, a => //foreach (string a in arcFiles3) { var afs = new ArcFileSystem(); ++count; if (mcount == 100 || mcount >= arcFiles.Count() || count == 1) { Console.Write("\r" + Program.rm.GetString("LCMArc") + " " + count + "/" + arcFiles.Count() + " "); mcount = 0; } else if (mcount > 100) { mcount = 0; } else { ++mcount; } foreach (string s in Arc.GetFiles(a)) { tempbag.Add(s); } }); } } break; } } fs.Close(); } } return(tempbag.ToList()); }
private void DumpStrings() { foreach (string arcFile in files) { ArcFileSystem fileSystem = new ArcFileSystem(); if (!fileSystem.LoadArc(arcFile)) { Program.Logger.Error($"Failed to load {arcFile}"); continue; } Program.Logger.Info($"Opened {fileSystem}"); bool specifiedFileName = false; int fileCount = 0; int maxFiles = fileSystem.Files.Count(); foreach (ArcFileEntry file in fileSystem.Files) { fileCount++; Program.Logger.Info($"Processing file {fileCount}/{maxFiles} : {file.Name}"); if (Path.GetExtension(file.Name) != Program.SCRIPT_EXTENSION) { Program.Logger.Info("File is not a script. Skipping..."); continue; } bool specifiedScriptName = false; FilePointerBase pointer = file.Pointer; byte[] data = pointer.Compressed ? pointer.Decompress().Data : pointer.Data; using (StreamReader reader = new StreamReader(new MemoryStream(data), Encoding.GetEncoding(932))) { string line; while ((line = reader.ReadLine()) != null) { line = line.Trim(); if (!line.Contains(Program.VOICE_TAG)) { continue; } Match voiceMatch = Program.VoiceRegex.Match(line); if (!voiceMatch.Success) { continue; } string subFileName = voiceMatch.Groups["voice"].Value.Trim(); if (string.IsNullOrEmpty(subFileName)) { continue; } string transcript = reader.ReadLine(); if (transcript == null) { continue; } transcript = transcript.Replace(";", "").Trim(); if (string.IsNullOrEmpty(transcript) || transcript.StartsWith("@") || transcript.StartsWith("*L")) { continue; } lock (Program.ExistingSubtitles) { if (Program.ExistingSubtitles.TryGetValue(subFileName, out string existingSubtitle) && (transcript.StartsWith("//") || existingSubtitle.Equals(transcript, StringComparison.InvariantCulture))) { continue; } } lock (Program.FoundSubtitles) { if (Program.FoundSubtitles.TryGetValue(subFileName, out string found) && (transcript.StartsWith("//") || found.Equals(transcript, StringComparison.InvariantCulture))) { continue; } Program.FoundSubtitles[subFileName] = transcript; } if (!specifiedFileName) { specifiedFileName = true; CapturedSubtitles.Add($"; {fileSystem.Name}", string.Empty); } if (!specifiedScriptName) { specifiedScriptName = true; CapturedSubtitles.Add($"; From {fileSystem.Name}\\{file.Name}", string.Empty); } CapturedSubtitles[subFileName] = transcript; } } if (Program.MergeType == MergeType.None && CapturedSubtitles.Count != 0) { string filePath = file.FullName.Substring(fileSystem.Root.Name.Length + 1); filePath = Path.Combine(Path.GetFileNameWithoutExtension(fileSystem.Name), filePath.Remove(filePath.Length - 3, 3) + ".txt"); string outputPath = Path.Combine(Program.OUTPUT_DIR, filePath); WriteSubtitlesToFile(outputPath); } } if (Program.MergeType == MergeType.PerArc && CapturedSubtitles.Count != 0) { string outputPath = Path.Combine(Program.OUTPUT_DIR, Path.GetFileNameWithoutExtension(fileSystem.Name) + ".txt"); WriteSubtitlesToFile(outputPath); } } }
public static void ExtractFilesFromFiles(string[] files) { using (var fbd = new FolderBrowserDialog()) { fbd.ShowDialog(); if (!String.IsNullOrEmpty(fbd.SelectedPath)) { form1.textBox1.AppendText($"=== start === \r\n"); neis.Clear(); int cnt = 0; form1.textBox1.Clear(); foreach (string fl in files) { ArcFileSystem fileSystem = new ArcFileSystem(); fileSystem.LoadArc(fl); form1.textBox1.AppendText($"{fl} , {fileSystem.Files.Count} , {cnt} \r\n"); form1.Refresh(); bool s = fl.ToLower().StartsWith("script"); foreach (ArcFileEntry f in fileSystem.Files.Values) { var p = f.Parent.FullName.Replace("CM3D2ToolKit:", String.Empty); if (!Directory.Exists(fbd.SelectedPath + p)) { Directory.CreateDirectory(fbd.SelectedPath + p); } var decompressed = f.Pointer.Decompress(); if (s && form1.checkBoxKs.Checked && f.Name.EndsWith(".ks")) { File.WriteAllTextAsync(fbd.SelectedPath + p + "\\" + f.Name, Encoding.GetEncoding(932).GetString(decompressed.Data)); } else { File.WriteAllBytesAsync(fbd.SelectedPath + p + "\\" + f.Name, decompressed.Data); } if (form1.checkBoxNeiToCsv.Checked && f.Name.EndsWith(".nei")) { var item = fbd.SelectedPath + p + "\\" + f.Name; form1.textBox1.AppendText($"{item} \r\n"); //neis.Add(fbd.SelectedPath + p + "\\" + f.Name); var st = NeiConverter.ToCSV(new MemoryStream(decompressed.Data)); FileStream fs = File.Create(item.Replace(".nei", ".csv")); var sr = new StreamReader(st); var sw = new StreamWriter(fs); sw.Write(sr.ReadToEnd().Replace("\0", ",")); form1.textBox1.AppendText($"{item} , {st.Length} , {fs.Length} \r\n"); } } cnt += fileSystem.Files.Count; } form1.textBox1.AppendText($"Pulled {cnt} files. \r\n"); /* * form1.textBox1.AppendText($"{form1.checkBoxNeiToCsv.Checked}. \r\n"); * form1.textBox1.AppendText($"Count {neis.Count}. \r\n"); * * if (form1.checkBoxNeiToCsv.Checked) * { * foreach (var item in neis) * { * * using var s = NeiConverter.ToCSV(item); * using FileStream f = File.Create(item.Replace(".nei", ".csv")); * * using var sr = new StreamReader(s); * using var sw = new StreamWriter(f); * * sw.Write(sr.ReadToEnd().Replace("\0", ",")); * * form1.textBox1.AppendText($"{item} , {s.Length} , {f.Length} \r\n"); * * //form1.textBox1.AppendText($"{item} end \r\n"); * } * } */ form1.textBox1.AppendText($"=== end === \r\n"); } } }