public static void CopyChangesFromOneSubscriptToAnother(string originalSubScriptPath, string modifiedSubScriptPath, string subScriptToPortToPath, string outputScriptPath) { const string marker = "|||ADDED_LINE"; //Do a diff between "originalSubScriptPath" and "modifedSubScriptPath". Lines with a "+" are added lines. //Convert lines with a "+" to "|||ADDED_LINE" (if there are any '-' lines it is an error). Trim the first character of every line of the diff List <string> origToModifiedDiff = Differ.RunDiffToolNoHeader(originalSubScriptPath, modifiedSubScriptPath); List <string> fixedLines = new List <string>(); foreach (string line in origToModifiedDiff) { char c = line[0]; string restOfLine = line.Substring(1); if (c == '+') { fixedLines.Add(marker + "+" + restOfLine); } else if (c == '-') { fixedLines.Add(marker + "-" + restOfLine); } else if (c == ' ') { fixedLines.Add(restOfLine); } else { throw new Exception("Diff resulted in a removed or other type of line!"); } } //Write out the diff to a temp file so it can be consumed by the differ string tempFilePath = Path.GetTempFileName(); try { File.WriteAllLines(tempFilePath, fixedLines); //Do a diff that takes you FROM the less censored script TO the more censored script. List <string> modifiedToSubScriptToPortDiff = Differ.RunDiffToolNoHeader(subScriptToPortToPath, tempFilePath); List <string> outputScript = new List <string>(); //Keep all " " and "-" lines. Throw away any "+" lines, unless they start with "|||ADDED_LINE". Save to outputScriptPath foreach (string line in modifiedToSubScriptToPortDiff) { char c = line[0]; string restOfLine = line.Substring(1); if (restOfLine.StartsWith(marker)) { // If a line is marked, apply the changes in the payload (don't obey the outer level change type) char payloadType = restOfLine[marker.Length]; string payload = restOfLine.Substring(marker.Length + 1); if (payloadType == '+') { //new line to be added outputScript.Add(payload); //"SHOULD ADD:" + payload); } else if (payloadType == '-') { if (outputScript[outputScript.Count - 1] == payload) { outputScript.RemoveAt(outputScript.Count - 1); } else { throw new Exception("Couldn't port change from censored to uncensored script?"); } //previous line to be removed if identical //outputScript.Add("REMOVED:" + payload); } else { throw new Exception($"Unexpected payload diff type for line {line}"); } } else { // If a line is not marked, "undo" the changes by keeping original if (c == '+') { //Console.WriteLine($"Throwing away {line}"); } else if (c == '-' || c == ' ') { outputScript.Add(restOfLine); } else { throw new Exception($"Unexpected diff type for line {line}"); } } } File.WriteAllLines(outputScriptPath, outputScript); } finally { File.Delete(tempFilePath); } }
/// <summary> /// processes a single mangagamer script, attempting to merge the matching ps3 instructions /// </summary> /// <param name="pS3DialogueInstructionsPreFilter"></param> /// <param name="config"></param> /// <param name="mgInfo"></param> /// <param name="guessedInputInfos"></param> static List <PartialSubScriptToMerge> ProcessSingleFile( List <PS3DialogueInstruction> pS3DialogueInstructionsPreFilter, MergerConfiguration config, InputInfo mgInfo, List <InputInfo> guessedInputInfos, Counter counter) { string fullPath = Path.Combine(config.input_folder, mgInfo.path); string pathNoExt = Path.GetFileNameWithoutExtension(fullPath); string debug_side_by_side_diff_path_MG = Path.Combine(config.output_folder, pathNoExt + "_side_by_side_debug.html"); string debug_alignment_statistics = Path.Combine(config.output_folder, pathNoExt + "_statistics_debug.txt"); List <PS3DialogueInstruction> pS3DialogueInstructions = GetFilteredPS3Instructions(pS3DialogueInstructionsPreFilter, mgInfo.ps3_regions); //load all the mangagamer lines from the mangagamer file List <MangaGamerDialogue> allMangaGamerDialogue = MangaGamerScriptReader.GetDialogueLinesFromMangaGamerScript(fullPath, out List <string> mg_leftovers); //PS3 Dialogue fragments List <PS3DialogueFragment> ps3DialogueFragments = new List <PS3DialogueFragment>(); int ps3DialogueIndex = 0; foreach (PS3DialogueInstruction ps3Dialogue in pS3DialogueInstructions) { List <string> splitDialogueStrings = PS3DialogueTools.SplitPS3StringNoNames(ps3Dialogue.data); PS3DialogueFragment previousPS3DialogueFragment = null; for (int i = 0; i < splitDialogueStrings.Count; i++) { //dummy instructions index into the ps3DialogueList (for now...) PS3DialogueFragment ps3DialogueFragment = new PS3DialogueFragment(ps3Dialogue, splitDialogueStrings[i], i, previousPS3DialogueFragment); ps3DialogueFragments.Add(ps3DialogueFragment); previousPS3DialogueFragment = ps3DialogueFragment; } ps3DialogueIndex++; } //If no ps3 regions specified, scan for regions, then print and let user fill in? if (mgInfo.ps3_regions.Count == 0) { Console.WriteLine($"The file [{mgInfo.path}] does not have the PS3 region marked in the conf.toml file!"); Console.WriteLine($"Scanning for PS3 region..."); //print the first few and last mangagamer instructions //skip if length too small? Console.WriteLine("------- Finding first 5 entries -------"); int?startResult = AnalyseEntries(ps3DialogueFragments, allMangaGamerDialogue, amount: 10, isStart: true); if (startResult.HasValue) { Console.WriteLine($"Best guess at start PS3 ID: {startResult.Value}"); } else { Console.WriteLine("Not sure about start PS3 ID. Please inspect manually."); } Console.WriteLine("------- Finding last 5 entries -------"); int?endResult = AnalyseEntries(ps3DialogueFragments, allMangaGamerDialogue, amount: 10, isStart: false); if (endResult.HasValue) { Console.WriteLine($"Best guess at last PS3 ID: {endResult.Value}"); } else { Console.WriteLine("Not sure about last PS3 ID. Please inspect manually."); } string result_start_id = "<START_REGION>"; string result_end_id = "<END_REGION>"; if (startResult.HasValue && endResult.HasValue) { Console.WriteLine("AUTOREGION SUCCESS: You can copy this into the conf.toml file\n\n"); result_start_id = startResult.Value.ToString(); result_end_id = endResult.Value.ToString(); } else { Console.WriteLine($"AUTOREGION FAIL: Region couldn't be determined confidently. Please use the above information and the ps3 script" + $"to determine the PS3 region manually, then place the results in the conf.toml file as per below"); } Console.WriteLine("[[input]]"); Console.WriteLine($@"path = ""{mgInfo.path}"""); Console.WriteLine($"ps3_regions = [[{result_start_id}, {result_end_id}]]"); Console.WriteLine("No output will be generated for this script until the program is run again."); Console.WriteLine("Press ENTER to move to the next script..."); Console.ReadKey(); return(new List <PartialSubScriptToMerge>()); } //Diff the dialogue List <AlignmentPoint> allAlignmentPoints = Differ.DoDiff(config.temp_folder, allMangaGamerDialogue, ps3DialogueFragments, debugFilenamePrefix: pathNoExt); //Sanity check the alignment points by making sure there aren't missing any values SanityCheckAlignmentPoints(allAlignmentPoints, allMangaGamerDialogue, ps3DialogueFragments); //trim alignment points to reduce output List <AlignmentPoint> alignmentPoints = config.trim_after_diff ? TrimAlignmentPoints(allAlignmentPoints) : allAlignmentPoints; //Write statistics on how well matched the alignment points are WriteAlignmentStatistics(alignmentPoints, debug_alignment_statistics); //DEBUG: generate the side-by-side diff DifferDebugUtilities.PrintHTMLSideBySideDiff(alignmentPoints, debug_side_by_side_diff_path_MG); //Insert PS3 instructions string mergedOutputPath = Path.Combine(config.output_folder, pathNoExt + "_merged.xml.txt"); SaveMergedMGScript(alignmentPoints, mergedOutputPath, mg_leftovers); // >>>> UnMerge ModCallScriptSection: Before using the results, we need to reverse the step we did earlier, by unmerging any merged files back into multiple files. //Use the inserted instructions string finalOutputWithMergedForkedScripts = Path.Combine(config.output_folder, pathNoExt + ".txt"); MergedScriptPostProcessing.PostProcessingMain.InsertMGLinesUsingPS3XML(mergedOutputPath, finalOutputWithMergedForkedScripts, config, counter); List <PartialSubScriptToMerge> partialSubScriptsToMerge = ForkingScriptMerger.GetForkedScriptContentFromMergedScript(config.pre_input_folder, finalOutputWithMergedForkedScripts); ForkingScriptMerger.RemoveForkedScriptContentFromMergedScript(finalOutputWithMergedForkedScripts); return(partialSubScriptsToMerge); }