From 46121e7f85b5e0889437d9b277b27fea1fc790d5 Mon Sep 17 00:00:00 2001 From: Dingo Date: Fri, 13 Jan 2023 18:55:00 +0200 Subject: [PATCH] 2.0 release - Switched to BepInEx - Simplified code following vanilla changes - Added translations --- .../StorageInfo/Languages/English.json | 1 - .../plugins/StorageInfo/Languages/French.json | 5 + .../StorageInfo/Languages/German.json | 1 - .../plugins/StorageInfo/Languages/Polish.json | 5 + .../StorageInfo}/Languages/Russian.json | 1 - BepInEx/plugins/StorageInfo/StorageInfo.dll | Bin 0 -> 8192 bytes HarmonyPatches.cs | 65 +++++++ ModPlugin.cs | 23 +++ .../Properties => Properties}/AssemblyInfo.cs | 6 +- QMods/StorageInfo/Languages/Russian.json | 6 - QMods/StorageInfo/StorageInfo.dll | Bin 9216 -> 0 bytes QMods/StorageInfo/mod.json | 10 -- README.md | 73 ++++---- .../StorageInfo.csproj => StorageInfo.csproj | 65 ++++--- StorageInfo/Entry.cs | 22 --- StorageInfo/HarmonyPatches.cs | 162 ------------------ StorageInfo/Languages/English.json | 6 - StorageInfo/Languages/German.json | 6 - StorageInfo/mod.json | 10 -- StorageInfo/Translation.cs => Translation.cs | 25 +-- 20 files changed, 184 insertions(+), 308 deletions(-) rename {QMods => BepInEx/plugins}/StorageInfo/Languages/English.json (71%) create mode 100644 BepInEx/plugins/StorageInfo/Languages/French.json rename {QMods => BepInEx/plugins}/StorageInfo/Languages/German.json (73%) create mode 100644 BepInEx/plugins/StorageInfo/Languages/Polish.json rename {StorageInfo => BepInEx/plugins/StorageInfo}/Languages/Russian.json (72%) create mode 100644 BepInEx/plugins/StorageInfo/StorageInfo.dll create mode 100644 HarmonyPatches.cs create mode 100644 ModPlugin.cs rename {StorageInfo/Properties => Properties}/AssemblyInfo.cs (90%) delete mode 100644 QMods/StorageInfo/Languages/Russian.json delete mode 100644 QMods/StorageInfo/StorageInfo.dll delete mode 100644 QMods/StorageInfo/mod.json rename StorageInfo/StorageInfo.csproj => StorageInfo.csproj (61%) delete mode 100644 StorageInfo/Entry.cs delete mode 100644 StorageInfo/HarmonyPatches.cs delete mode 100644 StorageInfo/Languages/English.json delete mode 100644 StorageInfo/Languages/German.json delete mode 100644 StorageInfo/mod.json rename StorageInfo/Translation.cs => Translation.cs (76%) diff --git a/QMods/StorageInfo/Languages/English.json b/BepInEx/plugins/StorageInfo/Languages/English.json similarity index 71% rename from QMods/StorageInfo/Languages/English.json rename to BepInEx/plugins/StorageInfo/Languages/English.json index 03d467f..3b082bb 100644 --- a/QMods/StorageInfo/Languages/English.json +++ b/BepInEx/plugins/StorageInfo/Languages/English.json @@ -1,6 +1,5 @@ { "ContainerEmpty": "empty", - "ContainerOneItem": "1 item (not full)", "ContainerFull": "full", "ContainerNonempty": "{0} items (not full)" } diff --git a/BepInEx/plugins/StorageInfo/Languages/French.json b/BepInEx/plugins/StorageInfo/Languages/French.json new file mode 100644 index 0000000..5ffa5a1 --- /dev/null +++ b/BepInEx/plugins/StorageInfo/Languages/French.json @@ -0,0 +1,5 @@ +{ + "ContainerEmpty": "vide", + "ContainerFull": "plein", + "ContainerNonempty": "{0} objets (pas plein)" +} diff --git a/QMods/StorageInfo/Languages/German.json b/BepInEx/plugins/StorageInfo/Languages/German.json similarity index 73% rename from QMods/StorageInfo/Languages/German.json rename to BepInEx/plugins/StorageInfo/Languages/German.json index 0415633..4f3ff98 100644 --- a/QMods/StorageInfo/Languages/German.json +++ b/BepInEx/plugins/StorageInfo/Languages/German.json @@ -1,6 +1,5 @@ { "ContainerEmpty": "Leer", - "ContainerOneItem": "1 Gegenstand", "ContainerFull": "Voll", "ContainerNonempty": "{0} Gegenstände" } diff --git a/BepInEx/plugins/StorageInfo/Languages/Polish.json b/BepInEx/plugins/StorageInfo/Languages/Polish.json new file mode 100644 index 0000000..5aa02df --- /dev/null +++ b/BepInEx/plugins/StorageInfo/Languages/Polish.json @@ -0,0 +1,5 @@ +{ + "ContainerEmpty": "puste", + "ContainerFull": "pełne", + "ContainerNonempty": "{0} przedmioty/ów (nie pełne)" +} diff --git a/StorageInfo/Languages/Russian.json b/BepInEx/plugins/StorageInfo/Languages/Russian.json similarity index 72% rename from StorageInfo/Languages/Russian.json rename to BepInEx/plugins/StorageInfo/Languages/Russian.json index 963b2e3..8f69162 100644 --- a/StorageInfo/Languages/Russian.json +++ b/BepInEx/plugins/StorageInfo/Languages/Russian.json @@ -1,6 +1,5 @@ { "ContainerEmpty": "Пусто", - "ContainerOneItem": "Заполнено 1 предметом", "ContainerFull": "Полностью заполнено", "ContainerNonempty": "Заполнено {0} предметами" } diff --git a/BepInEx/plugins/StorageInfo/StorageInfo.dll b/BepInEx/plugins/StorageInfo/StorageInfo.dll new file mode 100644 index 0000000000000000000000000000000000000000..c53278e863886b108ea705979ad25eab99785061 GIT binary patch literal 8192 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 literal 0 HcmV?d00001 diff --git a/HarmonyPatches.cs b/HarmonyPatches.cs new file mode 100644 index 0000000..7500723 --- /dev/null +++ b/HarmonyPatches.cs @@ -0,0 +1,65 @@ +using HarmonyLib; +using SMLHelper.V2.Utility; + +namespace StorageInfo +{ + public class HarmonyPatches + { + private static void Patch_OnHandHover_Postfix(StorageContainer __instance) + { + ItemsContainer itemStorage = __instance.container; + + if (itemStorage != null) + { + SetCustomInteractText(itemStorage); + } + } + + private static void Patch_SetCurrentLanguage_Postfix() + { + Translation.ReloadLanguage(); + } + + internal static void InitializeHarmony() + { + Harmony harmony = new Harmony("Dingo.Harmony.StorageInfo"); + + /* Remove original SetInteractText and inject SetCustomInteractText */ + // Patch: StorageContainer.OnHandHover + harmony.Patch( + original: AccessTools.Method(typeof(StorageContainer), nameof(StorageContainer.OnHandHover)), + postfix: new HarmonyMethod(typeof(HarmonyPatches), nameof(HarmonyPatches.Patch_OnHandHover_Postfix))); + + /* Reset language cache on game language change */ + // Patch: Language.SetCurrentLanguage + harmony.Patch( + original: AccessTools.Method(typeof(Language), nameof(Language.SetCurrentLanguage)), + postfix: new HarmonyMethod(typeof(HarmonyPatches), nameof(HarmonyPatches.Patch_SetCurrentLanguage_Postfix))); + } + + public static void SetCustomInteractText(ItemsContainer itemStorage) + { + string customSubscriptText = string.Empty; + + if (itemStorage != null) + { + if (itemStorage.IsEmpty()) + { + customSubscriptText = "ContainerEmpty".Translate(); + } + + else if (itemStorage.IsFull()) + { + customSubscriptText = "ContainerFull".Translate(); + } + + else + { + customSubscriptText = "ContainerNonempty".FormatTranslate(itemStorage.count.ToString()); + } + } + + HandReticle.main.SetText(HandReticle.TextType.HandSubscript, customSubscriptText, false); + } + } +} diff --git a/ModPlugin.cs b/ModPlugin.cs new file mode 100644 index 0000000..d146c79 --- /dev/null +++ b/ModPlugin.cs @@ -0,0 +1,23 @@ +using BepInEx; +using UnityEngine; + +namespace StorageInfo +{ + [BepInPlugin(modGUID, modName, modVersion)] + public class ModPlugin : BaseUnityPlugin + { + private const string modGUID = "Dingo.SN.StorageInfo"; + internal const string modName = "Storage Info"; + private const string modVersion = "2.0.0"; + + internal static void LogMessage(string message) + { + Debug.Log($"{modName} :: " + message); + } + + public void Start() + { + HarmonyPatches.InitializeHarmony(); + } + } +} diff --git a/StorageInfo/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs similarity index 90% rename from StorageInfo/Properties/AssemblyInfo.cs rename to Properties/AssemblyInfo.cs index e0da178..6686f09 100644 --- a/StorageInfo/Properties/AssemblyInfo.cs +++ b/Properties/AssemblyInfo.cs @@ -10,7 +10,7 @@ [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("StorageInfo")] -[assembly: AssemblyCopyright("Copyright © Dingo 2019")] +[assembly: AssemblyCopyright("Copyright © Dingo 2023")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.4.0")] -[assembly: AssemblyFileVersion("1.0.4.0")] +[assembly: AssemblyVersion("2.0.0.0")] +[assembly: AssemblyFileVersion("2.0.0.0")] diff --git a/QMods/StorageInfo/Languages/Russian.json b/QMods/StorageInfo/Languages/Russian.json deleted file mode 100644 index 963b2e3..0000000 --- a/QMods/StorageInfo/Languages/Russian.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "ContainerEmpty": "Пусто", - "ContainerOneItem": "Заполнено 1 предметом", - "ContainerFull": "Полностью заполнено", - "ContainerNonempty": "Заполнено {0} предметами" -} diff --git a/QMods/StorageInfo/StorageInfo.dll b/QMods/StorageInfo/StorageInfo.dll deleted file mode 100644 index 83845baace33877d8d448a5bf02af7706c2536f3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9216 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 DY3pTb diff --git a/QMods/StorageInfo/mod.json b/QMods/StorageInfo/mod.json deleted file mode 100644 index c77784e..0000000 --- a/QMods/StorageInfo/mod.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "Id": "StorageInfo", - "DisplayName": "Storage Info", - "Author": "Dingo", - "Version": "1.0.4", - "Enable": true, - "Game": "Subnautica", - "AssemblyName": "StorageInfo.dll", - "EntryMethod": "StorageInfo.Entry.Initialize" -} diff --git a/README.md b/README.md index 586542f..ffea822 100644 --- a/README.md +++ b/README.md @@ -1,54 +1,39 @@ -## **Storage Info by Dingo** +# **Storage Info for Subnautica** -#### **Description:** -In Subnautica, only empty containers relay their status to the player. With this mod containers will always show if they are: -* Empty -* Full -* Have a certain amount of items, but aren't full +### **Description:** -#### **Installation:** -1) Install [QMods](https://www.nexusmods.com/subnautica/mods/201) if you haven't already -2) Install [SMLHelper (Modding Helper)](https://www.nexusmods.com/subnautica/mods/113) -3) Download the zip file from the [Files tab](https://www.nexusmods.com/subnautica/mods/229/?tab=files) -4) Unzip the contents of the zip to the game's main directory (where Subnautica.exe can be found) +In Subnautica, only empty containers relay their status to the player. With this mod containers will always show if they are: +- Empty +- Full +- Have a certain amount of items, but aren't full -#### **(Optional) Translation:** -If you want to contribute a translation for this mod, please follow these steps: -1) Look at the file *"English.json"* in *QMods\StorageInfo\Languages* -2) Copy that file and change the file name to your language. It needs to match the file name in *Subnautica\SNUnmanagedData\LanguageFiles* -3) Translate the file. Do not touch the keys ("ContainerFull"), only the translated values ("completely full") -4) Share the file with me, preferrably over GitHub, a Nexus private message or (if you must) a comment +### **Installation:** -#### **FAQ:** +1. Install [BepInEx for Subnautica](https://www.nexusmods.com/subnautica/mods/1108) +2. Install [SMLHelper (Modding Helper)](https://www.nexusmods.com/subnautica/mods/113) +3. Download the latest zip file from the [Files tab](https://www.nexusmods.com/subnautica/mods/229/?tab=files) +4. Unzip the contents of the zip to the game's main directory (where Subnautica.exe can be found) -* **Q. Is this mod safe to add or remove from an existing save file?** -* A. Perfectly safe. -* **Q. Does this mod have any known conflicts?** -* A. No, unless some other mod patches *StorageContainer.OnHandHover* and doesn't play nice. +### **(Optional) Translation:** -[Source code can be found here.](https://github.com/DingoDjango/snStorageInfo) +1. Navigate to *...\Subnautica\BepInEx\plugins\StorageInfo\Languages* +2. Copy *English.json* and change the file name to match your language + > Valid language names are found in *...\Subnautica\Subnautica_Data\StreamingAssets\SNUnmanagedData\LanguageFiles* +3. Translate the file. Do not touch the keys ("ContainerFull"), only the values ("full") +4. Share the file with me on GitHub or in a Nexus private message -#### **Credits:** -- Powered by [Harmony](https://github.com/pardeike/Harmony) -- Made for the [QMods Subnautica Mod System](https://www.nexusmods.com/subnautica/mods/201) -- Using [SMLHelper](https://www.nexusmods.com/subnautica/mods/113) -- German translation by [acidscorch](https://github.com/acidscorch) -- Russian translation by [mstislavovich](https://forums.nexusmods.com/index.php?/user/23416669-mstislavovich/) +### **FAQ:** +- **Q. Does this mod support the latest Subnautica update?** +- A. Tested on Subnautica version Dec-2022 71137 (Living Large update) +- **Q. Is this mod safe to add or remove from an existing save?** +- A. Yes +- **Q. Does this mod have any known conflicts?** +- A. No, unless some other mod patches *StorageContainer.OnHandHover* and doesn't play nice -2019-03-17 - v1.0.4 -- Added Russian translation by mstislavovich +[Source code can be found here.](https://github.com/DingoDjango/snStorageInfo) -2019-03-16 - v1.0.3 -- Small refactor to language loading - -2019-03-16 - v1.0.2 -- Added German translation by acidscorch -- Some refactoring to load languages properly -- Internal mod structure changes - -2019-03-15 - v1.0.1 -- Bug fixes - -2019-03-15 - v1.0.0 -- Initial mod release +### **Credits:** +- Powered by [Harmony](https://github.com/pardeike/Harmony) +- Using [SMLHelper](https://www.nexusmods.com/subnautica/mods/113) +- Translations by [acidscorch](https://github.com/acidscorch), [mstislavovich](https://forums.nexusmods.com/index.php?/user/23416669-mstislavovich/), [Yanuut](https://github.com/Yanuut), [Zemogiter](https://github.com/Zemogiter) diff --git a/StorageInfo/StorageInfo.csproj b/StorageInfo.csproj similarity index 61% rename from StorageInfo/StorageInfo.csproj rename to StorageInfo.csproj index cf9e324..71a50b4 100644 --- a/StorageInfo/StorageInfo.csproj +++ b/StorageInfo.csproj @@ -9,24 +9,27 @@ Properties StorageInfo StorageInfo - v3.5 + v4.7.2 512 + true embedded false - ..\QMods\$(AssemblyName)\ + BepInEx\plugins\StorageInfo\ DEBUG;TRACE prompt 4 Off 7.1 + false + false none true - ..\QMods\$(AssemblyName)\ + BepInEx\plugins\StorageInfo\ prompt @@ -34,20 +37,34 @@ Off 7.1 AnyCPU + false + false - - C:\Program Files (x86)\Steam\steamapps\common\Subnautica\Subnautica_Data\Managed\0Harmony-1.2.0.1.dll + + C:\Program Files (x86)\Steam\steamapps\common\Subnautica\BepInEx\core\0Harmony.dll False C:\Program Files (x86)\Steam\steamapps\common\Subnautica\Subnautica_Data\Managed\Assembly-CSharp.dll False + + C:\Program Files (x86)\Steam\steamapps\common\Subnautica\Subnautica_Data\Managed\Assembly-CSharp-firstpass.dll + False + + + C:\Program Files (x86)\Steam\steamapps\common\Subnautica\BepInEx\core\BepInEx.dll + False + C:\Program Files (x86)\Steam\steamapps\common\Subnautica\Subnautica_Data\Managed\LitJson.dll False + + C:\Program Files (x86)\Steam\steamapps\common\Subnautica\BepInEx\plugins\Modding Helper\SMLHelper.dll + False + @@ -58,28 +75,36 @@ C:\Program Files (x86)\Steam\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.dll False + + C:\Program Files (x86)\Steam\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.CoreModule.dll + False + + + C:\Program Files (x86)\Steam\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.UI.dll + False + - + - - - Always - - - Always - - - Always - - - Always - - + + SET MODDIR=C:\Program Files (x86)\Steam\steamapps\common\Subnautica\BepInEx\ +SET ZIPFILE=D:\Downloads\$(ProjectName).zip + +xcopy "$(ProjectDir)BepInEx\*" "%25MODDIR%25" /i /e /r /y + +7z a -mx9 "%25ZIPFILE%25" "$(ProjectDir)BepInEx" + +cd $(ProjectDir) +del /f /s /q bin +del /f /s /q obj +rmdir /s /q bin +rmdir /s /q obj + IL_0033: ldarg.0 - * IL_0034: ldfld string StorageContainer::hoverText - * IL_0039: ldarg.0 - * IL_003A: call instance bool StorageContainer::IsEmpty() - * IL_003F: brfalse IL_004E - * IL_0044: ldstr "Empty" - * IL_0049: br IL_0053 - * IL_004E: ldsfld string [mscorlib]System.String::Empty - * IL_0053: callvirt instance void HandReticle::SetInteractText(string, string) - * Last IL index we snip, folding the IL nicely on itself ---> IL_0058: ldsfld class HandReticle HandReticle::main */ - private static IEnumerable Patch_StorageContainer_OnHandHover_Transpiler(IEnumerable instructions) - { - FieldInfo handleReticleMain = AccessTools.Field(typeof(HandReticle), nameof(HandReticle.main)); - MethodInfo setInteractText = AccessTools.Method(typeof(HandReticle), nameof(HandReticle.SetInteractText), new Type[] { typeof(string), typeof(string) }); - MethodInfo callCustomInteractText = AccessTools.Method(typeof(HarmonyPatches), nameof(HarmonyPatches.SetCustomInteractText)); - - if (handleReticleMain == null || setInteractText == null || callCustomInteractText == null) - { - Debug.Log("[StorageInfo] :: Something went wrong while populating transpiler variables. Aborting."); - - return instructions; - } - - List codes = instructions.ToList(); - bool foundFirstHandReticle = false; - int firstIndexToRemove = -1; - int lastIndexToRemove = -1; - - // Find the IL we need to replace - for (int i = 0; i < codes.Count; i++) - { - CodeInstruction instruction = codes[i]; - - // IL_0033 is the first IL we aim to replace - if (!foundFirstHandReticle) - { - if (instruction.opcode == OpCodes.Ldsfld && instruction.operand == handleReticleMain - && codes[i + 1].opcode == OpCodes.Ldarg_0) - { - // Replace Ldarg_0 IL because the first HandleReticle::main is used as an IL label - firstIndexToRemove = i + 1; - - foundFirstHandReticle = true; - } - } - - // IL_0058 is the final IL we aim to replace - else if (instruction.opcode == OpCodes.Ldsfld && instruction.operand == handleReticleMain - && codes[i - 1].opcode == OpCodes.Callvirt && codes[i - 1].operand == setInteractText) - { - lastIndexToRemove = i; - - break; - } - } - - // If all goes well, we now have a range of IL to remove - if (firstIndexToRemove != -1 && lastIndexToRemove != -1) - { - codes.RemoveRange(firstIndexToRemove, lastIndexToRemove - firstIndexToRemove + 1); // Account for zero-based indexing - - // Insert custom text interaction - codes.Insert(codes.Count - 1, new CodeInstruction(OpCodes.Ldarg_0, null)); - codes.Insert(codes.Count - 1, new CodeInstruction(OpCodes.Call, callCustomInteractText)); - - return codes; - } - - else - { - Debug.Log("[StorageInfo] :: Patch error - could not find IL index to modify! Mod has not been enabled."); - Debug.Log($"[StorageInfo] :: emptyCheckIndex = {firstIndexToRemove.ToString()}, stringEmptyIndex = {lastIndexToRemove.ToString()}"); - } - - return instructions; - } - - private static void Patch_SetCurrentLanguage_Postfix() - { - Translation.ReloadLanguage(); - } - - internal static void InitializeHarmony() - { - HarmonyInstance harmony = HarmonyInstance.Create("dingo.storageinfo"); - -#if DEBUG - HarmonyInstance.DEBUG = true; -#endif - - MethodInfo containerOnHandHover = AccessTools.Method(typeof(StorageContainer), nameof(StorageContainer.OnHandHover)); - MethodInfo setLanguage = AccessTools.Method(typeof(Language), nameof(Language.SetCurrentLanguage)); - - // Remove original SetInteractText and inject SetCustomInteractText - harmony.Patch( - original: containerOnHandHover, - prefix: null, - postfix: null, - transpiler: new HarmonyMethod(typeof(HarmonyPatches), nameof(HarmonyPatches.Patch_StorageContainer_OnHandHover_Transpiler))); - - // Reset language cache upon language change - harmony.Patch( - original: setLanguage, - prefix: null, - postfix: new HarmonyMethod(typeof(HarmonyPatches), nameof(HarmonyPatches.Patch_SetCurrentLanguage_Postfix)), - transpiler: null); - } - - public static void SetCustomInteractText(StorageContainer _storage) - { - if (_storage != null) - { - string customInfoText = string.Empty; - ItemsContainer container = _storage.container; - - if (container != null) - { - if (container.count <= 0) // replace with container.IsEmpty() - { - customInfoText = "ContainerEmpty".Translate(); - } - - else if (container.count == 1) - { - customInfoText = "ContainerOneItem".Translate(); - } - - else if (!container.HasRoomFor(1, 1)) // replace with container.IsFull() - { - customInfoText = "ContainerFull".Translate(); - } - - else - { - customInfoText = "ContainerNonempty".FormatSingle(container.count.ToString()); - } - } - - HandReticle.main.SetInteractText(_storage.hoverText, customInfoText, true, false, HandReticle.Hand.Left); // From HandReticle.SetInteractText(string, string) - } - } - } -} diff --git a/StorageInfo/Languages/English.json b/StorageInfo/Languages/English.json deleted file mode 100644 index 03d467f..0000000 --- a/StorageInfo/Languages/English.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "ContainerEmpty": "empty", - "ContainerOneItem": "1 item (not full)", - "ContainerFull": "full", - "ContainerNonempty": "{0} items (not full)" -} diff --git a/StorageInfo/Languages/German.json b/StorageInfo/Languages/German.json deleted file mode 100644 index 0415633..0000000 --- a/StorageInfo/Languages/German.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "ContainerEmpty": "Leer", - "ContainerOneItem": "1 Gegenstand", - "ContainerFull": "Voll", - "ContainerNonempty": "{0} Gegenstände" -} diff --git a/StorageInfo/mod.json b/StorageInfo/mod.json deleted file mode 100644 index c77784e..0000000 --- a/StorageInfo/mod.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "Id": "StorageInfo", - "DisplayName": "Storage Info", - "Author": "Dingo", - "Version": "1.0.4", - "Enable": true, - "Game": "Subnautica", - "AssemblyName": "StorageInfo.dll", - "EntryMethod": "StorageInfo.Entry.Initialize" -} diff --git a/StorageInfo/Translation.cs b/Translation.cs similarity index 76% rename from StorageInfo/Translation.cs rename to Translation.cs index a6de930..99bf4e9 100644 --- a/StorageInfo/Translation.cs +++ b/Translation.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.IO; -using System.Reflection; using LitJson; using UnityEngine; @@ -10,17 +9,11 @@ namespace StorageInfo internal static class Translation { private const string LanguagesFolder = "Languages"; + private const string DefaultLanguage = "English"; private static readonly Dictionary languageStrings = new Dictionary(); - private static string GetAssemblyDirectory - { - get - { - string fullPath = Assembly.GetExecutingAssembly().Location; - return Path.GetDirectoryName(fullPath); - } - } + private static string GetAssemblyDirectory => Path.GetDirectoryName(typeof(Translation).Assembly.Location); // Json streaming code taken from Language.LoadLanguageFile(string) private static void LoadLanguageData() @@ -29,7 +22,7 @@ private static void LoadLanguageData() if (string.IsNullOrEmpty(currentLanguage)) { - currentLanguage = "English"; + currentLanguage = DefaultLanguage; } string langFolder = Path.Combine(GetAssemblyDirectory, LanguagesFolder); @@ -37,11 +30,11 @@ private static void LoadLanguageData() if (!File.Exists(langFile)) { - langFile = Path.Combine(langFolder, "English.json"); + langFile = Path.Combine(langFolder, DefaultLanguage + ".json"); if (!File.Exists(langFile)) { - throw new Exception("[StorageInfo] :: Could not find language file."); + throw new Exception($"{ModPlugin.modName} :: Could not find language file."); } } @@ -57,7 +50,7 @@ private static void LoadLanguageData() catch (Exception ex) { Debug.Log(ex.ToString()); - Debug.Log($"[StorageInfo] :: Failed while loading language json."); + ModPlugin.LogMessage("Failed while loading language json."); return; } @@ -96,12 +89,12 @@ internal static string Translate(this string source) return translated; } - Debug.Log($"[StorageInfo] :: Could not find translated string for `{source}`"); + ModPlugin.LogMessage($"Could not find translated string for `{source}`"); return source; } - internal static string FormatSingle(this string source, string arg0) + internal static string FormatTranslate(this string source, string arg0) { string basic = source.Translate(); @@ -115,7 +108,7 @@ internal static string FormatSingle(this string source, string arg0) catch (Exception ex) { Debug.Log(ex.ToString()); - Debug.Log($"[StorageInfo] :: Failed to format '{source}' with arg0 `{arg0}'"); + ModPlugin.LogMessage($"Failed to format '{source}' with arg0 `{arg0}'"); } }