diff --git a/Controls/ModInfos.xaml.cs b/Controls/ModInfos.xaml.cs index 0268279..b3213bb 100644 --- a/Controls/ModInfos.xaml.cs +++ b/Controls/ModInfos.xaml.cs @@ -6,6 +6,8 @@ using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; +using ModShardLauncher.Core.Errors; +using ModShardLauncher.Core.UI; using ModShardLauncher.Mods; using Serilog; @@ -36,38 +38,33 @@ private async void Save_Click(object sender, EventArgs e) return; } - bool patchSucess = false; + MSLDiagnostic? diag = ModLoader.PatchFile(); - Stopwatch watch = Stopwatch.StartNew(); - try + if (diag is null) { - ModLoader.PatchFile(); - long elapsedMs = watch.ElapsedMilliseconds; Main.Instance.LogModListStatus(); - Log.Information("Patching lasts {{{0}}} ms", elapsedMs); Log.Information("Successfully patch vanilla"); - patchSucess = true; + + Task save = DataLoader.DoSaveDialog(); + await save; + if (save.Result) + { + LootUtils.SaveLootTables(Msl.ThrowIfNull(Path.GetDirectoryName(DataLoader.savedDataPath))); + } + else + { + Log.Information("Saved cancelled."); + } } - catch (Exception ex) + else { Main.Instance.LogModListStatus(); - Log.Error(ex, "Something went wrong"); Log.Information("Failed patching vanilla"); - MessageBox.Show(ex.ToString(), Application.Current.FindResource("SaveDataWarning").ToString()); - } - - // attempt to save the patched data - if (patchSucess) - { - Task save = DataLoader.DoSaveDialog(); - await save; - if (!save.Result) Log.Information("Saved cancelled."); - // copy the dataloot.json in the stoneshard directory - LootUtils.SaveLootTables(Msl.ThrowIfNull(Path.GetDirectoryName(DataLoader.savedDataPath))); + ErrorMessageDialog.Show(diag.Title(), diag.MessageDialog(), Main.Instance.logPath); } // reload the data - await DataLoader.LoadFile(DataLoader.dataPath, true); + await DataLoader.LoadFile(DataLoader.dataPath); Main.Instance.Refresh(); } diff --git a/Controls/SourceBar.xaml.cs b/Controls/SourceBar.xaml.cs index ccbd698..e5d1a1a 100644 --- a/Controls/SourceBar.xaml.cs +++ b/Controls/SourceBar.xaml.cs @@ -38,7 +38,7 @@ private void CompileButton_Click(object sender, RoutedEventArgs e) Log.Error(ex, "Something went wrong"); } - Msl.ThrowIfNull(Main.Instance.Viewer.Content as UserControl).UpdateLayout(); + Msl.ThrowIfNull((UserControl)Main.Instance.Viewer.Content).UpdateLayout(); Main.Instance.Refresh(); } diff --git a/Core/Errors/MSLDiagnostic.cs b/Core/Errors/MSLDiagnostic.cs new file mode 100644 index 0000000..388584e --- /dev/null +++ b/Core/Errors/MSLDiagnostic.cs @@ -0,0 +1,81 @@ +using System; +using System.Drawing; +using System.Windows.Forms; +using Serilog; + +namespace ModShardLauncher.Core.Errors +{ + public class MSLDiagnostic + { + public string ModName; + public string? FileName; + public string? PatchingMethod; + public Exception exception; + public MSLDiagnostic(Exception ex, ModFile modFile) + { + if (ex.Data.Contains("fileName")) + { + object? fileName = ex.Data["fileName"]; + FileName = $"{fileName}"; + } + if (ex.Data.Contains("patchingWay")) + { + object? patchingWay = ex.Data["patchingWay"]; + PatchingMethod = $"{patchingWay}"; + } + ModName = modFile.Name; + exception = ex; + } + public void ToLog() + { + string extraInformation = " for {{{0}}}"; + if (FileName is not null) + { + extraInformation += " in file {{{1}}}"; + } + if (PatchingMethod is not null) + { + extraInformation += " while patching by {{{2}}}"; + } + Log.Error(exception, "Something went wrong" + extraInformation, ModName, FileName, PatchingMethod); + } + public string Title() + { + return $"Patching {ModName} failed"; + } + public string MessageDialog() + { + RichTextBox message = new(); + + message.SelectionColor = Color.Black; + message.AppendText("An error was encountered while patching the mod "); + message.SelectionColor = Color.Blue; + message.AppendText(ModName); + message.SelectionColor = Color.Black; + message.AppendText(":\n"); + + if (FileName is not null) + { + message.SelectionColor = Color.Black; + message.AppendText("In file "); + message.SelectionColor = Color.Blue; + message.AppendText(FileName); + } + if (PatchingMethod is not null) + { + message.SelectionColor = Color.Black; + message.AppendText(" by "); + message.SelectionColor = Color.Blue; + message.AppendText(PatchingMethod); + message.SelectionColor = Color.Black; + message.AppendText(":\n"); + } + + message.SelectionColor = Color.Black; + message.AppendText("\n"); + message.SelectionFont = new Font(message.Font, FontStyle.Bold); + message.AppendText(exception.ToString()); + return message.Rtf; + } + } +} \ No newline at end of file diff --git a/Core/UI/ErrorMessageDialog.cs b/Core/UI/ErrorMessageDialog.cs new file mode 100644 index 0000000..e437b37 --- /dev/null +++ b/Core/UI/ErrorMessageDialog.cs @@ -0,0 +1,145 @@ +using System; +using System.Drawing; +using System.Windows.Forms; +using Serilog; + +namespace ModShardLauncher.Core.UI +{ + public class ErrorMessageDialog : Form + { + private readonly RichTextBox messageTextBox; + public DialogResult Result { get; private set; } + private readonly TableLayoutPanel panel; + private readonly Button okButton; + private readonly Button cpyButton; + private readonly Button logButton; + public ErrorMessageDialog(string title, string message, string? logPath = null) + { + panel = new(); + messageTextBox = new RichTextBox(); + okButton = new Button(); + cpyButton = new Button(); + logButton = new Button(); + + InitializeComponent(); + SetupDialog(title, message, logPath); + } + private void InitializeComponent() + { + SuspendLayout(); + + Text = string.Empty; + Size = new Size(450, 200); + StartPosition = FormStartPosition.CenterParent; + FormBorderStyle = FormBorderStyle.FixedDialog; + MaximizeBox = false; + MinimizeBox = false; + ShowIcon = false; + ShowInTaskbar = false; + Dock = DockStyle.Fill; + + // panel + panel.Anchor = AnchorStyles.Top; + panel.Size = new Size(300, 150); + panel.BorderStyle = BorderStyle.None; + panel.ColumnCount = 3; + panel.RowCount = 2; + panel.RowStyles.Add(new RowStyle(SizeType.AutoSize)); + panel.RowStyles.Add(new RowStyle(SizeType.Absolute, 44)); + panel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100)); + panel.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize)); + panel.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize)); + panel.Dock = DockStyle.Fill; + + // Message TextBox + messageTextBox.ReadOnly = true; + messageTextBox.BorderStyle = BorderStyle.None; + messageTextBox.BackColor = BackColor; + messageTextBox.ScrollBars = RichTextBoxScrollBars.Vertical; + messageTextBox.TabStop = false; + + // ok button + okButton.Text = "OK"; + okButton.Size = new Size(75, 23); + okButton.DialogResult = DialogResult.OK; + okButton.Click += (s, e) => { Result = DialogResult.OK; Close(); }; + + // copy button + cpyButton.Text = "Copy error"; + cpyButton.Size = new Size(100, 23); + cpyButton.Click += CopyButton_Click; + + // log button + logButton.Text = "Open Log Folder"; + logButton.Size = new Size(120, 23); + logButton.Click += LogButton_Click; + + panel.Controls.Add(messageTextBox, 0, 0); + panel.SetColumnSpan(messageTextBox, 3); + panel.Controls.Add(okButton, 0, 1); + panel.Controls.Add(cpyButton, 1, 1); + panel.Controls.Add(logButton, 2, 1); + + Controls.Add(panel); + + // Set default button and cancel button + AcceptButton = okButton; + CancelButton = okButton; + + ResumeLayout(); + } + private void SetupDialog(string title, string message, string? logPath = null) + { + Text = title; + messageTextBox.Rtf = message; + messageTextBox.AutoSize = true; + + Size size = messageTextBox.GetPreferredSize(new Size(800, 0)) + new Size(0, 50); + int newHeight = size.Height + 100; + int newWidth = Math.Max(450, size.Width + 50); + + messageTextBox.Size = new Size(size.Width, size.Height); + Size = new Size(newWidth, newHeight); + + // Hide log button if no path provided + if (string.IsNullOrEmpty(logPath)) + { + logButton.Visible = false; + okButton.Location = new Point(340, 125); // Center the OK button + } + else + { + logButton.Tag = logPath; // Store the log path + } + } + private void LogButton_Click(object? sender, EventArgs e) + { + try + { + string? logPath = logButton.Tag?.ToString(); + if (!string.IsNullOrEmpty(logPath)) + { + System.Diagnostics.Process.Start("explorer.exe", logPath); + } + } + catch (Exception ex) + { + MessageBox.Show($"Could not open log folder: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning); + } + + // nifty trick: use Retry to indicate log button was clicked + Result = DialogResult.Retry; + Close(); + } + private void CopyButton_Click(object? sender, EventArgs e) + { + Clipboard.SetText(messageTextBox.Text); + } + public static DialogResult Show(string title, string message, string? logPath = null) + { + using var dialog = new ErrorMessageDialog(title, message, logPath); + dialog.ShowDialog(); + return dialog.Result; + } + } +} \ No newline at end of file diff --git a/DataLoader.cs b/DataLoader.cs index 526ee26..b97cc43 100644 --- a/DataLoader.cs +++ b/DataLoader.cs @@ -1,17 +1,13 @@ using UndertaleModLib; -using UndertaleModLib.Models; using System.Threading.Tasks; using System.IO; using System; -using System.Windows; using UndertaleModLib.Util; using System.Linq; using Microsoft.Win32; using System.Collections.Generic; -using Newtonsoft.Json; using Serilog; -using UndertaleModLib.Decompiler; -using System.Security.Cryptography; +using ModShardLauncher.Loader; namespace ModShardLauncher { @@ -20,15 +16,19 @@ public class DataLoader public static UndertaleData data = new(); internal static string dataPath = ""; internal static string savedDataPath = ""; - public delegate void FileMessageEventHandler(string message); - public static event FileMessageEventHandler FileMessageEvent; - public static void ShowWarning(string warning, string title) + public static void LogUTMTWarnings(string warning) { - Console.WriteLine(title + ":" + warning); + Log.Warning("[UTMT WARNING]: {0}", warning); } - public static void ShowError(string error, string title) + public static void LogUTMTMessages(string message) { - Console.WriteLine(title + ":" + error); + return; //Log.Information("[UTMT MESSAGE]: {0}", message); + } + public static void Reset() + { + data = new(); + dataPath = ""; + savedDataPath = ""; } public static async Task DoOpenDialog() { @@ -42,132 +42,34 @@ public static async Task DoOpenDialog() // load if (dlg.ShowDialog() == true) { - await LoadFile(dlg.FileName); - return true; - } - - // nothing was load - return false; - } - private static void ExportData() - { - File.WriteAllText("json_dump_code.json", JsonConvert.SerializeObject(data.Code.Select(t => t.Name.Content))); - File.WriteAllText("json_dump_variables.json", JsonConvert.SerializeObject(data.Variables.Select(t => t.Name.Content))); - File.WriteAllText("json_dump_rooms.json", JsonConvert.SerializeObject(data.Rooms.Select(t => t.Name.Content))); - Msl.GenerateNRandomLinesFromCode(data.Code, new GlobalDecompileContext(data, false), 100, 1, 0); - } - /// - /// Export all items, weapons and armors in csv files. - /// - private static void ExportItems() - { - try - { - DirectoryInfo dir = new("export"); - if (dir.Exists) dir.Delete(true); - dir.Create(); - - List? weapons = ModLoader.GetTable("gml_GlobalScript_table_weapons"); - List? armor = ModLoader.GetTable("gml_GlobalScript_table_armor"); - - File.WriteAllLines( - Path.Join(dir.FullName, Path.DirectorySeparatorChar.ToString(), "_all_items.csv"), - data.GameObjects.Select(t => t.Name.Content).Where(x => x.Contains("o_inv_")).Select(x => x.Replace("o_inv_", "")) - ); - - if (weapons != null) + try { - File.WriteAllLines( - Path.Join(dir.FullName, Path.DirectorySeparatorChar.ToString(), "_all_weapons.csv"), - weapons.Select(x => string.Join(';', x.Split(';').Take(4))) - ); + // save the filename for later + dataPath = dlg.FileName; + await LoadFile(dlg.FileName); + return true; } - - if (armor != null) + catch (Exception ex) { - File.WriteAllLines( - Path.Join(dir.FullName, Path.DirectorySeparatorChar.ToString(), "_all_armors.csv"), - armor.Select(x => string.Join(';', x.Split(';').Take(6))) - ); + Log.Error(ex, "Something went wrong while loading {0}.", dlg.FileName); + Reset(); } } - catch(Exception ex) - { - Log.Error(ex, "Something went wrong"); - throw; - } - } - private static void ExportPreset() - { - GlobalDecompileContext context = new(ModLoader.Data, false); - File.WriteAllText("json_preset_bastion.json", Decompiler.Decompile(data.Code.First(t => t.Name.Content.Contains("scr_preset_bastion_1")), context)); - File.WriteAllText("json_preset_catacombs.json", Decompiler.Decompile(data.Code.First(t => t.Name.Content.Contains("scr_preset_catacombs")), context)); - File.WriteAllText("json_preset_crypt.json", Decompiler.Decompile(data.Code.First(t => t.Name.Content.Contains("scr_preset_crypt_1")), context)); - } - /// - /// Compute the MD5 checksum of a file located in a FileStream. - /// - /// - /// - private static string ComputeChecksum(FileStream stream) - { - using var md5 = MD5.Create(); - return Convert.ToHexString(md5.ComputeHash(stream)); - } - /// - /// Return True if the MD5 checksum of a file is equal either to the MD5 checksum of the GOG data.win of Stoneshard or to the MD5 checksum of the STEAM data.win of Stoneshard. - /// - /// - /// - private static bool CompareChecksum(FileStream stream) - { - string hash = ComputeChecksum(stream); - // Log.Information(hash); // uncomment to log the checksum of new versions and add to the array - string[] checksums = - { - "6E37E076EDFDC25468195EC1FFA937A5", // GOG 0.8.2.10 - "392EE0E8C6A09A16DED58C5737ECF1B5", // Steam 0.8.2.10 - "5F91989CA7E2A2B1234B2CD2A6AF9821", // Steam 0.9.1.16-vm - "2BD331F728428746FA337D6C7B67040A", // Steam 0.9.1.17-vm - "6F9F1E29275EEF60E3A725ECA1033DF8" // Steam 0.9.1.18-vm - }; - return checksums.Contains(hash); + + // nothing was load + return false; } - private static bool LoadUmt(string filename) + private static void LoadUmt(string filename) { - bool hadWarnings = false; - using (FileStream stream = new(filename, FileMode.Open, FileAccess.Read)) + using FileStream stream = new(filename, FileMode.Open, FileAccess.Read); + if (!ChecksumChecker.CompareChecksum(stream)) { - if(!CompareChecksum(stream)) - { - Log.Warning("Checksum inconsistency, {{{0}}} may not be vanilla or is a new version.", filename); - } - data = UndertaleIO.Read( - stream, warning => - { - ShowWarning(warning, "Loading warning"); - - if (warning.Contains("unserializeCountError.txt") || warning.Contains("object pool size")) - return; - - hadWarnings = true; - }, - delegate (string message) - { - FileMessageEvent?.Invoke(message); - } - ); + Log.Warning("Checksum inconsistency, {{{0}}} may not be steam vanilla from the modbranch beta branch or is a new version.", filename); } - - //UndertaleEmbeddedTexture.TexData.ClearSharedStream(); - Log.Information(string.Format("Successfully load: {0}.", filename)); - - return hadWarnings; + data = UndertaleIO.Read(stream, LogUTMTWarnings, LogUTMTMessages); } - public static async Task LoadFile(string filename, bool re = false) + public static async Task LoadFile(string filename) { - // save the filename for later - dataPath = filename; // create a new dialog box LoadingDialog dialog = new() { @@ -176,16 +78,7 @@ public static async Task LoadFile(string filename, bool re = false) // task load a data.win with umt Task taskLoadDataWinWithUmt = Task.Run(() => { - bool hadWarnings = false; - try - { - hadWarnings = LoadUmt(filename); - } - catch (Exception ex) - { - Log.Error(ex, "Something went wrong"); - throw; - } + LoadUmt(filename); Main.Instance.Dispatcher.Invoke(() => { dialog.Hide(); @@ -194,10 +87,21 @@ public static async Task LoadFile(string filename, bool re = false) // run dialog.ShowDialog(); await taskLoadDataWinWithUmt; + + if (data.IsYYC()) + { + throw new InvalidDataException(string.Format( + "{{{0}}} was made with YYC (YoYo Compiler) which is unmodable currently. You should move to the beta branch called modbranch instead.", + filename + )); + } + + Log.Information("Successfully load: {0}.", filename); + ModLoader.Initalize(); // cleaning loot table LootUtils.ResetLootTables(); - ExportItems(); + data.Export(DataType.Items); } public static async Task DoSaveDialog() { @@ -211,8 +115,23 @@ public static async Task DoSaveDialog() if (dlg.ShowDialog() == true) { savedDataPath = dlg.FileName; - await SaveFile(dlg.FileName); - return true; + try + { + await SaveFile(dlg.FileName); + return true; + } + catch (AggregateException exs) + { + Log.Error("Multiple exceptions occurred during save operation for {{{0}}:", dlg.FileName); + foreach (Exception ex in exs.InnerExceptions) + { + Log.Error(ex, "Exception: {Message}", ex.Message); + } + } + catch (Exception ex) + { + Log.Error(ex, "An exception occurred during save operation for {{{0}}:", dlg.FileName); + } } return false; @@ -221,36 +140,20 @@ private static void SaveTempWithUmt(string filename) { using (FileStream stream = new(filename + "temp", FileMode.Create, FileAccess.Write)) { - UndertaleIO.Write(stream, data, message => - { - FileMessageEvent?.Invoke(message); - }); + UndertaleIO.Write(stream, data, LogUTMTMessages); } //UndertaleEmbeddedTexture.TexData.ClearSharedStream(); QoiConverter.ClearSharedBuffer(); } - private static void HandleFailedSave(Exception exception) + private static void HandleFailedSave() { if (!UndertaleIO.IsDictionaryCleared) { - try - { - IEnumerable enumerableChunks = data.FORM.Chunks.Values.Where(x => x is not null).Select((UndertaleChunk x) => x as IUndertaleListChunk); - Parallel.ForEach(enumerableChunks, (chunk) => - { - chunk.ClearIndexDict(); - }); - - UndertaleIO.IsDictionaryCleared = true; - } - catch { } + IEnumerable enumerableChunks = data.FORM.Chunks.Values.Where(x => x is not null).Select(x => (IUndertaleListChunk)x); + Parallel.ForEach(enumerableChunks, (chunk) => chunk.ClearIndexDict()); + UndertaleIO.IsDictionaryCleared = true; } - - Main.Instance.Dispatcher.Invoke(() => - { - ShowError("An error occured while trying to save:\n" + exception.Message, "Save error"); - }); } public static async Task SaveFile(string filename) { @@ -260,21 +163,30 @@ public static async Task SaveFile(string filename) Owner = Main.Instance }; - Task t = Task.Run(() => + Task taskSaveDataWinWithUmt = Task.Run(() => { + List exceptions = new(); bool SaveSucceeded = true; // try temp save first try { SaveTempWithUmt(filename); } - catch (Exception e) + catch (Exception savedException) { - HandleFailedSave(e); + exceptions.Add(savedException); + try + { + HandleFailedSave(); + } + catch (Exception handledException) + { + exceptions.Add(handledException); + } SaveSucceeded = false; } - // move save + // clean after saving try { if (SaveSucceeded) @@ -287,13 +199,9 @@ public static async Task SaveFile(string filename) if (File.Exists(filename + "temp")) File.Delete(filename + "temp"); } } - catch (Exception exc) + catch (Exception cleanUpException) { - Main.Instance.Dispatcher.Invoke(() => - { - ShowError("An error occured while trying to save:\n" + exc.Message, "Save error"); - }); - + exceptions.Add(cleanUpException); SaveSucceeded = false; } @@ -301,11 +209,13 @@ public static async Task SaveFile(string filename) { dialog.Hide(); }); + + if (!SaveSucceeded) throw new AggregateException(exceptions); }); //run dialog.ShowDialog(); - await t; + await taskSaveDataWinWithUmt; } } } \ No newline at end of file diff --git a/FilePacker.cs b/FilePacker.cs index 260e302..39bc43a 100644 --- a/FilePacker.cs +++ b/FilePacker.cs @@ -13,35 +13,16 @@ public static class UtilsPacker /// /// /// - public static bool Pack(string path) + public static void Pack(string path) { - bool resultPacking = false; - - try - { - resultPacking = FilePacker.Pack( - null, - path, - ModLoader.ModPath, - path, - Main.Instance.mslVersion, - new Type[2] {typeof(ModShardLauncher.Mods.Mod), typeof(UndertaleModLib.Models.UndertaleCode)} - ); - } - catch(Exception ex) - { - if (ex is ArgumentNullException || ex is ArgumentException || ex is IOException || ex is DirectoryNotFoundException) - { - Log.Error(ex.ToString()); - } - else - { - Log.Error(ex, "Unexpected error"); - } - Console.WriteLine(ex.Message); - } - - return resultPacking; + FilePacker.Pack( + null, + path, + ModLoader.ModPath, + path, + Main.Instance.mslVersion, + new Type[2] {typeof(ModShardLauncher.Mods.Mod), typeof(UndertaleModLib.Models.UndertaleCode)} + ); } } } diff --git a/FileReader.cs b/FileReader.cs index 1782a1b..dfc9947 100644 --- a/FileReader.cs +++ b/FileReader.cs @@ -14,9 +14,9 @@ namespace ModShardLauncher { - public class FileChunk + public class FileChunk { - public string name; + public string name = string.Empty; public int offset; public int length; } @@ -58,7 +58,7 @@ public byte[] GetFile(string fileName) { if(!Existed) { - MessageBox.Show(Application.Current.FindResource("ModLostWarning").ToString() + " : " + Name); + Log.Error("The mod {0} which was located at {1} does not exist anymore.", Name, Path); ModLoader.LoadFiles(); return Array.Empty(); } @@ -79,41 +79,27 @@ public byte[] GetFile(string fileName) } public string GetCode(string fileName) { - try + byte[] data = GetFile(fileName); + if (data.Length == 0) { - byte[] data = GetFile(fileName); - if (data.Length == 0) - { - Log.Warning($"{fileName} is empty."); - return ""; - } - // if a BOM is found aka: 0xEF 0xBB 0xBF at the beginning of the file, remove it since UTMT will not understand these characters. - // BOM are produced if a script is made through Visual Studio - if (data[0] == 0xEF && data[1] == 0xBB && data[2] == 0xBF) data = data.Skip(3).ToArray(); - - string text = Encoding.UTF8.GetString(data); - if(text.Length == 0) - { - MessageBox.Show(Application.Current.FindResource("ModLostWarning").ToString() + " : " + fileName); - throw new ArgumentException("String cannot be of length zero"); - } - return text; + Log.Warning("{0} is empty.", fileName); + return ""; } - catch + // if a BOM is found aka: 0xEF 0xBB 0xBF at the beginning of the file, remove it since UTMT will not understand these characters. + // BOM are produced if a script is made through Visual Studio + if (data[0] == 0xEF && data[1] == 0xBB && data[2] == 0xBF) data = data.Skip(3).ToArray(); + + string text = Encoding.UTF8.GetString(data); + if(text.Length == 0) { - throw; + Log.Error("The mod {0} which was located at {1} does not exist anymore.", Name, Path); + throw new ArgumentException("String cannot be of length zero"); } + return text; } public bool FileExist(string fileName) { - try - { - return GetFile(fileName).Length > 0; - } - catch - { - throw; - } + return GetFile(fileName).Length > 0; } } public static class FileReader @@ -165,7 +151,7 @@ public static class FileReader byte[] versionbytes = Read(fs, size); file.Version = reg.Replace(Encoding.UTF8.GetString(versionbytes), "$1"); - Log.Information(string.Format("Reading {{{0}}} built with version {{{1}}}", nameMod, file.Version)); + Log.Information("Reading {{{0}}} built with version {{{1}}}", nameMod, file.Version); // read textures int count = BitConverter.ToInt32(Read(fs, 4), 0); @@ -250,7 +236,7 @@ public static class FileReader } catch { - Log.Information(string.Format("Cannot find the icon.png associated to {0}", fs.Name.Split("\\")[^1])); + Log.Information("Cannot find the icon.png associated to {0}", fs.Name.Split("\\")[^1]); } fs.Close(); @@ -263,7 +249,7 @@ public static byte[] Read(FileStream fs, int length) if(fs.Length - fs.Position < length) { fs.Close(); - throw new Exception(string.Format("In FileReader.Read cannot read {0} bytes in the mod {1} ", length, fs.Name.Split("\\")[^1])); + throw new Exception($"In FileReader.Read cannot read {length} bytes in the mod {fs.Name.Split("\\")[^1]}"); } fs.Read(bytes, 0, length); return bytes; diff --git a/Loader/ChecksumChecker.cs b/Loader/ChecksumChecker.cs new file mode 100644 index 0000000..e11fc76 --- /dev/null +++ b/Loader/ChecksumChecker.cs @@ -0,0 +1,34 @@ +using System.IO; +using System; +using System.Linq; +using System.Security.Cryptography; + +namespace ModShardLauncher.Loader +{ + static public class ChecksumChecker + { + private static string ComputeChecksum(FileStream stream) + { + using MD5 md5 = MD5.Create(); + return Convert.ToHexString(md5.ComputeHash(stream)); + } + /// + /// Return True if the MD5 checksum of a file is equal a valid precomputed checksum. + /// + /// + /// + public static bool CompareChecksum(FileStream stream) + { + string hash = ComputeChecksum(stream); + + string[] checksums = + { + "5F91989CA7E2A2B1234B2CD2A6AF9821", // Steam 0.9.1.16-vm + "2BD331F728428746FA337D6C7B67040A", // Steam 0.9.1.17-vm + "6F9F1E29275EEF60E3A725ECA1033DF8", // Steam 0.9.1.18-vm + "47282D0C650216D88AE25FA99615F9CB", // Steam 0.9.3.9-vm + }; + return checksums.Contains(hash); + } + } +} \ No newline at end of file diff --git a/Loader/Exporter.cs b/Loader/Exporter.cs new file mode 100644 index 0000000..2c214a6 --- /dev/null +++ b/Loader/Exporter.cs @@ -0,0 +1,98 @@ +using UndertaleModLib; +using System.IO; +using System; +using System.Linq; +using System.Collections.Generic; +using Newtonsoft.Json; +using Serilog; +using UndertaleModLib.Decompiler; + +namespace ModShardLauncher.Loader +{ + public enum DataType + { + Codes, + Items, + DungeonPresets, + } + static public class ExporterExtensions + { + /// + /// Export all code, variables and rooms name in json. + /// + private static void ExportCodes(UndertaleData data) + { + File.WriteAllText("json_dump_code.json", JsonConvert.SerializeObject(data.Code.Select(t => t.Name.Content))); + File.WriteAllText("json_dump_variables.json", JsonConvert.SerializeObject(data.Variables.Select(t => t.Name.Content))); + File.WriteAllText("json_dump_rooms.json", JsonConvert.SerializeObject(data.Rooms.Select(t => t.Name.Content))); + } + /// + /// Export all items, weapons and armors in csv. + /// + private static void ExportItems(UndertaleData data) + { + DirectoryInfo dir = new("export"); + if (dir.Exists) dir.Delete(true); + dir.Create(); + + List? weapons = ModLoader.GetTable("gml_GlobalScript_table_weapons"); + List? armor = ModLoader.GetTable("gml_GlobalScript_table_armor"); + + File.WriteAllLines( + Path.Join(dir.FullName, Path.DirectorySeparatorChar.ToString(), "_all_items.csv"), + data.GameObjects.Select(t => t.Name.Content).Where(x => x.Contains("o_inv_")).Select(x => x.Replace("o_inv_", "")) + ); + + if (weapons != null) + { + File.WriteAllLines( + Path.Join(dir.FullName, Path.DirectorySeparatorChar.ToString(), "_all_weapons.csv"), + weapons.Select(x => string.Join(';', x.Split(';').Take(4))) + ); + } + + if (armor != null) + { + File.WriteAllLines( + Path.Join(dir.FullName, Path.DirectorySeparatorChar.ToString(), "_all_armors.csv"), + armor.Select(x => string.Join(';', x.Split(';').Take(6))) + ); + } + } + /// + /// Export all preset data for all dungeons in json. + /// + private static void ExportPresets(UndertaleData data) + { + GlobalDecompileContext context = new(ModLoader.Data, false); + File.WriteAllText("json_preset_bastion.json", Decompiler.Decompile(data.Code.First(t => t.Name.Content.Contains("scr_preset_bastion_1")), context)); + File.WriteAllText("json_preset_catacombs.json", Decompiler.Decompile(data.Code.First(t => t.Name.Content.Contains("scr_preset_catacombs")), context)); + File.WriteAllText("json_preset_crypt.json", Decompiler.Decompile(data.Code.First(t => t.Name.Content.Contains("scr_preset_crypt_1")), context)); + } + /// + /// Export data for code exploration in json or csv. + /// + public static void Export(this UndertaleData data, DataType dataType) + { + try + { + switch (dataType) + { + case DataType.Codes: + ExportCodes(data); + break; + case DataType.Items: + ExportItems(data); + break; + case DataType.DungeonPresets: + ExportPresets(data); + break; + } + } + catch (Exception ex) + { + Log.Error(ex, "Something went wrong while exporting {{{0}}}", dataType); + } + } + } +} \ No newline at end of file diff --git a/Main.xaml.cs b/Main.xaml.cs index cc2127f..6b4360e 100644 --- a/Main.xaml.cs +++ b/Main.xaml.cs @@ -38,7 +38,7 @@ public partial class Main : Window public static IntPtr handle; public string mslVersion; public string utmtlibVersion; - // + public readonly string logPath = "logs"; private const double DefaultWidth = 960; // Исходная ширина private const double DefaultHeight = 800; // Исходная высота private const double AspectRatio = DefaultWidth / DefaultHeight; // Соотношение сторон @@ -62,7 +62,7 @@ public Main() // create File and Console (controlledby a switch) sinks LoggerConfiguration logger = new LoggerConfiguration() .MinimumLevel.Debug() - .WriteTo.File(string.Format("logs/log_{0}.txt", DateTime.Now.ToString("yyyyMMdd_HHmm"))) + .WriteTo.File(string.Format("{0}/log_{1}.txt", logPath, DateTime.Now.ToString("yyyyMMdd_HHmm"))) .WriteTo.Logger(log => log .MinimumLevel.ControlledBy(lls) .WriteTo.Console() @@ -157,6 +157,10 @@ public static void LogModStatus(ModFile modFile) } Log.Warning("Patching {{{2}}} for {{{0}}} {{{1}}}", modFile.Name, modFile.Version, statusMessage); } + public ModFile GetFailingMod() + { + return ModPage.Mods.Where(x => x.Enabled).First(x => x.PatchStatus == PatchStatus.Patching); ; + } private void MyToggleButton_Checked(object sender, EventArgs e) { foreach (var i in stackPanel.Children) @@ -244,7 +248,7 @@ public static void LoadSettings() { (int indexMod, ModFile? modFile) = listModFile.Enumerate().FirstOrDefault(t => t.Item2.Name == i); if (modFile != null) listModFile[indexMod].Enabled = true; - else Log.Warning($"Mod {i} not found"); + else Log.Warning("Mod {0} not found", i); } } } diff --git a/ModLoader.cs b/ModLoader.cs index 5d2ffef..c79d6eb 100644 --- a/ModLoader.cs +++ b/ModLoader.cs @@ -13,6 +13,7 @@ using UndertaleModLib.Models; using ModShardLauncher.Controls; using Serilog; +using ModShardLauncher.Core.Errors; namespace ModShardLauncher { @@ -67,22 +68,14 @@ public static void AddMenu(string name, params UIComponent[] components) } public static void SetTable(List table, string name) { - try - { - string ret = JsonConvert.SerializeObject(table).Replace("\n", ""); - UndertaleCode target = Data.Code.First(t => t.Name.Content == name); - GlobalDecompileContext context = new(Data, false); - string text = Decompiler.Decompile(target, context); - text = Regex.Replace(text, "\\[.*\\]", ret); - target.ReplaceGML(text, Data); + string ret = JsonConvert.SerializeObject(table).Replace("\n", ""); + UndertaleCode target = Data.Code.First(t => t.Name.Content == name); + GlobalDecompileContext context = new(Data, false); + string text = Decompiler.Decompile(target, context); + text = Regex.Replace(text, "\\[.*\\]", ret); + target.ReplaceGML(text, Data); - Log.Information(string.Format("Successfully set table: {0}", name.ToString())); - } - catch(Exception ex) - { - Log.Error(ex, "Something went wrong"); - throw; - } + Log.Information("Successfully set table: {0}", name); } public static void LoadFiles() { @@ -127,37 +120,32 @@ public static void LoadFiles() } catch(Exception ex) { - Log.Information(ex, string.Format("Cannot read the mod {0}", file)); + Log.Information(ex, "Cannot read the mod {0}", file); } if (f == null) continue; - try - { - Assembly assembly = f.Assembly; - // for array or list, use the available search method instead of Linq one - // use the Linq ones for IEnumerable - Type? modType = Array.Find(assembly.GetTypes(), t => t.IsSubclassOf(typeof(Mod))); - if (modType == null) - { - MessageBox.Show("加载错误: " + assembly.GetName().Name + " 此Mod需要一个Mod类"); - continue; - } - else - { - if (Activator.CreateInstance(modType) is not Mod mod) continue; - mod.LoadAssembly(); - mod.ModFiles = f; - f.instance = mod; + Assembly assembly = f.Assembly; + // for array or list, use the available search method instead of Linq one + // use the Linq ones for IEnumerable + Type? modType = Array.Find(assembly.GetTypes(), t => t.IsSubclassOf(typeof(Mod))); + + if (modType == null) + { + // MessageBox.Show("Loading error: " + assembly.GetName().Name + " This Mod need a Mod class"); + MessageBox.Show("加载错误: " + assembly.GetName().Name + " 此Mod需要一个Mod类"); + continue; + } + else + { + if (Activator.CreateInstance(modType) is not Mod mod) continue; + mod.LoadAssembly(); + mod.ModFiles = f; + f.instance = mod; ModFile? old = mods.Find(t => t.Name == f.Name); if (old != null) f.Enabled = old.Enabled; - modCaches.Add(f); - } - } - catch - { - throw; + modCaches.Add(f); } } mods.Clear(); @@ -177,7 +165,7 @@ public static void PatchMods() if (!mod.Enabled) continue; if (!mod.Existed) { - MessageBox.Show(Application.Current.FindResource("ModLostWarning").ToString() + " : " + mod.Name); + Log.Warning("The mod {0} which was located at {1} does not exist anymore.", mod.Name, mod.Path); continue; } @@ -197,13 +185,23 @@ public static void PatchMods() Msl.ChainDisclaimerRooms(Disclaimers); Msl.CreateMenu(Menus); } - public static void PatchFile() + public static MSLDiagnostic? PatchFile() { - // add new msl log function - LogUtils.InjectLog(); - PatchMods(); - // add the new loot related functions if there is any - LootUtils.InjectLootScripts(); + try + { + // add new msl log function + LogUtils.InjectLog(); + PatchMods(); + // add the new loot related functions if there is any + LootUtils.InjectLootScripts(); + return null; + } + catch (Exception ex) + { + MSLDiagnostic diag = new(ex, Main.Instance.GetFailingMod()); + diag.ToLog(); + return diag; + } } } } diff --git a/ModShardLauncher.csproj b/ModShardLauncher.csproj index 0ed98f9..df3a24c 100644 --- a/ModShardLauncher.csproj +++ b/ModShardLauncher.csproj @@ -16,11 +16,12 @@ + - + @@ -39,6 +40,7 @@ + diff --git a/ModShardLauncherTest/CodeUtilsTest.cs b/ModShardLauncherTest/CodeUtilsTest.cs index 52464a8..052cbac 100644 --- a/ModShardLauncherTest/CodeUtilsTest.cs +++ b/ModShardLauncherTest/CodeUtilsTest.cs @@ -263,10 +263,10 @@ public void MatchFrom_EmptyString_WithNonEmptyString(string input) IEnumerable stringList = "".Split('\n'); // Act - Exception ex = Assert.Throws(() => stringList.MatchFrom(input).ToList()); + InvalidOperationException ex = Assert.Throws(() => stringList.MatchFrom(input).ToList()); // Assert - Assert.Contains("MatchFrom: No matching lines found", ex.Message); + Assert.Equal($"MatchFrom: No matching lines found. Items to match:\n{input}", ex.Message); } [Theory] @@ -327,11 +327,10 @@ public void MatchFrom_NonEmptyString_NoMatch(string input, string stringToMatch) IEnumerable stringList = input.Split('\n'); // Act - Exception ex = Assert.Throws(() => stringList.MatchFrom(stringToMatch).ToList()); + InvalidOperationException ex = Assert.Throws(() => stringList.MatchFrom(stringToMatch).ToList()); // Assert - Assert.Contains("MatchFrom: No matching lines found", ex.Message); - Assert.Contains(stringToMatch, ex.Message); + Assert.Equal($"MatchFrom: No matching lines found. Items to match:\n{stringToMatch}", ex.Message); } [Theory] @@ -422,10 +421,10 @@ public void MatchBelow_EmptyString_WithNonEmptyString(string input) IEnumerable stringList = "".Split('\n'); // Act - Exception ex = Assert.Throws(() => stringList.MatchBelow(input, 0).ToList()); + InvalidOperationException ex = Assert.Throws(() => stringList.MatchBelow(input, 0).ToList()); // Assert - Assert.Contains("MatchBelow: No matching lines found", ex.Message); + Assert.Equal($"MatchBelow: No matching lines found. Items to match:\n{input}", ex.Message); } [Theory] @@ -502,11 +501,10 @@ public void MatchBelow_NonEmptyString_NoMatch(string input, string stringToMatch IEnumerable stringList = input.Split('\n'); // Act - Exception ex = Assert.Throws(() => stringList.MatchBelow(stringToMatch, len).ToList()); + InvalidOperationException ex = Assert.Throws(() => stringList.MatchBelow(stringToMatch, len).ToList()); // Assert - Assert.Contains("MatchBelow: No matching lines found", ex.Message); - Assert.Contains(stringToMatch, ex.Message); + Assert.Equal($"MatchBelow: No matching lines found. Items to match:\n{stringToMatch}", ex.Message); } [Theory] @@ -596,10 +594,10 @@ public void MatchFromUntil_EmptyString_FromNonEmptyStringUntilEmptyString(string IEnumerable stringList = "".Split('\n'); // Act - Exception ex = Assert.Throws(() => stringList.MatchFromUntil(input, "").ToList()); + InvalidOperationException ex = Assert.Throws(() => stringList.MatchFromUntil(input, "").ToList()); // Assert - Assert.Contains("MatchFrom: No matching lines found", ex.Message); + Assert.Equal($"MatchFrom: No matching lines found. Items to match:\n{input}", ex.Message); } [Theory] @@ -619,11 +617,10 @@ public void MatchFromUntil_FromNoMatch_UntilEmptyString(string input, string fro IEnumerable stringList = input.Split('\n'); // Act - Exception ex = Assert.Throws(() => stringList.MatchFromUntil(from, "").ToList()); + InvalidOperationException ex = Assert.Throws(() => stringList.MatchFromUntil(from, "").ToList()); // Assert - Assert.Contains("MatchFrom: No matching lines found", ex.Message); - Assert.Contains(from, ex.Message); + Assert.Equal($"MatchFrom: No matching lines found. Items to match:\n{from}", ex.Message); } [Theory] diff --git a/ModUtils/AsmUtils.cs b/ModUtils/AsmUtils.cs index 1515bda..53740f4 100644 --- a/ModUtils/AsmUtils.cs +++ b/ModUtils/AsmUtils.cs @@ -39,112 +39,65 @@ public static void CheckInstructionsVariables(UndertaleCode originalCode, string } else { - Log.Warning($"Cannot infer the instance type of {instruction}. There is a risk it will lead to an undefined variable."); + Log.Warning( + "Cannot infer the instance type of {0}. There is a risk it will lead to an undefined variable.", + instruction + ); } } } } public static string GetAssemblyString(string fileName) { - try - { - UndertaleCode originalCode = GetUMTCodeFromFile(fileName); - return originalCode.Disassemble(ModLoader.Data.Variables, ModLoader.Data.CodeLocals.For(originalCode)); - } - catch (Exception ex) - { - Log.Error(ex, "Something went wrong"); - throw; - } + UndertaleCode originalCode = GetUMTCodeFromFile(fileName); + return originalCode.Disassemble(ModLoader.Data.Variables, ModLoader.Data.CodeLocals.For(originalCode)); } public static void SetAssemblyString(string codeAsString, string fileName) { - try - { - UndertaleCode originalCode = GetUMTCodeFromFile(fileName); - originalCode.Replace(Assembler.Assemble(codeAsString, ModLoader.Data)); - } - catch (Exception ex) - { - Log.Error(ex, "Something went wrong"); - throw; - } + UndertaleCode originalCode = GetUMTCodeFromFile(fileName); + originalCode.Replace(Assembler.Assemble(codeAsString, ModLoader.Data)); } public static void InsertAssemblyString(string codeAsString, string fileName, int position) { - try - { - Log.Information(string.Format("Trying insert assembly in: {0}", fileName.ToString())); + Log.Information("Trying insert assembly in: {0}", fileName); - List? originalCode = GetAssemblyString(fileName).Split("\n").ToList(); - originalCode.Insert(position, codeAsString); - SetAssemblyString(string.Join("\n", originalCode), fileName); + List? originalCode = GetAssemblyString(fileName).Split("\n").ToList(); + originalCode.Insert(position, codeAsString); + SetAssemblyString(string.Join("\n", originalCode), fileName); - Log.Information(string.Format("Patched function with InsertAssemblyString: {0}", fileName.ToString())); - } - catch (Exception ex) - { - Log.Error(ex, "Something went wrong"); - throw; - } + Log.Information("Patched function with InsertAssemblyString: {0}", fileName); } public static void ReplaceAssemblyString(string codeAsString, string fileName, int position) { - try - { - Log.Information(string.Format("Trying replace assembly in: {0}", fileName.ToString())); + Log.Information("Trying replace assembly in: {0}", fileName); - List? originalCode = GetAssemblyString(fileName).Split("\n").ToList(); - originalCode[position] = codeAsString; - SetAssemblyString(string.Join("\n", originalCode), fileName); + List? originalCode = GetAssemblyString(fileName).Split("\n").ToList(); + originalCode[position] = codeAsString; + SetAssemblyString(string.Join("\n", originalCode), fileName); - Log.Information(string.Format("Patched function with ReplaceAssemblyString: {0}", fileName.ToString())); - } - catch (Exception ex) - { - Log.Error(ex, "Something went wrong"); - throw; - } + Log.Information("Patched function with ReplaceAssemblyString: {0}", fileName); } public static void ReplaceAssemblyString(string codeAsString, string fileName, int start, int len) { - try - { - Log.Information(string.Format("Trying replace assembly in: {0}", fileName.ToString())); - - List? originalCode = GetAssemblyString(fileName).Split("\n").ToList(); - originalCode[start] = codeAsString; - for (int i = 1; i < Math.Min(len, originalCode.Count - start); i++) - { - originalCode[start + i] = ""; - } - - SetAssemblyString(string.Join("\n", originalCode), fileName); + Log.Information("Trying replace assembly in: {0}", fileName); - Log.Information(string.Format("Patched function with ReplaceAssemblyString: {0}", fileName.ToString())); - } - catch (Exception ex) - { - Log.Error(ex, "Something went wrong"); - throw; + List? originalCode = GetAssemblyString(fileName).Split("\n").ToList(); + originalCode[start] = codeAsString; + for (int i = 1; i < Math.Min(len, originalCode.Count - start); i++) { + originalCode[start + i] = ""; } + SetAssemblyString(string.Join("\n", originalCode), fileName); + + Log.Information("Patched function with ReplaceAssemblyString: {0}", fileName); } public static void InjectAssemblyInstruction(string name, Func, IEnumerable> patch) { - try - { - Log.Information(string.Format("Trying inject assembly in: {0}", name.ToString())); + Log.Information("Trying inject assembly in: {0}", name); - UndertaleCode originalCode = GetUMTCodeFromFile(name); - originalCode.Replace(patch(originalCode.Instructions).ToList()); + UndertaleCode originalCode = GetUMTCodeFromFile(name); + originalCode.Replace(patch(originalCode.Instructions).ToList()); - Log.Information(string.Format("Patched function with InjectAssemblyInstruction: {0}", name.ToString())); - } - catch (Exception ex) - { - Log.Error(ex, "Something went wrong"); - throw; - } + Log.Information("Patched function with InjectAssemblyInstruction: {0}", name); } public static IEnumerable ReplaceTable(this IEnumerable original, IEnumerable injected) { @@ -231,7 +184,7 @@ public static UndertaleInstruction.Reference CreateRefVariabl NameStringID = id }; ModLoader.Data.Variables.Add(variable); - Log.Information($"Created {variable.InstanceType} variable: {variable.Name.Content} {variable.VarID}"); + Log.Information("Created {0} variable: {1} {2}", variable.InstanceType, variable.Name.Content, variable.VarID); return new UndertaleInstruction.Reference(variable, UndertaleInstruction.VariableType.Normal); } @@ -252,57 +205,43 @@ public static void CheckRefLocalVariableOrCreate(UndertaleCode code, string name } else { - Log.Information($"Found local variable: {localvar.Name.Content}"); + Log.Information("Found local variable: {0}", localvar.Name.Content); } } public static void CheckRefVariableOrCreate(string name, UndertaleInstruction.InstanceType instanceType) { - try + UndertaleVariable? variable = null; + if (instanceType == UndertaleInstruction.InstanceType.Local) { - UndertaleVariable? variable = null; - if (instanceType == UndertaleInstruction.InstanceType.Local) - { - throw new ArgumentException("Wrong method used for checking Local Variables"); - } - else - { - variable = ModLoader.Data.Variables.FirstOrDefault(t => t.Name?.Content == name && t.InstanceType == instanceType); - } + throw new ArgumentException("Wrong method used for checking Local Variables"); + } + else + { + variable = ModLoader.Data.Variables.FirstOrDefault(t => t.Name?.Content == name && t.InstanceType == instanceType); + } - if (variable == null) - { - CreateRefVariable(name, instanceType); - } - else - { - Log.Information($"Found variable: {variable.Name.Content} of type {variable.InstanceType}"); - } + if (variable == null) + { + CreateRefVariable(name, instanceType); } - catch + else { - throw; + Log.Information("Found variable: {0} of type {1}", variable.Name.Content, variable.InstanceType); } } public static UndertaleInstruction.Reference GetRefVariableOrCreate(string name, UndertaleInstruction.InstanceType instanceType) { - try - { - UndertaleInstruction.Reference refVariable; - UndertaleVariable? variable = ModLoader.Data.Variables.FirstOrDefault(t => t.Name?.Content == name); - - if (variable == null) - refVariable = CreateRefVariable(name, instanceType); - else - refVariable = new UndertaleInstruction.Reference(variable, UndertaleInstruction.VariableType.Normal); + UndertaleInstruction.Reference refVariable; + UndertaleVariable? variable = ModLoader.Data.Variables.FirstOrDefault(t => t.Name?.Content == name); + + if (variable == null) + refVariable = CreateRefVariable(name, instanceType); + else + refVariable = new UndertaleInstruction.Reference(variable, UndertaleInstruction.VariableType.Normal); - Log.Information(string.Format("Found variable: {0}", refVariable.ToString())); + Log.Information("Found variable: {0}", refVariable); - return refVariable; - } - catch - { - throw; - } + return refVariable; } public static string CreateLocalVarAssemblyAsString(UndertaleCode code) { @@ -329,31 +268,22 @@ public static string CreateLocalVarAssemblyAsString(UndertaleCode code) public static UndertaleResourceById CreateString(string name) { UndertaleString str = ModLoader.Data.Strings.MakeString(name, out int ind); - Log.Information(string.Format("Created string: {0}", str.ToString())); + Log.Information("Created string: {0}", str); return new UndertaleResourceById(str, ind); } public static UndertaleResourceById GetStringOrCreate(string name) { - try - { - UndertaleResourceById stringById; - (int ind, UndertaleString str) = ModLoader.Data.Strings.Enumerate().FirstOrDefault(x => x.Item2.Content == name); - - if (str == null) - { - stringById = CreateString(name); - Log.Information(string.Format("Created string: {0}", stringById.ToString())); - } - else - stringById = new UndertaleResourceById(str, ind); - - return stringById; - } - catch (Exception ex) + UndertaleResourceById stringById; + (int ind, UndertaleString str) = ModLoader.Data.Strings.Enumerate().FirstOrDefault(x => x.Item2.Content == name); + + if (str == null) { - Log.Error(ex, "Something went wrong"); - throw; + stringById = CreateString(name); + Log.Information(string.Format("Created string: {0}", stringById.ToString())); } + else stringById = new UndertaleResourceById(str, ind); + + return stringById; } public static UndertaleInstruction PushShort(short val) { diff --git a/ModUtils/CodeUtils.cs b/ModUtils/CodeUtils.cs index 12e54ae..d2bf107 100644 --- a/ModUtils/CodeUtils.cs +++ b/ModUtils/CodeUtils.cs @@ -86,18 +86,10 @@ public static partial class Msl /// public static UndertaleCode GetUMTCodeFromFile(string fileName) { - try - { - UndertaleCode code = ModLoader.Data.Code.First(t => t.Name?.Content == fileName); - Log.Information(string.Format("Found function: {0}", code.ToString())); + UndertaleCode code = ModLoader.Data.Code.First(t => t.Name?.Content == fileName); + Log.Information("Found function: {0}", code); - return code; - } - catch (Exception ex) - { - Log.Error(ex, "Something went wrong"); - throw; - } + return code; } /// /// Add a new UndertaleCode named using the code . It is expected to be written in GML. @@ -107,28 +99,21 @@ public static UndertaleCode GetUMTCodeFromFile(string fileName) /// public static UndertaleCode AddCode(string codeAsString, string name) { - try - { - UndertaleCode code = new(); - UndertaleCodeLocals locals = new(); - code.Name = ModLoader.Data.Strings.MakeString(name); - locals.Name = code.Name; - UndertaleCodeLocals.LocalVar argsLocal = new() - { - Name = ModLoader.Data.Strings.MakeString("arguments"), - Index = 0 - }; - locals.Locals.Add(argsLocal); - code.LocalsCount = 1; - ModLoader.Data.CodeLocals.Add(locals); - code.ReplaceGML(codeAsString, ModLoader.Data); - ModLoader.Data.Code.Add(code); - return code; - } - catch + UndertaleCode code = new(); + UndertaleCodeLocals locals = new(); + code.Name = ModLoader.Data.Strings.MakeString(name); + locals.Name = code.Name; + UndertaleCodeLocals.LocalVar argsLocal = new() { - throw; - } + Name = ModLoader.Data.Strings.MakeString("arguments"), + Index = 0 + }; + locals.Locals.Add(argsLocal); + code.LocalsCount = 1; + ModLoader.Data.CodeLocals.Add(locals); + code.ReplaceGML(codeAsString, ModLoader.Data); + ModLoader.Data.Code.Add(code); + return code; } /// /// Add a new UndertaleCode named using the code . It is expected to be written in ASM abstraction. @@ -138,31 +123,24 @@ public static UndertaleCode AddCode(string codeAsString, string name) /// public static UndertaleCode AddCodeAsm(string codeAsString, string name) { - try - { - UndertaleCode code = new(); - UndertaleCodeLocals locals = new(); - code.Name = ModLoader.Data.Strings.MakeString(name); - locals.Name = code.Name; - UndertaleCodeLocals.LocalVar argsLocal = new() - { - Name = ModLoader.Data.Strings.MakeString("arguments"), - Index = 0 - }; - locals.Locals.Add(argsLocal); - code.LocalsCount = 1; - ModLoader.Data.CodeLocals.Add(locals); - CheckInstructionsVariables(code, codeAsString); - string newLocalVarsAsString = AssemblyWrapper.CreateLocalVarAssemblyAsString(code); - codeAsString = codeAsString.Insert(codeAsString.IndexOf('\n') + 1, newLocalVarsAsString); - code.Replace(Assembler.Assemble(codeAsString, ModLoader.Data)); - ModLoader.Data.Code.Add(code); - return code; - } - catch - { - throw; - } + UndertaleCode code = new(); + UndertaleCodeLocals locals = new(); + code.Name = ModLoader.Data.Strings.MakeString(name); + locals.Name = code.Name; + UndertaleCodeLocals.LocalVar argsLocal = new() + { + Name = ModLoader.Data.Strings.MakeString("arguments"), + Index = 0 + }; + locals.Locals.Add(argsLocal); + code.LocalsCount = 1; + ModLoader.Data.CodeLocals.Add(locals); + CheckInstructionsVariables(code, codeAsString); + string newLocalVarsAsString = AssemblyWrapper.CreateLocalVarAssemblyAsString(code); + codeAsString = codeAsString.Insert(codeAsString.IndexOf('\n') + 1, newLocalVarsAsString); + code.Replace(Assembler.Assemble(codeAsString, ModLoader.Data)); + ModLoader.Data.Code.Add(code); + return code; } /// /// Get code from file in this tool. @@ -187,21 +165,14 @@ internal static string GetCodeRes(string name) /// public static UndertaleCode AddFunction(string codeAsString, string name) { - try - { - Log.Information(string.Format("Trying to add the function : {0}", name.ToString())); + Log.Information("Trying to add the function : {0}", name); - UndertaleCode scriptCode = AddCode(codeAsString, name); - ModLoader.Data.Code.Add(ModLoader.Data.Code[0]); - ModLoader.Data.Code.RemoveAt(0); + UndertaleCode scriptCode = AddCode(codeAsString, name); + ModLoader.Data.Code.Add(ModLoader.Data.Code[0]); + ModLoader.Data.Code.RemoveAt(0); - Log.Information(string.Format("Successfully added the function : {0}", name.ToString())); - return scriptCode; - } - catch - { - throw; - } + Log.Information("Successfully added the function : {0}", name); + return scriptCode; } /// /// Add a new function from the code in this tool. @@ -214,34 +185,18 @@ public static UndertaleCode AddFunction(string codeAsString, string name) /// public static string GetStringGMLFromFile(string fileName) { - try - { - UndertaleCode code = GetUMTCodeFromFile(fileName); - GlobalDecompileContext context = new(ModLoader.Data, false); + UndertaleCode code = GetUMTCodeFromFile(fileName); + GlobalDecompileContext context = new(ModLoader.Data, false); - return Decompiler.Decompile(code, context); - } - catch (Exception ex) - { - Log.Error(ex, "Something went wrong"); - throw; - } + return Decompiler.Decompile(code, context); } /// /// Set the UndertaleCode in as . /// public static void SetStringGMLInFile(string codeAsString, string fileName) { - try - { - UndertaleCode code = GetUMTCodeFromFile(fileName); - code.ReplaceGML(codeAsString, ModLoader.Data); - } - catch (Exception ex) - { - Log.Error(ex, "Something went wrong"); - throw; - } + UndertaleCode code = GetUMTCodeFromFile(fileName); + code.ReplaceGML(codeAsString, ModLoader.Data); } /// /// Insert GML from a string in at a given . @@ -259,21 +214,13 @@ public static void SetStringGMLInFile(string codeAsString, string fileName) /// The exact position to insert. public static void InsertGMLString(string codeAsString, string fileName, int position) { - try - { - Log.Information(string.Format("Trying insert code in: {0}", fileName.ToString())); + Log.Information("Trying insert code in: {0}", fileName); - List? originalCode = GetStringGMLFromFile(fileName).Split("\n").ToList(); - originalCode.Insert(position, codeAsString); - SetStringGMLInFile(string.Join("\n", originalCode), fileName); + List? originalCode = GetStringGMLFromFile(fileName).Split("\n").ToList(); + originalCode.Insert(position, codeAsString); + SetStringGMLInFile(string.Join("\n", originalCode), fileName); - Log.Information(string.Format("Patched function with InsertGMLString: {0}", fileName.ToString())); - } - catch (Exception ex) - { - Log.Error(ex, "Something went wrong"); - throw; - } + Log.Information("Patched function with InsertGMLString: {0}", fileName); } /// /// Replace an existing GML code by another from a string in at a given . @@ -291,21 +238,13 @@ public static void InsertGMLString(string codeAsString, string fileName, int pos /// The exact position to insert. public static void ReplaceGMLString(string codeAsString, string fileName, int position) { - try - { - Log.Information(string.Format("Trying replace code in: {0}", fileName.ToString())); + Log.Information("Trying replace code in: {0}", fileName); - List? originalCode = GetStringGMLFromFile(fileName).Split("\n").ToList(); - originalCode[position] = codeAsString; - SetStringGMLInFile(string.Join("\n", originalCode), fileName); + List? originalCode = GetStringGMLFromFile(fileName).Split("\n").ToList(); + originalCode[position] = codeAsString; + SetStringGMLInFile(string.Join("\n", originalCode), fileName); - Log.Information(string.Format("Patched function with ReplaceGMLString: {0}", fileName.ToString())); - } - catch (Exception ex) - { - Log.Error(ex, "Something went wrong"); - throw; - } + Log.Information("Patched function with ReplaceGMLString: {0}", fileName); } /// /// Replace an existing GML code by another from a string in at a given @@ -325,26 +264,18 @@ public static void ReplaceGMLString(string codeAsString, string fileName, int po /// The exact position to insert. public static void ReplaceGMLString(string codeAsString, string fileName, int start, int len) { - try - { - Log.Information(string.Format("Trying replace code in: {0}", fileName.ToString())); - - List? originalCode = GetStringGMLFromFile(fileName).Split("\n").ToList(); - originalCode[start] = codeAsString; - for (int i = 1; i < Math.Min(len, originalCode.Count - start); i++) - { - originalCode[start + i] = ""; - } + Log.Information("Trying replace code in: {0}", fileName); - SetStringGMLInFile(string.Join("\n", originalCode), fileName); - - Log.Information(string.Format("Patched function with ReplaceGMLString: {0}", fileName.ToString())); - } - catch (Exception ex) + List? originalCode = GetStringGMLFromFile(fileName).Split("\n").ToList(); + originalCode[start] = codeAsString; + for (int i = 1; i < Math.Min(len, originalCode.Count - start); i++) { - Log.Error(ex, "Something went wrong"); - throw; + originalCode[start + i] = ""; } + + SetStringGMLInFile(string.Join("\n", originalCode), fileName); + + Log.Information("Patched function with ReplaceGMLString: {0}", fileName); } /// /// Convert a (Match, string) IEnumerable into a string IEnumerable by selecting for all elements only the string part. @@ -461,7 +392,10 @@ public static string Collect(this FileEnumerable<(Match, string)> fe) if (!foundMatch) { - throw new Exception("MatchFrom: No matching lines found. Items to match: " + string.Join(", ", other)); + throw new InvalidOperationException(string.Format( + "MatchFrom: No matching lines found. Items to match:\n{0}", + string.Join("\n", other)) + ); } } @@ -484,7 +418,16 @@ public static string Collect(this FileEnumerable<(Match, string)> fe) /// public static FileEnumerable<(Match, string)> MatchFrom(this FileEnumerable fe, ModFile modFile, string fileName) { - return new(fe.header, fe.ienumerable.MatchFrom(modFile.GetCode(fileName).Split("\n"))); + try + { + return new(fe.header, fe.ienumerable.MatchFrom(modFile.GetCode(fileName).Split("\n"))); + } + catch (Exception ex) + { + ex.Data.Add("fileName", fe.header.fileName); + ex.Data.Add("patchingWay", fe.header.patchingWay); + throw; + } } /// /// A selector that tags the -th lines of code below a given list of string. @@ -540,7 +483,10 @@ public static string Collect(this FileEnumerable<(Match, string)> fe) if (!encounteredBlock) { - throw new Exception("MatchBelow: No matching lines found. Items to match: " + string.Join("\r\n", other)); + throw new InvalidOperationException( + string.Format("MatchBelow: No matching lines found. Items to match:\n{0}", + string.Join("\n", other)) + ); } } /// @@ -562,7 +508,16 @@ public static string Collect(this FileEnumerable<(Match, string)> fe) /// public static FileEnumerable<(Match, string)> MatchBelow(this FileEnumerable fe, ModFile modFile, string fileName, int len) { - return new(fe.header, fe.ienumerable.MatchBelow(modFile.GetCode(fileName).Split("\n"), len)); + try + { + return new(fe.header, fe.ienumerable.MatchBelow(modFile.GetCode(fileName).Split("\n"), len)); + } + catch (Exception ex) + { + ex.Data.Add("fileName", fe.header.fileName); + ex.Data.Add("patchingWay", fe.header.patchingWay); + throw; + } } /// /// A selector that tags the all lines of the input. @@ -612,6 +567,7 @@ public static string Collect(this FileEnumerable<(Match, string)> fe) if (otherUntilEnumerator.MoveNext()) otherUntilString = otherUntilEnumerator.Current; + foreach ((Match m, string element) in ienumerable.MatchFrom(otherfrom)) { if (m == Match.Before || m == Match.Matching) @@ -664,7 +620,16 @@ public static string Collect(this FileEnumerable<(Match, string)> fe) /// public static FileEnumerable<(Match, string)> MatchFromUntil(this FileEnumerable fe, ModFile modFile, string filenameOther, string filenameUntil) { - return new(fe.header, fe.ienumerable.MatchFromUntil(modFile.GetCode(filenameOther).Split("\n"), modFile.GetCode(filenameUntil).Split("\n"))); + try + { + return new(fe.header, fe.ienumerable.MatchFromUntil(modFile.GetCode(filenameOther).Split("\n"), modFile.GetCode(filenameUntil).Split("\n"))); + } + catch (Exception ex) + { + ex.Data.Add("fileName", fe.header.fileName); + ex.Data.Add("patchingWay", fe.header.patchingWay); + throw; + } } /// /// An action on an IEnumerable that prints each line on the log console but does not alter the data flow. @@ -827,7 +792,16 @@ public static FileEnumerable InsertBelow(this FileEnumerable<(Match, str /// public static FileEnumerable InsertBelow(this FileEnumerable<(Match, string)> fe, ModFile modFile, string fileName) { - return new(fe.header, fe.ienumerable.InsertBelow(modFile.GetCode(fileName).Split("\n"))); + try + { + return new(fe.header, fe.ienumerable.InsertBelow(modFile.GetCode(fileName).Split("\n"))); + } + catch (Exception ex) + { + ex.Data.Add("fileName", fe.header.fileName); + ex.Data.Add("patchingWay", fe.header.patchingWay); + throw; + } } /// /// An action on an IEnumerable that inserts lines of code above the Matching block. @@ -875,7 +849,16 @@ public static FileEnumerable InsertAbove(this FileEnumerable<(Match, str /// public static FileEnumerable InsertAbove(this FileEnumerable<(Match, string)> fe, ModFile modFile, string fileName) { - return new(fe.header, fe.ienumerable.InsertAbove(modFile.GetCode(fileName).Split("\n"))); + try + { + return new(fe.header, fe.ienumerable.InsertAbove(modFile.GetCode(fileName).Split("\n"))); + } + catch (Exception ex) + { + ex.Data.Add("fileName", fe.header.fileName); + ex.Data.Add("patchingWay", fe.header.patchingWay); + throw; + } } /// /// An action on an IEnumerable that replace the Matching block with the lines given. @@ -929,7 +912,16 @@ public static FileEnumerable ReplaceBy(this FileEnumerable<(Match, strin /// public static FileEnumerable ReplaceBy(this FileEnumerable<(Match, string)> fe, ModFile modFile, string fileName) { - return new(fe.header, fe.ienumerable.ReplaceBy(modFile.GetCode(fileName).Split("\n"))); + try + { + return new(fe.header, fe.ienumerable.ReplaceBy(modFile.GetCode(fileName).Split("\n"))); + } + catch (Exception ex) + { + ex.Data.Add("fileName", fe.header.fileName); + ex.Data.Add("patchingWay", fe.header.patchingWay); + throw; + } } /// /// Apply an to an . @@ -975,15 +967,17 @@ public static ModSummary Save(this FileEnumerable fe) default: break; } - Log.Information("Successfully patched function {{{0}}} with {{{1}}}", fe.header.fileName, fe.header.patchingWay.ToString()); + Log.Information("Successfully patched function {{{0}}} with {{{1}}}", fe.header.fileName, fe.header.patchingWay); return new( fe.header.fileName, newCode, fe.header.patchingWay ); } - catch + catch (Exception ex) { + ex.Data.Add("fileName", fe.header.fileName); + ex.Data.Add("patchingWay", fe.header.patchingWay); throw; } } diff --git a/ModUtils/EventUtils.cs b/ModUtils/EventUtils.cs index cf6b8bd..ab241f7 100644 --- a/ModUtils/EventUtils.cs +++ b/ModUtils/EventUtils.cs @@ -42,14 +42,7 @@ public MslEvent(string code, EventType eventType, uint subtype) /// public void Apply(string objectName, ModFile modFile) { - try - { - Msl.AddNewEvent(objectName, modFile.GetCode(Code), EventType, Subtype); - } - catch - { - throw; - } + Msl.AddNewEvent(objectName, modFile.GetCode(Code), EventType, Subtype); } /// /// Given a , load the source code of the event and add it in the data.win through the function. @@ -58,14 +51,7 @@ public void Apply(string objectName, ModFile modFile) /// public void Apply(UndertaleGameObject gameObject, ModFile modFile) { - try - { - Msl.AddNewEvent(gameObject, modFile.GetCode(Code), EventType, Subtype); - } - catch - { - throw; - } + Msl.AddNewEvent(gameObject, modFile.GetCode(Code), EventType, Subtype); } /// /// Given an named , load the source code of the event and add it in the data.win through the function. @@ -74,14 +60,7 @@ public void Apply(UndertaleGameObject gameObject, ModFile modFile) /// public void Apply(string objectName) { - try - { - Msl.AddNewEvent(objectName, Code, EventType, Subtype); - } - catch - { - throw; - } + Msl.AddNewEvent(objectName, Code, EventType, Subtype); } /// /// Given a , load the source code of the event and add it in the data.win through the function. @@ -90,14 +69,7 @@ public void Apply(string objectName) /// public void Apply(UndertaleGameObject objectName) { - try - { - Msl.AddNewEvent(objectName, Code, EventType, Subtype); - } - catch - { - throw; - } + Msl.AddNewEvent(objectName, Code, EventType, Subtype); } } public static partial class Msl @@ -137,43 +109,35 @@ public static void AddNewEvent(string objectName, string eventCode, EventType ev /// public static void AddNewEvent(string objectName, string eventCode, EventType eventType, uint subtype, bool asAsm = false) { - try + CheckSubEvent(eventType, subtype); + // find the object + UndertaleGameObject gameObject = GetObject(objectName); + // check if the subEvent already exists + Event? subtypeObj = gameObject.Events[(int)eventType].FirstOrDefault(x => x.EventSubtype == subtype); + if (subtypeObj != null) { - CheckSubEvent(eventType, subtype); - // find the object - UndertaleGameObject gameObject = GetObject(objectName); - // check if the subEvent already exists - Event? subtypeObj = gameObject.Events[(int)eventType].FirstOrDefault(x => x.EventSubtype == subtype); - if (subtypeObj != null) - { - throw new ArgumentException(string.Format("Cannot add the event {0}_{1} in {2} since it already exists", eventType, subtype, objectName)); - } + throw new ArgumentException(string.Format("Cannot add the event {0}_{1} in {2} since it already exists", eventType, subtype, objectName)); + } - // create a new code - string newEventName = EventName(objectName, eventType, subtype); - if (asAsm) - { - AddCodeAsm(eventCode, newEventName); - } - else - { - AddCode(eventCode, newEventName); - } - // add the previous code to the event - Event newEvent = new() { EventSubtype = subtype }; - newEvent.Actions.Add(new EventAction() - { - CodeId = GetUMTCodeFromFile(newEventName), - }); - - gameObject.Events[(int)eventType].Add(newEvent); - Log.Information(string.Format("Successfully added event {{{0}_{1}}} in object {{{2}}}", eventType, subtype, objectName)); + // create a new code + string newEventName = EventName(objectName, eventType, subtype); + if (asAsm) + { + AddCodeAsm(eventCode, newEventName); } - catch(Exception ex) + else { - Log.Error(ex, "Something went wrong"); - throw; + AddCode(eventCode, newEventName); } + // add the previous code to the event + Event newEvent = new() { EventSubtype = subtype }; + newEvent.Actions.Add(new EventAction() + { + CodeId = GetUMTCodeFromFile(newEventName), + }); + + gameObject.Events[(int)eventType].Add(newEvent); + Log.Information("Successfully added event {{{0}_{1}}} in object {{{2}}}", eventType, subtype, objectName); } /// /// Add a new event (, ) associated to a . @@ -185,14 +149,7 @@ public static void AddNewEvent(string objectName, string eventCode, EventType ev /// public static void AddNewEvent(UndertaleGameObject objectName, string eventCode, EventType eventType, uint subtype) { - try - { - AddNewEvent(objectName, eventCode, eventType, subtype, false); - } - catch - { - throw; - } + AddNewEvent(objectName, eventCode, eventType, subtype, false); } /// /// Add a new event (, ) associated to a . @@ -204,42 +161,34 @@ public static void AddNewEvent(UndertaleGameObject objectName, string eventCode, /// public static void AddNewEvent(UndertaleGameObject gameObject, string eventCode, EventType eventType, uint subtype, bool asAsm = false) { - try + CheckSubEvent(eventType, subtype); + // check if the subEvent already exists + Event? subtypeObj = gameObject.Events[(int)eventType].FirstOrDefault(x => x.EventSubtype == subtype); + if (subtypeObj != null) { - CheckSubEvent(eventType, subtype); - // check if the subEvent already exists - Event? subtypeObj = gameObject.Events[(int)eventType].FirstOrDefault(x => x.EventSubtype == subtype); - if (subtypeObj != null) - { - throw new ArgumentException(string.Format("Cannot add the event {0}_{1} in {2} since it already exists", eventType, subtype, gameObject.Name.Content)); - } + throw new ArgumentException(string.Format("Cannot add the event {0}_{1} in {2} since it already exists", eventType, subtype, gameObject.Name.Content)); + } - // create a new code - string newEventName = EventName(gameObject.Name.Content, eventType, subtype); + // create a new code + string newEventName = EventName(gameObject.Name.Content, eventType, subtype); - if (asAsm) - { - AddCodeAsm(eventCode, newEventName); - } - else - { - AddCode(eventCode, newEventName); - } - // add the previous code to the event - Event newEvent = new() { EventSubtype = subtype }; - newEvent.Actions.Add(new EventAction() - { - CodeId = GetUMTCodeFromFile(newEventName), - }); - - gameObject.Events[(int)eventType].Add(newEvent); - Log.Information(string.Format("Successfully added event {{{0}_{1}}} in object {{{2}}}", eventType, subtype, gameObject.Name.Content)); + if (asAsm) + { + AddCodeAsm(eventCode, newEventName); } - catch(Exception ex) + else { - Log.Error(ex, "Something went wrong"); - throw; + AddCode(eventCode, newEventName); } + // add the previous code to the event + Event newEvent = new() { EventSubtype = subtype }; + newEvent.Actions.Add(new EventAction() + { + CodeId = GetUMTCodeFromFile(newEventName), + }); + + gameObject.Events[(int)eventType].Add(newEvent); + Log.Information("Successfully added event {{{0}_{1}}} in object {{{2}}}", eventType, subtype, gameObject.Name.Content); } /// /// Check if the combination and are correct. Raise an exception if not. diff --git a/ModUtils/GeneralUtils.cs b/ModUtils/GeneralUtils.cs index 983434e..75ea566 100644 --- a/ModUtils/GeneralUtils.cs +++ b/ModUtils/GeneralUtils.cs @@ -17,46 +17,30 @@ public static partial class Msl { public static FileEnumerable LoadGML(string fileName) { - try - { - UndertaleCode code = GetUMTCodeFromFile(fileName); - GlobalDecompileContext context = new(ModLoader.Data, false); + UndertaleCode code = GetUMTCodeFromFile(fileName); + GlobalDecompileContext context = new(ModLoader.Data, false); - return new( - new( - fileName, - code, - PatchingWay.GML - ), - Decompiler.Decompile(code, context).Split("\n") - ); - } - catch(Exception ex) - { - Log.Error(ex, "Something went wrong"); - throw; - } + return new( + new( + fileName, + code, + PatchingWay.GML + ), + Decompiler.Decompile(code, context).Split("\n") + ); } public static FileEnumerable LoadAssemblyAsString(string fileName) { - try - { - UndertaleCode code = GetUMTCodeFromFile(fileName); + UndertaleCode code = GetUMTCodeFromFile(fileName); - return new( - new( - fileName, - code, - PatchingWay.AssemblyAsString - ), - code.Disassemble(ModLoader.Data.Variables, ModLoader.Data.CodeLocals.For(code)).Split("\n") - ); - } - catch(Exception ex) - { - Log.Error(ex, "Something went wrong"); - throw; - } + return new( + new( + fileName, + code, + PatchingWay.AssemblyAsString + ), + code.Disassemble(ModLoader.Data.Variables, ModLoader.Data.CodeLocals.For(code)).Split("\n") + ); } /// /// Equivalent of enumerate found in Python but for C# IEnumerable. @@ -106,10 +90,10 @@ public static FileEnumerable LoadAssemblyAsString(string fileName) public static void LogInstruction(UndertaleInstruction instruction) { try { - Log.Information(string.Format(@"{{{0}}}: - ( - .Address = {10}, - .JumpOffset = {11}, + Log.Information(@"{{{0}}}: + ( + .Address = {10}, + .JumpOffset = {11}, .Kind = {1}, .ComparisonKind = {8}, .Type1 = {2}, @@ -121,12 +105,12 @@ public static void LogInstruction(UndertaleInstruction instruction) .ArgumentsCount = {9}, ) ", - instruction.ToString(), - instruction.Kind.ToString(), - instruction.Type1.ToString(), - instruction.Type2.ToString(), - instruction.TypeInst.ToString(), - (instruction.Destination != null) ? + instruction, + instruction.Kind, + instruction.Type1, + instruction.Type2, + instruction.TypeInst, + (instruction.Destination != null) ? string.Format(@"( .Type = {0}, .Target = ( .Name = {1}, .InstanceType = {2}, ), @@ -135,7 +119,7 @@ public static void LogInstruction(UndertaleInstruction instruction) instruction.Destination?.Target.Name.ToString(), instruction.Destination?.Target.InstanceType.ToString()) : "", - (instruction.Value is UndertaleInstruction.Reference) ? + (instruction.Value is UndertaleInstruction.Reference) ? string.Format(@"( .Type = {0}, .Target = ( .Name = {1}, .InstanceType = {2}, ), @@ -144,8 +128,7 @@ public static void LogInstruction(UndertaleInstruction instruction) (instruction.Value as UndertaleInstruction.Reference)?.Target.Name.ToString(), (instruction.Value as UndertaleInstruction.Reference)?.Target.InstanceType.ToString()) : instruction.Value?.ToString() ?? "", - - (instruction.Function != null) ? + (instruction.Function != null) ? string.Format(@"( .Type = {0}, .Target = ( .Name = {1}, .Classification = {2}, ), @@ -154,14 +137,14 @@ public static void LogInstruction(UndertaleInstruction instruction) instruction.Function?.Target.Name.ToString(), instruction.Function?.Target.Classification.ToString()) : "", - instruction.ComparisonKind.ToString(), - instruction.ArgumentsCount.ToString(), - instruction.Address.ToString(), - instruction.JumpOffset.ToString() - )); + instruction.ComparisonKind, + instruction.ArgumentsCount, + instruction.Address, + instruction.JumpOffset + ); } catch(Exception ex) { - Log.Error(ex, string.Format("Cannot log {0}", instruction.ToString())); + Log.Error(ex, "Cannot log {0}", instruction); throw; } @@ -175,7 +158,7 @@ public static T ThrowIfNull( { if (argument is null) { - Log.Error(string.Format("{0} is null.", argument)); + Log.Error("{0} is null.", argument); throw new ArgumentNullException(paramName, message); } else @@ -191,7 +174,7 @@ public static T ThrowIfNull( { if (argument is null) { - Log.Error(string.Format("{0} is null.", argument)); + Log.Error("{0} is null.", argument); throw new ArgumentNullException(paramName, message); } else @@ -215,20 +198,20 @@ public static void GenerateNRandomLinesFromCode(IList code, Globa { try { - Log.Information(invalid.ToString()); + Log.Information("{0}", invalid); // we encounter an error since we can't decompile a nested function // the error message indicates where to look instead // but you need to parse the message to retrieve the needed code // "This code block represents a function nested inside " + code.ParentEntry.Name + " - decompile that instead" string name = invalid.Message.Split('\"')[1]; - Log.Information(string.Format("Looking for {{{0}}} instead", name)); + Log.Information("Looking for {{{0}}} instead", name); s.AddRange(Decompiler.Decompile(code.First(x => x.Name.Content == name), context).Split('\n').SelectionSamplingTechnique(numberLinesByCode)); } // not all code can be decompiled sadly catch { string name = invalid.Message.Split('\"')[1]; - Log.Information(string.Format("Cannot decompile {{{0}}}, skipping that file", name)); + Log.Information("Cannot decompile {{{0}}}, skipping that file", name); continue; } diff --git a/ModUtils/HookUtils.cs b/ModUtils/HookUtils.cs index 90b14c7..79d9214 100644 --- a/ModUtils/HookUtils.cs +++ b/ModUtils/HookUtils.cs @@ -18,20 +18,12 @@ public static partial class Msl /// All the things you want to get. public static void HookFunction(string functionName, string hookName, params string[] paramNames) { - try - { - Log.Information(string.Format("Trying add hook in: {0}", functionName)); + Log.Information("Trying add hook in: {0}", functionName); - List? originalCode = GetStringGMLFromFile(functionName).Split("\n").ToList(); - originalCode.Append($"var {hookName} = createHookObj({paramNames.Length}, {string.Join(", ", paramNames)})"); - originalCode.Append($"SendMsg(\"HOK\", \"{hookName}\" + {hookName}, false)"); - SetStringGMLInFile(string.Join("\n", originalCode), functionName); - } - catch (Exception ex) - { - Log.Error(ex, "Something went wrong"); - throw; - } + List? originalCode = GetStringGMLFromFile(functionName).Split("\n").ToList(); + originalCode.Append($"var {hookName} = createHookObj({paramNames.Length}, {string.Join(", ", paramNames)})"); + originalCode.Append($"SendMsg(\"HOK\", \"{hookName}\" + {hookName}, false)"); + SetStringGMLInFile(string.Join("\n", originalCode), functionName); } } } diff --git a/ModUtils/LootUtils.cs b/ModUtils/LootUtils.cs index ed2a824..3ef10db 100644 --- a/ModUtils/LootUtils.cs +++ b/ModUtils/LootUtils.cs @@ -82,15 +82,22 @@ public static void ResetLootTables() } public static void SaveLootTables(string DirPath) { - if (LootTables.Count > 0) + try { - File.WriteAllText(Path.Combine(DirPath, "loot_table.json"), JsonConvert.SerializeObject(LootTables)); - Log.Information("Successfully saving the loot table json."); + if (LootTables.Count > 0) + { + File.WriteAllText(Path.Combine(DirPath, "loot_table.json"), JsonConvert.SerializeObject(LootTables)); + Log.Information("Successfully saving the loot table json."); + } + if (ReferenceTables.Count > 0) + { + File.WriteAllText(Path.Combine(DirPath, "reference_table.json"), JsonConvert.SerializeObject(ReferenceTables)); + Log.Information("Successfully saving the reference table json."); + } } - if (ReferenceTables.Count > 0) + catch (Exception ex) { - File.WriteAllText(Path.Combine(DirPath, "reference_table.json"), JsonConvert.SerializeObject(ReferenceTables)); - Log.Information("Successfully saving the reference table json."); + Log.Error(ex, "Saving Loot table failed for {0}", DirPath); } } public static void InjectLootScripts() diff --git a/ModUtils/ModMenuUtils.cs b/ModUtils/ModMenuUtils.cs index ae5f6ab..146b2fb 100644 --- a/ModUtils/ModMenuUtils.cs +++ b/ModUtils/ModMenuUtils.cs @@ -34,7 +34,7 @@ public UIComponent(string name, string associatedGlobal, UIComponentType compome { case UIComponentType.ComboBox: case UIComponentType.Slider: - Log.Error($"Incorrect use of UIComponent, you cannot define a {compomentType} using these parameters."); + Log.Error("Incorrect use of UIComponent, you cannot define a {0} using these parameters.", compomentType); throw new ValueUnavailableException(); default: @@ -52,7 +52,7 @@ public UIComponent(string name, string associatedGlobal, UIComponentType compome { case UIComponentType.CheckBox: case UIComponentType.Slider: - Log.Error($"Incorrect use of UIComponent, you cannot define a {compomentType} using these parameters."); + Log.Error("Incorrect use of UIComponent, you cannot define a {0} using these parameters.", compomentType); throw new ValueUnavailableException(); default: @@ -71,7 +71,7 @@ public UIComponent(string name, string associatedGlobal, UIComponentType compome { case UIComponentType.CheckBox: case UIComponentType.ComboBox: - Log.Error($"Incorrect use of UIComponent, you cannot define a {compomentType} using these parameters."); + Log.Error("Incorrect use of UIComponent, you cannot define a {0} using these parameters.", compomentType); throw new ValueUnavailableException(); default: diff --git a/ModUtils/ObjectUtils.cs b/ModUtils/ObjectUtils.cs index 57197ea..bb34005 100644 --- a/ModUtils/ObjectUtils.cs +++ b/ModUtils/ObjectUtils.cs @@ -101,7 +101,7 @@ public static UndertaleGameObject AddObject( UndertaleGameObject? existingObj = ModLoader.Data.GameObjects.FirstOrDefault(t => t.Name.Content == name); if(existingObj != null) { - Log.Information(string.Format("Cannot create the GameObject since it already exists: {0}", name.ToString())); + Log.Information("Cannot create the GameObject since it already exists: {0}", name); return existingObj; } @@ -123,7 +123,7 @@ public static UndertaleGameObject AddObject( Awake = isAwake, }; ModLoader.Data.GameObjects.Add(obj); - Log.Information(string.Format("Successfully created gameObject: {0}", name.ToString())); + Log.Information("Successfully created gameObject: {0}", name); return obj; } catch @@ -138,16 +138,9 @@ public static UndertaleGameObject AddObject( /// public static UndertaleGameObject GetObject(string name) { - try - { - UndertaleGameObject gameObject = ModLoader.Data.GameObjects.First(t => t.Name.Content == name); - Log.Information(string.Format("Found gameObject: {0}", name.ToString())); - return gameObject; - } - catch - { - throw; - } + UndertaleGameObject gameObject = ModLoader.Data.GameObjects.First(t => t.Name.Content == name); + Log.Information("Found gameObject: {0}", name); + return gameObject; } /// /// Replace the named by . @@ -157,17 +150,9 @@ public static UndertaleGameObject GetObject(string name) /// public static void SetObject(string name, UndertaleGameObject o) { - try - { - (int indexObj, _) = ModLoader.Data.GameObjects.Enumerate().First(t => t.Item2.Name.Content == name); - ModLoader.Data.GameObjects[indexObj] = o; - Log.Information(string.Format("Successfully replaced gameObject: {0}", name.ToString())); - } - catch(Exception ex) - { - Log.Error(ex, "Something went wrong"); - throw; - } + (int indexObj, _) = ModLoader.Data.GameObjects.Enumerate().First(t => t.Item2.Name.Content == name); + ModLoader.Data.GameObjects[indexObj] = o; + Log.Information("Successfully replaced gameObject: {0}", name); } } } \ No newline at end of file diff --git a/ModUtils/RoomUtils.cs b/ModUtils/RoomUtils.cs index 148b4e7..3072984 100644 --- a/ModUtils/RoomUtils.cs +++ b/ModUtils/RoomUtils.cs @@ -25,7 +25,7 @@ public static void AddRoomJson(string jsonString) { UndertaleRoom newRoom = new UndertaleRoom(); - Log.Information($"A room is being added or edited"); + Log.Information("A room is being added or edited"); byte[] jsonUtf8Bytes = Encoding.UTF8.GetBytes(jsonString); JsonReaderOptions options = new JsonReaderOptions @@ -52,7 +52,7 @@ public static void AddRoomJson(string jsonString) if (ModLoader.Data.Rooms.ByName(newRoom.Name.Content) == null) ModLoader.Data.Rooms.Add(newRoom); - Log.Information($"Successfully created room {newRoom.Name}."); + Log.Information("Successfully created room {0}.", newRoom.Name); } #region AddRoomJson @@ -742,12 +742,12 @@ public static UndertaleRoom GetRoom(string name) try { UndertaleRoom room = ModLoader.Data.Rooms.First(t => t.Name.Content == name); - Log.Information($"Found room {name}"); + Log.Information("Found room {0}", name); return room; } catch { - Log.Error($"Cannot find room {name}."); + Log.Error("Cannot find room {0}.", name); throw; } } @@ -762,12 +762,12 @@ public static UndertaleRoom AddRoom(string name) Flags = UndertaleRoom.RoomEntryFlags.IsGMS2 ^ UndertaleRoom.RoomEntryFlags.EnableViews, }; ModLoader.Data.Rooms.Add(room); - Log.Information($"Successfully created room {name}."); + Log.Information("Successfully created room {0}.", name); return room; } catch { - Log.Error($"Cannot add Room {name} since it already exists."); + Log.Error("Cannot add Room {0} since it already exists.", name); throw; } } @@ -858,7 +858,7 @@ public static UndertaleRoom AddRoom(string name, uint width, uint height) } newLayer.ParentRoom = room; - Log.Information($"Successfully created layer {name} of type {type} in room {room.Name}."); + Log.Information("Successfully created layer {0} of type {1} in room {2}.", name, type, room.Name); return newLayer; } public static UndertaleRoom.Layer AddLayer(this UndertaleRoom room, UndertaleRoom.LayerType type, string name) where T : UndertaleRoom.Layer.LayerData, new() @@ -878,12 +878,12 @@ public static UndertaleRoom.Layer GetLayer(this UndertaleRoom room, UndertaleRoo try { UndertaleRoom.Layer layer = room.Layers.First(t => t.LayerName.Content == name && t.LayerType == type); - Log.Information($"Found layer {name} of type {type} in room {room.Name}."); + Log.Information("Found layer {0} of type {1} in room {2}.", name, type, room.Name); return layer; } catch { - Log.Error($"Cannot find layer {name} of type {type} in room {room.Name}."); + Log.Error("Cannot find layer {0} of type {1} in room {2}.", name, type, room.Name); throw; } } @@ -904,12 +904,12 @@ public static UndertaleRoom.GameObject AddGameObject(this UndertaleRoom room, st room.GameObjects.Add(gameObject); room.GetLayer(UndertaleRoom.LayerType.Instances, layerName).InstancesData.Instances.Add(gameObject); - Log.Information($"Successfully created gameobject {obName} in layer {layerName} in room {room.Name}"); + Log.Information("Successfully created gameobject {0} in layer {1} in room {2}", obName, layerName, room.Name); return gameObject; } catch { - Log.Error($"Cannot add the gameobject {obName} in layer {layerName} in room {room.Name}."); + Log.Error("Cannot add the gameobject {0} in layer {1} in room {2}.", obName, layerName, room.Name); throw; } } @@ -930,12 +930,12 @@ public static UndertaleRoom.GameObject AddGameObject(this UndertaleRoom room, Un room.GameObjects.Add(gameObject); layer.InstancesData.Instances.Add(gameObject); - Log.Information($"Successfully created gameobject {obName} in layer {layer.LayerName} in room {room.Name}"); + Log.Information("Successfully created gameobject {0} in layer {1} in room {2}", obName, layer.LayerName, room.Name); return gameObject; } catch { - Log.Error($"Cannot add the gameobject {obName} in layer {layer.LayerName} in room {room.Name}."); + Log.Error("Cannot add the gameobject {0} in layer {1} in room {2}.", obName, layer.LayerName, room.Name); throw; } } @@ -955,12 +955,12 @@ public static UndertaleRoom.GameObject AddGameObject(this UndertaleRoom room, st room.GameObjects.Add(gameObject); room.GetLayer(UndertaleRoom.LayerType.Instances, layerName).InstancesData.Instances.Add(gameObject); - Log.Information($"Successfully created gameobject {ob.Name} in layer {layerName} in room {room.Name}"); + Log.Information("Successfully created gameobject {0} in layer {1} in room {2}", ob.Name, layerName, room.Name); return gameObject; } catch { - Log.Error($"Cannot add the gameobject {ob.Name} in layer {layerName} in room {room.Name}."); + Log.Error("Cannot add the gameobject {0} in layer {1} in room {2}.", ob.Name, layerName, room.Name); throw; } } @@ -980,12 +980,12 @@ public static UndertaleRoom.GameObject AddGameObject(this UndertaleRoom room, Un room.GameObjects.Add(gameObject); layer.InstancesData.Instances.Add(gameObject); - Log.Information($"Successfully created gameobject {ob.Name} in layer {layer.LayerName} in room {room.Name}"); + Log.Information("Successfully created gameobject {0} in layer {1} in room {2}", ob.Name, layer.LayerName, room.Name); return gameObject; } catch { - Log.Error($"Cannot add the gameobject {ob.Name} in layer {layer.LayerName} in room {room.Name}."); + Log.Error("Cannot add the gameobject {0} in layer {1} in room {2}.", ob.Name, layer.LayerName, room.Name); throw; } } @@ -994,12 +994,12 @@ public static UndertaleRoom.GameObject GetGameObject(this UndertaleRoom room, st try { UndertaleRoom.GameObject go = room.GetLayer(UndertaleRoom.LayerType.Instances, layerName).InstancesData.Instances.First(t => t.ObjectDefinition.Name.Content == obName); - Log.Information($"Found GameObject {obName} in layer {layerName} in room {room.Name}"); + Log.Information("Found GameObject {0} in layer {1} in room {2}", obName, layerName, room.Name); return go; } catch { - Log.Error($"Cannot find instance of gameobject {obName} in layer {layerName} in room {room.Name}."); + Log.Error("Cannot find instance of gameobject {0} in layer {1} in room {2}.", obName, layerName, room.Name); throw; } } diff --git a/ModUtils/TableUtils/Backers.cs b/ModUtils/TableUtils/Backers.cs index 1c90c36..8ad027c 100644 --- a/ModUtils/TableUtils/Backers.cs +++ b/ModUtils/TableUtils/Backers.cs @@ -19,6 +19,6 @@ public static void InjectTableBackers(string? name = null, string? nickname = nu // Add line to table table.Add(newline); ModLoader.SetTable(table, tableName); - Log.Information($"Injected {name}:{nickname} into {tableName} table."); + Log.Information("Injected {0}:{1} into {2} table.", name, nickname, tableName); } } \ No newline at end of file diff --git a/ModUtils/TableUtils/ContractsStats.cs b/ModUtils/TableUtils/ContractsStats.cs index ff378e8..18a9fa7 100644 --- a/ModUtils/TableUtils/ContractsStats.cs +++ b/ModUtils/TableUtils/ContractsStats.cs @@ -66,11 +66,11 @@ float k { table.Insert(ind + 1, newline); ModLoader.SetTable(table, tableName); - Log.Information($"Injected contract {id} into {tableName}"); + Log.Information("Injected contract {0} into {1}", id, tableName); } else { - Log.Error($"Hook not found in {tableName}. {id} was not injected."); + Log.Error("Hook not found in {0}. {1} was not injected.", tableName, id); throw new Exception($"Hook not found in {tableName}. {id} was not injected."); } } diff --git a/ModUtils/TableUtils/Drops.cs b/ModUtils/TableUtils/Drops.cs index 0506d62..b97bef0 100644 --- a/ModUtils/TableUtils/Drops.cs +++ b/ModUtils/TableUtils/Drops.cs @@ -137,11 +137,11 @@ public static void InjectTableDrops( { table.Insert(ind + 1, newline); ModLoader.SetTable(table, tableName); - Log.Information($"Injected Drop {id} into table {tableName} under {hook}"); + Log.Information("Injected Drop {0} into table {1} under {2}", id, tableName, hook); } else { - Log.Error($"Cannot find hook {hook} in table {tableName}"); + Log.Error("Cannot find hook {0} in table {1}", hook, tableName); throw new Exception($"Cannot find hook {hook} in table {tableName}"); } } diff --git a/ModUtils/TableUtils/DungeonsSpawn.cs b/ModUtils/TableUtils/DungeonsSpawn.cs index ee1715c..1cad658 100644 --- a/ModUtils/TableUtils/DungeonsSpawn.cs +++ b/ModUtils/TableUtils/DungeonsSpawn.cs @@ -83,11 +83,11 @@ public static void InjectTableDungeonsSpawn( { table.Insert(ind + 1, newline); ModLoader.SetTable(table, tableName); - Log.Information($"Injected Dungeon Spawn {id} into {tableName} under {hook}"); + Log.Information("Injected Dungeon Spawn {0} into {1} under {2}", id, tableName, hook); } else { - Log.Error($"Cannot find Hook {hook} in table {tableName}"); + Log.Error("Cannot find Hook {0} in table {1}", hook, tableName); throw new Exception($"Hook {hook} not found in table {tableName}"); } } diff --git a/ModUtils/TableUtils/MobsStats.cs b/ModUtils/TableUtils/MobsStats.cs index 725a6be..2566900 100644 --- a/ModUtils/TableUtils/MobsStats.cs +++ b/ModUtils/TableUtils/MobsStats.cs @@ -251,6 +251,6 @@ public static void InjectTableMobsStats( // Add line to table table.Add(newline); ModLoader.SetTable(table, tableName); - Log.Information($"Injected Mob Stat {name} into table"); + Log.Information("Injected Mob Stat {0} into table", name); } } \ No newline at end of file diff --git a/ModUtils/TableUtils/PotionsStats.cs b/ModUtils/TableUtils/PotionsStats.cs index eb10733..9230e9d 100644 --- a/ModUtils/TableUtils/PotionsStats.cs +++ b/ModUtils/TableUtils/PotionsStats.cs @@ -33,6 +33,6 @@ public static void InjectTablePotionsStats(string name, string effectScript, par // Add line to end of table table.Add(newline); ModLoader.SetTable(table, tableName); - Log.Information($"Injected {name} into {tableName} table."); + Log.Information("Injected {0} into {1} table.", name, tableName); } } \ No newline at end of file diff --git a/ModUtils/TableUtils/RecipesCook.cs b/ModUtils/TableUtils/RecipesCook.cs index 50761b6..b36ae52 100644 --- a/ModUtils/TableUtils/RecipesCook.cs +++ b/ModUtils/TableUtils/RecipesCook.cs @@ -86,11 +86,11 @@ public static void InjectTableRecipesCook( { table.Insert(ind + 1, newline); ModLoader.SetTable(table, tableName); - Log.Information($"Injected Armor {NAME} into table {tableName} under {hook}"); + Log.Information("Injected Armor {0} into table {1} under {2}", NAME, tableName, hook); } else { - Log.Error($"Cannot find hook {hook} in table {tableName}"); + Log.Error("Cannot find hook {0} in table {1}", hook, tableName); throw new Exception($"Cannot find hook {hook} in table {tableName}"); } } diff --git a/ModUtils/TableUtils/RecipesCraft.cs b/ModUtils/TableUtils/RecipesCraft.cs index 6b6c48c..dd5964a 100644 --- a/ModUtils/TableUtils/RecipesCraft.cs +++ b/ModUtils/TableUtils/RecipesCraft.cs @@ -66,11 +66,11 @@ public static void InjectTableRecipesCraft( { table.Insert(ind + 1, newline); ModLoader.SetTable(table, tableName); - Log.Information($"Injected craft recipe {NAME} into {tableName} under {hook}"); + Log.Information("Injected craft recipe {0} into {1} under {2}", NAME, tableName, hook); } else { - Log.Error($"Cannot find hook {hook} in table {tableName}"); + Log.Error("Cannot find hook {0} in table {1}", hook, tableName); throw new Exception($"Hook {hook} not found in table {tableName}"); } } diff --git a/ModUtils/TableUtils/SkillsStats.cs b/ModUtils/TableUtils/SkillsStats.cs index c64e83f..93ca3f4 100644 --- a/ModUtils/TableUtils/SkillsStats.cs +++ b/ModUtils/TableUtils/SkillsStats.cs @@ -177,11 +177,11 @@ public static void InjectTableSkillsStats( { table.Insert(ind + 1, newline); ModLoader.SetTable(table, tableName); - Log.Information($"Injected Skill Stat {id} into {tableName} under {hook}"); + Log.Information("Injected Skill Stat {0} into {1} under {2}", id, tableName, hook); } else { - Log.Error($"Cannot find Hook {hook} in table {tableName}"); + Log.Error("Cannot find Hook {0} in table {1}", hook, tableName); throw new Exception($"Hook {hook} not found in table {tableName}"); } } diff --git a/ModUtils/TableUtils/SurfaceSpawn.cs b/ModUtils/TableUtils/SurfaceSpawn.cs index 02b4904..edf6a86 100644 --- a/ModUtils/TableUtils/SurfaceSpawn.cs +++ b/ModUtils/TableUtils/SurfaceSpawn.cs @@ -89,6 +89,6 @@ public static void InjectTableSurfaceSpawn( // Add line to table table.Add(newline); ModLoader.SetTable(table, tableName); - Log.Information($"Injected a Spawn into table {tableName}"); + Log.Information("Injected a Spawn into table {0}", tableName); } } \ No newline at end of file diff --git a/ModUtils/TableUtils/TableArmor.cs b/ModUtils/TableUtils/TableArmor.cs index c36ab27..80ff875 100644 --- a/ModUtils/TableUtils/TableArmor.cs +++ b/ModUtils/TableUtils/TableArmor.cs @@ -208,11 +208,11 @@ public static void InjectTableArmor( { table.Insert(ind + 1, newline); ModLoader.SetTable(table, tableName); - Log.Information($"Injected Armor {id} into table {tableName} under {hook}"); + Log.Information("Injected Armor {0} into table {1} under {2}", id, tableName, hook); } else { - Log.Error($"Cannot find hook {hook} in table {tableName}"); + Log.Error("Cannot find hook {0} in table {1}", hook, tableName); throw new Exception($"Cannot find hook {hook} in table {tableName}"); } } diff --git a/ModUtils/TableUtils/TableWeapons.cs b/ModUtils/TableUtils/TableWeapons.cs index 17eeba7..7c6432a 100644 --- a/ModUtils/TableUtils/TableWeapons.cs +++ b/ModUtils/TableUtils/TableWeapons.cs @@ -192,6 +192,6 @@ public static void InjectTableWeapons( // Add line to table table.Add(newline); ModLoader.SetTable(table, tableName); - Log.Information($"Injected Weapon {id} into table {tableName}"); + Log.Information("Injected Weapon {0} into table {1}", id, tableName); } } \ No newline at end of file diff --git a/ModUtils/TextureUtils.cs b/ModUtils/TextureUtils.cs index 589045a..76987f2 100644 --- a/ModUtils/TextureUtils.cs +++ b/ModUtils/TextureUtils.cs @@ -101,100 +101,58 @@ public static UndertaleSprite CreateSpriteNoCollisionMasks(string spriteName, Ma } public static UndertaleSprite GetSprite(string name) { - try - { - UndertaleSprite sprite = ModLoader.Data.Sprites.First(t => t.Name.Content == name); - Log.Information(string.Format("Found sprite: {0}", name.ToString())); - return sprite; - } - catch(Exception ex) - { - Log.Error(ex, "Something went wrong"); - throw; - } + UndertaleSprite sprite = ModLoader.Data.Sprites.First(t => t.Name.Content == name); + Log.Information("Found sprite: {0}", name); + return sprite; } public static UndertaleEmbeddedTexture GetEmbeddedTexture(string name) { - try - { - UndertaleEmbeddedTexture embeddedTexture = ModLoader.Data.EmbeddedTextures.First(t => t.Name.Content == name); - Log.Information(string.Format("Found embedded texture: {0}", name.ToString())); - return embeddedTexture; - } - catch(Exception ex) - { - Log.Error(ex, "Something went wrong"); - throw; - } + UndertaleEmbeddedTexture embeddedTexture = ModLoader.Data.EmbeddedTextures.First(t => t.Name.Content == name); + Log.Information("Found embedded texture: {0}", name); + return embeddedTexture; } public static UndertaleTexturePageItem GetTexturePageItem(string name) { - try - { - UndertaleTexturePageItem texturePageItem = ModLoader.Data.TexturePageItems.First(t => t.Name.Content == name); - Log.Information(string.Format("Found texture page item: {0}", name.ToString())); - return texturePageItem; - } - catch(Exception ex) - { - Log.Error(ex, "Something went wrong"); - throw; - } + UndertaleTexturePageItem texturePageItem = ModLoader.Data.TexturePageItems.First(t => t.Name.Content == name); + Log.Information("Found texture page item: {0}", name); + return texturePageItem; } public static string AddNewTexturePageItem(string embeddedTextureName, RectTexture source, RectTexture target, BoundingData bounding) { - try - { - UndertaleEmbeddedTexture embeddedTexture = GetEmbeddedTexture(embeddedTextureName); - - UndertaleTexturePageItem texturePageItem = CreateTexureItem( - embeddedTexture, - source, - target, - bounding - ); - ModLoader.Data.TexturePageItems.Add(texturePageItem); - Log.Information(string.Format("Successfully added a new texture from: {0}", embeddedTextureName.ToString())); - return texturePageItem.Name.Content; + UndertaleEmbeddedTexture embeddedTexture = GetEmbeddedTexture(embeddedTextureName); - } - catch(Exception ex) - { - Log.Error(ex, "Something went wrong"); - throw; - } + UndertaleTexturePageItem texturePageItem = CreateTexureItem( + embeddedTexture, + source, + target, + bounding + ); + ModLoader.Data.TexturePageItems.Add(texturePageItem); + Log.Information("Successfully added a new texture from: {0}", embeddedTextureName); + return texturePageItem.Name.Content; } public static string AddNewSprite(string spriteName, List texturePageItemNames, MarginData margin, OriginData origin, BoundingData bounding) { - try - { - UndertaleSprite newSprite = CreateSpriteNoCollisionMasks( - spriteName, - margin, - origin, - bounding - ); + UndertaleSprite newSprite = CreateSpriteNoCollisionMasks( + spriteName, + margin, + origin, + bounding + ); - IEnumerable texturePageItems = texturePageItemNames - .Select(x => GetTexturePageItem(x)) - .Select(x => new UndertaleSprite.TextureEntry(){ Texture = x }); + IEnumerable texturePageItems = texturePageItemNames + .Select(x => GetTexturePageItem(x)) + .Select(x => new UndertaleSprite.TextureEntry(){ Texture = x }); - foreach(UndertaleSprite.TextureEntry texturePageItem in texturePageItems) - { - newSprite.Textures.Add(texturePageItem); - } - - ModLoader.Data.Sprites.Add(newSprite); - - Log.Information(string.Format("Successfully added new sprite: {0}", newSprite.Name.Content)); - return newSprite.Name.Content; - - } - catch(Exception ex) + foreach(UndertaleSprite.TextureEntry texturePageItem in texturePageItems) { - Log.Error(ex, "Something went wrong"); - throw; + newSprite.Textures.Add(texturePageItem); } + + ModLoader.Data.Sprites.Add(newSprite); + + Log.Information("Successfully added new sprite: {0}", newSprite.Name.Content); + return newSprite.Name.Content; } } } \ No newline at end of file diff --git a/ModUtils/VariableUtils.cs b/ModUtils/VariableUtils.cs index 85df9d1..5eb2828 100644 --- a/ModUtils/VariableUtils.cs +++ b/ModUtils/VariableUtils.cs @@ -9,31 +9,17 @@ public static partial class Msl { public static UndertaleVariable GetVariable(string name) { - try - { - UndertaleVariable variable = ModLoader.Data.Variables.First(t => t.Name?.Content == name); - Log.Information(string.Format("Found variable: {0}", variable.ToString())); + UndertaleVariable variable = ModLoader.Data.Variables.First(t => t.Name?.Content == name); + Log.Information("Found variable: {0}", variable); - return variable; - } - catch(Exception ex) { - Log.Error(ex, "Something went wrong"); - throw; - } + return variable; } public static UndertaleString GetString(string name) { - try - { - UndertaleString variable = ModLoader.Data.Strings.First(t => t.Content == name); - Log.Information(string.Format("Found string: {0}", variable.ToString())); + UndertaleString variable = ModLoader.Data.Strings.First(t => t.Content == name); + Log.Information("Found string: {0}", variable); - return variable; - } - catch(Exception ex) { - Log.Error(ex, "Something went wrong"); - throw; - } + return variable; } } } \ No newline at end of file diff --git a/ModUtils/WeaponUtils.cs b/ModUtils/WeaponUtils.cs index 99a9947..de08d73 100644 --- a/ModUtils/WeaponUtils.cs +++ b/ModUtils/WeaponUtils.cs @@ -10,64 +10,48 @@ public static partial class Msl { public static Weapon GetWeapon(string id) { - try - { - string weaponsName = ModLoader.Weapons.First(t => t.StartsWith(id)); + string weaponsName = ModLoader.Weapons.First(t => t.StartsWith(id)); - // for a lazy evaluation to avoid going through all the WeaponDescriptions list - IEnumerator weaponDescriptionEnumerator = ModLoader.WeaponDescriptions.Where(t => t.StartsWith(id)).GetEnumerator(); + // for a lazy evaluation to avoid going through all the WeaponDescriptions list + IEnumerator weaponDescriptionEnumerator = ModLoader.WeaponDescriptions.Where(t => t.StartsWith(id)).GetEnumerator(); - // getting the first element - the localization name - weaponDescriptionEnumerator.MoveNext(); - List localizationNames = weaponDescriptionEnumerator.Current.Split(";").ToList(); - localizationNames.Remove(""); - localizationNames.RemoveAt(0); + // getting the first element - the localization name + weaponDescriptionEnumerator.MoveNext(); + List localizationNames = weaponDescriptionEnumerator.Current.Split(";").ToList(); + localizationNames.Remove(""); + localizationNames.RemoveAt(0); - // getting the second element - the description - weaponDescriptionEnumerator.MoveNext(); - List weaponDescription = weaponDescriptionEnumerator.Current.Split(";").ToList(); - weaponDescription.Remove(""); - weaponDescription.RemoveAt(0); + // getting the second element - the description + weaponDescriptionEnumerator.MoveNext(); + List weaponDescription = weaponDescriptionEnumerator.Current.Split(";").ToList(); + weaponDescription.Remove(""); + weaponDescription.RemoveAt(0); - Log.Information(string.Format("Found weapon: {0}", weaponsName.ToString())); - return new(weaponsName, weaponDescription, localizationNames); - } - catch(Exception ex) - { - Log.Error(ex, "Something went wrong"); - throw; - } + Log.Information("Found weapon: {0}", weaponsName); + return new(weaponsName, weaponDescription, localizationNames); } public static void SetWeapon(string id, Weapon weapon) { - try - { - string targetName = ModLoader.Weapons.First(t => t.StartsWith(id)); - int indexTargetName = ModLoader.Weapons.IndexOf(targetName); + string targetName = ModLoader.Weapons.First(t => t.StartsWith(id)); + int indexTargetName = ModLoader.Weapons.IndexOf(targetName); - // for a lazy evaluation to avoid going through all the WeaponDescriptions list - IEnumerator<(int, string)> weaponDescriptionEnumerator = ModLoader.WeaponDescriptions.Where(t => t.StartsWith(id)).Enumerate().GetEnumerator(); + // for a lazy evaluation to avoid going through all the WeaponDescriptions list + IEnumerator<(int, string)> weaponDescriptionEnumerator = ModLoader.WeaponDescriptions.Where(t => t.StartsWith(id)).Enumerate().GetEnumerator(); - // getting the first element - the localization name - weaponDescriptionEnumerator.MoveNext(); - (int indexLocalizationName, _) = weaponDescriptionEnumerator.Current; + // getting the first element - the localization name + weaponDescriptionEnumerator.MoveNext(); + (int indexLocalizationName, _) = weaponDescriptionEnumerator.Current; - // getting the first element - the description - weaponDescriptionEnumerator.MoveNext(); - (int indexDescription, _) = weaponDescriptionEnumerator.Current; + // getting the first element - the description + weaponDescriptionEnumerator.MoveNext(); + (int indexDescription, _) = weaponDescriptionEnumerator.Current; - (string, string, string) w2s = Weapon.Weapon2String(weapon); - ModLoader.Weapons[indexTargetName] = w2s.Item1; - ModLoader.WeaponDescriptions[indexDescription] = w2s.Item2; - ModLoader.WeaponDescriptions[indexLocalizationName] = w2s.Item3; + (string, string, string) w2s = Weapon.Weapon2String(weapon); + ModLoader.Weapons[indexTargetName] = w2s.Item1; + ModLoader.WeaponDescriptions[indexDescription] = w2s.Item2; + ModLoader.WeaponDescriptions[indexLocalizationName] = w2s.Item3; - Log.Information(string.Format("Successfully set weapon: {0}", targetName.ToString())); - } - catch(Exception ex) - { - Log.Error(ex, "Something went wrong"); - throw; - } + Log.Information("Successfully set weapon: {0}", targetName); } } } \ No newline at end of file diff --git a/TextureLoader.cs b/TextureLoader.cs index 2c2f86b..a0763c2 100644 --- a/TextureLoader.cs +++ b/TextureLoader.cs @@ -329,7 +329,7 @@ private static void ScanForTextures(ModFile modFile) Source = fileChunk.name.Split("\\")[^1], Data = byteFile }; - Log.Information(string.Format("Successfully load texture {0}", fileChunk.name)); + Log.Information("Successfully load texture {0}", fileChunk.name); SourceTextures.Add(textureInfo); } else