bool AfterLoopsAndConditions(ILBlock method) { HashSet <ILBlock> badblocks = new HashSet <ILBlock>(); foreach (ILBlock block in method.GetSelfAndChildrenRecursive <ILBlock>()) { foreach (var child in block.GetChildren().OfType <ILExpression>().Where(x => x.Code == GMCode.B || x.Code == GMCode.Bt || x.Code == GMCode.Bf)) { badblocks.Add(block); } } if (badblocks.Contains(method)) { badblocks.Remove(method); } if (badblocks.Count > 0) // we shouldn't have any branches anymore { TryPrintParrents(method); ILBlock badmethod = new ILBlock(); badmethod.Body = badblocks.Select(b => (ILNode)b).ToList(); error.Error("After Loop And Conditions failed, look at bad_after_stuff.txt"); error.CheckDebugThenSave(badmethod, "bad_after_stuff.txt"); using (Writers.BlockToCode code = new Writers.BlockToCode("test.js")) code.Write(method); return(true); } if (Context.Debug) { Debug.Assert(badblocks.Count == 0); } return(false); }
static void Main(string[] args) { // Context.doThreads = false; // Context.doXML = true; // Context.doAssigmentOffsets = true; // ugh have to do it here? string dataWinFileName = args.ElementAtOrDefault(0); if (string.IsNullOrWhiteSpace(dataWinFileName)) { InstructionError("Missing data.win file"); } try { File.LoadDataWin(dataWinFileName); } catch (Exception e) { Context.Error(e); InstructionError("Could not open data.win file {0}\n Exception:", dataWinFileName, e.Message); } List<string> chunks = new List<string>(); byte[] changedData = null; for(int i=1; i < args.Length; i++) { string a = args[i]; if (string.IsNullOrWhiteSpace(a)) continue; // does this ever happen? switch (a) { case "-printOffset": { Context.saveChangedDataWin = true; string offset_name = args.ElementAtOrDefault(i + 1); i += 1; uint offset_int; if (!TryParseOffset(offset_name, out offset_int)) Context.FatalError("Cannot parse {0} value in -printOffset", offset_name); Context.Message(Context.FormatDebugOffset(changedData ?? File.DataWinRaw, (int)offset_int)); } break; case "-changeInt": case "-changeShort": { Context.saveChangedDataWin = true; string offset_name = args.ElementAtOrDefault(i + 1); string to_value = args.ElementAtOrDefault(i + 2); i += 2; uint offset_int; int to_int; if (!TryParseOffset(offset_name, out offset_int)) Context.FatalError("Cannot parse {0} value in -changeShort", offset_name); if (!TryParseHex(to_value, out to_int)) Context.FatalError("Cannot parse {0} value in -changeShort", to_value); if (changedData == null) { changedData = File.CopyData(); File.LoadEveything(); } if(a == "-changeShort") File.ChangeOffset(changedData, offset_int, (short)to_int); else File.ChangeOffset(changedData, offset_int, to_int); } break; case "-changeVar": { Context.saveChangedDataWin = true; string code_name = args.ElementAtOrDefault(i + 1); string var_name = args.ElementAtOrDefault(i + 2) ?? ""; string from_value = args.ElementAtOrDefault(i + 3) ?? ""; string to_value = args.ElementAtOrDefault(i + 4) ?? ""; int from_int; int to_int; if (!TryParseHex(from_value, out from_int)) Context.FatalError("Cannot parse {0} value in -change",from_value); if (!TryParseHex(to_value, out to_int)) Context.FatalError("Cannot parse {0} value in -change", to_value); i += 4; if (changedData == null) { changedData = File.CopyData(); File.LoadEveything(); } File.Code code=null; File.Script script=null; if (File.TryLookup(code_name, out code) || File.TryLookup(code_name, out script)) { if (script != null) code = script.Code; File.ChangeVarValue(changedData, code, var_name, from_int, to_int); } else Context.Error("'{0}' code/script not found", code_name); } break; case "-output": { i++; string dir = args.ElementAtOrDefault(i); if(string.IsNullOrWhiteSpace(dir)) InstructionError("Missing otuput directory"); Context.CheckAndSetOutputDirectory(dir); } break; case "-delete": Context.deleteDirectorys = true; break; case "-lua": Context.doLua = true; Context.doXML = false; break; case "-oneFile": Context.oneFile = true; break; case "-constOffsets": Context.doAssigmentOffsets = true; break; case "-mask": Context.saveAllMasks = true; break; case "-png": Context.saveAllPngs = true; break; case "-xml": Context.doXML = true; break; case "-search": Context.doSearch = true; break; case "-json": Context.doXML = false; break; case "-old": Context.Version = UndertaleVersion.V10000; break; case "-debug": Context.Debug = true; break; case "-nothread": Context.doThreads = false; break; case "-watch": Context.debugSearch = true; break; default: if (a[0] == '-') InstructionError("bad flag '{0}'", a); if (char.IsLetter(a[0])) chunks.Add(a); break; } } Context.CheckAndSetOutputDirectory(); ErrorContext.StartErrorSystem(); if (Context.saveChangedDataWin) { if (changedData != null) { using (var file = Context.CreateFileStream("changed_data.win", FileMode.Create, true)) { file.Write(changedData, 0, changedData.Length); file.Flush(); } } } else { File.LoadEveything(); var w = new Writers.AllWriter(); if (Context.doSearch) { var results = File.Search(chunks); if (results.Count == 0) Context.Error("No data found in search"); string path = "."; if (Context.doThreads) { Parallel.ForEach(results, result => AllWriter.DoSingleItem(path, result)); } else { foreach (var result in results) AllWriter.DoSingleItem(path, result); } } else if (Context.debugSearch) { Context.doThreads = false; Context.Debug = true; var results = File.Search(chunks); if (results.Count == 0) Context.FatalError("No data found in search"); foreach (var f in new DirectoryInfo(".").GetFiles("*.txt")) { if (System.IO.Path.GetFileName(f.Name) != "errors.txt") f.Delete(); // clear out eveything } foreach (var a in results) { File.Code c = a as File.Code; if (c != null) { var error = new ErrorContext(c.Name); error.Message("Decompiling"); Context.Debug = true; var block = c.Block; if (block != null) { using (Writers.BlockToCode to = new Writers.BlockToCode(c.Name + "_watch.js")) to.Write(block); error.Message("Finished Decompiling"); } else error.Message("Block is null"); } else Context.Error("Code '{0} not found", a); } //Context.HackyDebugWatch = new HashSet<string>(chunks); // w.AddAction("code"); } else { if (chunks.Count == 0) chunks.Add("everything"); foreach (var a in chunks) w.AddAction(a); } w.FinishProcessing(); } GoodExit(); }