diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 525e474..1858c3c 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -66,10 +66,6 @@ jobs:
- name: Move NuGet Packages
run: mv (Get-ChildItem -Recurse ./ -Include *.nupkg) ./
-
- # Removes the version number from the package name
- - name: Rename NuGet Packages
- run: Get-ChildItem -Include *.nupkg -Path ./* | Rename-Item -NewName { $_.Name -Replace '\.\d+\.\d+\.\d+.*$','.nupkg' }
# Publish the NuGet package(s) as an artifact, so they can be used in the following jobs
- name: Upload NuGet Packages Artifact
@@ -78,7 +74,7 @@ jobs:
name: NuGet Packages
if-no-files-found: error
retention-days: 7
- path: ./*.nupkg
+ path: ./MonkeyLoader.GamePacks.ResoniteModLoader.nupkg
# Only when it's not from a PR to avoid any funny packages in the cache
- name: Save NuGet Package Cache
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
index c61aa44..3e65cc7 100644
--- a/.github/workflows/publish.yml
+++ b/.github/workflows/publish.yml
@@ -70,9 +70,6 @@ jobs:
with:
dotnet-version: 10.x
source-url: https://nuget.pkg.github.com/ResoniteModdingGroup/index.json
-
- - name: Add MonkeyLoader NuGet Source
- run: dotnet nuget add source https://pkg.munally.com/MonkeyModdingTroop/index.json
# Publish all NuGet packages to the GitHub feed
# Use --skip-duplicate to prevent errors if a package with the same version already exists.
diff --git a/MonkeyLoader.GamePacks.ResoniteModLoader.sln b/MonkeyLoader.GamePacks.ResoniteModLoader.sln
deleted file mode 100644
index 246ab67..0000000
--- a/MonkeyLoader.GamePacks.ResoniteModLoader.sln
+++ /dev/null
@@ -1,40 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 17
-VisualStudioVersion = 17.5.33516.290
-MinimumVisualStudioVersion = 10.0.40219.1
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{CEAAAF5F-3B06-40E0-B0D2-3BBD3513038B}"
- ProjectSection(SolutionItems) = preProject
- Directory.Build.props = Directory.Build.props
- README.md = README.md
- EndProjectSection
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MonkeyLoader.GamePacks.ResoniteModLoader", "MonkeyLoader.GamePacks.ResoniteModLoader\MonkeyLoader.GamePacks.ResoniteModLoader.csproj", "{41F303F4-2BE1-4462-B5DC-144ECA630242}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{02EA681E-C7D8-13C7-8484-4AC65E1B71E8}"
- ProjectSection(SolutionItems) = preProject
- .github\workflows\build.yml = .github\workflows\build.yml
- .github\workflows\publish.yml = .github\workflows\publish.yml
- EndProjectSection
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Release|Any CPU = Release|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {41F303F4-2BE1-4462-B5DC-144ECA630242}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {41F303F4-2BE1-4462-B5DC-144ECA630242}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {41F303F4-2BE1-4462-B5DC-144ECA630242}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {41F303F4-2BE1-4462-B5DC-144ECA630242}.Release|Any CPU.Build.0 = Release|Any CPU
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
- GlobalSection(NestedProjects) = preSolution
- {02EA681E-C7D8-13C7-8484-4AC65E1B71E8} = {CEAAAF5F-3B06-40E0-B0D2-3BBD3513038B}
- EndGlobalSection
- GlobalSection(ExtensibilityGlobals) = postSolution
- SolutionGuid = {7D505B2E-FBA2-4F50-BC1C-838BC8DF0D5C}
- EndGlobalSection
-EndGlobal
diff --git a/MonkeyLoader.GamePacks.ResoniteModLoader.slnx b/MonkeyLoader.GamePacks.ResoniteModLoader.slnx
new file mode 100644
index 0000000..f72a922
--- /dev/null
+++ b/MonkeyLoader.GamePacks.ResoniteModLoader.slnx
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/MonkeyLoader.GamePacks.ResoniteModLoader/ExecutionHook.cs b/MonkeyLoader.GamePacks.ResoniteModLoader/ExecutionHook.cs
index 7c73a2b..af396f5 100644
--- a/MonkeyLoader.GamePacks.ResoniteModLoader/ExecutionHook.cs
+++ b/MonkeyLoader.GamePacks.ResoniteModLoader/ExecutionHook.cs
@@ -41,7 +41,7 @@ public void NotifyOfScreenshot(World world, string file, ScreenshotType type, Da
public Task Initialize(PlatformInterface platformInterface)
{
- ModLoader.Logger.Debug(() => "Initialize() from platformInterface");
+ ModLoaderHook.Logger.Debug(() => "Initialize() from platformInterface");
Platform = platformInterface;
return Task.FromResult(true);
}
diff --git a/MonkeyLoader.GamePacks.ResoniteModLoader/Locale/de.json b/MonkeyLoader.GamePacks.ResoniteModLoader/Locale/de.json
index 7d19eba..a8c3e75 100644
--- a/MonkeyLoader.GamePacks.ResoniteModLoader/Locale/de.json
+++ b/MonkeyLoader.GamePacks.ResoniteModLoader/Locale/de.json
@@ -2,6 +2,34 @@
"localeCode": "de",
"authors": [ "Banane9" ],
"messages": {
- "MonkeyLoader.GamePacks.ResoniteModLoader.ModLoader.Description": "Läd Resonite Mod Loader (RML) Bibliotheken und Mods von ihren üblichen Orten."
+ "MonkeyLoader.GamePacks.ResoniteModLoader.ModLoader.Description": "Läd ResoniteModLoader (RML) Bibliotheken und Mods von ihren üblichen Orten.",
+
+ "Settings.Category.ResoniteModLoader": "ResoniteModLoader",
+ "Settings.ModLoaderSettings": "ResoniteModLoader-Einstellungen",
+
+ "Settings.ModLoaderSettings.DebugMode": "Debugmodus",
+ "Settings.ModLoaderSettings.DebugMode.Description": "Aktiviert Debug-Logging.",
+ "Settings.ModLoaderSettings.HideVisuals": "Visuelle Elemente verstecken",
+ "Settings.ModLoaderSettings.HideVisuals.Description": "Versteckt die Fortschrittsanzeige des Modloaders während des Startvorgangs.",
+ "Settings.ModLoaderSettings.LoadedMods": "Geladene Mods",
+ "Settings.ModLoaderSettings.ModLoaderVersion": "Version",
+ "Settings.ModLoaderSettings.ProjectLink": "GitHub Repo",
+
+ "Settings.ModLoaderDebugSettings": "Debug-Einstellungen",
+ "Settings.ModLoaderDebugSettings.RefreshLocale": "Lokalisierung neu laden",
+ "Settings.ModLoaderDebugSettings.LocaleCount": "Einträge in der Lokalisierung zählen",
+ "Settings.ModLoaderDebugSettings.LocaleKeyCount": "Anzahl der Lokalisierungseinträge",
+ "Settings.ModLoaderDebugSettings.ForceAssetUpdate": "Asset-Update erzwingen",
+
+ "Settings.ModSettings": "Mod-Einstellungen",
+ "Settings.ModSettings.ModList": "Mod-Einstellungen editieren",
+ "Settings.ModSettings.ModList.Breadcrumb": "Mod-Einstellungen",
+ "Settings.ModSettings.NoMods": "Keine Mods geladen",
+ "Settings.ModSettings.NoModsWithConfig": "Keine Mods mit Einstellungen zum anzeigen vorhanden",
+ "Settings.ModSettings.NoConfigs": "Keine Einstellungen für die ausgewählte Mod verfügbar.",
+ "Settings.ModSettings.ShowInternal": "Zeige Einstellungen für interne Nutzung",
+ "Settings.ModSettings.ShowInternal.Description": "Interne Einstellungen sind üblicherweise nicht für die direkte Änderung durch den Nutzer gedacht. Dies kann unbeabsichtige Auswirkungen haben.",
+ "Settings.ModSettings.ShowAll": "Alle Mods anzeigen",
+ "Settings.ModSettings.ShowAll.Description": "Zeigt Einträge für alle Mods, inklusive der ohne Einstellungsmöglichkeiten."
}
}
\ No newline at end of file
diff --git a/MonkeyLoader.GamePacks.ResoniteModLoader/Locale/en.json b/MonkeyLoader.GamePacks.ResoniteModLoader/Locale/en.json
index d4d55f6..289aace 100644
--- a/MonkeyLoader.GamePacks.ResoniteModLoader/Locale/en.json
+++ b/MonkeyLoader.GamePacks.ResoniteModLoader/Locale/en.json
@@ -1,7 +1,36 @@
{
"localeCode": "en",
- "authors": [ "Banane9" ],
+ "authors": [ "Banane9", "Delta" ],
"messages": {
- "MonkeyLoader.GamePacks.ResoniteModLoader.ModLoader.Description": "Loads Resonite Mod Loader (RML) libraries and mods from their usual locations."
+ "MonkeyLoader.GamePacks.ResoniteModLoader.ModLoader.Name": "ResoniteModLoader",
+ "MonkeyLoader.GamePacks.ResoniteModLoader.ModLoader.Description": "Loads ResoniteModLoader (RML) libraries and mods from their usual locations.",
+
+ "Settings.Category.ResoniteModLoader": "ResoniteModLoader",
+ "Settings.ModLoaderSettings": "ResoniteModLoader Settings",
+
+ "Settings.ModLoaderSettings.DebugMode": "Enable Debug",
+ "Settings.ModLoaderSettings.DebugMode.Description": "Enables Debug Logging",
+ "Settings.ModLoaderSettings.HideVisuals": "Hide Visuals",
+ "Settings.ModLoaderSettings.HideVisuals.Description": "Hides Modloader progress indicator when launching",
+ "Settings.ModLoaderSettings.LoadedMods": "Loaded Mods",
+ "Settings.ModLoaderSettings.ModLoaderVersion": "Version",
+ "Settings.ModLoaderSettings.ProjectLink": "Github Repo",
+
+ "Settings.ModLoaderDebugSettings": "Debugging Settings",
+ "Settings.ModLoaderDebugSettings.RefreshLocale": "Refresh Locale",
+ "Settings.ModLoaderDebugSettings.LocaleCount": "Count Locale Keys",
+ "Settings.ModLoaderDebugSettings.LocaleKeyCount": "Locale Key Count",
+ "Settings.ModLoaderDebugSettings.ForceAssetUpdate": "Force Asset Update",
+
+ "Settings.ModSettings": "Mod Settings",
+ "Settings.ModSettings.ModList": "Edit Mod Settings",
+ "Settings.ModSettings.ModList.Breadcrumb": "Mod Settings",
+ "Settings.ModSettings.NoMods": "No mods loaded",
+ "Settings.ModSettings.NoModsWithConfig": "No mods with configs to show",
+ "Settings.ModSettings.NoConfigs": "No settings are available for the selected mod.",
+ "Settings.ModSettings.ShowInternal": "Show internal use configs",
+ "Settings.ModSettings.ShowInternal.Description": "Internal configs aren't generally intended to be changed directly by the user. Can cause unintended behaviour.",
+ "Settings.ModSettings.ShowAll": "Show all mods",
+ "Settings.ModSettings.ShowAll.Description": "Show all entries for mods, including ones with no settings."
}
}
\ No newline at end of file
diff --git a/MonkeyLoader.GamePacks.ResoniteModLoader/Locale/eo.json b/MonkeyLoader.GamePacks.ResoniteModLoader/Locale/eo.json
new file mode 100644
index 0000000..13abe74
--- /dev/null
+++ b/MonkeyLoader.GamePacks.ResoniteModLoader/Locale/eo.json
@@ -0,0 +1,22 @@
+{
+ "localeCode": "eo",
+ "authors": [ "Delta" ],
+ "messages": {
+ "Settings.Category.ResoniteModLoader": "ResoniteModLoader",
+ "Settings.ModLoaderSettings": "Agordoj de ResoniteModLoader",
+
+ "Settings.ModLoaderSettings.DebugMode": "Ebligi Sencimigon",
+ "Settings.ModLoaderSettings.DebugMode.Description": "Ebligu Sencimigan Protokolon",
+ "Settings.ModLoaderSettings.HideVisuals": "Kaŝi Vidaĵojn",
+ "Settings.ModLoaderSettings.HideVisuals.Description": "Kaŝas la progresa indikilo de la modŝargilo dum lanĉo",
+ "Settings.ModLoaderSettings.LoadedMods": "Ŝargitaj Modoj",
+ "Settings.ModLoaderSettings.ModLoaderVersion": "Versio",
+ "Settings.ModLoaderSettings.ProjectLink": "Github-Deponejo",
+
+ "Settings.ModLoaderDebugSettings": "Sencimigaj Agordoj",
+ "Settings.ModLoaderDebugSettings.RefreshLocale": "Refreŝigi Lokalon",
+ "Settings.ModLoaderDebugSettings.LocaleCount": "Nombri Lokajn Ŝlosilojn",
+ "Settings.ModLoaderDebugSettings.LocaleKeyCount": "Nombri Lokajn Ŝlosilojn",
+ "Settings.ModLoaderDebugSettings.ForceAssetUpdate": "Devigi Asetan Ĝisdatigon"
+ }
+}
\ No newline at end of file
diff --git a/MonkeyLoader.GamePacks.ResoniteModLoader/Locale/ja.json b/MonkeyLoader.GamePacks.ResoniteModLoader/Locale/ja.json
index 362086f..43db164 100644
--- a/MonkeyLoader.GamePacks.ResoniteModLoader/Locale/ja.json
+++ b/MonkeyLoader.GamePacks.ResoniteModLoader/Locale/ja.json
@@ -2,6 +2,22 @@
"localeCode": "ja",
"authors": [ "kazu" ],
"messages": {
- "MonkeyLoader.GamePacks.ResoniteModLoader.ModLoader.Description": "Resonite Mod Loader (RML) ライブラリ 及び モッド を通常の場所から読み込めるようにします。"
+ "MonkeyLoader.GamePacks.ResoniteModLoader.ModLoader.Description": "ResoniteModLoader (RML) ライブラリ 及び モッド を通常の場所から読み込めるようにします。",
+
+ "Settings.Category.ResoniteModLoader": "ResoniteModLoader",
+ "Settings.ModLoaderSettings": "ResoniteModLoader 設定",
+
+ "Settings.ModLoaderSettings.DebugMode": "デバッグログを有効化",
+ "Settings.ModLoaderSettings.DebugMode.Description": "デバッグログを記録するようにします。",
+ "Settings.ModLoaderSettings.HideVisuals": "表示を隠す",
+ "Settings.ModLoaderSettings.HideVisuals.Description": "起動時に表示される Modloader の読み込み表示を隠します。",
+ "Settings.ModLoaderSettings.LoadedMods": "読み込まれた Mod",
+ "Settings.ModLoaderSettings.ModLoaderVersion": "バージョン",
+
+ "Settings.ModLoaderDebugSettings": "デバック設定",
+ "Settings.ModLoaderDebugSettings.RefreshLocale": "ロケールを更新",
+ "Settings.ModLoaderDebugSettings.LocaleCount": "ロケールキーを数える",
+ "Settings.ModLoaderDebugSettings.LocaleKeyCount": "ロケールの個数",
+ "Settings.ModLoaderDebugSettings.ForceAssetUpdate": "アセットを強制的に更新"
}
}
\ No newline at end of file
diff --git a/MonkeyLoader.GamePacks.ResoniteModLoader/Locale/pl.json b/MonkeyLoader.GamePacks.ResoniteModLoader/Locale/pl.json
new file mode 100644
index 0000000..a551a17
--- /dev/null
+++ b/MonkeyLoader.GamePacks.ResoniteModLoader/Locale/pl.json
@@ -0,0 +1,31 @@
+{
+ "localeCode": "pl",
+ "authors": [ "Alex_2Pi" ],
+ "messages": {
+ "Settings.ModLoaderSettings": "ResoniteModLoader Ustawienia",
+
+ "Settings.ModLoaderSettings.DebugMode": "Włącz Debugowanie",
+ "Settings.ModLoaderSettings.DebugMode.Description": "Włącza dziennik debugowania",
+ "Settings.ModLoaderSettings.HideVisuals": "Ukryj podgląd",
+ "Settings.ModLoaderSettings.HideVisuals.Description": "Ukrywa pasek postępu Modloadera podczas uruchamiania",
+ "Settings.ModLoaderSettings.LoadedMods": "Załadowane Modyfikacje",
+ "Settings.ModLoaderSettings.ModLoaderVersion": "Wersja",
+
+ "Settings.ModLoaderDebugSettings": "Ustawienia debugowania",
+ "Settings.ModLoaderDebugSettings.RefreshLocale": "Odśwież ustawienia językowe",
+ "Settings.ModLoaderDebugSettings.LocaleCount": "Zlicz klucze językowe",
+ "Settings.ModLoaderDebugSettings.LocaleKeyCount": "Ilość kluczy lokalnych",
+ "Settings.ModLoaderDebugSettings.ForceAssetUpdate": "Wymuszona aktualizacja zasobów",
+
+ "Settings.ModSettings": "Ustawienia modyfikacji",
+ "Settings.ModSettings.ModList": "Edytuj ustawienia modyfikacji",
+ "Settings.ModSettings.ModList.Breadcrumb": "Ustawienia modyfikacji",
+ "Settings.ModSettings.NoMods": "Brak załadowanych modów",
+ "Settings.ModSettings.NoModsWithConfig": "Brak modów z konfiguracjami do pokazania",
+ "Settings.ModSettings.NoConfigs": "Dla wybranego modu nie są dostępne żadne ustawienia.",
+ "Settings.ModSettings.ShowInternal": "Pokaż konfiguracje do użytku wewnętrznego",
+ "Settings.ModSettings.ShowInternal.Description": "Konfiguracje wewnętrzne nie są zazwyczaj przeznaczone do bezpośredniej zmiany przez użytkownika. Zmiana ich spowodować niepożądane zachowania.",
+ "Settings.ModSettings.ShowAll": "Pokaż wszystkie modyfikacje",
+ "Settings.ModSettings.ShowAll.Description": "Pokaż wszystkie wpisy dotyczące modów, w tym te bez ustawień."
+ }
+}
\ No newline at end of file
diff --git a/MonkeyLoader.GamePacks.ResoniteModLoader/Locale/zh-cn.json b/MonkeyLoader.GamePacks.ResoniteModLoader/Locale/zh-cn.json
new file mode 100644
index 0000000..f01f90a
--- /dev/null
+++ b/MonkeyLoader.GamePacks.ResoniteModLoader/Locale/zh-cn.json
@@ -0,0 +1,33 @@
+{
+ "localeCode": "zh-cn",
+ "authors": [ "modimobeikete" ],
+ "messages": {
+ "Settings.Category.ResoniteModLoader": "Resonite模组加载器",
+ "Settings.ModLoaderSettings": "Resonite模组加载器设置",
+
+ "Settings.ModLoaderSettings.DebugMode": "开启调试模式",
+ "Settings.ModLoaderSettings.DebugMode.Description": "开启调试日志",
+ "Settings.ModLoaderSettings.HideVisuals": "隐藏模组加载器进度条",
+ "Settings.ModLoaderSettings.HideVisuals.Description": "启动时隐藏模组加载器进度条",
+ "Settings.ModLoaderSettings.LoadedMods": "已加载的模组",
+ "Settings.ModLoaderSettings.ModLoaderVersion": "版本",
+ "Settings.ModLoaderSettings.ProjectLink": "Github仓库",
+
+ "Settings.ModLoaderDebugSettings": "调试设置",
+ "Settings.ModLoaderDebugSettings.RefreshLocale": "刷新语言",
+ "Settings.ModLoaderDebugSettings.LocaleCount": "计算语言文本",
+ "Settings.ModLoaderDebugSettings.LocaleKeyCount": "语言文本数",
+ "Settings.ModLoaderDebugSettings.ForceAssetUpdate": "资产强制更新",
+
+ "Settings.ModSettings": "模组设置",
+ "Settings.ModSettings.ModList": "编辑模组设置",
+ "Settings.ModSettings.ModList.Breadcrumb": "模组设置",
+ "Settings.ModSettings.NoMods": "没有加载的模组",
+ "Settings.ModSettings.NoModsWithConfig": "模组内没有可显示的配置",
+ "Settings.ModSettings.NoConfigs": "该模组没有可用的设置",
+ "Settings.ModSettings.ShowInternal": "显示内部可用配置",
+ "Settings.ModSettings.ShowInternal.Description": "内部配置通常不打算由用户直接更改。可能会导致意外行为。",
+ "Settings.ModSettings.ShowAll": "展示所有模组",
+ "Settings.ModSettings.ShowAll.Description": "显示模组的所有内容,包括没有设置的。"
+ }
+}
\ No newline at end of file
diff --git a/MonkeyLoader.GamePacks.ResoniteModLoader/Locale/zh-tw.json b/MonkeyLoader.GamePacks.ResoniteModLoader/Locale/zh-tw.json
new file mode 100644
index 0000000..04e0e89
--- /dev/null
+++ b/MonkeyLoader.GamePacks.ResoniteModLoader/Locale/zh-tw.json
@@ -0,0 +1,32 @@
+{
+ "localeCode": "zh-tw",
+ "authors": [ "Meow Wei 魏喵" ],
+ "messages": {
+ "Settings.Category.ResoniteModLoader": "RML",
+ "Settings.ModLoaderSettings": "ResoniteModLoader 設定",
+
+ "Settings.ModLoaderSettings.DebugMode": "啟用除錯模式",
+ "Settings.ModLoaderSettings.DebugMode.Description": "本選項會啟用除錯記錄檔。",
+ "Settings.ModLoaderSettings.HideVisuals": "隱藏 Mod 載入顯示",
+ "Settings.ModLoaderSettings.HideVisuals.Description": "本選項啟動時,會隱藏 Mod 載入狀態的顯示。",
+ "Settings.ModLoaderSettings.LoadedMods": "已載入的 Mod 數量",
+ "Settings.ModLoaderSettings.ModLoaderVersion": "版本",
+ "Settings.ModLoaderSettings.ProjectLink": "GitHub 專案網址",
+
+ "Settings.ModLoaderDebugSettings": "除錯設定",
+ "Settings.ModLoaderDebugSettings.RefreshLocale": "更新語系檔",
+ "Settings.ModLoaderDebugSettings.LocaleCount": "統計語系鍵",
+ "Settings.ModLoaderDebugSettings.LocaleKeyCount": "語系鍵數量",
+ "Settings.ModLoaderDebugSettings.ForceAssetUpdate": "強制更新資產",
+
+ "Settings.ModSettings": "Mod 設定",
+ "Settings.ModSettings.ModList": "變更 Mod 設定",
+ "Settings.ModSettings.ModList.Breadcrumb": "Mod 設定",
+ "Settings.ModSettings.NoMods": "未載入任何 Mod",
+ "Settings.ModSettings.NoConfigs": "目前選擇的 Mod 沒有提供任何設定。",
+ "Settings.ModSettings.ShowInternal": "顯示內部用設定",
+ "Settings.ModSettings.ShowInternal.Description": "內部用設定通常不是設計給使用者調整的選項,調整可能會導致非預期的效果。",
+ "Settings.ModSettings.ShowAll": "顯示所有 Mod",
+ "Settings.ModSettings.ShowAll.Description": "在列表中顯示所有 Mod,包含沒有提供設定在內的 Mod。"
+ }
+}
\ No newline at end of file
diff --git a/MonkeyLoader.GamePacks.ResoniteModLoader/ModConfigurationKey.cs b/MonkeyLoader.GamePacks.ResoniteModLoader/ModConfigurationKey.cs
index 269ce2b..de0eef6 100644
--- a/MonkeyLoader.GamePacks.ResoniteModLoader/ModConfigurationKey.cs
+++ b/MonkeyLoader.GamePacks.ResoniteModLoader/ModConfigurationKey.cs
@@ -158,7 +158,7 @@ public ModConfigurationKey(string name, string? description = null, Func? com
{
if (string.IsNullOrWhiteSpace(name))
{
- ModLoader.Logger.Warn(() => $"ModConfigurationKey with description [{description}] has null or whitespace name - using Spacer name!");
+ ModLoaderHook.Logger.Warn(() => $"ModConfigurationKey with description [{description}] has null or whitespace name - using Spacer name!");
Key = new($"Spacer-{name?.GetHashCode() ?? description?.GetHashCode() ?? _replacementCounter++}",
description, computeDefault, internalAccessOnly, valueValidator);
diff --git a/MonkeyLoader.GamePacks.ResoniteModLoader/ModLoader.cs b/MonkeyLoader.GamePacks.ResoniteModLoader/ModLoader.cs
index 0f2156b..b50a47b 100644
--- a/MonkeyLoader.GamePacks.ResoniteModLoader/ModLoader.cs
+++ b/MonkeyLoader.GamePacks.ResoniteModLoader/ModLoader.cs
@@ -1,14 +1,4 @@
using Elements.Core;
-using FrooxEngine;
-using HarmonyLib;
-using MonkeyLoader;
-using MonkeyLoader.Meta;
-using MonkeyLoader.NuGet;
-using MonkeyLoader.Patching;
-using MonkeyLoader.Resonite;
-using MonkeyLoader.Resonite.Features.FrooxEngine;
-using NuGet.Packaging.Core;
-using NuGet.Versioning;
using System.Reflection;
namespace ResoniteModLoader
@@ -16,20 +6,29 @@ namespace ResoniteModLoader
///
/// Contains the actual mod loader.
///
- [HarmonyPatchCategory(nameof(ModLoader))]
- [HarmonyPatch(typeof(EngineInitializer), nameof(EngineInitializer.InitializeFrooxEngine))]
- public sealed class ModLoader : ResoniteMonkey
+ public sealed class ModLoader
{
///
/// ResoniteModLoader's version
///
public static readonly string VERSION = VERSION_CONSTANT;
- internal const string VERSION_CONSTANT = "4.2.0";
+ internal const string VERSION_CONSTANT = "5.0.1";
private static readonly Lazy _isHeadless = new(()
=> AppDomain.CurrentDomain.GetAssemblies()
- .Any(assembly => assembly.GetName().Name?.StartsWith("Resonite") ?? false));
+ .SelectMany(static assembly =>
+ {
+ try
+ {
+ return assembly.GetTypes();
+ }
+ catch (ReflectionTypeLoadException typeLoadException)
+ {
+ return typeLoadException.Types ?? [];
+ }
+ })
+ .Any(static type => type?.Namespace is "FrooxEngine.Headless"));
///
/// Gets whether this is running on a headless client.
@@ -37,137 +36,11 @@ public sealed class ModLoader : ResoniteMonkey
/// true if ResoniteModLoader was loaded by a headless; otherwise, false.
public static bool IsHeadless => _isHeadless.Value;
- ///
- public override string Name { get; } = "ModLoader";
-
///
- /// Allows reading metadata for all loaded mods
+ /// Allows reading metadata for all loaded mods.
///
- /// A new list containing each loaded mod
+ /// A sequence of all loaded resonite mods.
public static IEnumerable Mods()
- {
- return Mod.Loader.RegularMods
- .OfType()
- .SelectMany(rmlMod => rmlMod.Monkeys)
- .Cast();
- }
-
- ///
- protected override IEnumerable GetFeaturePatches()
- {
- yield return new FeaturePatch(PatchCompatibility.HookOnly);
- }
-
- ///
- protected override bool OnEngineInit()
- {
- LoadProgressReporter.AddFixedPhases(4);
-
- return base.OnEngineInit();
- }
-
- ///
- protected override bool OnEngineReady() => true;
-
- ///
- protected override bool OnLoaded() => base.OnEngineReady();
-
- private static IEnumerable GetAssemblyPaths(string root)
- {
- if (!Directory.Exists(root))
- yield break;
-
- foreach (var file in Directory.EnumerateFiles(root, "*.dll"))
- {
- if (Path.GetExtension(file).Equals(".dll", StringComparison.OrdinalIgnoreCase))
- yield return file;
- }
- }
-
- [HarmonyPostfix]
- private static async Task InitializeFrooxEnginePostfixAsync(Task __result)
- {
- await __result;
-
- LoadProgressReporter.AdvanceFixedPhase("Loading RML Libraries...");
-
- try
- {
- foreach (var file in GetAssemblyPaths("rml_libs"))
- {
- LoadProgressReporter.SetSubphase($"{Environment.NewLine} {Path.GetFileNameWithoutExtension(file)}");
-
- try
- {
- var assembly = Mod.Loader.AssemblyLoadStrategy.LoadFile(Path.GetFullPath(file));
- var name = assembly.GetName();
-
- Mod.Loader.NuGet.Add(new LoadedNuGetPackage(new PackageIdentity(name.Name, new NuGetVersion(name.Version!)), NuGetHelper.Framework));
-
- Logger.Info(() => $"Loaded library {name.Name}.{name.Version} from rml_libs: {file}");
- }
- catch (Exception ex)
- {
- Logger.Warn(() => ex.Format($"Failed to load library from rml_libs: {file}"));
- }
- }
-
- LoadProgressReporter.AdvanceFixedPhase("Collecting RML Mods...");
-
- var rmlMods = await LoadModsAsync().ToArrayAsync();
-
- LoadProgressReporter.AdvanceFixedPhase("Running RML Mods...");
- await Task.Run(() => Mod.Loader.RunMods(rmlMods));
- LoadProgressReporter.AdvanceFixedPhase("Done with RML");
- }
- catch (Exception ex)
- {
- Logger.Error(() => ex.Format("Exception in execution hook!"));
- LoadProgressReporter.AdvanceFixedPhase("Error running RML Mods!");
- }
- }
-
- private static async IAsyncEnumerable LoadModsAsync()
- {
- var modAssemblies = new List();
-
- foreach (var file in GetAssemblyPaths("rml_mods"))
- {
- try
- {
- var modAssembly = await Task.Run(() => Mod.Loader.AssemblyLoadStrategy.LoadFile(Path.GetFullPath(file!)));
- modAssemblies.Add(modAssembly);
- }
- catch (Exception ex)
- {
- Logger.Warn(() => ex.Format($"Failed to load assembly from rml_mods: {file}"));
- }
- }
-
- foreach (var modAssembly in modAssemblies)
- {
- var fileName = Path.GetFileName(modAssembly.Location);
- LoadProgressReporter.SetSubphase($"{Environment.NewLine} {modAssembly.GetName().Name!}");
-
- RmlMod? rmlMod = null;
- var success = true;
-
- try
- {
- rmlMod = new RmlMod(Mod.Loader, modAssembly);
- Logger.Info(() => $"Loaded mod from rml_mods: {fileName}");
-
- Mod.Loader.AddMod(rmlMod);
- }
- catch (Exception ex)
- {
- success = false;
- Logger.Warn(() => ex.Format($"Failed to load mod from rml_mods: {fileName}"));
- }
-
- if (success)
- yield return rmlMod!;
- }
- }
+ => ModLoaderHook.ResoniteMods;
}
}
\ No newline at end of file
diff --git a/MonkeyLoader.GamePacks.ResoniteModLoader/ModLoaderHook.cs b/MonkeyLoader.GamePacks.ResoniteModLoader/ModLoaderHook.cs
new file mode 100644
index 0000000..31aa831
--- /dev/null
+++ b/MonkeyLoader.GamePacks.ResoniteModLoader/ModLoaderHook.cs
@@ -0,0 +1,229 @@
+using Elements.Assets;
+using FrooxEngine;
+using HarmonyLib;
+using MonkeyLoader;
+using MonkeyLoader.Meta;
+using MonkeyLoader.NuGet;
+using MonkeyLoader.Patching;
+using MonkeyLoader.Resonite;
+using MonkeyLoader.Resonite.Features.FrooxEngine;
+using MonkeyLoader.Resonite.Locale;
+using NuGet.Packaging.Core;
+using NuGet.Versioning;
+using System.Reflection;
+using System.Security.Cryptography;
+using System.Text.Json;
+
+namespace ResoniteModLoader
+{
+ ///
+ /// Contains the actual mod loading hook executed by MonkeyLoader.
+ ///
+ [HarmonyPatchCategory(nameof(ModLoaderHook))]
+ [HarmonyPatch(typeof(EngineInitializer), nameof(EngineInitializer.InitializeFrooxEngine))]
+ internal sealed class ModLoaderHook : ResoniteAsyncEventHandlerMonkey
+ {
+ ///
+ /// Gets a sequence of all currently loaded localized s.
+ ///
+ public static IEnumerable LocalizedResoniteMods
+ => RmlMods.Where(static rmlMod => rmlMod.IsLocalized)
+ .SelectMany(static rmlMod => rmlMod.Monkeys)
+ .Cast();
+
+ ///
+ /// Gets a sequence of all currently loaded s.
+ ///
+ public static IEnumerable ResoniteMods
+ => RmlMods.SelectMany(static rmlMod => rmlMod.Monkeys)
+ .Cast();
+
+ ///
+ /// Gets a sequence of all currently loaded s.
+ ///
+ public static IEnumerable RmlMods
+ => Mod.Loader.RegularMods.OfType();
+
+ ///
+ public override string Name { get; } = "ModLoader";
+
+ public override int Priority => HarmonyLib.Priority.VeryLow;
+
+ ///
+ protected override IEnumerable GetFeaturePatches()
+ {
+ yield return new FeaturePatch(PatchCompatibility.HookOnly);
+ }
+
+ ///
+ /// Loads locale json files from the loaded assemblies.
+ ///
+ protected override async Task Handle(LocaleLoadingEvent eventData)
+ {
+ // We don't need to load the ResoniteModLoader locale here, as that will be handled by the ML Resonite Integration
+ // However the files are also included as embedded resources for completeness and compatibility with the reference
+
+ foreach (var mod in LocalizedResoniteMods)
+ {
+ var type = mod.GetType();
+ var assembly = type.Assembly;
+ var localeResourceName = $"{type.Namespace}.Locale.{eventData.LocaleCode}.json";
+
+ var realName = assembly.GetManifestResourceNames()
+ .FirstOrDefault(resourceName => localeResourceName.Equals(resourceName, StringComparison.OrdinalIgnoreCase));
+
+ if (realName is null)
+ continue;
+
+ try
+ {
+ if (assembly.GetManifestResourceStream(realName) is not System.IO.Stream resourceStream)
+ continue;
+
+ var localeData = await JsonSerializer.DeserializeAsync(resourceStream);
+
+ if (localeData is null)
+ continue;
+
+ if (!eventData.LocaleCode.Equals(localeData.LocaleCode, StringComparison.OrdinalIgnoreCase))
+ Logger.Warn(() => $"Detected locale data with wrong locale code from locale resource! Wanted [{eventData.LocaleCode}] - got [{localeData.LocaleCode}] in file: {mod.Mod.Id}:{realName}");
+
+ eventData.LocaleResource.LoadDataAdditively(localeData);
+ }
+ catch (Exception ex)
+ {
+ Logger.Error(() => ex.Format($"Failed to deserialize resource as LocaleData: {mod.Mod.Id}:{realName}"));
+ }
+ }
+ }
+
+ ///
+ protected override bool OnEngineInit()
+ {
+ LoadProgressReporter.AddFixedPhases(4);
+
+ return base.OnEngineInit();
+ }
+
+ ///
+ protected override bool OnEngineReady() => true;
+
+ ///
+ protected override bool OnLoaded() => base.OnEngineReady();
+
+ private static string GenerateSHA256(string filepath)
+ {
+ try
+ {
+ using var hasher = SHA256.Create();
+ using var stream = File.OpenRead(filepath);
+
+ return Convert.ToHexString(hasher.ComputeHash(stream));
+ }
+ catch
+ {
+ return "Failed to generate hash";
+ }
+ }
+
+ private static IEnumerable GetAssemblyPaths(string root)
+ {
+ if (!Directory.Exists(root))
+ yield break;
+
+ foreach (var file in Directory.EnumerateFiles(root, "*.dll"))
+ {
+ if (Path.GetExtension(file).Equals(".dll", StringComparison.OrdinalIgnoreCase))
+ yield return file;
+ }
+ }
+
+ [HarmonyPostfix]
+ private static async Task InitializeFrooxEnginePostfixAsync(Task __result)
+ {
+ await __result;
+
+ LoadProgressReporter.AdvanceFixedPhase("Loading RML Libraries...");
+
+ try
+ {
+ foreach (var file in GetAssemblyPaths("rml_libs"))
+ {
+ LoadProgressReporter.SetSubphase($"{Environment.NewLine} {Path.GetFileNameWithoutExtension(file)}");
+
+ try
+ {
+ var assembly = Mod.Loader.AssemblyLoadStrategy.LoadFile(Path.GetFullPath(file));
+ var name = assembly.GetName();
+
+ Mod.Loader.NuGet.Add(new LoadedNuGetPackage(new PackageIdentity(name.Name, new NuGetVersion(name.Version!)), NuGetHelper.Framework));
+
+ Logger.Info(() => $"Loaded library {name.Name}.{name.Version} from rml_libs: {file}");
+ }
+ catch (Exception ex)
+ {
+ Logger.Warn(() => ex.Format($"Failed to load library from rml_libs: {file}"));
+ }
+ }
+
+ LoadProgressReporter.AdvanceFixedPhase("Collecting RML Mods...");
+
+ var rmlMods = await LoadModsAsync().ToArrayAsync();
+
+ LoadProgressReporter.AdvanceFixedPhase("Running RML Mods...");
+ await Task.Run(() => Mod.Loader.RunMods(rmlMods));
+ LoadProgressReporter.AdvanceFixedPhase("Done with RML");
+ }
+ catch (Exception ex)
+ {
+ Logger.Error(() => ex.Format("Exception in execution hook!"));
+ LoadProgressReporter.AdvanceFixedPhase("Error running RML Mods!");
+ }
+ }
+
+ private static async IAsyncEnumerable LoadModsAsync()
+ {
+ var modAssemblies = new List<(Assembly, string)>();
+
+ foreach (var file in GetAssemblyPaths("rml_mods"))
+ {
+ var hash = GenerateSHA256(file);
+
+ try
+ {
+ var modAssembly = await Task.Run(() => Mod.Loader.AssemblyLoadStrategy.LoadFile(Path.GetFullPath(file!)));
+ modAssemblies.Add((modAssembly, hash));
+ }
+ catch (Exception ex)
+ {
+ Logger.Warn(() => ex.Format($"Failed to load assembly from rml_mods: {file} with SHA256: {hash}"));
+ }
+ }
+
+ foreach (var (modAssembly, hash) in modAssemblies)
+ {
+ var fileName = Path.GetFileName(modAssembly.Location);
+ LoadProgressReporter.SetSubphase($"{Environment.NewLine} {modAssembly.GetName().Name!}");
+
+ RmlMod? rmlMod = null;
+ var success = true;
+
+ try
+ {
+ rmlMod = new RmlMod(Mod.Loader, modAssembly);
+ Logger.Info(() => $"Loaded mod [{rmlMod.Id}/{rmlMod.Version}] ({fileName}) by {rmlMod.Authors.Join()} with SHA256: {hash}");
+
+ Mod.Loader.AddMod(rmlMod);
+ }
+ catch (Exception ex)
+ {
+ success = false;
+ Logger.Warn(() => ex.Format($"Failed to load mod from rml_mods: {fileName}"));
+ }
+
+ if (success)
+ yield return rmlMod!;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/MonkeyLoader.GamePacks.ResoniteModLoader/MonkeyLoader.GamePacks.ResoniteModLoader.csproj b/MonkeyLoader.GamePacks.ResoniteModLoader/MonkeyLoader.GamePacks.ResoniteModLoader.csproj
index 389da76..a4a5ff3 100644
--- a/MonkeyLoader.GamePacks.ResoniteModLoader/MonkeyLoader.GamePacks.ResoniteModLoader.csproj
+++ b/MonkeyLoader.GamePacks.ResoniteModLoader/MonkeyLoader.GamePacks.ResoniteModLoader.csproj
@@ -15,7 +15,7 @@
Banane9, Nytra
- 4.2.0.1
+ 5.0.1
This MonkeyLoader Game Pack for Resonite enables loading ResoniteModLoader mods as MonkeyLoader mods.
README.md
@@ -29,18 +29,18 @@
+
+
-
-
+
-
-
+
$(PkgMonkeyLoader_GamePacks_Resonite)\lib\net10.0\pre-patchers\MonkeyLoader.Resonite.Data.dll
diff --git a/MonkeyLoader.GamePacks.ResoniteModLoader/ResoniteMod.cs b/MonkeyLoader.GamePacks.ResoniteModLoader/ResoniteMod.cs
index 2deb69c..e67e889 100644
--- a/MonkeyLoader.GamePacks.ResoniteModLoader/ResoniteMod.cs
+++ b/MonkeyLoader.GamePacks.ResoniteModLoader/ResoniteMod.cs
@@ -154,7 +154,7 @@ internal static Logger GetLoggerFromStackTrace(StackTrace stackTrace)
}
}
- return ModLoader.Logger;
+ return ModLoaderHook.Logger;
}
///
diff --git a/MonkeyLoader.GamePacks.ResoniteModLoader/RmlMod.cs b/MonkeyLoader.GamePacks.ResoniteModLoader/RmlMod.cs
index b200b9b..851edf2 100644
--- a/MonkeyLoader.GamePacks.ResoniteModLoader/RmlMod.cs
+++ b/MonkeyLoader.GamePacks.ResoniteModLoader/RmlMod.cs
@@ -19,9 +19,8 @@ internal sealed class RmlMod : Mod
internal static readonly Dictionary AssemblyLookupMap = [];
private static readonly Type _resoniteModType = typeof(ResoniteMod);
- private static readonly Uri _rmlIconUrl = new("https://avatars.githubusercontent.com/u/145755526");
- private readonly Assembly _assembly;
+ private static readonly Uri _rmlIconUrl = new("https://avatars.githubusercontent.com/u/145755526");
///
public override string Description => "RML Mods don't have descriptions.";
@@ -50,13 +49,24 @@ internal sealed class RmlMod : Mod
///
public override NuGetFramework TargetFramework => NuGetHelper.Framework;
+ ///
+ /// Gets the this mod is defined in.
+ ///
+ internal Assembly Assembly { get; }
+
+ ///
+ /// Gets whether this mod's contains locale
+ /// resources.
+ ///
+ internal bool IsLocalized { get; }
+
///
public RmlMod(MonkeyLoader.MonkeyLoader loader, Assembly assembly)
: base(loader, assembly.Location, false)
{
FileSystem = new MemoryFileSystem() { Name = $"Dummy FileSystem for {assembly.GetName().Name}" };
- _assembly = assembly;
+ Assembly = assembly;
var modType = assembly.GetTypes().Single(_resoniteModType.IsAssignableFrom);
var resoniteMod = (ResoniteMod)Activator.CreateInstance(modType)!;
@@ -81,18 +91,23 @@ public RmlMod(MonkeyLoader.MonkeyLoader loader, Assembly assembly)
// Add dependencies after refactoring MKL
//foreach (var referencedAssembly in assembly.GetReferencedAssemblies())
// dependencies.Add(referencedAssembly.Name, new DependencyReference())
+
+ var localePrefix = $"{modType.Namespace}.Locale.";
+
+ IsLocalized = assembly.GetManifestResourceNames()
+ .Any(name => name.StartsWith(localePrefix, StringComparison.OrdinalIgnoreCase) && name.EndsWith(".json", StringComparison.OrdinalIgnoreCase));
}
public override bool TryResolveAssembly(AssemblyName assemblyName, [NotNullWhen(true)] out Assembly? assembly)
{
- if (assemblyName.Name != _assembly.GetName().FullName)
+ if (assemblyName.Name != Assembly.GetName().FullName)
{
assembly = null;
return false;
}
- Logger.Debug(() => $"Resolving assembly {assemblyName.Name} to {_assembly.FullName} through RmlMod");
- assembly = _assembly;
+ Logger.Debug(() => $"Resolving assembly {assemblyName.Name} to {Assembly.FullName} through RmlMod");
+ assembly = Assembly;
return true;
}