public static void FramecapRemover(UndertaleData data) { var cst = data.GameObjects.ByName("obj_constant"); cst.EventHandlerFor(EventType.Create, data.Strings, data.Code, data.CodeLocals).AppendGML(RabbitRunCode.speedycreate, data); cst.EventHandlerFor(EventType.Step, data.Strings, data.Code, data.CodeLocals).AppendGML(RabbitRunCode.speedystepper, data); }
public void DiscoverRuntimes(string dataFilePath, UndertaleData data) { Runtimes.Clear(); DiscoverGameExe(dataFilePath, data); DiscoverGMS2(); DiscoverGMS1(); }
private void DisassemblyEditor_LostFocus(object sender, RoutedEventArgs e) { UndertaleCode code = this.DataContext as UndertaleCode; if (code == null) { return; // Probably loaded another data.win or something. } UndertaleData data = (Application.Current.MainWindow as MainWindow).Data; try { var instructions = Assembler.Assemble(DisassemblyEditor.Text, data); code.Replace(instructions); } catch (Exception ex) { MessageBox.Show(ex.ToString(), "Assembler error", MessageBoxButton.OK, MessageBoxImage.Error); return; } CurrentDisassembled = null; CurrentDecompiled = null; CurrentGraphed = null; DisassembleCode(code); DisassemblyView.Visibility = Visibility.Visible; DisassemblyEditor.Visibility = Visibility.Collapsed; }
public static CompileContext CompileGMLText(string input, UndertaleData data, UndertaleCode code, MainThreadDelegate mainThreadDelegate) { var ctx = new CompileContext(data, code); ctx.MainThreadDelegate = mainThreadDelegate; return(CompileGMLText(input, ctx)); }
private static void IntroPatch(UndertaleData data) { Console.WriteLine("for skipping intros in normal saves on version 1.1.0.2 and up, see SETTINGS>GAME OPTIONS>Speedrun mode"); UndertaleCode ea = data.Code.ByName("gml_Script_start_new_game"); ReplaceInGML("loadroom = rm_intro", "if (global.CurrentFile == \"savedfile4.sav\")loadroom = rm_house;\n" + "else loadroom = rm_intro", ea, data); }
private void Command_New(object sender, ExecutedRoutedEventArgs e) { Data = UndertaleData.CreateNew(); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Data")); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("IsGMS2")); ChangeSelection(Highlighted = new DescriptionView("Welcome to UndertaleModTool!", "New file created, have fun making a game out of nothing\nI TOLD YOU to open data.win, not create a new file! :P")); SelectionHistory.Clear(); }
public static void DebugPatches(UndertaleData data) { UndertaleCode ee = data.Code.ByName("gml_Object_obj_menus_Create_0"); ReplaceInGML("1, 2], [\"\", 9],", "1, 2], [\"EXTRAS\", 1, 9], ", ee, data); ee.UpdateAddresses(); data.Code.ByName("gml_Object_obj_constant_Draw_64").AppendGML(RabbitRunCode.constBruhwer, data); }
public async Task <bool> MakeNewDataFile() { // This call has no use except to suppress the "method is not doing anything async" warning await Task.Delay(1); Data = UndertaleData.CreateNew(); Console.WriteLine("New file created."); return(true); }
public void CreateAndSaveEmptyGame() { UndertaleData data = UndertaleData.CreateNew(); using (MemoryStream ms = new MemoryStream()) { UndertaleIO.Write(ms, data); } }
static void Main(string[] args) { UndertaleData data = UndertaleIO.Read(new FileStream(@"deltarune\data.win", FileMode.Open, FileAccess.Read)); foreach (var code in data.Code) { Debug.WriteLine(code.Name.Content); code.Replace(Assembler.Assemble(code.Disassemble(data.Variables, data.CodeLocals.For(code)), data.Functions, data.Variables, data.Strings)); } UndertaleIO.Write(new FileStream(@"deltarune\newdata.win", FileMode.Create), data); }
private static int ParseResourceName(string line, UndertaleData data) { if (data != null) { int id = data.IndexOf(data.ByName(line)); if (id >= 0) { return(id); } } throw new FormatException("Unable to parse " + line + " as number or resource name"); }
/// <summary> /// Read supplied filename and return the data file. /// </summary> /// <param name="datafile">The datafile to read</param> /// <param name="warningHandler">Handler for Warnings</param> /// <param name="messageHandler">Handler for Messages</param> /// <returns></returns> /// <exception cref="FileNotFoundException">If the data file cannot be found</exception> private static UndertaleData ReadDataFile(FileInfo datafile, WarningHandlerDelegate warningHandler = null, MessageHandlerDelegate messageHandler = null) { try { using FileStream fs = datafile.OpenRead(); UndertaleData gmData = UndertaleIO.Read(fs, warningHandler, messageHandler); return(gmData); } catch (FileNotFoundException e) { throw new FileNotFoundException($"Data file '{e.FileName}' does not exist"); } }
private void button_corrupt_Click(object sender, RoutedEventArgs e) { UndertaleData OldData = new UndertaleData(); rng = new Random(Convert.ToInt32(tbox_seedcamp.Text)); if (!EnsureDataLoaded()) { MessageBox.Show("Load the game first!", "Egg!!!!", MessageBoxButton.OK, MessageBoxImage.Error); return; } DoSaveDialog(); }
//Finding salt public static string[] Decompile(string inFile) { FileStream file = new FileStream(inFile, FileMode.Open, FileAccess.Read); UndertaleData data = UndertaleIO.Read(file); var scrSetGlobalOptions = data.Scripts.ByName("scrSetGlobalOptions"); var locals = scrSetGlobalOptions.Code.Instructions; string instruction = ""; for (int i = 0; i < locals.Count; i++) { if (locals[i].ToString().Contains("md5StrAdd")) { instruction = locals[i - 1].ToString(); instruction = instruction[(instruction.IndexOf('"') + 1)..];
private void DecompiledEditor_LostFocus(object sender, RoutedEventArgs e) { UndertaleCode code = this.DataContext as UndertaleCode; if (code == null) { return; // Probably loaded another data.win or something. } if (code.DuplicateEntry) { return; } UndertaleData data = (Application.Current.MainWindow as MainWindow).Data; CompileContext compileContext = Compiler.CompileGMLText(DecompiledEditor.Text, data, code); if (compileContext.HasError) { MessageBox.Show(compileContext.ResultError, "Compiler error", MessageBoxButton.OK, MessageBoxImage.Error); return; } if (!compileContext.SuccessfulCompile) { MessageBox.Show(compileContext.ResultAssembly, "Compile failed", MessageBoxButton.OK, MessageBoxImage.Error); return; } try { var instructions = Assembler.Assemble(compileContext.ResultAssembly, data); code.Replace(instructions); } catch (Exception ex) { MessageBox.Show(ex.ToString(), "Assembler error", MessageBoxButton.OK, MessageBoxImage.Error); return; } // Show new code, decompiled. CurrentDisassembled = null; CurrentDecompiled = null; CurrentGraphed = null; DecompileCode(code); DecompiledView.Visibility = Visibility.Visible; DecompiledEditor.Visibility = Visibility.Collapsed; }
static void Main(string[] args) { UndertaleData data = UndertaleIO.Read(new FileStream(@"C:\Program Files (x86)\Steam\steamapps\common\undertale\data.win", FileMode.Open)); //UndertaleIO.Write(new FileStream("newdata.win", FileMode.Create), data); UndertaleDebugData debug = DebugDataGenerator.GenerateDebugData(data, DebugDataMode.Decompiled); using (FileStream stream = new FileStream("data.yydebug", FileMode.Create)) { using (UndertaleWriter writer = new UndertaleWriter(stream)) { debug.FORM.Serialize(writer); } } }
/// <summary> /// Reads the data from data.win using UndertaleModLib /// </summary> /// <param name="dataWinPath">Path to data.win</param> static void ReadData(string dataWinPath) { Console.WriteLine("Reading data.win"); FileStream fs = new FileStream(dataWinPath, FileMode.Open, FileAccess.Read); try { data = UndertaleIO.Read(fs); } catch (IOException e) { Console.WriteLine(e.Message); Console.ReadLine(); Environment.Exit(1); } fs.Close(); }
/// <summary> /// Method that gets executed on the "new" command /// </summary> /// <param name="options">The arguments that have been provided with the "new" command</param> /// <returns><see cref="EXIT_SUCCESS"/> and <see cref="EXIT_FAILURE"/> for being successful and failing respectively</returns> private static int New(NewOptions options) { //TODO: this should probably create a new Program instance, with just the properties that it needs UndertaleData data = UndertaleData.CreateNew(); // If stdout flag is set, write new data to stdout and quit if (options.Stdout) { if (options.Verbose) { Console.WriteLine("Attempting to write new Data file to STDOUT..."); } using MemoryStream ms = new MemoryStream(); UndertaleIO.Write(ms, data); Console.OpenStandardOutput().Write(ms.ToArray(), 0, (int)ms.Length); Console.Out.Flush(); if (options.Verbose) { Console.WriteLine("Successfully wrote new Data file to STDOUT."); } return(EXIT_SUCCESS); } // If not STDOUT, write to file instead. Check first if we have permission to overwrite if (options.Output.Exists && !options.Overwrite) { Console.Error.WriteLine($"'{options.Output}' already exists. Pass --overwrite to overwrite"); return(EXIT_FAILURE); } // We're not writing to STDOUT, and overwrite flag was given, so we write to specified file. if (options.Verbose) { Console.WriteLine($"Attempting to write new Data file to '{options.Output}'..."); } using FileStream fs = options.Output.OpenWrite(); UndertaleIO.Write(fs, data); if (options.Verbose) { Console.WriteLine($"Successfully wrote new Data file to '{options.Output}'."); } return(EXIT_SUCCESS); }
public Runtime Pick(string dataFilePath, UndertaleData data) { DiscoverRuntimes(dataFilePath, data); if (Runtimes.Count == 0) { MessageBox.Show("Unable to find game EXE or any installed Studio runtime", "Run error", MessageBoxButton.OK, MessageBoxImage.Error); return(null); } else if (Runtimes.Count == 1) { return(Runtimes[0]); } else { ShowDialog(); return(Selected); } }
public Runtime Pick(string dataFilePath, UndertaleData data) { DiscoverRuntimes(dataFilePath, data); if (Runtimes.Count == 0) { this.ShowError("Unable to find game EXE or any installed Studio runtime", "Run error"); return(null); } else if (Runtimes.Count == 1) { return(Runtimes[0]); } else { ShowDialog(); return(Selected); } }
private static int ParseResourceName(string line, UndertaleData data) { if (data != null) { UndertaleNamedResource byName = data.ByName(line); if (byName == null) { throw new FormatException("Could not locate resource named '" + line + "'."); } int id = data.IndexOf(byName); if (id >= 0) { return(id); } } throw new FormatException("Unable to parse " + line + " as number or resource name"); }
private void loadInputButton_Click(object sender, EventArgs e) { label1.Text = boxWorkingMsg; try { fsin = new FileStream(inputFileTB.Text, FileMode.Open); Data = UndertaleIO.Read(fsin); while (null == Data) { Application.DoEvents(); } } catch (Exception es) { label1.Text = es.ToString(); MessageBox.Show(es.Message, "Loading error", MessageBoxButtons.OK, MessageBoxIcon.Error); } label1.Text = boxCompleteMsg; }
public void LoadData() { if (!File.Exists(path)) { Assert.Inconclusive("Unable to test, file not found: " + path); } using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read)) { string fileMD5 = GenerateMD5(fs); if (fileMD5 != expectedMD5) { Assert.Inconclusive("Unable to test, incorrect file: got " + fileMD5 + " expected " + expectedMD5); } fs.Position = 0; data = UndertaleIO.Read(fs); } }
public static int New(NewOptions options) { var data = UndertaleData.CreateNew(); if (options.Stdout) { WriteStdout(); } else { if (WriteFile() == EXIT_FAILURE) { return(EXIT_FAILURE); } } return(EXIT_SUCCESS); int WriteFile() { if (options.Output.Exists && !options.Overwrite) { Console.Error.WriteLine($"{options.Output} already exists. Pass --overwrite to overwrite"); return(EXIT_FAILURE); } using (var fs = options.Output.OpenWrite()) { UndertaleIO.Write(fs, data); return(EXIT_SUCCESS); } } void WriteStdout() { using (var ms = new MemoryStream()) { UndertaleIO.Write(ms, data); System.Console.OpenStandardOutput().Write(ms.ToArray(), 0, (int)ms.Length); System.Console.Out.Flush(); } } }
private async Task LoadFile(string filename) { LoaderDialog dialog = new LoaderDialog("Loading", "Loading, please wait..."); dialog.Owner = this; Task t = Task.Run(() => { UndertaleData data = null; try { using (var stream = new FileStream(filename, FileMode.Open)) { data = UndertaleIO.Read(stream); } } catch (Exception e) { MessageBox.Show("An error occured while trying to load:\n" + e.Message, "Load error", MessageBoxButton.OK, MessageBoxImage.Error); } Dispatcher.Invoke(() => { if (data != null) { if (data.GeneralInfo.Major >= 2) { MessageBox.Show("Game Maker: Studio 2 game loaded! I just hacked this together quickly for the Nintendo Switch release of Undertale, so some things may be broken. Saving should work, but not all editors have the new data. Expect a release with fixes soon!", "GMS2 game loaded", MessageBoxButton.OK, MessageBoxImage.Warning); } this.Data = data; this.FilePath = filename; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Data")); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("IsGMS2")); ChangeSelection(Highlighted = new DescriptionView("Welcome to UndertaleModTool!", "Double click on the items on the left to view them!")); SelectionHistory.Clear(); } dialog.Hide(); }); }); dialog.ShowDialog(); await t; }
private void DiscoverGameExe(string dataFilePath, UndertaleData data) { string gameExeName = data?.GeneralInfo?.Filename?.Content; if (gameExeName == null) { return; } string gameExePath = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(dataFilePath), gameExeName + ".exe"); if (!File.Exists(gameExePath)) { return; } Runtimes.Add(new Runtime() { Version = "Game EXE", Path = gameExePath }); }
private async Task LoadFile(string filename) { LoadDlg dialogue = new LoadDlg { Owner = this }; Task t = Task.Run(() => { Data = null; UndertaleData data = null; try { using (var stream = new FileStream(filename, FileMode.Open)) { data = UndertaleIO.Read(stream, warning => { MessageBox.Show(warning, "Loading warning", MessageBoxButton.OK, MessageBoxImage.Warning); }); } } catch (Exception e) { MessageBox.Show("An error occured while trying to load:\n" + e.Message, "Load error", MessageBoxButton.OK, MessageBoxImage.Error); } Dispatcher.Invoke(() => { //if (data != null) //{ this.Data = data; this.FilePath = filename; //} dialogue.Close(); }); }); dialogue.ShowDialog(); await t; }
public static void ClockPatches(UndertaleData data) { UndertaleGameObject go = new UndertaleGameObject(); go.Name = data.Strings.MakeString("obj_clock"); go.Sprite = null; go.Persistent = true; go.CollisionShape = 0; go.Depth = -1; go.Awake = true; go.Visible = true; CreateEvent(RabbitRunCode.coinstants, data, go, EventType.Create, 0u); CreateEvent(RabbitRunCode.yote, data, go, EventType.Other, (uint)EventSubtypeOther.RoomEnd); CreateEvent(RabbitRunCode.rabstart, data, go, EventType.Other, (uint)EventSubtypeOther.RoomStart); CreateEvent(RabbitRunCode.constantDrawer, data, go, EventType.Draw, (uint)EventSubtypeDraw.DrawGUIEnd); CreateEvent(RabbitRunCode.constantStepper, data, go, EventType.Step, (uint)EventSubtypeStep.Step); CreateEvent(RabbitRunCode.doneThisShit, data, go, EventType.Other, (uint)EventSubtypeOther.User0); data.GameObjects.Add(go); data.Code.ByName("gml_Script_pausegame").AppendGML("instance_activate_object(obj_clock);", data); UndertaleCode c = data.Code.ByName("gml_Script_goto_mainmenu"); c.AppendGML(RabbitRunCode.gohomebyebye, data); UndertaleCode endingCutscene = data.Code.ByName("gml_RoomCC_rm_n4_760_Create"); ReplaceInGML("t_scene_info = [", @"t_scene_info = [[cutscene_checkiflist, obj_constant.flagList, 191, 1, 1],[cutscene_activate_userevent, obj_clock,0],", data.Code.ByName("gml_RoomCC_rm_n4_760_Create"), data); ReplaceInGML("t_scene_info = [", @"t_scene_info = [[cutscene_activate_userevent, obj_clock,0],", data.Code.ByName("gml_RoomCC_rm_n5_33_Create"), data); var house = data.Rooms.ByName("rm_init"); UndertaleRoom.GameObject rogo = new UndertaleRoom.GameObject { ObjectDefinition = go, InstanceID = 108990u, GMS2_2_2 = true }; house.GameObjects.Add(rogo); house.Layers.Single((layer) => layer.LayerName.Content == "Instances").InstancesData.Instances.Add(rogo); }
public static int GetAssetTagID(UndertaleData data, UndertaleNamedResource resource) { ResourceType type = resource switch { UndertaleGameObject => ResourceType.Object, UndertaleSprite => ResourceType.Sprite, UndertaleSound => ResourceType.Sound, UndertaleRoom => ResourceType.Room, UndertalePath => ResourceType.Path, UndertaleScript => ResourceType.Script, UndertaleFont => ResourceType.Font, UndertaleTimeline => ResourceType.Timeline, UndertaleBackground => ResourceType.Background, UndertaleShader => ResourceType.Shader, UndertaleSequence => ResourceType.Sequence, UndertaleAnimationCurve => ResourceType.AnimCurve, _ => throw new ArgumentException("Invalid resource type!") }; IList list = data[resource.GetType()] as IList; int offset = resource is UndertaleScript ? 100000 : 0; return(((int)type << 24) | ((list.IndexOf(resource) + offset) & 0xFFFFFF)); }
private async Task LoadFile(string filename) { LoaderDialog dialog = new LoaderDialog("Loading", "Loading, please wait..."); dialog.Owner = this; Task t = Task.Run(() => { bool hadWarnings = false; UndertaleData data = null; try { using (var stream = new FileStream(filename, FileMode.Open, FileAccess.Read)) { data = UndertaleIO.Read(stream, warning => { MessageBox.Show(warning, "Loading warning", MessageBoxButton.OK, MessageBoxImage.Warning); hadWarnings = true; }); } } catch (Exception e) { MessageBox.Show("An error occured while trying to load:\n" + e.Message, "Load error", MessageBoxButton.OK, MessageBoxImage.Error); } Dispatcher.Invoke(() => { if (data != null) { if (data.UnsupportedBytecodeVersion) { MessageBox.Show("Only bytecode versions 15, 16, and (partially) 17 are supported for now, you are trying to load " + data.GeneralInfo.BytecodeVersion + ". A lot of code is disabled and will likely break something. Saving/exporting is disabled.", "Unsupported bytecode version", MessageBoxButton.OK, MessageBoxImage.Warning); CanSave = false; } else if (hadWarnings) { MessageBox.Show("Warnings occurred during loading. Saving has been disabled.", "Saving disabled", MessageBoxButton.OK, MessageBoxImage.Warning); CanSave = false; } else { CanSave = true; } if (data.Code == null) { MessageBox.Show("This game uses YYC (YoYo Compiler), which means the code is embedded into the game .exe. This configuration is currently not fully supported, continue at your own risk", "YYC", MessageBoxButton.OK, MessageBoxImage.Warning); } if (data.GeneralInfo?.BytecodeVersion == 17) { MessageBox.Show("Bytecode version 17 has been loaded. There may be some problems remaining, as thorough research into the changes are yet to be done.", "Bytecode version 17", MessageBoxButton.OK, MessageBoxImage.Warning); } if (System.IO.Path.GetDirectoryName(FilePath) != System.IO.Path.GetDirectoryName(filename)) { CloseChildFiles(); } this.Data = data; this.FilePath = filename; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Data")); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("FilePath")); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("IsGMS2")); ChangeSelection(Highlighted = new DescriptionView("Welcome to UndertaleModTool!", "Double click on the items on the left to view them!")); SelectionHistory.Clear(); } dialog.Hide(); }); }); dialog.ShowDialog(); await t; }