diff --git a/Build/InstallerExtensions.dll b/Build/InstallerExtensions.dll
index 0a6c6513..6c0d6fa5 100644
Binary files a/Build/InstallerExtensions.dll and b/Build/InstallerExtensions.dll differ
diff --git a/Build/QModInstaller.dll b/Build/QModInstaller.dll
index 215a5e1f..25a60828 100644
Binary files a/Build/QModInstaller.dll and b/Build/QModInstaller.dll differ
diff --git a/Build/QModInstaller.xml b/Build/QModInstaller.xml
index c23d3d51..b9b789df 100644
--- a/Build/QModInstaller.xml
+++ b/Build/QModInstaller.xml
@@ -457,6 +457,41 @@
The color of the text.
Whether or not to apply formatting tags to the message, or show it as it is.
+
+ A simple logging class. Can be used for basic logging or to know which logging level is enabled.
+
+
+ Possible logging levels.
+
+
+ Debugging log level
+
+
+ Informational log level
+
+
+ Warning log level
+
+
+ Error log level
+
+
+ Fatal log level
+
+
+ Used to know if debug logging is enabled or not.
+
+
+
+ This function will log given message and/or exception. It can optionally show the message on screen.
+ You need to provide a message and/or an exception (this function will do nothing if both are set to null).
+ Warning: You can call this function from any mod but don't call it from QModManager ( would fail).
+
+ The level of the log.
+ Optional: The message that needs to be logged.
+ Optional: The exception that needs to be logged.
+ Optional: Whether to show the message on screen or not.
+
Container class for the entry point
diff --git a/Build/QModManager.exe b/Build/QModManager.exe
index 82cf530d..5189fa30 100644
Binary files a/Build/QModManager.exe and b/Build/QModManager.exe differ
diff --git a/Build/QModManager_Setup.exe b/Build/QModManager_Setup.exe
index 436f6fb6..cb4d5763 100644
Binary files a/Build/QModManager_Setup.exe and b/Build/QModManager_Setup.exe differ
diff --git a/Data/latest-version.txt b/Data/latest-version.txt
index c2c147f2..ec285fb6 100644
--- a/Data/latest-version.txt
+++ b/Data/latest-version.txt
@@ -1 +1 @@
-3.2.1.0
+3.3.0.0
diff --git a/Executable/Properties/AssemblyInfo.cs b/Executable/Properties/AssemblyInfo.cs
index 9af66fa4..48316489 100644
--- a/Executable/Properties/AssemblyInfo.cs
+++ b/Executable/Properties/AssemblyInfo.cs
@@ -12,5 +12,5 @@
[assembly: ComVisible(false)]
-[assembly: AssemblyVersion("3.2.1.0")]
-[assembly: AssemblyFileVersion("3.2.1.0")]
+[assembly: AssemblyVersion("3.3.0.0")]
+[assembly: AssemblyFileVersion("3.3.0.0")]
diff --git a/Installer/Properties/AssemblyInfo.cs b/Installer/Properties/AssemblyInfo.cs
index b54c9192..4fcf20da 100644
--- a/Installer/Properties/AssemblyInfo.cs
+++ b/Installer/Properties/AssemblyInfo.cs
@@ -14,5 +14,5 @@
[assembly: Guid("8c6c9a0b-80c4-43d2-89f2-749e6f09fdda")]
-[assembly: AssemblyVersion("3.2.1.0")]
-[assembly: AssemblyFileVersion("3.2.1.0")]
+[assembly: AssemblyVersion("3.3.0.0")]
+[assembly: AssemblyFileVersion("3.3.0.0")]
diff --git a/Installer/QModsInstallerScript.iss b/Installer/QModsInstallerScript.iss
index 802759cf..e3739f08 100644
--- a/Installer/QModsInstallerScript.iss
+++ b/Installer/QModsInstallerScript.iss
@@ -5,7 +5,7 @@
#endif
#define Name "QModManager" ; The name of the game will be added after it
-#define Version "3.2.1"
+#define Version "3.3.0"
#define Author "QModManager"
#define URL "https://github.com/QModManager/QModManager"
#define SupportURL "https://discord.gg/UpWuWwq"
diff --git a/QModManager/Checks/NitroxCheck.cs b/QModManager/Checks/NitroxCheck.cs
index 43457487..111ab3d7 100644
--- a/QModManager/Checks/NitroxCheck.cs
+++ b/QModManager/Checks/NitroxCheck.cs
@@ -9,7 +9,7 @@ internal static class NitroxCheck
{
internal static bool IsInstalled { get; set; } = false;
- [HarmonyPatch(typeof(GameInput), "Awake")]
+ [HarmonyPatch(typeof(GameInput), nameof(GameInput.Awake))]
internal static class AwakePatch
{
internal static IEnumerable Transpiler(IEnumerable instructions)
diff --git a/QModManager/HarmonyPatches/EnableConsoleSetting.cs b/QModManager/HarmonyPatches/EnableConsoleSetting.cs
index de1d0119..6482db63 100644
--- a/QModManager/HarmonyPatches/EnableConsoleSetting.cs
+++ b/QModManager/HarmonyPatches/EnableConsoleSetting.cs
@@ -2,9 +2,6 @@
{
using Harmony;
using QModManager.Utility;
- using System.Collections.Generic;
- using System.Reflection;
- using System.Reflection.Emit;
using UnityEngine;
[HarmonyPatch(typeof(DevConsole), nameof(DevConsole.Awake))]
@@ -26,13 +23,12 @@ internal static class PlayerPrefsUtils_PrefsToggle_Patch
// This patch syncronizes the "Disable console" UI element in the F3 debug menu
[HarmonyPostfix]
- public static void Postfix(bool __result, string key)
+ public static void Postfix(bool defaultVal, string key, string label, ref bool __result)
{
- if (key != "UWE.DisableConsole") return;
-
- Config.EnableConsole = !__result;
-
- return;
+ if (key == "UWE.DisableConsole")
+ {
+ Config.EnableConsole = !__result;
+ }
}
}
}
diff --git a/QModManager/OptionsManager.cs b/QModManager/OptionsManager.cs
index 371196b9..9a458f2b 100644
--- a/QModManager/OptionsManager.cs
+++ b/QModManager/OptionsManager.cs
@@ -8,9 +8,7 @@ internal static class OptionsManager
{
internal static int ModsTab;
-
-
- [HarmonyPatch(typeof(uGUI_OptionsPanel), "AddTabs")]
+ [HarmonyPatch(typeof(uGUI_OptionsPanel), nameof(uGUI_OptionsPanel.AddTabs))]
internal static class OptionsPatch
{
[HarmonyPostfix]
diff --git a/QModManager/Patching/ManifestValidator.cs b/QModManager/Patching/ManifestValidator.cs
index 64d67ac4..0215f663 100644
--- a/QModManager/Patching/ManifestValidator.cs
+++ b/QModManager/Patching/ManifestValidator.cs
@@ -144,6 +144,8 @@ public void CheckRequiredMods(QMod mod)
{
versionedDependencies.Add(new RequiredQMod(item.Key));
}
+
+ mod.RequiredDependencies.Add(item.Key);
}
mod.RequiredMods = versionedDependencies;
diff --git a/QModManager/Patching/Patcher.cs b/QModManager/Patching/Patcher.cs
index 8880367a..fa8328f8 100644
--- a/QModManager/Patching/Patcher.cs
+++ b/QModManager/Patching/Patcher.cs
@@ -41,7 +41,7 @@ internal static void Patch()
Patched = true;
- Logger.Info("Game Version: " + SNUtils.GetPlasticChangeSetOfBuild() + " Build Date: " + SNUtils.GetDateTimeOfBuild().ToLongDateString());
+ Logger.Info($"Game Version: {SNUtils.GetPlasticChangeSetOfBuild()} Build Date: {SNUtils.GetDateTimeOfBuild():dd-MMMM-yyyy}");
Logger.Info($"Loading QModManager v{Assembly.GetExecutingAssembly().GetName().Version.ToStringParsed()}...");
Logger.Info($"Today is {DateTime.Today:dd-MMMM-yyyy}");
@@ -64,7 +64,7 @@ internal static void Patch()
try
{
- Logger.Info($"Folder structure:\n{IOUtilities.GetFolderStructureAsTree()}\n");
+ Logger.Info($"Folder structure:{IOUtilities.GetFolderStructureAsTree()}");
}
catch (Exception e)
{
@@ -81,15 +81,7 @@ internal static void Patch()
CurrentlyRunningGame = gameDetector.CurrentlyRunningGame;
- try
- {
- PatchHarmony();
- }
- catch (Exception e)
- {
- Logger.Error("There was an error while trying to apply Harmony patches.");
- Logger.Exception(e);
- }
+ PatchHarmony();
if (NitroxCheck.IsInstalled)
{
@@ -171,9 +163,19 @@ private static void AddAssemblyResolveEvent()
private static void PatchHarmony()
{
- Logger.Debug("Applying Harmony patches...");
- HarmonyInstance.Create("qmodmanager").PatchAll();
- Logger.Debug("Patched!");
+ try
+ {
+ Logger.Debug("Applying Harmony patches...");
+
+ HarmonyInstance.Create("qmodmanager").PatchAll();
+
+ Logger.Debug("Patched!");
+ }
+ catch (Exception e)
+ {
+ Logger.Error("There was an error while trying to apply Harmony patches.");
+ Logger.Exception(e);
+ }
}
}
}
diff --git a/QModManager/Patching/QMod.cs b/QModManager/Patching/QMod.cs
index fec08845..18fbd613 100644
--- a/QModManager/Patching/QMod.cs
+++ b/QModManager/Patching/QMod.cs
@@ -19,40 +19,40 @@ public QMod()
// Empty public constructor for JSON
}
- [JsonProperty(Required = Required.Always)]
+ [JsonProperty]
public string Id { get; set; }
- [JsonProperty(Required = Required.Always)]
+ [JsonProperty]
public string DisplayName { get; set; }
- [JsonProperty(Required = Required.Always)]
+ [JsonProperty]
public string Author { get; set; }
- [JsonProperty(Required = Required.Always)]
+ [JsonProperty]
public string Version { get; set; }
- [JsonProperty(Required = Required.Default)]
+ [JsonProperty]
public string[] Dependencies { get; set; } = new string[0];
- [JsonProperty(Required = Required.Default)]
+ [JsonProperty]
public Dictionary VersionDependencies { get; set; } = new Dictionary();
- [JsonProperty(Required = Required.Default)]
+ [JsonProperty]
public string[] LoadBefore { get; set; } = new string[0];
- [JsonProperty(Required = Required.Default)]
+ [JsonProperty]
public string[] LoadAfter { get; set; } = new string[0];
- [JsonProperty(Required = Required.DisallowNull, DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
+ [JsonProperty]
public bool Enable { get; set; } = true;
- [JsonProperty(Required = Required.DisallowNull)]
+ [JsonProperty]
public string Game { get; set; } = $"{QModGame.Subnautica}";
- [JsonProperty(Required = Required.Always)]
+ [JsonProperty]
public string AssemblyName { get; set; }
- [JsonProperty(Required = Required.Default)]
+ [JsonProperty]
public string EntryMethod { get; set; }
#endregion
diff --git a/QModManager/Patching/QModFactory.cs b/QModManager/Patching/QModFactory.cs
index 2e63b91b..fc0dc9d0 100644
--- a/QModManager/Patching/QModFactory.cs
+++ b/QModManager/Patching/QModFactory.cs
@@ -165,14 +165,17 @@ private static QMod CreateFromJsonManifestFile(string subDirectory)
try
{
- var settings = new JsonSerializerSettings
+ var deserializer = new JsonSerializer
{
+ NullValueHandling = NullValueHandling.Ignore,
MissingMemberHandling = MissingMemberHandling.Ignore
};
string jsonText = File.ReadAllText(jsonFile);
- QMod mod = JsonConvert.DeserializeObject(jsonText);
+ using StreamReader sr = new StreamReader(jsonFile);
+ using JsonReader reader = new JsonTextReader(sr);
+ QMod mod = deserializer.Deserialize(reader);
mod.SubDirectory = subDirectory;
diff --git a/QModManager/Properties/AssemblyInfo.cs b/QModManager/Properties/AssemblyInfo.cs
index 95f310b7..4bc431ac 100644
--- a/QModManager/Properties/AssemblyInfo.cs
+++ b/QModManager/Properties/AssemblyInfo.cs
@@ -13,8 +13,8 @@
[assembly: ComVisible(false)]
-[assembly: AssemblyVersion("3.2.1.0")]
-[assembly: AssemblyFileVersion("3.2.1.0")]
+[assembly: AssemblyVersion("3.3.0.0")]
+[assembly: AssemblyFileVersion("3.3.0.0")]
[assembly: InternalsVisibleTo("QMMTests")]
[assembly: InternalsVisibleTo("QModManager")]
diff --git a/QModManager/Utility/Config.cs b/QModManager/Utility/Config.cs
index 8dfa78f3..c46325ef 100644
--- a/QModManager/Utility/Config.cs
+++ b/QModManager/Utility/Config.cs
@@ -35,18 +35,30 @@ internal static bool EnableDevMode
private static Dictionary Cfg = new Dictionary();
private static bool Loaded = false;
+ private static readonly JsonSerializer serializer = new JsonSerializer
+ {
+ NullValueHandling = NullValueHandling.Ignore,
+ MissingMemberHandling = MissingMemberHandling.Ignore,
+ DefaultValueHandling = DefaultValueHandling.Ignore
+ };
- private static void Load()
+ private static void Load()
{
try
{
- if (!File.Exists(ConfigPath)) File.WriteAllText(ConfigPath, "{}");
- string text = File.ReadAllText(ConfigPath);
- Cfg = JsonConvert.DeserializeObject>(text);
+ if (!File.Exists(ConfigPath))
+ {
+ Save();
+ }
+
+ using StreamReader sr = new StreamReader(ConfigPath);
+ using JsonReader reader = new JsonTextReader(sr);
+ Cfg = serializer.Deserialize>(reader);
+
if (Cfg == null)
{
- File.WriteAllText(ConfigPath, "{}");
Cfg = new Dictionary();
+ Save();
}
Loaded = true;
@@ -62,8 +74,9 @@ private static void Save()
{
try
{
- string text = JsonConvert.SerializeObject(Cfg, Formatting.Indented);
- File.WriteAllText(ConfigPath, text);
+ using StreamWriter sw = new StreamWriter(ConfigPath);
+ using JsonWriter writer = new JsonTextWriter(sw);
+ serializer.Serialize(writer, Cfg);
}
catch (Exception e)
{
@@ -74,7 +87,10 @@ private static void Save()
private static T Get(string field, T def = default)
{
- if (!Loaded) Load();
+ if (!Loaded)
+ {
+ Load();
+ }
if (!Cfg.TryGetValue(field, out object value))
return def;
diff --git a/QModManager/Utility/IOUtilities.cs b/QModManager/Utility/IOUtilities.cs
index 95ae1b41..c75d1a52 100644
--- a/QModManager/Utility/IOUtilities.cs
+++ b/QModManager/Utility/IOUtilities.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
+using System.Text;
namespace QModManager.Utility
{
@@ -16,7 +17,9 @@ internal static class IOUtilities
"SNAppData",
"SNUnmanagedData",
"Subnautica_Data",
+ "SubnauticaZero_Data",
"_CommonRedist",
+ "steam_shader_cache",
};
internal static string GetFolderStructureAsTree(string directory = null)
@@ -25,7 +28,7 @@ internal static string GetFolderStructureAsTree(string directory = null)
{
directory ??= Environment.CurrentDirectory;
- return GenerateFolderStructure(directory) + "\n";
+ return GenerateFolderStructure(directory);
}
catch (Exception e)
{
@@ -35,13 +38,15 @@ internal static string GetFolderStructureAsTree(string directory = null)
internal static string GenerateFolderStructure(string directory)
{
+ var builder = new StringBuilder();
try
{
- string toWrite = $"+ {new DirectoryInfo(directory).Name}\n";
+ builder.AppendLine();
+ builder.AppendLine($"+ {new DirectoryInfo(directory).Name}");
foreach (string dir in Directory.GetDirectories(directory))
{
- toWrite += GetFolderStructureRecursively(dir, 0);
+ GetFolderStructureRecursively(builder, dir, 0);
}
string[] files = Directory.GetFiles(directory);
@@ -49,34 +54,35 @@ internal static string GenerateFolderStructure(string directory)
{
FileInfo fileinfo = new FileInfo(files[i - 1]);
if (i != files.Length)
- toWrite += $"{GenerateSpaces(0)}|---- {fileinfo.Name} ({ParseSize(fileinfo.Length)})\n";
- else
- toWrite += $"{GenerateSpaces(0)}`---- {fileinfo.Name} ({ParseSize(fileinfo.Length)})\n";
+ builder.AppendLine($"{GenerateSpaces(0)}|---- {fileinfo.Name} ({ParseSize(fileinfo.Length)})");
+ else
+ builder.AppendLine($"{GenerateSpaces(0)}|---- {fileinfo.Name} ({ParseSize(fileinfo.Length)})");
}
- return toWrite;
+ builder.AppendLine();
+ return builder.ToString();
}
catch (Exception e)
{
throw e;
}
}
- internal static string GetFolderStructureRecursively(string directory, int spaces = 0)
+ internal static void GetFolderStructureRecursively(StringBuilder builder, string directory, int spaces = 0)
{
try
{
DirectoryInfo dirInfo = new DirectoryInfo(directory);
- string toWrite = $"{GenerateSpaces(spaces)}|---+ {dirInfo.Name}\n";
+ builder.AppendLine($"{GenerateSpaces(spaces)}|---+ {dirInfo.Name}");
if (BannedFolders.Contains(dirInfo.Name) || BannedFolders.Contains($"{dirInfo.Parent.Name}/{dirInfo.Name}"))
{
- toWrite += $"{GenerateSpaces(spaces + 4)}`---- (Folder content not shown)\n";
- return toWrite;
+ builder.AppendLine($"{GenerateSpaces(spaces + 4)}`---- (Folder content not shown)");
+ return;
}
foreach (string dir in Directory.GetDirectories(directory))
{
- toWrite += GetFolderStructureRecursively(dir, spaces + 4);
+ GetFolderStructureRecursively(builder, dir, spaces + 4);
}
string[] files = Directory.GetFiles(directory);
@@ -84,12 +90,10 @@ internal static string GetFolderStructureRecursively(string directory, int space
{
FileInfo fileinfo = new FileInfo(files[i - 1]);
if (i != files.Length)
- toWrite += $"{GenerateSpaces(spaces + 4)}|---- {fileinfo.Name} ({ParseSize(fileinfo.Length)})\n";
+ builder.AppendLine($"{GenerateSpaces(spaces + 4)}|---- {fileinfo.Name} ({ParseSize(fileinfo.Length)})");
else
- toWrite += $"{GenerateSpaces(spaces + 4)}`---- {fileinfo.Name} ({ParseSize(fileinfo.Length)})\n";
+ builder.AppendLine($"{GenerateSpaces(spaces + 4)}`---- {fileinfo.Name} ({ParseSize(fileinfo.Length)})");
}
-
- return toWrite;
}
catch (Exception e)
{
diff --git a/QModManager/Utility/Logger.cs b/QModManager/Utility/Logger.cs
index 2a94821b..dae2ba21 100644
--- a/QModManager/Utility/Logger.cs
+++ b/QModManager/Utility/Logger.cs
@@ -1,127 +1,171 @@
namespace QModManager.Utility
{
using System;
- using System.Diagnostics;
- using System.IO;
- internal static class Logger
+ /// A simple logging class. Can be used for basic logging or to know which logging level is enabled.
+ public static class Logger
{
- internal enum Level
+ /// Possible logging levels.
+ public enum Level
{
+ /// Debugging log level
Debug,
+ /// Informational log level
Info,
+ /// Warning log level
Warn,
+ /// Error log level
Error,
+ /// Fatal log level
Fatal
}
- private static void Log(string logLevel, params string[] text)
+ private const string AssemblyName = "QModManager";
+
+ #region Private functions (used by the Logger)
+
+ private static string GetCallingAssemblyName() => ReflectionHelper.CallingAssemblyByStackTrace()?.GetName().Name;
+
+ private static void Debug(string msg, bool showOnScreen = false, string callingAssembly = null, bool force = false)
{
- if (text == null || text.Length < 1)
+ if (!force && !Config.EnableDebugLogs)
return;
- string from;
- Type classType = GetCallingClass();
+ Console.WriteLine($"[{callingAssembly ?? GetCallingAssemblyName()}:DEBUG] {msg}");
- if (classType == null)
- from = null;
- else if (classType.Namespace.Contains("SMLHelper"))
- from = "SMLHelper";
- else
- from = classType.Name;
+ if (showOnScreen)
+ ErrorMessage.AddDebug(msg);
+ }
- string toWrite = "[QModManager] ";
- if (!string.IsNullOrEmpty(from) && !from.Contains("<>"))
- toWrite += $"[{from}] ";
- else if (!string.IsNullOrEmpty(from) && from.Contains("<>"))
- toWrite += $"[Anonymous] ";
- if (!string.IsNullOrEmpty(logLevel))
- toWrite += $"[{logLevel}] ";
+ private static void Info(string msg, bool showOnScreen = false, string callingAssembly = null)
+ {
+ Console.WriteLine($"[{callingAssembly ?? GetCallingAssemblyName()}:INFO] {msg}");
- int length = toWrite.Length;
+ if (showOnScreen)
+ ErrorMessage.AddMessage(msg);
+ }
- Console.WriteLine($"{toWrite}{text[0]}");
+ private static void Warn(string msg, bool showOnScreen = false, string callingAssembly = null)
+ {
+ Console.WriteLine($"[{callingAssembly ?? GetCallingAssemblyName()}:WARN] {msg}");
- for (int i = 1; i < text.Length; i++)
- Console.WriteLine($"{text[i]}");
+ if (showOnScreen)
+ ErrorMessage.AddWarning(msg);
}
- internal static void Log(params string[] text)
+ private static void Error(string msg = null, Exception ex = null, bool showOnScreen = false, string callingAssembly = null)
{
- Log("", text);
+ if (ex != null)
+ msg = (string.IsNullOrEmpty(msg) ? ex.ToString() : msg + Environment.NewLine + ex.ToString());
+
+ Console.WriteLine($"[{callingAssembly ?? GetCallingAssemblyName()}:ERROR] {msg}");
+
+ if (showOnScreen && !string.IsNullOrEmpty(msg))
+ ErrorMessage.AddError(msg);
}
- internal static void Log(Level logLevel, params string[] text)
+ private static void Exception(Exception e, bool selfAssembly = false) => Error(null, e, false, selfAssembly ? AssemblyName : GetCallingAssemblyName());
+
+ private static void Fatal(string msg = null, Exception ex = null, bool showOnScreen = false, string callingAssembly = null)
+ {
+ if (ex != null)
+ msg = (string.IsNullOrEmpty(msg) ? ex.ToString() : msg + Environment.NewLine + ex.ToString());
+ Console.WriteLine($"[{callingAssembly ?? GetCallingAssemblyName()}:FATAL] {msg}");
+
+ if (showOnScreen && !string.IsNullOrEmpty(msg))
+ ErrorMessage.AddError(msg);
+ }
+
+ #endregion
+
+ #region Internal functions (used by QModManager)
+
+ internal static void Debug(string msg) => Debug(msg, false, AssemblyName, false);
+
+ internal static void DebugForce(string msg) => Debug(msg, false, AssemblyName, true);
+
+ internal static void Info(string msg) => Info(msg, false, AssemblyName);
+
+ internal static void Warn(string msg) => Warn(msg, false, AssemblyName);
+
+ internal static void Error(string msg) => Error(msg, null, false, AssemblyName);
+
+ internal static void Exception(Exception e) => Exception(e, true);
+
+ internal static void Fatal(string msg) => Fatal(msg, null, false, AssemblyName);
+
+ internal static void Log(Level logLevel, string msg)
{
+ if (msg == null) // Return if there is no messages
+ return;
+
switch (logLevel)
{
case Level.Debug:
- Debug(text);
- break;
- case Level.Info:
- Info(text);
+ Debug(msg);
break;
case Level.Warn:
- Warn(text);
+ Warn(msg);
break;
case Level.Error:
- Error(text);
+ Error(msg);
break;
case Level.Fatal:
- Fatal(text);
+ Fatal(msg);
+ break;
+ default: // Defaults to informational logging
+ Info(msg);
break;
}
}
- internal static void Debug(params string[] text)
- {
- if (Config.EnableDebugLogs)
- Log("Debug", text);
- }
-
- internal static void DebugForce(params string[] text)
- {
- Log("Debug", text);
- }
-
- internal static void Info(params string[] text)
- {
- Log("Info", text);
- }
+ #endregion
- internal static void Warn(params string[] text)
- {
- Log("Warn", text);
- }
+ #region Public functions (used by mods)
- internal static void Error(params string[] text)
- {
- Log("Error", text);
- }
-
- internal static void Exception(Exception e)
- {
- Log("Exception", e.ToString());
- }
-
- internal static void Fatal(params string[] text)
- {
- Log("Fatal", text);
- }
+ /// Used to know if debug logging is enabled or not.
+ public static bool DebugLogsEnabled => Config.EnableDebugLogs;
- private static Type GetCallingClass()
+ ///
+ /// This function will log given message and/or exception. It can optionally show the message on screen.
+ /// You need to provide a message and/or an exception (this function will do nothing if both are set to null).
+ /// Warning: You can call this function from any mod but don't call it from QModManager ( would fail).
+ ///
+ /// The level of the log.
+ /// Optional: The message that needs to be logged.
+ /// Optional: The exception that needs to be logged.
+ /// Optional: Whether to show the message on screen or not.
+ public static void Log(Level logLevel, string msg = null, Exception ex = null, bool showOnScreen = false)
{
- var stackTrace = new StackTrace();
- StackFrame[] frames = stackTrace.GetFrames();
-
- foreach (StackFrame stackFrame in frames)
+ if (ex != null)
{
- Type declaringClass = stackFrame.GetMethod().DeclaringType;
- if (declaringClass != typeof(Logger))
- return declaringClass;
+ // If exception was provided, concatenate its message to the log message
+ if (logLevel != Level.Error && logLevel != Level.Fatal)
+ msg = (msg == null) ? ex.Message : msg + Environment.NewLine + ex.Message;
}
+ else if (msg == null) // Return if both given message and exception were null
+ return;
- return null;
+ switch (logLevel)
+ {
+ case Level.Debug:
+ Debug(msg, showOnScreen, null, false);
+ break;
+ case Level.Warn:
+ Warn(msg, showOnScreen, null);
+ break;
+ case Level.Error:
+ Error(msg, ex, showOnScreen, null);
+ break;
+ case Level.Fatal:
+ Fatal(msg, ex, showOnScreen, null);
+ break;
+ default: // Defaults to informational logging
+ Info(msg, showOnScreen, null);
+ break;
+ }
}
+
+ #endregion
}
}
diff --git a/QModManager/Utility/MainMenuMessages.cs b/QModManager/Utility/MainMenuMessages.cs
index 1a20e538..18e79462 100644
--- a/QModManager/Utility/MainMenuMessages.cs
+++ b/QModManager/Utility/MainMenuMessages.cs
@@ -1,10 +1,10 @@
namespace QModManager.Utility
{
+ using System;
using System.Reflection;
using System.Reflection.Emit;
using System.Collections;
using System.Collections.Generic;
-
using Harmony;
using UnityEngine;
using UnityEngine.SceneManagement;
@@ -63,6 +63,7 @@ private static void Init()
if (inited)
return;
+ LoadDynamicAssembly();
messageQueue = new List();
messages = new List();
Patches.Patch();
@@ -77,7 +78,8 @@ private static void AddInternal(string msg)
var message = ErrorMessage.main.GetExistingMessage(msg);
messages.Add(message);
message.timeEnd += 1e6f;
- message.entry.rectTransform.sizeDelta = new Vector2(1920f - ErrorMessage.main.offset.x * 2f, 0f);
+
+ GetRectTransform(message).sizeDelta = new Vector2(1920f - ErrorMessage.main.offset.x * 2f, 0f);
}
private static void OnSceneLoaded(Scene scene, LoadSceneMode _)
@@ -98,8 +100,10 @@ static IEnumerator _waitForLoad()
messages.ForEach(msg => msg.timeEnd = Time.time + 1f);
yield return new WaitForSeconds(1.1f); // wait for messages to dissapear
- Vector2 originalSize = ErrorMessage.main.prefabMessage.rectTransform.sizeDelta;
- messages.ForEach(msg => msg.entry.rectTransform.sizeDelta = originalSize);
+ Vector2 originalSize = GetRectTransform(ErrorMessage.main.prefabMessage.GetComponent(SelectedTextType)).sizeDelta;
+
+ messages.ForEach(msg => GetRectTransform(msg).sizeDelta = originalSize);
+
messages.Clear();
Patches.Unpatch();
@@ -109,6 +113,48 @@ static IEnumerator _waitForLoad()
}
}
+ #region Dynamic assembly loading
+
+ private static Type SelectedTextType;
+ private static Func