Ejemplo n.º 1
0
        public string GetDecompiledText(UndertaleCode code, GlobalDecompileContext context = null)
        {
            string output = "GetDecompiledText(): " + code?.ToString();

            Console.Write(output);
            return(output);
        }
Ejemplo n.º 2
0
        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;
        }
Ejemplo n.º 3
0
        public string GetDisassemblyText(UndertaleCode code)
        {
            string output = "GetDisassemblyText(): " + code?.ToString();

            Console.Write(output);
            return(output);
        }
Ejemplo n.º 4
0
        private void TabControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            UndertaleCode code = this.DataContext as UndertaleCode;

            Directory.CreateDirectory(MainPath);
            Directory.CreateDirectory(TempPath);
            if (code == null)
            {
                return;
            }
            DecompiledSearchPanel.Close();
            DisassemblySearchPanel.Close();
            DecompiledEditor_LostFocus(sender, null);
            DisassemblyEditor_LostFocus(sender, null);
            if (DisassemblyTab.IsSelected && code != CurrentDisassembled)
            {
                DisassembleCode(code);
            }
            if (DecompiledTab.IsSelected && code != CurrentDecompiled)
            {
                DecompileCode(code);
            }
            if (GraphTab.IsSelected && code != CurrentGraphed)
            {
                GraphCode(code);
            }
        }
Ejemplo n.º 5
0
        private void Details_Click(object sender, RoutedEventArgs e)
        {
            if (ObjectReference is null)
            {
                MessageBox.Show("This feature is very WIP, so expect it to be broken.");

                MainWindow mainWindow = Application.Current.MainWindow as MainWindow;

                if (mainWindow.Selected is null)
                {
                    MainWindow.ShowError("Nothing currently selected! This is currently unsupported.");
                    return;
                }
                else if (mainWindow.Selected is UndertaleGameObject gameObject)
                {
                    // Generate the code entry
                    UndertaleCode code = gameObject.EventHandlerFor(ObjectEventType, ObjectEventSubtype, mainWindow.Data.Strings, mainWindow.Data.Code, mainWindow.Data.CodeLocals);

                    ObjectReference = code;
                }
                else
                {
                    MainWindow.ShowError("Adding to non-objects is currently unsupported.");
                    return;
                }
            }
            else
            {
                (Application.Current.MainWindow as MainWindow).ChangeSelection(ObjectReference);
            }
        }
Ejemplo n.º 6
0
        public static string GenerateLocalVarDefinitions(this UndertaleCode code, IList <UndertaleVariable> vars, UndertaleCodeLocals locals)
        {
            if (code.WeirdLocalFlag)
            {
                return("");
            }
            if (locals == null)
            {
                return("; Missing code locals- possibly due to unsupported bytecode version or brand new code entry.\n");
            }

            StringBuilder sb = new StringBuilder();

            var referenced = code.FindReferencedLocalVars();

            if (locals.Name != code.Name)
            {
                throw new Exception("Name of the locals block does not match name of the code block");
            }
            foreach (var arg in locals.Locals)
            {
                sb.Append(".localvar " + arg.Index + " " + arg.Name.Content);
                var refvar = referenced.Where((x) => x.Name == arg.Name && x.VarID == arg.Index).FirstOrDefault();
                if (refvar != null)
                {
                    sb.Append(" " + vars.IndexOf(refvar));
                }
                sb.Append('\n');
            }

            return(sb.ToString());
        }
Ejemplo n.º 7
0
        static void AddAsyncEvent(string path)
        {
            string eventSrc = File.ReadAllText(path);
            string name     = "gml_Object_objControlerN_Other_75";

            // Make a code entry.
            UndertaleCode codeEntry = new UndertaleCode
            {
                Name = Data.Strings.MakeString(name)
            };

            Data.Code.Add(codeEntry);

            // Make a code locals entry.
            UndertaleCodeLocals locals = new UndertaleCodeLocals
            {
                Name = codeEntry.Name
            };

            // Make a `var arguments;` entry.
            UndertaleCodeLocals.LocalVar argsLocal = new UndertaleCodeLocals.LocalVar
            {
                Name  = Data.Strings.MakeString("arguments"),
                Index = 0
            };

            // Glue everything together.
            locals.Locals.Add(argsLocal);
            Data.CodeLocals.Add(locals);

            // Set code locals entry for the code entry.
            codeEntry.LocalsCount = 1;
            //codeEntry.GenerateLocalVarDefinitions(codeEntry.FindReferencedLocalVars(), locals); // fails here.

            // FINALLY compile our script.
            Data.Code.ByName(name).ReplaceGML(eventSrc, Data);

            // Add this code entry to Async System event in objControllerN...

            var  obj           = Data.GameObjects.ByName("objControlerN");
            int  OtherEventInd = 7;
            uint MethodNumber  = 75;

            UndertaleGameObject.EventAction action = new UndertaleGameObject.EventAction
            {
                ActionName = codeEntry.Name,
                CodeId     = codeEntry
            };

            UndertaleGameObject.Event evnt = new UndertaleGameObject.Event
            {
                EventSubtype = MethodNumber
            };
            evnt.Actions.Add(action);

            var eventList = obj.Events[OtherEventInd];

            eventList.Add(evnt);
        }
Ejemplo n.º 8
0
        public static void ReplaceInGML(string str1, string str2, UndertaleCode code, UndertaleData data)
        {
            string decomp = Decompiler.Decompile(code, new DecompileContext(data, false));

            decomp = decomp.Replace(str1, str2);
            code.ReplaceGML(decomp, data);
            code.UpdateAddresses();
        }
Ejemplo n.º 9
0
        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);
        }
Ejemplo n.º 10
0
        private async void GraphCode(UndertaleCode code)
        {
            if (code.DuplicateEntry)
            {
                GraphView.Source = null;
                CurrentGraphed   = code;
                return;
            }

            LoaderDialog dialog = new LoaderDialog("Generating graph", "Generating graph, please wait...");

            dialog.Owner = Window.GetWindow(this);
            Task t = Task.Run(() =>
            {
                ImageSource image = null;
                try
                {
                    code.UpdateAddresses();
                    var blocks = Decompiler.DecompileFlowGraph(code);
                    string dot = Decompiler.ExportFlowGraph(blocks);

                    try
                    {
                        var getStartProcessQuery        = new GetStartProcessQuery();
                        var getProcessStartInfoQuery    = new GetProcessStartInfoQuery();
                        var registerLayoutPluginCommand = new RegisterLayoutPluginCommand(getProcessStartInfoQuery, getStartProcessQuery);
                        var wrapper = new GraphGeneration(getStartProcessQuery, getProcessStartInfoQuery, registerLayoutPluginCommand);

                        byte[] output = wrapper.GenerateGraph(dot, Enums.GraphReturnType.Png); // TODO: Use SVG instead

                        image = new ImageSourceConverter().ConvertFrom(output) as ImageSource;
                    }
                    catch (Exception e)
                    {
                        Debug.WriteLine(e.ToString());
                        if (MessageBox.Show("Unable to execute GraphViz: " + e.Message + "\nMake sure you have downloaded it and set the path in settings.\nDo you want to open the download page now?", "Graph generation failed", MessageBoxButton.YesNo, MessageBoxImage.Error) == MessageBoxResult.Yes)
                        {
                            Process.Start("https://graphviz.gitlab.io/_pages/Download/Download_windows.html");
                        }
                    }
                }
                catch (Exception e)
                {
                    Debug.WriteLine(e.ToString());
                    MessageBox.Show(e.Message, "Graph generation failed", MessageBoxButton.OK, MessageBoxImage.Error);
                }

                Dispatcher.Invoke(() =>
                {
                    GraphView.Source = image;
                    CurrentGraphed   = code;
                    dialog.Hide();
                });
            });

            dialog.ShowDialog();
            await t;
        }
Ejemplo n.º 11
0
        public void ReplaceTextInGML(UndertaleCode code, string keyword, string replacement, bool caseSensitive = false, bool isRegex = false, GlobalDecompileContext context = null)
        {
            EnsureDataLoaded();

            string passBack = "";
            string codeName = code.Name.Content;
            GlobalDecompileContext DECOMPILE_CONTEXT = context is null ? new(Data, false) : context;

            if (!Data.ToolInfo.ProfileMode)
            {
                try
                {
                    passBack = GetPassBack((code != null ? Decompiler.Decompile(code, DECOMPILE_CONTEXT) : ""), keyword, replacement, caseSensitive, isRegex);
                    code.ReplaceGML(passBack, Data);
                }
                catch (Exception exc)
                {
                    throw new Exception("Error during GML code replacement:\n" + exc.ToString());
                }
            }
            else
            {
                try
                {
                    string path = Path.Combine(ProfilesFolder, Data.ToolInfo.CurrentMD5, "Temp", codeName + ".gml");
                    if (File.Exists(path))
                    {
                        passBack = GetPassBack(File.ReadAllText(path), keyword, replacement, caseSensitive, isRegex);
                        File.WriteAllText(path, passBack);
                        code.ReplaceGML(passBack, Data);
                    }
                    else
                    {
                        try
                        {
                            if (context is null)
                            {
                                passBack = GetPassBack((code != null ? Decompiler.Decompile(code, new GlobalDecompileContext(Data, false)) : ""), keyword, replacement, caseSensitive, isRegex);
                            }
                            else
                            {
                                passBack = GetPassBack((code != null ? Decompiler.Decompile(code, context) : ""), keyword, replacement, caseSensitive, isRegex);
                            }
                            code.ReplaceGML(passBack, Data);
                        }
                        catch (Exception exc)
                        {
                            throw new Exception("Error during GML code replacement:\n" + exc.ToString());
                        }
                    }
                }
                catch (Exception exc)
                {
                    throw new Exception("Error during writing of GML code to profile:\n" + exc.ToString() + "\n\nCode:\n\n" + passBack);
                }
            }
        }
Ejemplo n.º 12
0
        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);
        }
Ejemplo n.º 13
0
        public void ReplaceTextInGML(string codeName, string keyword, string replacement, bool case_sensitive = false, bool isRegex = false, GlobalDecompileContext context = null)
        {
            UndertaleCode code = Data.Code.ByName(codeName);

            if (code is null)
            {
                throw new ScriptException($"No code named \"{codeName}\" was found!");
            }

            ReplaceTextInGML(code, keyword, replacement, case_sensitive, isRegex, context);
        }
Ejemplo n.º 14
0
        static void AddScriptFromFile(string path)
        {
            string scriptSource = File.ReadAllText(path);
            string gmlWeirdName = "gml_Script_" + Path.GetFileNameWithoutExtension(path);

            // Make a code entry.
            UndertaleCode codeEntry = new UndertaleCode
            {
                Name = Data.Strings.MakeString(gmlWeirdName)
            };

            Data.Code.Add(codeEntry);

            // Make a code locals entry.
            UndertaleCodeLocals locals = new UndertaleCodeLocals
            {
                Name = codeEntry.Name
            };

            // Make a `var arguments;` entry.
            UndertaleCodeLocals.LocalVar argsLocal = new UndertaleCodeLocals.LocalVar
            {
                Name  = Data.Strings.MakeString("arguments"),
                Index = 0
            };

            // Glue everything together.
            locals.Locals.Add(argsLocal);
            Data.CodeLocals.Add(locals);

            // Set code locals entry for the code entry.
            codeEntry.LocalsCount = 1;
            //codeEntry.GenerateLocalVarDefinitions(codeEntry.FindReferencedLocalVars(), locals); // fails here.

            // FINALLY compile our script.
            Data.Code.ByName(gmlWeirdName).ReplaceGML(scriptSource, Data);

            // ... and actually add it like a script...
            var scr = new UndertaleScript
            {
                Code = Data.Code.ByName(gmlWeirdName),
                Name = Data.Strings.MakeString(Path.GetFileNameWithoutExtension(path))
            };

            Data.Scripts.Add(scr);

            // ... oh, and don't forget to add a *function* reference.
            var funcentry = new UndertaleFunction
            {
                Name = Data.Strings.MakeString(Path.GetFileNameWithoutExtension(path))
            };

            Data.Functions.Add(funcentry);
        }
Ejemplo n.º 15
0
 public string GetDisassemblyText(UndertaleCode code)
 {
     try
     {
         return(code != null?code.Disassemble(Data.Variables, Data.CodeLocals.For(code)) : "");
     }
     catch (Exception e)
     {
         return("/*\nDISASSEMBLY FAILED!\n\n" + e.ToString() + "\n*/"); // Please don't
     }
 }
Ejemplo n.º 16
0
 private void UpdateGettext(UndertaleCode gettextCode)
 {
     gettext = new Dictionary <string, int>();
     foreach (var line in Decompiler.Decompile(gettextCode, new DecompileContext(null, true)).Replace("\r\n", "\n").Split('\n'))
     {
         Match m = Regex.Match(line, "^ds_map_add\\(global.text_data_en, \"(.*)\"@([0-9]+), \"(.*)\"@([0-9]+)\\)");
         if (m.Success)
         {
             gettext.Add(m.Groups[1].Value, Int32.Parse(m.Groups[4].Value));
         }
     }
 }
Ejemplo n.º 17
0
        public string GetDecompiledText(UndertaleCode code, GlobalDecompileContext context = null)
        {
            GlobalDecompileContext DECOMPILE_CONTEXT = context is null ? new(Data, false) : context;

            try
            {
                return(code != null?Decompiler.Decompile(code, DECOMPILE_CONTEXT) : "");
            }
            catch (Exception e)
            {
                return("/*\nDECOMPILER FAILED!\n\n" + e.ToString() + "\n*/");
            }
        }
    /// <inheritdoc/>
    public void ReplaceTextInGML(UndertaleCode code, string keyword, string replacement, bool caseSensitive = false, bool isRegex = false, GlobalDecompileContext context = null)
    {
        if (code == null)
        {
            throw new ArgumentNullException(nameof(code));
        }

        EnsureDataLoaded();

        string passBack = "";
        GlobalDecompileContext decompileContext = context is null ? new(Data, false) : context;

        if (!Data.ToolInfo.ProfileMode)
        {
            try
            {
                passBack = GetPassBack(Decompiler.Decompile(code, decompileContext), keyword, replacement, caseSensitive, isRegex);
                code.ReplaceGML(passBack, Data);
            }
            catch (Exception exc)
            {
                throw new Exception("Error during GML code replacement:\n" + exc);
            }
        }
        else if (Data.ToolInfo.ProfileMode)
        {
            try
            {
                try
                {
                    if (context is null)
                    {
                        passBack = GetPassBack(Decompiler.Decompile(code, new GlobalDecompileContext(Data, false)), keyword, replacement, caseSensitive, isRegex);
                    }
                    else
                    {
                        passBack = GetPassBack(Decompiler.Decompile(code, context), keyword, replacement, caseSensitive, isRegex);
                    }
                    code.ReplaceGML(passBack, Data);
                }
                catch (Exception exc)
                {
                    throw new Exception("Error during GML code replacement:\n" + exc);
                }
            }
            catch (Exception exc)
            {
                throw new Exception("Error during writing of GML code to profile:\n" + exc + "\n\nCode:\n\n" + passBack);
            }
        }
    }
Ejemplo n.º 19
0
        public string GetDecompiledText(string codeName)
        {
            UndertaleCode code = Data.Code.ByName(codeName);
            ThreadLocal <GlobalDecompileContext> DECOMPILE_CONTEXT = new ThreadLocal <GlobalDecompileContext>(() => new GlobalDecompileContext(Data, false));

            try
            {
                return(code != null?Decompiler.Decompile(code, DECOMPILE_CONTEXT.Value) : "");
            }
            catch (Exception e)
            {
                return("/*\nDECOMPILER FAILED!\n\n" + e.ToString() + "\n*/");
            }
        }
Ejemplo n.º 20
0
        public static string Disassemble(this UndertaleCode code, IList <UndertaleVariable> vars, UndertaleCodeLocals locals)
        {
            StringBuilder sb = new StringBuilder();

            if (locals == null && !code.WeirdLocalFlag)
            {
                sb.Append("; WARNING: Missing code locals, possibly due to unsupported bytecode version or a brand new code entry.\n");
            }
            else
            {
                sb.Append(code.GenerateLocalVarDefinitions(vars, locals));
            }

            Dictionary <uint, string> fragments = new Dictionary <uint, string>();

            foreach (var dup in code.Duplicates)
            {
                fragments.Add(dup.Offset / 4, (dup.Name?.Content ?? "<null>") + $" (locals={dup.LocalsCount}, argc={dup.ArgumentsCount})");
            }
            List <uint> blocks = FindBlockAddresses(code);

            foreach (var inst in code.Instructions)
            {
                bool doNewline = true;
                if (fragments.TryGetValue(inst.Address, out string entry))
                {
                    sb.AppendLine();
                    sb.AppendLine($"> {entry}");
                    doNewline = false;
                }

                int ind = blocks.IndexOf(inst.Address);
                if (ind != -1)
                {
                    if (doNewline)
                    {
                        sb.AppendLine();
                    }
                    sb.AppendLine($":[{ind}]");
                }

                sb.AppendLine(inst.ToString(code, blocks));
            }

            sb.AppendLine();
            sb.Append(":[end]");

            return(sb.ToString());
        }
Ejemplo n.º 21
0
        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;
        }
Ejemplo n.º 22
0
        public void ReplaceTextInGML(UndertaleCode code, string keyword, string replacement, bool case_sensitive = false, bool isRegex = false, GlobalDecompileContext context = null)
        {
            EnsureDataLoaded();

            string passBack = "";
            string codeName = code.Name.Content;
            GlobalDecompileContext DECOMPILE_CONTEXT = context is null ? new(Data, false) : context;

            if (Data.ToolInfo.ProfileMode == false || Data.GMS2_3)
            {
                try
                {
                    passBack = GetPassBack((code != null ? Decompiler.Decompile(code, DECOMPILE_CONTEXT) : ""), keyword, replacement, case_sensitive, isRegex);
                    code.ReplaceGML(passBack, Data);
                }
                catch (Exception exc)
                {
                    throw new Exception("Error during GML code replacement:\n" + exc.ToString());
                }
            }
            else if (Data.ToolInfo.ProfileMode && !Data.GMS2_3)
            {
                try
                {
                    try
                    {
                        if (context is null)
                        {
                            passBack = GetPassBack((code != null ? Decompiler.Decompile(code, new GlobalDecompileContext(Data, false)) : ""), keyword, replacement, case_sensitive, isRegex);
                        }
                        else
                        {
                            passBack = GetPassBack((code != null ? Decompiler.Decompile(code, context) : ""), keyword, replacement, case_sensitive, isRegex);
                        }
                        code.ReplaceGML(passBack, Data);
                    }
                    catch (Exception exc)
                    {
                        throw new Exception("Error during GML code replacement:\n" + exc.ToString());
                    }
                }
                catch (Exception exc)
                {
                    throw new Exception("Error during writing of GML code to profile:\n" + exc.ToString() + "\n\nCode:\n\n" + passBack);
                }
            }
        }
Ejemplo n.º 23
0
 private void UpdateGettext(UndertaleCode gettextCode)
 {
     gettext = new Dictionary <string, int>();
     string[] DecompilationOutput;
     if (!SettingsWindow.ProfileModeEnabled)
     {
         DecompilationOutput = Decompiler.Decompile(gettextCode, new DecompileContext(null, true)).Replace("\r\n", "\n").Split('\n');
     }
     else
     {
         try
         {
             string path = Path.Combine(TempPath, gettextCode.Name.Content + ".gml");
             if (File.Exists(path))
             {
                 DecompilationOutput = File.ReadAllText(path).Replace("\r\n", "\n").Split('\n');
             }
             else
             {
                 DecompilationOutput = Decompiler.Decompile(gettextCode, new DecompileContext(null, true)).Replace("\r\n", "\n").Split('\n');
             }
         }
         catch
         {
             DecompilationOutput = Decompiler.Decompile(gettextCode, new DecompileContext(null, true)).Replace("\r\n", "\n").Split('\n');
         }
     }
     foreach (var line in DecompilationOutput)
     {
         Match m = Regex.Match(line, "^ds_map_add\\(global.text_data_en, \"(.*)\"@([0-9]+), \"(.*)\"@([0-9]+)\\)");
         if (m.Success)
         {
             try
             {
                 gettext.Add(m.Groups[1].Value, Int32.Parse(m.Groups[4].Value));
             }
             catch (ArgumentException)
             {
                 MessageBox.Show("There is a duplicate key in textdata_en. This may cause errors in the comment display of text.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
             }
             catch
             {
                 MessageBox.Show("Unknown error in textdata_en. This may cause errors in the comment display of text.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
             }
         }
     }
 }
Ejemplo n.º 24
0
    /// <summary>
    /// Replaces a code entry with text from another file.
    /// </summary>
    /// <param name="codeEntry">The code entry to replace</param>
    /// <param name="fileToReplace">File path which should replace the code entry.</param>
    private void ReplaceCodeEntryWithFile(string codeEntry, FileInfo fileToReplace)
    {
        UndertaleCode code = Data.Code.ByName(codeEntry);

        if (code == null)
        {
            Console.Error.WriteLine($"Data file does not contain a code entry named {codeEntry}!");
            return;
        }

        if (Verbose)
        {
            Console.WriteLine("Replacing " + codeEntry);
        }

        ImportGMLString(codeEntry, File.ReadAllText(fileToReplace.FullName));
    }
Ejemplo n.º 25
0
        void SafeImport(string codeName, string gmlCode, bool IsGML, bool destroyASM = true, bool CheckDecompiler = false, bool throwOnError = false)
        {
            UndertaleCode code = Data.Code.ByName(codeName);

            try
            {
                if (IsGML)
                {
                    code.ReplaceGML(gmlCode, Data);

                    // Write to profile if necessary.
                    string path = Path.Combine(ProfilesFolder, Data.ToolInfo.CurrentMD5, "Temp", codeName + ".gml");
                    if (File.Exists(path))
                    {
                        File.WriteAllText(path, GetDecompiledText(code));
                    }
                }
                else
                {
                    var instructions = Assembler.Assemble(gmlCode, Data);
                    code.Replace(instructions);
                    if (destroyASM)
                    {
                        NukeProfileGML(codeName);
                    }
                }
            }
            catch (Exception ex)
            {
                if (!CheckDecompiler)
                {
                    string errorText = $"Code import error at {(IsGML ? "GML" : "ASM")} code \"{codeName}\":\n\n{ex.Message}";
                    this.ShowWarning(errorText);

                    if (throwOnError)
                    {
                        throw new ScriptException("*codeImportError*");
                    }
                }
                else
                {
                    code.ReplaceGML("", Data);
                }
            }
        }
Ejemplo n.º 26
0
        private void UserControl_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            UndertaleCode code = this.DataContext as UndertaleCode;

            if (code == null)
            {
                return;
            }
            if (DisassemblyTab.IsSelected && code != CurrentDisassembled)
            {
                DisassembleCode(code);
            }
            if (DecompiledTab.IsSelected && code != CurrentDecompiled)
            {
                DecompileCode(code);
            }
            if (GraphTab.IsSelected && code != CurrentGraphed)
            {
                GraphCode(code);
            }
        }
Ejemplo n.º 27
0
        public static List <uint> FindBlockAddresses(UndertaleCode code)
        {
            HashSet <uint> addresses = new HashSet <uint>();

            if (code.Instructions.Count != 0)
            {
                addresses.Add(0);
            }

            foreach (var inst in code.Instructions)
            {
                switch (inst.Kind)
                {
                case UndertaleInstruction.Opcode.B:
                case UndertaleInstruction.Opcode.Bf:
                case UndertaleInstruction.Opcode.Bt:
                case UndertaleInstruction.Opcode.PushEnv:
                    addresses.Add(inst.Address + 1);
                    addresses.Add((uint)(inst.Address + inst.JumpOffset));
                    break;

                case UndertaleInstruction.Opcode.PopEnv:
                    if (!inst.JumpOffsetPopenvExitMagic)
                    {
                        addresses.Add((uint)(inst.Address + inst.JumpOffset));
                    }
                    break;

                case UndertaleInstruction.Opcode.Exit:
                case UndertaleInstruction.Opcode.Ret:
                    addresses.Add(inst.Address + 1);
                    break;
                }
            }

            List <uint> res = addresses.ToList();

            res.Sort();
            return(res);
        }
Ejemplo n.º 28
0
        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);
        }
Ejemplo n.º 29
0
    /// <summary>
    /// Dumps a code entry from a data file.
    /// </summary>
    /// <param name="codeEntry">The code entry that should get dumped</param>
    private void DumpCodeEntry(string codeEntry)
    {
        UndertaleCode code = Data.Code.ByName(codeEntry);


        if (code == null)
        {
            Console.Error.WriteLine($"Data file does not contain a code entry named {codeEntry}!");
            return;
        }

        string directory = $"{Output.FullName}/CodeEntries/";

        Directory.CreateDirectory(directory);

        if (Verbose)
        {
            Console.WriteLine($"Dumping {codeEntry}");
        }

        File.WriteAllText($"{directory}/{codeEntry}.gml", GetDecompiledText(code));
    }
Ejemplo n.º 30
0
        void SafeImport(string codeName, string gmlCode, bool IsGML, bool destroyASM = true, bool CheckDecompiler = false, bool throwOnError = false)
        {
            UndertaleCode code = Data.Code.ByName(codeName);

            try
            {
                if (IsGML)
                {
                    code.ReplaceGML(gmlCode, Data);
                }
                else
                {
                    var instructions = Assembler.Assemble(gmlCode, Data);
                    code.Replace(instructions);
                    if (destroyASM)
                    {
                        NukeProfileGML(codeName);
                    }
                }
            }
            catch (Exception ex)
            {
                if (!CheckDecompiler)
                {
                    string errorText = $"Code import error at {(IsGML ? "GML" : "ASM")} code \"{codeName}\":\n\n{ex.Message}";
                    Console.Error.WriteLine(errorText);

                    if (throwOnError)
                    {
                        throw new ScriptException("*codeImportError*");
                    }
                }
                else
                {
                    code.ReplaceGML("", Data);
                }
            }
        }