1161 lines
No EOL
38 KiB
C#
1161 lines
No EOL
38 KiB
C#
using Il2Cpp;
|
|
using Il2CppAlmanacData;
|
|
using Il2CppInterop.Runtime.InteropTypes.Arrays;
|
|
using JetBrains.Annotations;
|
|
using MelonLoader;
|
|
using MelonLoader.TinyJSON;
|
|
using Newtonsoft.Json;
|
|
using PvZ_Fusion_Translator.AssetStore;
|
|
using PvZ_Fusion_Translator.Patches.GameObjects;
|
|
using PvZ_Fusion_Translator.Patches.GameObjects.MinorObjects;
|
|
using PvZ_Fusion_Translator.Patches.Modes.Odyssey;
|
|
using PvZ_Fusion_Translator.Patches.OtherManagers;
|
|
using System.CodeDom.Compiler;
|
|
using System.Text;
|
|
using System.Text.Encodings.Web;
|
|
using System.Text.Json;
|
|
using UnityEngine;
|
|
|
|
namespace PvZ_Fusion_Translator
|
|
{
|
|
internal static class FileLoader
|
|
{
|
|
internal enum AssetType
|
|
{
|
|
Textures,
|
|
Strings,
|
|
Dumps,
|
|
Almanac,
|
|
Sprites
|
|
}
|
|
|
|
public static string GetAssetDir(AssetType assetType, Utils.LanguageEnum? language = null)
|
|
{
|
|
string languagePath = language.HasValue ? ("Localization" + Path.DirectorySeparatorChar + language.ToString()) : string.Empty;
|
|
return Path.Combine(Core.Instance.modsDirectory, languagePath, assetType.ToString());
|
|
}
|
|
// private static string GetAssetDir(AssetType assetType) => Path.Combine(Core.Instance.modsDirectory, assetType.ToString());
|
|
|
|
internal static void LoadStrings() => LoadStrings(Utils.Language);
|
|
|
|
internal static void LoadStrings(Utils.LanguageEnum language)
|
|
{
|
|
string stringDir = GetAssetDir(AssetType.Strings, Utils.Language);
|
|
if (!Directory.Exists(stringDir))
|
|
{
|
|
Directory.CreateDirectory(stringDir);
|
|
}
|
|
|
|
if(!Utils.useLocal)
|
|
{
|
|
// load translationStrings
|
|
string translationStringsContent = Utils.GetDataFromWeb($"https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/Localization/{Utils.Language.ToString()}/Strings/translation_strings.json").Result;
|
|
|
|
if(translationStringsContent != null)
|
|
{
|
|
LoadTranslationStrings(translationStringsContent);
|
|
}
|
|
else
|
|
{
|
|
string translationStringsPath = Path.Combine(GetAssetDir(AssetType.Strings, Utils.Language), "translation_strings.json");
|
|
if(File.Exists(translationStringsPath))
|
|
{
|
|
LoadTranslationStrings(File.ReadAllText(translationStringsPath));
|
|
}
|
|
}
|
|
|
|
// load translationRegexs
|
|
string translationRegexsContent = Utils.GetDataFromWeb($"https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/Localization/{Utils.Language.ToString()}/Strings/translation_regexs.json").Result;
|
|
|
|
if(translationRegexsContent != null)
|
|
{
|
|
LoadTranslationRegexs(translationRegexsContent);
|
|
}
|
|
else
|
|
{
|
|
string translationRegexsPath = Path.Combine(GetAssetDir(AssetType.Strings, Utils.Language), "translation_regexs.json");
|
|
if(File.Exists(translationRegexsPath))
|
|
{
|
|
LoadTranslationRegexs(File.ReadAllText(translationRegexsPath));
|
|
}
|
|
}
|
|
|
|
// load changelog
|
|
|
|
LoadChangelogText();
|
|
|
|
// load tips
|
|
string izTipsContent = Utils.GetDataFromWeb($"https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/Localization/{Utils.Language.ToString()}/Strings/tips_iz.json").Result;
|
|
|
|
if(izTipsContent != null)
|
|
{
|
|
LoadIZStrings(izTipsContent);
|
|
}
|
|
else
|
|
{
|
|
string izTipsPath = Path.Combine(GetAssetDir(AssetType.Strings, Utils.Language), "tips_iz.json");
|
|
if(File.Exists(izTipsPath))
|
|
{
|
|
LoadIZStrings(File.ReadAllText(izTipsPath));
|
|
}
|
|
}
|
|
|
|
string fsTipsContent = Utils.GetDataFromWeb($"https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/Localization/{Utils.Language.ToString()}/Strings/tips_fs.json").Result;
|
|
|
|
if(fsTipsContent != null)
|
|
{
|
|
LoadFSStrings(fsTipsContent);
|
|
}
|
|
else
|
|
{
|
|
string fsTipsPath = Path.Combine(GetAssetDir(AssetType.Strings, Utils.Language), "tips_fs.json");
|
|
if(File.Exists(fsTipsPath))
|
|
{
|
|
LoadFSStrings(File.ReadAllText(fsTipsPath));
|
|
}
|
|
}
|
|
|
|
// load almanacs
|
|
|
|
string almanacDir = GetAssetDir(AssetType.Almanac, Utils.Language);
|
|
|
|
if(!Directory.Exists(almanacDir))
|
|
{
|
|
Directory.CreateDirectory(almanacDir);
|
|
}
|
|
|
|
string plantAlmanacContent = Utils.GetDataFromWeb($"https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/Localization/{Utils.Language.ToString()}/Almanac/LawnStringsTranslate.json").Result;
|
|
|
|
if(plantAlmanacContent != null)
|
|
{
|
|
AlmanacPlantMenu_Patch.almanacJson = plantAlmanacContent;
|
|
}
|
|
else
|
|
{
|
|
string path = Path.Combine(almanacDir, "LawnStringsTranslate.json");
|
|
if(File.Exists(path))
|
|
{
|
|
AlmanacPlantMenu_Patch.almanacJson = File.ReadAllText(path);
|
|
}
|
|
}
|
|
|
|
string zombieAlmanacContent = Utils.GetDataFromWeb($"https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/Localization/{Utils.Language.ToString()}/Almanac/ZombieStringsTranslate.json").Result;
|
|
|
|
if(zombieAlmanacContent != null)
|
|
{
|
|
AlmanacZombieMenu_Patch.almanacJson = zombieAlmanacContent;
|
|
}
|
|
else
|
|
{
|
|
string path = Path.Combine(almanacDir, "ZombieStringsTranslate.json");
|
|
if(File.Exists(path))
|
|
{
|
|
AlmanacZombieMenu_Patch.almanacJson = File.ReadAllText(path);
|
|
}
|
|
}
|
|
|
|
string detailStringsContent = Utils.GetDataFromWeb($"https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/3.6/PvZ_Fusion_Translator/Localization/{Utils.Language.ToString()}/Almanac/DetailStrings.json").Result;
|
|
if(detailStringsContent != null)
|
|
{
|
|
LoadDetailStrings(detailStringsContent);
|
|
}
|
|
else
|
|
{
|
|
string path = Path.Combine(almanacDir, "DetailStringsTranslate.json");
|
|
if(File.Exists(path))
|
|
{
|
|
LoadDetailStrings(File.ReadAllText(path));
|
|
}
|
|
}
|
|
|
|
// load abyss buffs
|
|
|
|
Patches.Modes.Abyss.AbyssBuffMenu_Patch.LoadAbyssBuffData();
|
|
|
|
SaveStrings();
|
|
DumpJson();
|
|
}
|
|
else
|
|
{
|
|
if (!Directory.Exists(stringDir))
|
|
{
|
|
Directory.CreateDirectory(stringDir);
|
|
}
|
|
try
|
|
{
|
|
foreach (string filepath in Directory.EnumerateFiles(stringDir, "*.json", SearchOption.AllDirectories))
|
|
{
|
|
|
|
#if OBFUSCATE
|
|
if (CheckSumStore.IsModified(filepath))
|
|
{
|
|
Log.LogError("File {0} was modified!" , filepath);
|
|
continue;
|
|
}
|
|
#endif
|
|
|
|
string fileName = Path.GetFileNameWithoutExtension(filepath);
|
|
StringStore.stringsDict[fileName] = filepath;
|
|
#if DEBUG
|
|
Log.LogInfo("Loading File : " + filepath);
|
|
#endif
|
|
string jsonString = File.ReadAllText(filepath);
|
|
if (fileName.EndsWith("_strings"))
|
|
{
|
|
LoadTranslationStrings(jsonString);
|
|
}
|
|
else if (fileName.EndsWith("_regexs"))
|
|
{
|
|
LoadTranslationRegexs(jsonString);
|
|
}
|
|
else if(fileName.EndsWith("tips_iz"))
|
|
{
|
|
LoadIZStrings(jsonString);
|
|
}
|
|
else if(fileName.EndsWith("tips_fs"))
|
|
{
|
|
LoadFSStrings(jsonString);
|
|
}
|
|
else if(fileName.EndsWith("abyss_buffs"))
|
|
{
|
|
Patches.Modes.Abyss.AbyssBuffMenu_Patch.LoadAbyssBuffData();
|
|
}
|
|
}
|
|
|
|
string almanacDir = GetAssetDir(AssetType.Almanac, Utils.Language);
|
|
|
|
if(!Directory.Exists(almanacDir))
|
|
{
|
|
Directory.CreateDirectory(almanacDir);
|
|
}
|
|
|
|
string plantAlmanacPath = Path.Combine(almanacDir, "LawnStringsTranslate.json");
|
|
|
|
if(File.Exists(plantAlmanacPath))
|
|
{
|
|
AlmanacPlantMenu_Patch.almanacJson = File.ReadAllText(plantAlmanacPath);
|
|
}
|
|
|
|
string zombieAlmanacPath = Path.Combine(almanacDir, "ZombieStringsTranslate.json");
|
|
if(File.Exists(zombieAlmanacPath))
|
|
{
|
|
AlmanacZombieMenu_Patch.almanacJson = File.ReadAllText(zombieAlmanacPath);
|
|
}
|
|
|
|
string detailStringsPath = Path.Combine(almanacDir, "DetailStringsTranslate.json");
|
|
if(File.Exists(detailStringsPath))
|
|
{
|
|
LoadDetailStrings(File.ReadAllText(detailStringsPath));
|
|
}
|
|
|
|
SaveStrings();
|
|
DumpJson();
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Log.LogError("Error loading string.");
|
|
Log.LogError(e.GetType() + " " + e.Message);
|
|
}
|
|
}
|
|
|
|
Log.LogInfo("Strings loaded successfully.");
|
|
}
|
|
|
|
internal static void LoadTranslationStrings(string content)
|
|
{
|
|
Dictionary<string, string> dictionary = System.Text.Json.JsonSerializer.Deserialize<Dictionary<string, string>>(content);
|
|
foreach (var (key, value) in dictionary)
|
|
{
|
|
StringStore.translationString[key] = value;
|
|
}
|
|
}
|
|
|
|
internal static void LoadTranslationRegexs(string content)
|
|
{
|
|
Dictionary<string, string> dictionary = System.Text.Json.JsonSerializer.Deserialize<Dictionary<string, string>>(content);
|
|
foreach (var (key, value) in dictionary)
|
|
{
|
|
StringStore.translationStringRegex[key] = value;
|
|
}
|
|
Zombie_Patch.LoadHPStrings();
|
|
}
|
|
|
|
internal static void LoadIZStrings(string content)
|
|
{
|
|
var izDump = DumpIZStrings();
|
|
var izLevelData = izDump.Item1;
|
|
var izLevelDataDump = izDump.Item2;
|
|
|
|
var izTranslatedTips = System.Text.Json.JsonSerializer.Deserialize<Dictionary<string, string>>(content);
|
|
|
|
foreach (var level in izLevelData)
|
|
{
|
|
string data = level.text;
|
|
LevelData levelData = JsonUtility.FromJson<LevelData>(data);
|
|
if(levelData.tips != null)
|
|
{
|
|
if(izTranslatedTips.ContainsKey(level.name) && !StringStore.izTipCollectionString.ContainsKey(levelData.tips))
|
|
{
|
|
StringStore.izLevelTipDictionary.Add(level.name, izTranslatedTips[level.name]);
|
|
StringStore.izTipCollectionString.Add(levelData.tips, izTranslatedTips[level.name]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
internal static void LoadFSStrings(string content)
|
|
{
|
|
var fusionShowcaseDump = DumpFSStrings();
|
|
var fusionShowcaseData = fusionShowcaseDump.Item1;
|
|
var fusionShowcaseDataDump = fusionShowcaseDump.Item2;
|
|
|
|
var fsTranslatedTips = System.Text.Json.JsonSerializer.Deserialize<Dictionary<string, string>>(content);
|
|
|
|
foreach (var level in fusionShowcaseData)
|
|
{
|
|
string data = level.text;
|
|
LevelData levelData = JsonUtility.FromJson<LevelData>(data);
|
|
if (levelData.tips != null)
|
|
{
|
|
if (fsTranslatedTips.ContainsKey(level.name) && !StringStore.fsTipCollectionString.ContainsKey(levelData.tips))
|
|
{
|
|
StringStore.fsLevelTipDictionary.Add(level.name, fsTranslatedTips[level.name]);
|
|
StringStore.fsTipCollectionString.Add(levelData.tips, fsTranslatedTips[level.name]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
internal static void LoadDetailStrings(string content)
|
|
{
|
|
var detailStringsDump = DumpDetailStrings();
|
|
var detailStringsData = detailStringsDump.Item1;
|
|
var detailStrings = detailStringsDump.Item2;
|
|
|
|
var translatedDetailStrings = System.Text.Json.JsonSerializer.Deserialize<Dictionary<string, string>>(content);
|
|
AlmanacSelectMenu_Patch.detailStrings = translatedDetailStrings;
|
|
|
|
foreach (var detailString in detailStringsData.details)
|
|
{
|
|
if (translatedDetailStrings.ContainsKey(detailString.title))
|
|
{
|
|
if(!AlmanacSelectMenu_Patch.detailTranslateStrings.ContainsKey(detailString.text))
|
|
{
|
|
AlmanacSelectMenu_Patch.detailTranslateStrings.Add(detailString.text, translatedDetailStrings[detailString.title]);
|
|
}
|
|
else
|
|
{
|
|
AlmanacSelectMenu_Patch.detailTranslateStrings[detailString.text] = translatedDetailStrings[detailString.title];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
internal static void LoadChangelogText()
|
|
{
|
|
string stringDir = FileLoader.GetAssetDir(FileLoader.AssetType.Strings, Utils.Language);
|
|
string changelogDir = Path.Combine(stringDir, "changelog.txt");
|
|
string changelogText = "";
|
|
if (!File.Exists(changelogDir))
|
|
{
|
|
File.WriteAllText(changelogDir, "");
|
|
}
|
|
|
|
changelogText = File.ReadAllText(changelogDir);
|
|
|
|
if(!Utils.useLocal)
|
|
{
|
|
string changelogContent = Utils.GetDataFromWeb($"https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/Localization/{Utils.Language.ToString()}/Strings/changelog.txt").Result;
|
|
|
|
if(changelogContent != null)
|
|
{
|
|
changelogText = changelogContent;
|
|
}
|
|
}
|
|
|
|
NoticePauseMenu_Patch.changelogText = changelogText;
|
|
}
|
|
|
|
internal static void LoadTravelBuffs()
|
|
{
|
|
if (!Utils.useLocal)
|
|
{
|
|
string travelBuffsContent = Utils.GetDataFromWeb($"https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/Localization/{Utils.Language.ToString()}/Strings/travel_buffs.json").Result;
|
|
|
|
if (travelBuffsContent != null)
|
|
{
|
|
TravelMgr_Patch.translatedTravelBuffs = TravelMgr_Patch.GenerateTranslatedTravelBuffs(travelBuffsContent);
|
|
}
|
|
else
|
|
{
|
|
string travelBuffsPath = Path.Combine(GetAssetDir(AssetType.Strings, Utils.Language), "travel_buffs.json");
|
|
if (File.Exists(travelBuffsPath))
|
|
{
|
|
TravelMgr_Patch.translatedTravelBuffs = TravelMgr_Patch.GenerateTranslatedTravelBuffs(File.ReadAllText(travelBuffsPath));
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
string stringDir = FileLoader.GetAssetDir(FileLoader.AssetType.Strings, Utils.Language);
|
|
|
|
foreach (string filepath in Directory.EnumerateFiles(stringDir, "*.json", SearchOption.AllDirectories))
|
|
{
|
|
string fileName = Path.GetFileNameWithoutExtension(filepath);
|
|
string jsonString = File.ReadAllText(filepath);
|
|
if (fileName.EndsWith("travel_buffs"))
|
|
{
|
|
TravelMgr_Patch.translatedTravelBuffs = TravelMgr_Patch.GenerateTranslatedTravelBuffs(jsonString);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public static bool loadDefaultTextures = MelonPreferences.GetEntryValue<bool>("PvZ_Fusion_Translator", "DefaultTextures");
|
|
internal static void LoadTextures()
|
|
{
|
|
// Default or Custom Texturse -> English Textures -> Localized Textures
|
|
try
|
|
{
|
|
if (Utils.customTextures)
|
|
{
|
|
LoadCustomTextures();
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Log.LogError("Error loading texture setting.");
|
|
Log.LogError($"{e.GetType()} {e.Message}");
|
|
}
|
|
|
|
#if MULTI_LANGUAGE
|
|
LoadLocalizedTextures(Utils.Language);
|
|
LoadLocalizedSprites(Utils.Language);
|
|
#else
|
|
LoadLocalizedTextures();
|
|
#endif
|
|
|
|
Log.LogInfo("Textures loaded successfully.");
|
|
}
|
|
|
|
internal static void LoadLocalizedTextures(Utils.LanguageEnum? language = null)
|
|
{
|
|
string textureDir = GetAssetDir(AssetType.Textures, language);
|
|
|
|
if (!Directory.Exists(textureDir))
|
|
{
|
|
Directory.CreateDirectory(textureDir);
|
|
}
|
|
try
|
|
{
|
|
Dictionary<string, string> localTOC = new Dictionary<string, string>();
|
|
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<Dictionary<string, string>>(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<string, string> textureTOC = JsonConvert.DeserializeObject<Dictionary<string, string>>(textureTOCRequest);
|
|
|
|
List<string> 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.GetByteDataFromWeb(url).Result;
|
|
if(imageData != null)
|
|
{
|
|
string fileName = Path.GetFileName(downloadPath);
|
|
Texture2D texture2D = Utils.LoadImage(imageData);
|
|
TextureStore.textureDict[fileName] = imageData;
|
|
if(!Directory.Exists(Path.GetDirectoryName(downloadPath)))
|
|
{
|
|
Directory.CreateDirectory(Path.GetDirectoryName(downloadPath));
|
|
}
|
|
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))
|
|
{
|
|
Log.LogError("File {0} was modified!" , filepath);
|
|
continue;
|
|
}
|
|
#endif
|
|
|
|
#if DEBUG
|
|
Log.LogDebug("Loading File : " + filepath);
|
|
#endif
|
|
|
|
byte[] imageData = File.ReadAllBytes(filepath);
|
|
Texture2D texture2D = Utils.LoadImage(imageData);
|
|
TextureStore.textureDict[Path.GetFileNameWithoutExtension(filepath)] = imageData;
|
|
}
|
|
}
|
|
|
|
catch (Exception e)
|
|
{
|
|
Log.LogError("Error loading Texture.");
|
|
Log.LogError(e.GetType() + " " + e.Message);
|
|
}
|
|
}
|
|
|
|
internal static void LoadLocalizedSprites(Utils.LanguageEnum? language = null)
|
|
{
|
|
string textureDir = GetAssetDir(AssetType.Sprites, language);
|
|
|
|
if (!Directory.Exists(textureDir))
|
|
{
|
|
Directory.CreateDirectory(textureDir);
|
|
}
|
|
try
|
|
{
|
|
string trueTextureDir = GetAssetDir(AssetType.Textures, language);
|
|
Dictionary<string, string> localTOC = new Dictionary<string, string>();
|
|
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<Dictionary<string, string>>(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<string, string> textureTOC = JsonConvert.DeserializeObject<Dictionary<string, string>>(textureTOCRequest);
|
|
|
|
List<string> 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.GetByteDataFromWeb(url).Result;
|
|
if(imageData != null)
|
|
{
|
|
string fileName = Path.GetFileName(downloadPath);
|
|
Texture2D texture2D = Utils.LoadImage(imageData);
|
|
TextureStore.spriteDict[fileName] = imageData;
|
|
if(!Directory.Exists(Path.GetDirectoryName(downloadPath)))
|
|
{
|
|
Directory.CreateDirectory(Path.GetDirectoryName(downloadPath));
|
|
}
|
|
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))
|
|
{
|
|
Log.LogError("File {0} was modified!" , filepath);
|
|
continue;
|
|
}
|
|
#endif
|
|
|
|
#if DEBUG
|
|
Log.LogDebug("Loading File (Sprite): " + filepath);
|
|
#endif
|
|
|
|
byte[] imageData = File.ReadAllBytes(filepath);
|
|
Texture2D texture2D = Utils.LoadImage(imageData);
|
|
TextureStore.spriteDict[Path.GetFileNameWithoutExtension(filepath)] = imageData;
|
|
}
|
|
}
|
|
|
|
catch (Exception e)
|
|
{
|
|
Log.LogError("Error loading Texture.");
|
|
Log.LogError(e.GetType() + " " + e.Message);
|
|
}
|
|
}
|
|
|
|
internal static void LoadDefaultTextures()
|
|
{
|
|
if(Utils.customTextures == false)
|
|
{
|
|
string textureDefaultDir = Path.Combine(Core.Instance.modsDirectory, AssetType.Dumps.ToString(), "Default Textures [Do Not Remove]");
|
|
if (!Directory.Exists(textureDefaultDir))
|
|
{
|
|
Directory.CreateDirectory(textureDefaultDir);
|
|
}
|
|
try
|
|
{
|
|
string trueTextureDir = Path.Combine(Core.Instance.modsDirectory, "[Custom Textures]");
|
|
Dictionary<string, string> localTOC = new Dictionary<string, string>();
|
|
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<Dictionary<string, string>>(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<string, string> textureTOC = JsonConvert.DeserializeObject<Dictionary<string, string>>(textureTOCRequest);
|
|
|
|
List<string> 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.GetByteDataFromWeb(url).Result;
|
|
if (imageData != null)
|
|
{
|
|
string fileName = Path.GetFileName(downloadPath);
|
|
Texture2D texture2D = Utils.LoadImage(imageData);
|
|
TextureStore.textureDict[fileName] = imageData;
|
|
if(!Directory.Exists(Path.GetDirectoryName(downloadPath)))
|
|
{
|
|
Directory.CreateDirectory(Path.GetDirectoryName(downloadPath));
|
|
}
|
|
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))
|
|
{
|
|
Log.LogError("File {0} was modified!" , filepath);
|
|
continue;
|
|
}
|
|
#endif
|
|
|
|
byte[] imageData = File.ReadAllBytes(filepath);
|
|
Texture2D texture2D = Utils.LoadImage(imageData);
|
|
TextureStore.textureDict[Path.GetFileNameWithoutExtension(filepath)] = imageData;
|
|
}
|
|
}
|
|
|
|
catch (Exception e)
|
|
{
|
|
Log.LogError("Error loading Texture.");
|
|
Log.LogError(e.GetType() + " " + e.Message);
|
|
}
|
|
}
|
|
}
|
|
|
|
internal static void LoadCustomTextures()
|
|
{
|
|
string texturePackDir = Path.Combine(Core.Instance.modsDirectory, "[Custom Textures]");
|
|
|
|
if (!Directory.Exists(texturePackDir))
|
|
{
|
|
Directory.CreateDirectory(texturePackDir);
|
|
}
|
|
try
|
|
{
|
|
string trueTextureDir = Path.Combine(Core.Instance.modsDirectory, "[Custom Textures]");
|
|
Dictionary<string, string> localTOC = new Dictionary<string, string>();
|
|
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<Dictionary<string, string>>(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<string, string> textureTOC = JsonConvert.DeserializeObject<Dictionary<string, string>>(textureTOCRequest);
|
|
|
|
List<string> 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.GetByteDataFromWeb(url).Result;
|
|
if (imageData != null)
|
|
{
|
|
string fileName = Path.GetFileName(downloadPath);
|
|
Texture2D texture2D = Utils.LoadImage(imageData);
|
|
TextureStore.textureDict[fileName] = imageData;
|
|
if(!Directory.Exists(Path.GetDirectoryName(downloadPath)))
|
|
{
|
|
Directory.CreateDirectory(Path.GetDirectoryName(downloadPath));
|
|
}
|
|
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 (!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;
|
|
}
|
|
}
|
|
|
|
catch (Exception e)
|
|
{
|
|
Log.LogError("Error loading Texture.");
|
|
Log.LogError(e.GetType() + " " + e.Message);
|
|
}
|
|
}
|
|
|
|
internal static void SaveStrings()
|
|
{
|
|
#if MULTI_LANGUAGE
|
|
string stringDir = GetAssetDir(AssetType.Strings, Utils.Language);
|
|
#else
|
|
string stringDir = GetAssetDir(AssetType.Strings);
|
|
#endif
|
|
if (!Directory.Exists(stringDir))
|
|
{
|
|
Directory.CreateDirectory(stringDir);
|
|
}
|
|
|
|
// save regexs
|
|
|
|
string translationStringRegex = SerializeWithIndentation(StringStore.translationStringRegex, 2);
|
|
|
|
File.WriteAllText(Path.Combine(stringDir, "translation_regexs.json"), translationStringRegex);
|
|
|
|
// save strings
|
|
|
|
string translationString = SerializeWithIndentation(StringStore.translationString, 2);
|
|
|
|
File.WriteAllText(Path.Combine(stringDir, "translation_strings.json"), translationString);
|
|
|
|
// save iz tips
|
|
|
|
string izTipCollectionString = SerializeWithIndentation(StringStore.izLevelTipDictionary, 1, ' ');
|
|
|
|
File.WriteAllText(Path.Combine(stringDir, "tips_iz.json"), izTipCollectionString);
|
|
|
|
// save fs tips
|
|
|
|
string fsLevelTipDictionary = SerializeWithIndentation(StringStore.fsLevelTipDictionary);
|
|
|
|
File.WriteAllText(Path.Combine(stringDir, "tips_fs.json"), fsLevelTipDictionary);
|
|
|
|
// save changelog
|
|
|
|
if(NoticePauseMenu_Patch.changelogText != "")
|
|
{
|
|
File.WriteAllText(Path.Combine(stringDir, "changelog.txt"), NoticePauseMenu_Patch.changelogText);
|
|
}
|
|
|
|
// save abyss buffs
|
|
|
|
if(Patches.Modes.Abyss.AbyssBuffMenu_Patch.abyssBuffData != new Dictionary<string, string>())
|
|
{
|
|
string abyssBuffData = SerializeWithIndentation(Patches.Modes.Abyss.AbyssBuffMenu_Patch.abyssBuffData, 2);
|
|
File.WriteAllText(Path.Combine(stringDir, "abyss_buffs.json"), abyssBuffData);
|
|
}
|
|
|
|
// save almanacs
|
|
|
|
string almanacDir = GetAssetDir(AssetType.Almanac, Utils.Language);
|
|
|
|
if(AlmanacPlantMenu_Patch.almanacJson != "")
|
|
{
|
|
string plantAlmanac = SerializeWithIndentation(AlmanacPlantMenu_Patch.almanacJson);
|
|
|
|
File.WriteAllText(Path.Combine(almanacDir, "LawnStringsTranslate.json"), AlmanacPlantMenu_Patch.almanacJson);
|
|
}
|
|
|
|
if(AlmanacZombieMenu_Patch.almanacJson != "")
|
|
{
|
|
string zombieAlmanac = SerializeWithIndentation(AlmanacZombieMenu_Patch.almanacJson);
|
|
|
|
File.WriteAllText(Path.Combine(almanacDir, "ZombieStringsTranslate.json"), AlmanacZombieMenu_Patch.almanacJson);
|
|
}
|
|
|
|
if(AlmanacSelectMenu_Patch.detailStrings != new Dictionary<string, string>())
|
|
{
|
|
string detailStrings = SerializeWithIndentation(AlmanacSelectMenu_Patch.detailStrings);
|
|
|
|
File.WriteAllText(Path.Combine(almanacDir, "DetailStringsTranslate.json"), detailStrings);
|
|
}
|
|
}
|
|
|
|
public static string SerializeWithIndentation<T>(T value, int size = 4, char indentChar = ' ')
|
|
{
|
|
var stringBuilder = new StringBuilder();
|
|
var stringWriter = new StringWriter();
|
|
using (JsonTextWriter writer = new JsonTextWriter(stringWriter))
|
|
{
|
|
writer.Formatting = Formatting.Indented;
|
|
writer.Indentation = size;
|
|
writer.IndentChar = indentChar;
|
|
|
|
Newtonsoft.Json.JsonSerializer serializer = new Newtonsoft.Json.JsonSerializer();
|
|
serializer.Serialize(writer, value, typeof(T));
|
|
}
|
|
|
|
return stringWriter.ToString();
|
|
}
|
|
|
|
public static void DumpJson()
|
|
{
|
|
string dumpDir = GetAssetDir(AssetType.Dumps);
|
|
|
|
if (!Directory.Exists(dumpDir))
|
|
{
|
|
Directory.CreateDirectory(dumpDir);
|
|
}
|
|
string LawnStrings = Resources.Load<TextAsset>("LawnStrings").text;
|
|
string ZombieStrings = Resources.Load<TextAsset>("ZombieStrings").text;
|
|
string AbyssBuffData = Resources.Load<TextAsset>("AbyssBuffData").text;
|
|
File.WriteAllText(Path.Combine(dumpDir, "LawnStrings.json"), LawnStrings);
|
|
File.WriteAllText(Path.Combine(dumpDir, "ZombieStrings.json"), ZombieStrings);
|
|
File.WriteAllText(Path.Combine(dumpDir, "AbyssBuffData.json"), AbyssBuffData);
|
|
|
|
// dump iz tips
|
|
var izDump = DumpIZStrings();
|
|
var izLevelData = izDump.Item1;
|
|
var izLevelDataDump = izDump.Item2;
|
|
|
|
File.WriteAllText(Path.Combine(dumpDir, "tips_iz.json"), System.Text.Json.JsonSerializer.Serialize(izLevelDataDump, new JsonSerializerOptions
|
|
{
|
|
WriteIndented = true,
|
|
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
|
|
}));
|
|
|
|
// dump fusion showcase tips
|
|
var fusionShowcaseDump = DumpFSStrings();
|
|
var fusionShowcaseData = fusionShowcaseDump.Item1;
|
|
var fusionShowcaseDataDump = fusionShowcaseDump.Item2;
|
|
|
|
File.WriteAllText(Path.Combine(dumpDir, "tips_fs.json"), System.Text.Json.JsonSerializer.Serialize(fusionShowcaseDataDump, new JsonSerializerOptions
|
|
{
|
|
WriteIndented = true,
|
|
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
|
|
}));
|
|
|
|
// dump almanac mechanics
|
|
var detailStringsDump = DumpDetailStrings();
|
|
var detailStringsData = detailStringsDump.Item1;
|
|
var detailStrings = detailStringsDump.Item2;
|
|
|
|
File.WriteAllText(Path.Combine(dumpDir, "DetailStrings.json"), System.Text.Json.JsonSerializer.Serialize(detailStrings, new JsonSerializerOptions
|
|
{
|
|
WriteIndented = true,
|
|
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
|
|
}));
|
|
|
|
/*Dictionary<Achievement, AchievementObject> achievementsList = new Dictionary<Achievement, AchievementObject>();
|
|
foreach (Il2CppSystem.Collections.Generic.KeyValuePair<Achievement, Il2CppSystem.Tuple<string, string>> entry in AchievementClip.achievementsText)
|
|
{
|
|
achievementsList.Add(entry.Key, new AchievementObject(entry.Key, entry.Value.Item1, entry.Value.Item2));
|
|
}
|
|
File.WriteAllText(Path.Combine(dumpDir, "AchievementsText.json"), System.Text.Json.JsonSerializer.Serialize(achievementsList, new JsonSerializerOptions
|
|
{
|
|
WriteIndented = true,
|
|
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
|
|
}));*/
|
|
}
|
|
|
|
public static ValueTuple<Il2CppArrayBase<TextAsset>, Dictionary<string, string>> DumpIZStrings()
|
|
{
|
|
var izLevelData = Resources.LoadAll<TextAsset>("izleveldata");
|
|
Dictionary<string, string> izLevelDataDump = new Dictionary<string, string>();
|
|
foreach (var level in izLevelData)
|
|
{
|
|
string data = level.text;
|
|
LevelData levelData = JsonUtility.FromJson<LevelData>(data);
|
|
if(levelData.tips != null)
|
|
{
|
|
izLevelDataDump.Add(level.name, levelData.tips);
|
|
}
|
|
}
|
|
return new ValueTuple<Il2CppArrayBase<TextAsset>, Dictionary<string, string>>(izLevelData, izLevelDataDump);
|
|
}
|
|
|
|
public static ValueTuple<Il2CppArrayBase<TextAsset>, Dictionary<string, string>> DumpFSStrings()
|
|
{
|
|
var fusionShowcaseData = Resources.LoadAll<TextAsset>("leveldata/explore");
|
|
Dictionary<string, string> fusionShowcaseDataDump = new Dictionary<string, string>();
|
|
foreach (var level in fusionShowcaseData)
|
|
{
|
|
string data = level.text;
|
|
LevelData levelData = JsonUtility.FromJson<LevelData>(data);
|
|
if (levelData.tips != null)
|
|
{
|
|
fusionShowcaseDataDump.Add(level.name, levelData.tips);
|
|
}
|
|
}
|
|
return new ValueTuple<Il2CppArrayBase<TextAsset>, Dictionary<string, string>>(fusionShowcaseData, fusionShowcaseDataDump);
|
|
}
|
|
|
|
public static ValueTuple<Il2CppAlmanacData.AlmanacData, Dictionary<string, string>> DumpDetailStrings()
|
|
{
|
|
string detailStringsData = Resources.Load<TextAsset>("detailstrings").text;
|
|
Il2CppAlmanacData.AlmanacData detailStrings = JsonUtility.FromJson<Il2CppAlmanacData.AlmanacData>(detailStringsData);
|
|
|
|
Dictionary<string, string> detailStringsDump = new Dictionary<string, string>();
|
|
foreach (var detailString in detailStrings.details)
|
|
{
|
|
if(detailStringsDump.ContainsKey(detailString.title))
|
|
{
|
|
detailStringsDump[detailString.title] = detailString.text;
|
|
}
|
|
else
|
|
{
|
|
detailStringsDump.Add(detailString.title, detailString.text);
|
|
}
|
|
}
|
|
return new ValueTuple<Il2CppAlmanacData.AlmanacData, Dictionary<string, string>>(detailStrings, detailStringsDump);
|
|
}
|
|
|
|
#if DEBUG
|
|
public static void DumpUntranslatedStrings(string text)
|
|
{
|
|
string dumpDir = GetAssetDir(AssetType.Dumps);
|
|
string jsonFile = Path.Combine(dumpDir, "UntranslatedStrings.json");
|
|
|
|
if (!Directory.Exists(dumpDir))
|
|
{
|
|
Directory.CreateDirectory(dumpDir);
|
|
}
|
|
|
|
if (!File.Exists(jsonFile))
|
|
{
|
|
File.WriteAllText(jsonFile, "{}"); // Initialize empty JSON object
|
|
}
|
|
|
|
string json = File.ReadAllText(jsonFile);
|
|
var untranslatedStrings = System.Text.Json.JsonSerializer.Deserialize<Dictionary<string, string>>(json);
|
|
|
|
if (!untranslatedStrings.ContainsKey(text))
|
|
{
|
|
untranslatedStrings[text] = text;
|
|
var options = new JsonSerializerOptions
|
|
{
|
|
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
|
|
WriteIndented = true
|
|
};
|
|
File.WriteAllText(jsonFile, System.Text.Json.JsonSerializer.Serialize(untranslatedStrings, options));
|
|
}
|
|
}
|
|
#endif
|
|
|
|
|
|
#if MULTI_LANGUAGE
|
|
internal static void LoadLanguage()
|
|
{
|
|
try
|
|
{
|
|
// Load the language preference as a string and parse it into the enum
|
|
string languageName = MelonPreferences.GetEntryValue<string>("PvZ_Fusion_Translator", "Language");
|
|
if (Enum.TryParse(languageName, out Utils.LanguageEnum loadedLanguage))
|
|
{
|
|
Utils.Language = loadedLanguage;
|
|
}
|
|
else
|
|
{
|
|
Log.LogWarning($"Invalid language '{languageName}' found in preferences. Falling back to English.");
|
|
Utils.Language = Utils.LanguageEnum.English; // Default fallback
|
|
}
|
|
Log.LogWarning($"Loaded language {languageName}");
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Log.LogError("Error loading language setting.");
|
|
Log.LogError($"{e.GetType()} {e.Message}");
|
|
}
|
|
Log.LogInfo($"Language has been loaded: {Utils.Language}");
|
|
}
|
|
|
|
internal static void SaveLanguage()
|
|
{
|
|
try
|
|
{
|
|
// Save the current language as a string
|
|
MelonPreferences.SetEntryValue("PvZ_Fusion_Translator", "Language", Utils.Language.ToString());
|
|
|
|
// Ensure changes are written to the config file
|
|
// MelonPreferences.Save();
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Log.LogError("Error saving language setting.");
|
|
Log.LogError($"{e.GetType()} {e.Message}");
|
|
}
|
|
// Log.LogInfo($"Language has been saved: {Utils.Language}");
|
|
}
|
|
#endif
|
|
}
|
|
} |