From bf3516898c52c89158c79940bcbe65cd1831c125 Mon Sep 17 00:00:00 2001 From: SillyStar-Github <90102598+SillyStar-Github@users.noreply.github.com> Date: Mon, 6 Apr 2026 01:01:44 -0400 Subject: [PATCH] more code changes for 3.5 --- MelonLoader/AssetStore/TextureStore.cs | 8 +- MelonLoader/FileLoader.cs | 333 ++++++++++++++++-- .../BaseTextObjects/InGameText_Patch.cs | 8 +- .../ButtonObjects/OptLanguageBtn_Patch.cs | 56 ++- .../Patches/GameObjects/MainMenu_Patch.cs | 3 +- .../{GameAPP_Patch.cs => Screen_Patch.cs} | 10 +- .../GameLevel/LevelManager_Patch.cs | 27 ++ ...PvZ Fusion Translator [MelonLoader].csproj | 3 +- MelonLoader/Utils.cs | 119 ++++++- 9 files changed, 504 insertions(+), 63 deletions(-) rename MelonLoader/Patches/Managers/{GameAPP_Patch.cs => Screen_Patch.cs} (68%) create mode 100644 MelonLoader/Patches/Modes/Super Editor/GameLevel/LevelManager_Patch.cs diff --git a/MelonLoader/AssetStore/TextureStore.cs b/MelonLoader/AssetStore/TextureStore.cs index 9bf4ca4..f5760d5 100644 --- a/MelonLoader/AssetStore/TextureStore.cs +++ b/MelonLoader/AssetStore/TextureStore.cs @@ -6,8 +6,8 @@ namespace PvZ_Fusion_Translator.AssetStore { public static class TextureStore { - internal static Dictionary textureDict = []; - internal static Dictionary spriteDict = []; + internal static Dictionary textureDict = []; + internal static Dictionary spriteDict = []; internal static void Init() => FileLoader.LoadTextures(); @@ -55,13 +55,13 @@ namespace PvZ_Fusion_Translator.AssetStore } #endif - public static void LogAll() + /*public static void LogAll() { Log.LogInfo("Logging all TextureStore entries."); foreach (KeyValuePair entry in textureDict) { Log.LogInfo("TextureDict Entry: " + entry.Key + " | " + entry.Value); } - } + }*/ } } diff --git a/MelonLoader/FileLoader.cs b/MelonLoader/FileLoader.cs index bb70c78..0660f12 100644 --- a/MelonLoader/FileLoader.cs +++ b/MelonLoader/FileLoader.cs @@ -4,6 +4,7 @@ using JetBrains.Annotations; using MelonLoader; using MelonLoader.TinyJSON; using Newtonsoft.Json; +using NVorbis.Contracts; using PvZ_Fusion_Translator.AssetStore; using PvZ_Fusion_Translator.Patches.GameObjects; using PvZ_Fusion_Translator.Patches.GameObjects.MinorObjects; @@ -312,7 +313,13 @@ namespace PvZ_Fusion_Translator { string stringDir = FileLoader.GetAssetDir(FileLoader.AssetType.Strings, Utils.Language); string changelogDir = Path.Combine(stringDir, "changelog.txt"); - string changelogText = File.ReadAllText(changelogDir); + string changelogText = ""; + if (!File.Exists(changelogDir)) + { + File.WriteAllText(changelogDir, ""); + } + + changelogText = File.ReadAllText(changelogDir); if(!Utils.useLocal) { @@ -333,7 +340,6 @@ namespace PvZ_Fusion_Translator // Default or Custom Texturse -> English Textures -> Localized Textures try { - if (Utils.customTextures) { LoadCustomTextures(); @@ -365,6 +371,69 @@ namespace PvZ_Fusion_Translator } try { + Dictionary localTOC = new Dictionary(); + string localTOCDir = Path.Combine(textureDir, "Texture_TOC.json"); + if (!File.Exists(localTOCDir)) + { + File.WriteAllText(localTOCDir, "{}"); + } + + string localTOCContent = File.ReadAllText(localTOCDir); + localTOC = System.Text.Json.JsonSerializer.Deserialize>(localTOCContent); + + string basePath = Core.Instance.modsDirectory; + + if (!Utils.useLocal) + { + string textureTOCRequest = Utils.GetDataFromWeb($"https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/Localization/{Utils.Language.ToString()}/Textures/Texture_TOC.json").Result; + if (textureTOCRequest != null) + { + Dictionary textureTOC = JsonConvert.DeserializeObject>(textureTOCRequest); + + List toDownload = new(); + + foreach(var pair in textureTOC) + { + if(!localTOC.ContainsKey(pair.Key)) + { + toDownload.Add(pair.Key); + continue; + } + + if(pair.Value != localTOC[pair.Key]) + { + toDownload.Add(pair.Key); + } + + if(!File.Exists(Path.Combine(basePath, pair.Key))) + { + toDownload.Add(pair.Key); + continue; + } + } + + string toWriteText = SerializeWithIndentation(textureTOC); + File.WriteAllText(localTOCDir, toWriteText); + + foreach(string path in toDownload) + { + string downloadPath = Path.Combine(basePath, path); + + string baseUrl = $"https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/"; + string url = baseUrl + path; + + byte[] imageData = Utils.GetImageDataFromWeb(url).Result; + if(imageData != null) + { + string fileName = Path.GetFileName(downloadPath); + Texture2D texture2D = Utils.LoadImage(imageData); + TextureStore.textureDict[fileName] = imageData; + File.WriteAllBytes(downloadPath, imageData); + } + } + } + } + foreach (string filepath in Directory.EnumerateFiles(textureDir, "*.png", SearchOption.AllDirectories)) { if (filepath.Contains("[Custom Textures]", StringComparison.OrdinalIgnoreCase) && loadDefaultTextures) @@ -372,6 +441,9 @@ namespace PvZ_Fusion_Translator continue; } + if (!localTOC.ContainsKey(filepath.Replace(basePath + "\\", "").Replace("\\", "/")) + && (SerializeWithIndentation(localTOC) != "{}")) continue; + #if OBFUSCATE if (CheckSumStore.IsModified(filepath)) { @@ -384,8 +456,9 @@ namespace PvZ_Fusion_Translator Log.LogDebug("Loading File : " + filepath); #endif - Texture2D texture2D = Utils.LoadImage(filepath); - TextureStore.textureDict[Path.GetFileNameWithoutExtension(filepath)] = filepath; + byte[] imageData = File.ReadAllBytes(filepath); + Texture2D texture2D = Utils.LoadImage(imageData); + TextureStore.textureDict[Path.GetFileNameWithoutExtension(filepath)] = imageData; } } @@ -406,12 +479,79 @@ namespace PvZ_Fusion_Translator } try { - foreach (string filepath in Directory.EnumerateFiles(textureDir, "*.png", SearchOption.AllDirectories)) - { - if (filepath.Contains("[Custom Textures]", StringComparison.OrdinalIgnoreCase) && loadDefaultTextures) - { - continue; - } + string trueTextureDir = GetAssetDir(AssetType.Textures, language); + Dictionary localTOC = new Dictionary(); + string localTOCDir = Path.Combine(trueTextureDir, "Texture_TOC.json"); + if (!File.Exists(localTOCDir)) + { + File.WriteAllText(localTOCDir, "{}"); + } + + string localTOCContent = File.ReadAllText(localTOCDir); + localTOC = System.Text.Json.JsonSerializer.Deserialize>(localTOCContent); + + string basePath = Core.Instance.modsDirectory; + + if(!Utils.useLocal) + { + string textureTOCRequest = Utils.GetDataFromWeb($"https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/Localization/{Utils.Language.ToString()}/Textures/Texture_TOC.json").Result; + if (textureTOCRequest != null) + { + Dictionary textureTOC = JsonConvert.DeserializeObject>(textureTOCRequest); + + List toDownload = new(); + + foreach(var pair in textureTOC) + { + if(!localTOC.ContainsKey(pair.Key)) + { + toDownload.Add(pair.Key); + continue; + } + + if(pair.Value != localTOC[pair.Key]) + { + toDownload.Add(pair.Key); + } + + if(!File.Exists(Path.Combine(basePath, pair.Key))) + { + toDownload.Add(pair.Key); + continue; + } + } + + string toWriteText = SerializeWithIndentation(textureTOC); + File.WriteAllText(localTOCDir, toWriteText); + + foreach(string path in toDownload) + { + string downloadPath = Path.Combine(basePath, path); + + string baseUrl = $"https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/"; + string url = baseUrl + path; + + byte[] imageData = Utils.GetImageDataFromWeb(url).Result; + if(imageData != null) + { + string fileName = Path.GetFileName(downloadPath); + Texture2D texture2D = Utils.LoadImage(imageData); + TextureStore.spriteDict[fileName] = imageData; + File.WriteAllBytes(downloadPath, imageData); + } + } + } + } + + foreach (string filepath in Directory.EnumerateFiles(textureDir, "*.png", SearchOption.AllDirectories)) + { + if (filepath.Contains("[Custom Textures]", StringComparison.OrdinalIgnoreCase) && loadDefaultTextures) + { + continue; + } + + if (!localTOC.ContainsKey(filepath.Replace(basePath + "\\", "").Replace("\\", "/")) + && (SerializeWithIndentation(localTOC) != "{}")) continue; #if OBFUSCATE if (CheckSumStore.IsModified(filepath)) @@ -422,12 +562,13 @@ namespace PvZ_Fusion_Translator #endif #if DEBUG - Log.LogDebug("Loading File (Sprite): " + filepath); + Log.LogDebug("Loading File (Sprite): " + filepath); #endif - Texture2D texture2D = Utils.LoadImage(filepath); - TextureStore.spriteDict[Path.GetFileNameWithoutExtension(filepath)] = filepath; - } + byte[] imageData = File.ReadAllBytes(filepath); + Texture2D texture2D = Utils.LoadImage(imageData); + TextureStore.spriteDict[Path.GetFileNameWithoutExtension(filepath)] = imageData; + } } catch (Exception e) @@ -448,8 +589,74 @@ namespace PvZ_Fusion_Translator } try { - foreach (string filepath in Directory.EnumerateFiles(textureDefaultDir, "*.png", SearchOption.AllDirectories)) - { + string trueTextureDir = Path.Combine(Core.Instance.modsDirectory, "[Custom Textures]"); + Dictionary localTOC = new Dictionary(); + string localTOCDir = Path.Combine(trueTextureDir, "Default_TOC.json"); + if (!File.Exists(localTOCDir)) + { + File.WriteAllText(localTOCDir, "{}"); + } + + string localTOCContent = File.ReadAllText(localTOCDir); + localTOC = System.Text.Json.JsonSerializer.Deserialize>(localTOCContent); + + string basePath = Core.Instance.modsDirectory; + + if (!Utils.useLocal) + { + string textureTOCRequest = Utils.GetDataFromWeb($"https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/{Uri.EscapeDataString("[Custom Textures]")}/Default_TOC.json").Result; + if (textureTOCRequest != null) + { + Dictionary textureTOC = JsonConvert.DeserializeObject>(textureTOCRequest); + + List toDownload = new(); + + foreach (var pair in textureTOC) + { + if (!localTOC.ContainsKey(pair.Key)) + { + toDownload.Add(pair.Key); + continue; + } + + if (pair.Value != localTOC[pair.Key]) + { + toDownload.Add(pair.Key); + } + + if(!File.Exists(Path.Combine(basePath, pair.Key))) + { + toDownload.Add(pair.Key); + continue; + } + } + + string toWriteText = SerializeWithIndentation(textureTOC); + File.WriteAllText(localTOCDir, toWriteText); + + foreach (string path in toDownload) + { + string downloadPath = Path.Combine(basePath, path); + + string baseUrl = $"https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/"; + string url = baseUrl + path; + + byte[] imageData = Utils.GetImageDataFromWeb(url).Result; + if (imageData != null) + { + string fileName = Path.GetFileName(downloadPath); + Texture2D texture2D = Utils.LoadImage(imageData); + TextureStore.textureDict[fileName] = imageData; + File.WriteAllBytes(downloadPath, imageData); + } + } + } + } + + foreach (string filepath in Directory.EnumerateFiles(textureDefaultDir, "*.png", SearchOption.AllDirectories)) + { + if (!localTOC.ContainsKey(filepath.Replace(basePath + "\\", "").Replace("\\", "/")) + && (SerializeWithIndentation(localTOC) != "{}")) continue; #if OBFUSCATE if (CheckSumStore.IsModified(filepath)) @@ -459,9 +666,10 @@ namespace PvZ_Fusion_Translator } #endif - Texture2D texture2D = Utils.LoadImage(filepath); - TextureStore.textureDict[Path.GetFileNameWithoutExtension(filepath)] = filepath; - } + byte[] imageData = File.ReadAllBytes(filepath); + Texture2D texture2D = Utils.LoadImage(imageData); + TextureStore.textureDict[Path.GetFileNameWithoutExtension(filepath)] = imageData; + } } catch (Exception e) @@ -482,18 +690,87 @@ namespace PvZ_Fusion_Translator } try { + string trueTextureDir = Path.Combine(Core.Instance.modsDirectory, "[Custom Textures]"); + Dictionary localTOC = new Dictionary(); + string localTOCDir = Path.Combine(trueTextureDir, "Custom_TOC.json"); + if (!File.Exists(localTOCDir)) + { + File.WriteAllText(localTOCDir, "{}"); + } + + string localTOCContent = File.ReadAllText(localTOCDir); + localTOC = System.Text.Json.JsonSerializer.Deserialize>(localTOCContent); + + string basePath = Core.Instance.modsDirectory; + + if (!Utils.useLocal) + { + string textureTOCRequest = Utils.GetDataFromWeb($"https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/{Uri.EscapeDataString("[Custom Textures]")}/Custom_TOC.json").Result; + if (textureTOCRequest != null) + { + Dictionary textureTOC = JsonConvert.DeserializeObject>(textureTOCRequest); + + List toDownload = new(); + + foreach (var pair in textureTOC) + { + if (!localTOC.ContainsKey(pair.Key)) + { + toDownload.Add(pair.Key); + continue; + } + + if (pair.Value != localTOC[pair.Key]) + { + toDownload.Add(pair.Key); + continue; + } + + if(!File.Exists(Path.Combine(basePath, pair.Key))) + { + toDownload.Add(pair.Key); + continue; + } + } + + string toWriteText = SerializeWithIndentation(textureTOC); + File.WriteAllText(localTOCDir, toWriteText); + + foreach (string path in toDownload) + { + string downloadPath = Path.Combine(basePath, path); + + string baseUrl = $"https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/"; + string url = baseUrl + path; + + byte[] imageData = Utils.GetImageDataFromWeb(url).Result; + if (imageData != null) + { + string fileName = Path.GetFileName(downloadPath); + Texture2D texture2D = Utils.LoadImage(imageData); + TextureStore.textureDict[fileName] = imageData; + File.WriteAllBytes(downloadPath, imageData); + } + } + } + } + foreach (string filepath in Directory.EnumerateFiles(texturePackDir, "*.png", SearchOption.AllDirectories)) { - #if OBFUSCATE - if (CheckSumStore.IsModified(filepath)) - { - Log.LogError("File {0} was modified!" , filepath); - continue; - } - #endif + #if OBFUSCATE + if (CheckSumStore.IsModified(filepath)) + { + Log.LogError("File {0} was modified!" , filepath); + continue; + } + #endif - Texture2D texture2D = Utils.LoadImage(filepath); - TextureStore.textureDict[Path.GetFileNameWithoutExtension(filepath)] = filepath; + if (!localTOC.ContainsKey(filepath.Replace(basePath + "\\", "").Replace("\\", "/")) + && (SerializeWithIndentation(localTOC) != "{}")) continue; + + byte[] imageData = File.ReadAllBytes(filepath); + Texture2D texture2D = Utils.LoadImage(imageData); + TextureStore.textureDict[Path.GetFileNameWithoutExtension(filepath)] = imageData; } } diff --git a/MelonLoader/Patches/BaseTextObjects/InGameText_Patch.cs b/MelonLoader/Patches/BaseTextObjects/InGameText_Patch.cs index beb96e1..171ec7d 100644 --- a/MelonLoader/Patches/BaseTextObjects/InGameText_Patch.cs +++ b/MelonLoader/Patches/BaseTextObjects/InGameText_Patch.cs @@ -22,7 +22,7 @@ namespace PvZ_Fusion_Translator.Patches.BaseTextObjects { if(__instance.textHead == null) return; - if(!__instance.textHead.active) return; + if(!__instance.textHead.active || !__instance.textMesh.gameObject.active) return; TranslateInGameText(__instance); } @@ -33,7 +33,7 @@ namespace PvZ_Fusion_Translator.Patches.BaseTextObjects { if(__instance.textHead == null) return; - if(!__instance.textHead.active) return; + if(!__instance.textHead.active || !__instance.textMesh.gameObject.active) return; TranslateInGameText(__instance); } @@ -44,7 +44,7 @@ namespace PvZ_Fusion_Translator.Patches.BaseTextObjects { if(__instance.textHead == null) return; - if(!__instance.textHead.active) return; + if(!__instance.textHead.active || !__instance.textMesh.gameObject.active) return; TranslateInGameText(__instance); } @@ -53,7 +53,7 @@ namespace PvZ_Fusion_Translator.Patches.BaseTextObjects { if (__instance.textMesh == null) return; - if(!__instance.textHead.active) return; + if(!__instance.textHead.active || !__instance.textMesh.gameObject.active) return; TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); diff --git a/MelonLoader/Patches/GameObjects/ButtonObjects/OptLanguageBtn_Patch.cs b/MelonLoader/Patches/GameObjects/ButtonObjects/OptLanguageBtn_Patch.cs index 0695f5b..b1821de 100644 --- a/MelonLoader/Patches/GameObjects/ButtonObjects/OptLanguageBtn_Patch.cs +++ b/MelonLoader/Patches/GameObjects/ButtonObjects/OptLanguageBtn_Patch.cs @@ -162,10 +162,23 @@ namespace PvZ_Fusion_Translator.Patches.GameObjects.ButtonObjects btn.gameObject.SetActive(true); string buttonText = Utils.ToggleNames[toggle]; UpdateButtonText(btn, StringStore.TranslateText(buttonText), FontStore.LoadTMPFont(Utils.Language.ToString())); - if(i == 2) + string sourceMsg = ""; + switch(i) { - string sourceMsg = "" + (!(Utils.useLocal) ? "Translation Source:\nOnline" : "Translation Source:\nLocal"); - FlashMessage(btn, sourceMsg, 0.1f, false); + case 0: + sourceMsg = "" + (!(Utils.customTextures) ? "Texture Source:\nDefault" : "Texture Source:\nCustom"); + FlashMessage(btn, sourceMsg, 0.1f, false); + break; + case 1: + sourceMsg = "" + (!(Utils.customAudio) ? "Audio Source:\nDefault" : "Audio Source:\nCustom"); + FlashMessage(btn, sourceMsg, 0.1f, false); + break; + case 2: + sourceMsg = "" + (!(Utils.useLocal) ? "Translation Source:\nOnline" : "Translation Source:\nLocal"); + FlashMessage(btn, sourceMsg, 0.1f, false); + break; + default: + break; } } else @@ -223,8 +236,10 @@ namespace PvZ_Fusion_Translator.Patches.GameObjects.ButtonObjects if (child != null) { var text = child.GetComponent(); + string originalMsg = ""; if (text != null) { + originalMsg = text.text; text.text = message; OptionButtonData data; bool isToggle = ToggleBtnDict.TryGetValue(button.GetInstanceID(), out data); @@ -248,7 +263,24 @@ namespace PvZ_Fusion_Translator.Patches.GameObjects.ButtonObjects { if (button != null && child != null && child.gameObject.activeSelf) { - child.gameObject.SetActive(false); + OptionButtonData buttonData = ToggleBtnDict[button.GetInstanceID()]; + if(buttonData.Toggle != null) + { + string sourceMsg = originalMsg; + switch(buttonData.Toggle) + { + case Utils.ToggleEnum.Textures: + sourceMsg = "" + (!(Utils.customTextures) ? "Texture Source:\nDefault" : "Texture Source:\nCustom"); + break; + case Utils.ToggleEnum.Audio: + sourceMsg = "" + (!(Utils.customAudio) ? "Audio Source:\nDefault" : "Audio Source:\nCustom"); + break; + default: + break; + } + text.text = sourceMsg; + } + } }); } @@ -329,14 +361,14 @@ namespace PvZ_Fusion_Translator.Patches.GameObjects.ButtonObjects { string toggleType = toggleData.Toggle.ToString(); ToggleCustomAssets(toggleType); - if (toggleType == "Textures") - { - FlashMessage(toggleData.Button, "Toggled custom textures!", 0.1f); - } - else if (toggleType == "Audio") - { - FlashMessage(toggleData.Button, "Toggled custom audio!", 0.1f); - } + if (toggleType == "Textures") + { + FlashMessage(toggleData.Button, "Toggled custom textures!\n(Restart Required)", 0.1f); + } + else if (toggleType == "Audio") + { + FlashMessage(toggleData.Button, "Toggled custom audio!", 0.1f); + } } } diff --git a/MelonLoader/Patches/GameObjects/MainMenu_Patch.cs b/MelonLoader/Patches/GameObjects/MainMenu_Patch.cs index ee63097..68f0fa2 100644 --- a/MelonLoader/Patches/GameObjects/MainMenu_Patch.cs +++ b/MelonLoader/Patches/GameObjects/MainMenu_Patch.cs @@ -18,6 +18,7 @@ namespace PvZ_Fusion_Translator.Patches.GameObjects Transform changelogObj = __instance.transform.Find("Grave/UpdateInfo"); Transform langObj = UnityEngine.Object.Instantiate(changelogObj, changelogObj.position + new Vector3(0.0f, 0.855f), changelogObj.rotation, __instance.transform.Find("Grave")); langObj.name = "Languages"; + __instance.collider2Ds.Add(langObj.GetComponent()); UIButton langBtn = langObj.GetComponent(); foreach(TextMeshProUGUI text in langObj.GetComponentsInChildren()) @@ -27,7 +28,6 @@ namespace PvZ_Fusion_Translator.Patches.GameObjects langBtn.clickEvent = new UnityEvent(); langBtn.clickEvent.AddListener(new Action(() => OpenLanguageMenu(langBtn.gameObject))); - langBtn.clickEvent.AddListener(new Action(() => HideLangButton(langBtn.gameObject))); } public static void OpenLanguageMenu(GameObject langBtn) @@ -49,7 +49,6 @@ namespace PvZ_Fusion_Translator.Patches.GameObjects OptLanguageBtn_Patch.OptLangBtn_Patch.Awake(templateButton); UIButton goBackButton = newOptionsMenu.transform.Find("Goback").GetComponent(); - goBackButton.clickEvent.AddListener(new Action(() => ShowLangButton(langBtn.gameObject))); newOptionsMenu.transform.Find("F").gameObject.SetActive(false); diff --git a/MelonLoader/Patches/Managers/GameAPP_Patch.cs b/MelonLoader/Patches/Managers/Screen_Patch.cs similarity index 68% rename from MelonLoader/Patches/Managers/GameAPP_Patch.cs rename to MelonLoader/Patches/Managers/Screen_Patch.cs index 73943c3..da7c0ed 100644 --- a/MelonLoader/Patches/Managers/GameAPP_Patch.cs +++ b/MelonLoader/Patches/Managers/Screen_Patch.cs @@ -2,23 +2,23 @@ using Il2Cpp; using Il2CppTMPro; using PvZ_Fusion_Translator.AssetStore; +using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; namespace PvZ_Fusion_Translator.Patches.Managers { - [HarmonyPatch(typeof(GameAPP))] - public static class GameAPP_Patch + [HarmonyPatch(typeof(Screen))] + public static class Screen_Patch { - [HarmonyPatch(nameof(GameAPP.Update))] + [HarmonyPatch(nameof(Screen.SetResolution), argumentTypes: [typeof(int), typeof(int), typeof(bool)])] [HarmonyPrefix] - private static bool Update(GameAPP __instance) + private static bool SetResolution(Screen __instance) { if(EventSystem.current.currentSelectedGameObject != null) { if (EventSystem.current.currentSelectedGameObject.TryGetComponent(out TMP_InputField field)) { - __instance.MusicUpdate(); return false; } } diff --git a/MelonLoader/Patches/Modes/Super Editor/GameLevel/LevelManager_Patch.cs b/MelonLoader/Patches/Modes/Super Editor/GameLevel/LevelManager_Patch.cs new file mode 100644 index 0000000..5c620ad --- /dev/null +++ b/MelonLoader/Patches/Modes/Super Editor/GameLevel/LevelManager_Patch.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using HarmonyLib; +using Il2Cpp; +using Il2CppGameLevel; +using PvZ_Fusion_Translator.AssetStore; +using UnityEngine; + +namespace PvZ_Fusion_Translator.Patches.Modes.Super_Editor.GameLevel +{ + [HarmonyPatch(typeof(LevelManager))] + public static class LevelManager_Patch + { + [HarmonyPatch(nameof(LevelManager.SaveLevelData))] + [HarmonyPrefix] + public static void Pre_SaveLevelData(LevelManager __instance, ref SerializedLevelData serializedLevelData) + { + if(serializedLevelData.name == "未命名关卡") + { + serializedLevelData.name = StringStore.translationString.ContainsKey("LEVEL_UNNAMED") ? StringStore.TranslateText("LEVEL_UNNAMED") : "Unnamed"; + } + } + } +} diff --git a/MelonLoader/PvZ Fusion Translator [MelonLoader].csproj b/MelonLoader/PvZ Fusion Translator [MelonLoader].csproj index 1374c50..e6ea827 100644 --- a/MelonLoader/PvZ Fusion Translator [MelonLoader].csproj +++ b/MelonLoader/PvZ Fusion Translator [MelonLoader].csproj @@ -428,7 +428,7 @@ - + @@ -510,6 +510,7 @@ + diff --git a/MelonLoader/Utils.cs b/MelonLoader/Utils.cs index 648005c..cb0a263 100644 --- a/MelonLoader/Utils.cs +++ b/MelonLoader/Utils.cs @@ -28,11 +28,11 @@ namespace PvZ_Fusion_Translator { if (ogTexture != null) { - if (TextureStore.textureDict.TryGetValue(ogTexture.name, out string texturePath)) + if (TextureStore.textureDict.TryGetValue(ogTexture.name, out byte[] textureData)) { try { - ImageConversion.LoadImage(ogTexture, File.ReadAllBytes(texturePath)); + ImageConversion.LoadImage(ogTexture, textureData); Log.LogDebug("OK! Replaced Texture " + ogTexture.name); @@ -41,7 +41,7 @@ namespace PvZ_Fusion_Translator } catch (Exception ex) { - Log.LogError("Failed to replace texture: " + ogTexture.name + " at path: " + texturePath); + Log.LogError("Failed to replace texture: " + ogTexture.name); Log.LogError(ex.ToString()); } } @@ -62,6 +62,19 @@ namespace PvZ_Fusion_Translator return texture2D; } + internal static Texture2D LoadImage(byte[] bytes) + { + if (bytes == null) + { + throw new FileNotFoundException($"Byte array was null."); + } + + byte[] array = bytes; + Texture2D texture2D = new(2, 2, GraphicsFormat.R8G8B8A8_UNorm, TextureCreationFlags.None, 1, IntPtr.Zero, null); + ImageConversion.LoadImage(texture2D, array); + return texture2D; + } + public static Color HexToColor(string hex) { @@ -362,7 +375,7 @@ namespace PvZ_Fusion_Translator { Utils.useLocal = (Utils.useLocal) ? false : true; MelonPreferences.SetEntryValue("PvZ_Fusion_Translator", "UseLocal", Utils.useLocal); - StringStore.Reload(); + ChangeLanguage(Utils.Language.ToString()); string sourceMsg = "" + (!(Utils.useLocal) ? "Translation Source:\nOnline" : "Translation Source:\nLocal"); OptLanguageBtn_Patch.FlashMessage(OptLanguageBtn_Patch.toggleSlots[2], sourceMsg, 0.1f, false); } @@ -373,7 +386,99 @@ namespace PvZ_Fusion_Translator { Log.LogInfo($"Attempting to read {url}"); } - var dataRequest = await new HttpClient().GetAsync(url); + HttpClient client = new HttpClient(); + try + { + var dataRequest = await client.GetAsync(url); + if(dataRequest.StatusCode == System.Net.HttpStatusCode.OK) + { + if (isLog) + { + Log.LogInfo($"Successfully loaded data from {url}!"); + } + + string content = await dataRequest.Content.ReadAsStringAsync(); + return content; + } + else + { + if (isLog) + { + Log.LogError($"Failed to load data from {url}! Falling back..."); + Log.LogError($"Status code: {dataRequest.StatusCode}"); + } + new CancellationTokenSource().Cancel(); + return null; + } + } + catch(Exception ex) + { + Log.LogError($"Failed to load data from {url}! Falling back..."); + Log.LogError(ex); + new CancellationTokenSource().Cancel(); + return null; + } + } + + public static async Task GetImageDataFromWeb(string url, bool isLog = true) + { + if (isLog) + { + Log.LogInfo($"Attempting to read {url}"); + } + HttpClient client = new HttpClient(); + try + { + var dataRequest = await client.GetAsync(url); + if (dataRequest.StatusCode == System.Net.HttpStatusCode.OK) + { + if (isLog) + { + Log.LogInfo($"Successfully loaded data from {url}!"); + } + + byte[] content = await dataRequest.Content.ReadAsByteArrayAsync(); + return content; + } + else + { + if (isLog) + { + Log.LogError($"Failed to load data from {url}! Falling back..."); + Log.LogError($"Status code: {dataRequest.StatusCode}"); + } + new CancellationTokenSource().Cancel(); + return null; + } + } + catch(Exception ex) + { + Log.LogError($"Failed to load data from {url}! Falling back..."); + Log.LogError(ex); + new CancellationTokenSource().Cancel(); + return null; + } + } + + public static async Task GetDataFromWebWithInput(string url, bool isLog = true) + { + if (isLog) + { + Log.LogInfo($"Attempting to read {url}"); + } + HttpClient client = new HttpClient(); + + using var request = new HttpRequestMessage() + { + Method = HttpMethod.Get, + RequestUri = new Uri(url) + }; + request.Headers.Add("Accept", "*/*"); + request.Headers.Add("Accept-Encoding", "gzip, deflate, br"); + request.Headers.Add("User-Agent", "TranslatorMod"); + + + var dataRequest = await client.SendAsync(request); if(dataRequest.StatusCode == System.Net.HttpStatusCode.OK) { if (isLog) @@ -478,8 +583,8 @@ namespace PvZ_Fusion_Translator public static Dictionary ToggleNames = new Dictionary() { - { ToggleEnum.Textures, "Textures"}, - { ToggleEnum.Audio, "Audio"}, + { ToggleEnum.Textures, "Change Texture\nSource"}, + { ToggleEnum.Audio, "Change Audio\nSource"}, { ToggleEnum.SwapLocal, "Change Translation\nSource"} };