More spring cleaning

This commit is contained in:
Emik 2026-10-21 19:54:49 +02:00
parent 0e00b13a89
commit 314c33d327
Signed by: emik
GPG key ID: 6B0CD72A5E503BDF
6 changed files with 162 additions and 234 deletions

View file

@ -1,5 +1,6 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation"> <wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AAlmanacData_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2026_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F5fa4418c9b1a467da62bad48101c2172955800_003F58_003F8c883c96_003FAlmanacData_002Ecs/@EntryIndexedValue">ForceIncluded</s:String> <s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AAlmanacData_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2026_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F5fa4418c9b1a467da62bad48101c2172955800_003F58_003F8c883c96_003FAlmanacData_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AAPI_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2026_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fad21c822cc9645948d5cfdf885348ff4f7800_003Fd6_003F4ffbd890_003FAPI_002Ecs/@EntryIndexedValue">ForceIncluded</s:String> <s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AAPI_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2026_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fad21c822cc9645948d5cfdf885348ff4f7800_003Fd6_003F4ffbd890_003FAPI_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AEnum_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2026_002E3_003Fresharper_002Dhost_003FSourcesCache_003F6fb91b1b8378821dddcd68bf9ef76dbedde39b92261dd6557a21f5c40181a_003FEnum_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AInvestBuffData_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2026_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F5fa4418c9b1a467da62bad48101c2172955800_003F5e_003F78131568_003FInvestBuffData_002Ecs/@EntryIndexedValue">ForceIncluded</s:String> <s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AInvestBuffData_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2026_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F5fa4418c9b1a467da62bad48101c2172955800_003F5e_003F78131568_003FInvestBuffData_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AObject_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2026_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F34f66f6718614bd2bf1fb17f10bf229d5ac400_003F28_003F6d0414c0_003FObject_002Ecs/@EntryIndexedValue">ForceIncluded</s:String></wpf:ResourceDictionary> <s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AObject_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2026_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F34f66f6718614bd2bf1fb17f10bf229d5ac400_003F28_003F6d0414c0_003FObject_002Ecs/@EntryIndexedValue">ForceIncluded</s:String></wpf:ResourceDictionary>

View file

@ -48,7 +48,7 @@ internal static class AudioStore
} }
#if MELONLOADER #if MELONLOADER
var audioSourceType = typeof(AudioSource); var audioSourceType = typeof(AudioSource);
var sourceMethodName = "Play"; const string SourceMethodName = "Play";
var prefixMethod = typeof(AudioStore).GetMethod(nameof(AudioPlayPatch), BindingFlags.Static | BindingFlags.Public); var prefixMethod = typeof(AudioStore).GetMethod(nameof(AudioPlayPatch), BindingFlags.Static | BindingFlags.Public);
if (prefixMethod == null) if (prefixMethod == null)
@ -58,13 +58,13 @@ internal static class AudioStore
} }
_ = Core.Instance.HarmonyInstance.Patch( _ = Core.Instance.HarmonyInstance.Patch(
AccessTools.Method(audioSourceType, sourceMethodName), AccessTools.Method(audioSourceType, SourceMethodName),
new HarmonyMethod(prefixMethod) new(prefixMethod)
); );
Core.Instance.HarmonyInstance.Patch( Core.Instance.HarmonyInstance.Patch(
AccessTools.Method(audioSourceType, sourceMethodName, [typeof(ulong)]), AccessTools.Method(audioSourceType, SourceMethodName, [typeof(ulong)]),
new HarmonyMethod(prefixMethod) new(prefixMethod)
); );
#endif #endif
} }

View file

@ -6,7 +6,7 @@ global using MelonLoader.Utils;
global using Il2Cpp; global using Il2Cpp;
global using Il2CppAlmanacData; global using Il2CppAlmanacData;
global using Il2CppCore; global using Il2CppCore;
global using Il2CppGameLevel; global using Il2CppGameLevel; // ReSharper disable once RedundantUsingDirective.Global
global using Il2CppGameLevel.Abyss; global using Il2CppGameLevel.Abyss;
global using Il2CppGameLevel.EventNodes; global using Il2CppGameLevel.EventNodes;
global using Il2CppGameLevel.RogueShooting; global using Il2CppGameLevel.RogueShooting;
@ -44,6 +44,7 @@ global using Il2CppPlantInfo = AlmanacData.PlantInfo;
using PvZ_Fusion_Translator.AssetStore; using PvZ_Fusion_Translator.AssetStore;
using PvZ_Fusion_Translator.Patches.Managers; using PvZ_Fusion_Translator.Patches.Managers;
using PvZ_Fusion_Translator.Patches.Modes.Super_Editor; using PvZ_Fusion_Translator.Patches.Modes.Super_Editor;
#if MELONLOADER #if MELONLOADER
[assembly: [assembly:
MelonGame("LanPiaoPiao", "PlantsVsZombiesRH"), MelonGame("LanPiaoPiao", "PlantsVsZombiesRH"),

View file

@ -544,22 +544,20 @@ internal static class FileLoader
} }
} }
foreach (var filepath in Directory.EnumerateFiles(textureDir, "*.png", SearchOption.AllDirectories)) foreach (var path in Directory.EnumerateFiles(textureDir, "*.png", SearchOption.AllDirectories)
.Where(
p => (!p.Contains("[Custom Textures]", StringComparison.OrdinalIgnoreCase) ||
!Core.Instance.ConfigDefaultTextures.Value) &&
(localToc.ContainsKey(p.Replace(basePath + "\\", "").Replace("\\", "/")) ||
SerializeWithIndentation(localToc) == "{}")
))
{ {
if (filepath.Contains("[Custom Textures]", StringComparison.OrdinalIgnoreCase) &&
Core.Instance.ConfigDefaultTextures.Value)
continue;
if (!localToc.ContainsKey(filepath.Replace(basePath + "\\", "").Replace("\\", "/")) &&
SerializeWithIndentation(localToc) != "{}")
continue;
if (ModFeatures.IsDebug) if (ModFeatures.IsDebug)
Log.LogDebug("Loading File : " + filepath); Log.LogDebug("Loading File : " + path);
var imageData = File.ReadAllBytes(filepath); var imageData = File.ReadAllBytes(path);
var texture2D = Utils.LoadImage(imageData); _ = Utils.LoadImage(imageData);
TextureStore.TextureDict[Path.GetFileNameWithoutExtension(filepath)] = imageData; TextureStore.TextureDict[Path.GetFileNameWithoutExtension(path)] = imageData;
} }
} }
@ -570,6 +568,7 @@ internal static class FileLoader
} }
} }
// ReSharper disable once FunctionComplexityOverflow
internal static void LoadLocalizedSprites(Utils.LanguageEnum? language = null) internal static void LoadLocalizedSprites(Utils.LanguageEnum? language = null)
{ {
var textureDir = GetAssetDir(AssetType.Sprites, language); var textureDir = GetAssetDir(AssetType.Sprites, language);
@ -580,14 +579,13 @@ internal static class FileLoader
try try
{ {
var trueTextureDir = GetAssetDir(AssetType.Textures, language); var trueTextureDir = GetAssetDir(AssetType.Textures, language);
var localToc = new Dictionary<string, string>();
var localTocDir = Path.Combine(trueTextureDir, "Texture_TOC.json"); var localTocDir = Path.Combine(trueTextureDir, "Texture_TOC.json");
if (!File.Exists(localTocDir)) if (!File.Exists(localTocDir))
File.WriteAllText(localTocDir, "{}"); File.WriteAllText(localTocDir, "{}");
var localTocContent = File.ReadAllText(localTocDir); var localTocContent = File.ReadAllText(localTocDir);
localToc = System.Text.Json.JsonSerializer.Deserialize<Dictionary<string, string>>(localTocContent); var localToc = System.Text.Json.JsonSerializer.Deserialize<Dictionary<string, string>>(localTocContent);
var basePath = Core.ModDirectory; var basePath = Core.ModDirectory;
@ -627,44 +625,42 @@ internal static class FileLoader
{ {
var downloadPath = Path.Combine(basePath, path); var downloadPath = Path.Combine(basePath, path);
var baseUrl = const string BaseUrl =
$"https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/"; "https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/";
var url = baseUrl + path; var url = $"{BaseUrl}{path}";
var imageData = Utils.GetByteDataFromWeb(url).Result; var imageData = Utils.GetByteDataFromWeb(url).Result;
if (imageData != null) if (imageData == null)
{ continue;
var fileName = Path.GetFileName(downloadPath);
var texture2D = Utils.LoadImage(imageData);
TextureStore.SpriteDict[fileName] = imageData;
if (!Directory.Exists(Path.GetDirectoryName(downloadPath))) var fileName = Path.GetFileName(downloadPath);
Directory.CreateDirectory(Path.GetDirectoryName(downloadPath)); _ = Utils.LoadImage(imageData);
TextureStore.SpriteDict[fileName] = imageData;
File.WriteAllBytes(downloadPath, imageData); if (!Directory.Exists(Path.GetDirectoryName(downloadPath)))
} Directory.CreateDirectory(Path.GetDirectoryName(downloadPath));
File.WriteAllBytes(downloadPath, imageData);
} }
} }
} }
foreach (var filepath in Directory.EnumerateFiles(textureDir, "*.png", SearchOption.AllDirectories)) foreach (var path in Directory.EnumerateFiles(textureDir, "*.png", SearchOption.AllDirectories)
.Where(
p => (!p.Contains("[Custom Textures]", StringComparison.OrdinalIgnoreCase) ||
!Core.Instance.ConfigDefaultTextures.Value) &&
(localToc.ContainsKey(p.Replace(basePath + "\\", "").Replace("\\", "/")) ||
SerializeWithIndentation(localToc) == "{}")
))
{ {
if (filepath.Contains("[Custom Textures]", StringComparison.OrdinalIgnoreCase) &&
Core.Instance.ConfigDefaultTextures.Value)
continue;
if (!localToc.ContainsKey(filepath.Replace(basePath + "\\", "").Replace("\\", "/")) &&
SerializeWithIndentation(localToc) != "{}")
continue;
if (ModFeatures.IsDebug) if (ModFeatures.IsDebug)
Log.LogDebug("Loading File (Sprite): " + filepath); Log.LogDebug("Loading File (Sprite): " + path);
var imageData = File.ReadAllBytes(filepath); var imageData = File.ReadAllBytes(path);
var texture2D = Utils.LoadImage(imageData); _ = Utils.LoadImage(imageData);
TextureStore.SpriteDict[Path.GetFileNameWithoutExtension(filepath)] = imageData; TextureStore.SpriteDict[Path.GetFileNameWithoutExtension(path)] = imageData;
} }
} }
@ -692,14 +688,13 @@ internal static class FileLoader
try try
{ {
var trueTextureDir = Path.Combine(Core.ModDirectory, "[Custom Textures]"); var trueTextureDir = Path.Combine(Core.ModDirectory, "[Custom Textures]");
var localToc = new Dictionary<string, string>();
var localTocDir = Path.Combine(trueTextureDir, "Default_TOC.json"); var localTocDir = Path.Combine(trueTextureDir, "Default_TOC.json");
if (!File.Exists(localTocDir)) if (!File.Exists(localTocDir))
File.WriteAllText(localTocDir, "{}"); File.WriteAllText(localTocDir, "{}");
var localTocContent = File.ReadAllText(localTocDir); var localTocContent = File.ReadAllText(localTocDir);
localToc = System.Text.Json.JsonSerializer.Deserialize<Dictionary<string, string>>(localTocContent); var localToc = System.Text.Json.JsonSerializer.Deserialize<Dictionary<string, string>>(localTocContent);
var basePath = Core.ModDirectory; var basePath = Core.ModDirectory;
@ -739,24 +734,23 @@ internal static class FileLoader
{ {
var downloadPath = Path.Combine(basePath, path); var downloadPath = Path.Combine(basePath, path);
var baseUrl = const string BaseUrl = "https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/";
$"https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/";
var url = baseUrl + path; var url = $"{BaseUrl}{path}";
var imageData = Utils.GetByteDataFromWeb(url).Result; var imageData = Utils.GetByteDataFromWeb(url).Result;
if (imageData != null) if (imageData == null)
{ continue;
var fileName = Path.GetFileName(downloadPath);
var texture2D = Utils.LoadImage(imageData);
TextureStore.TextureDict[fileName] = imageData;
if (!Directory.Exists(Path.GetDirectoryName(downloadPath))) var fileName = Path.GetFileName(downloadPath);
Directory.CreateDirectory(Path.GetDirectoryName(downloadPath)); _ = Utils.LoadImage(imageData);
TextureStore.TextureDict[fileName] = imageData;
File.WriteAllBytes(downloadPath, imageData); if (!Directory.Exists(Path.GetDirectoryName(downloadPath)))
} Directory.CreateDirectory(Path.GetDirectoryName(downloadPath));
File.WriteAllBytes(downloadPath, imageData);
} }
} }
} }
@ -772,7 +766,7 @@ internal static class FileLoader
continue; continue;
var imageData = File.ReadAllBytes(filepath); var imageData = File.ReadAllBytes(filepath);
var texture2D = Utils.LoadImage(imageData); _ = Utils.LoadImage(imageData);
TextureStore.TextureDict[Path.GetFileNameWithoutExtension(filepath)] = imageData; TextureStore.TextureDict[Path.GetFileNameWithoutExtension(filepath)] = imageData;
} }
} }
@ -794,14 +788,13 @@ internal static class FileLoader
try try
{ {
var trueTextureDir = Path.Combine(Core.ModDirectory, "[Custom Textures]"); var trueTextureDir = Path.Combine(Core.ModDirectory, "[Custom Textures]");
var localToc = new Dictionary<string, string>();
var localTocDir = Path.Combine(trueTextureDir, "Custom_TOC.json"); var localTocDir = Path.Combine(trueTextureDir, "Custom_TOC.json");
if (!File.Exists(localTocDir)) if (!File.Exists(localTocDir))
File.WriteAllText(localTocDir, "{}"); File.WriteAllText(localTocDir, "{}");
var localTocContent = File.ReadAllText(localTocDir); var localTocContent = File.ReadAllText(localTocDir);
localToc = System.Text.Json.JsonSerializer.Deserialize<Dictionary<string, string>>(localTocContent); var localToc = System.Text.Json.JsonSerializer.Deserialize<Dictionary<string, string>>(localTocContent);
var basePath = Core.ModDirectory; var basePath = Core.ModDirectory;
@ -821,13 +814,7 @@ internal static class FileLoader
foreach (var pair in textureToc) foreach (var pair in textureToc)
{ {
if (!localToc.TryGetValue(pair.Key, out var value)) if (!localToc.TryGetValue(pair.Key, out var value) || pair.Value != value)
{
toDownload.Add(pair.Key);
continue;
}
if (pair.Value != value)
{ {
toDownload.Add(pair.Key); toDownload.Add(pair.Key);
continue; continue;
@ -844,24 +831,24 @@ internal static class FileLoader
{ {
var downloadPath = Path.Combine(basePath, path); var downloadPath = Path.Combine(basePath, path);
var baseUrl = const string BaseUrl =
$"https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/"; "https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/";
var url = baseUrl + path; var url = $"{BaseUrl}{path}";
var imageData = Utils.GetByteDataFromWeb(url).Result; var imageData = Utils.GetByteDataFromWeb(url).Result;
if (imageData != null) if (imageData == null)
{ continue;
var fileName = Path.GetFileName(downloadPath);
var texture2D = Utils.LoadImage(imageData);
TextureStore.TextureDict[fileName] = imageData;
if (!Directory.Exists(Path.GetDirectoryName(downloadPath))) var fileName = Path.GetFileName(downloadPath);
Directory.CreateDirectory(Path.GetDirectoryName(downloadPath)); _ = Utils.LoadImage(imageData);
TextureStore.TextureDict[fileName] = imageData;
File.WriteAllBytes(downloadPath, imageData); if (!Directory.Exists(Path.GetDirectoryName(downloadPath)))
} Directory.CreateDirectory(Path.GetDirectoryName(downloadPath));
File.WriteAllBytes(downloadPath, imageData);
} }
} }
} }
@ -873,7 +860,7 @@ internal static class FileLoader
continue; continue;
var imageData = File.ReadAllBytes(filepath); var imageData = File.ReadAllBytes(filepath);
var texture2D = Utils.LoadImage(imageData); _ = Utils.LoadImage(imageData);
TextureStore.TextureDict[Path.GetFileNameWithoutExtension(filepath)] = imageData; TextureStore.TextureDict[Path.GetFileNameWithoutExtension(filepath)] = imageData;
} }
} }
@ -934,31 +921,23 @@ internal static class FileLoader
var almanacDir = GetAssetDir(AssetType.Almanac, Utils.Language); var almanacDir = GetAssetDir(AssetType.Almanac, Utils.Language);
if (AlmanacPlantMenu_Patch.AlmanacJson != "") if (AlmanacPlantMenu_Patch.AlmanacJson != "")
{
var plantAlmanac = SerializeWithIndentation(AlmanacPlantMenu_Patch.AlmanacJson);
File.WriteAllText( File.WriteAllText(
Path.Combine(almanacDir, "LawnStringsTranslate.json"), Path.Combine(almanacDir, "LawnStringsTranslate.json"),
AlmanacPlantMenu_Patch.AlmanacJson AlmanacPlantMenu_Patch.AlmanacJson
); );
}
if (AlmanacZombieMenu_Patch.AlmanacJson != "") if (AlmanacZombieMenu_Patch.AlmanacJson != "")
{
var zombieAlmanac = SerializeWithIndentation(AlmanacZombieMenu_Patch.AlmanacJson);
File.WriteAllText( File.WriteAllText(
Path.Combine(almanacDir, "ZombieStringsTranslate.json"), Path.Combine(almanacDir, "ZombieStringsTranslate.json"),
AlmanacZombieMenu_Patch.AlmanacJson AlmanacZombieMenu_Patch.AlmanacJson
); );
}
if (AlmanacSelectMenu_Patch.DetailStrings != new Dictionary<string, string>()) if (AlmanacSelectMenu_Patch.DetailStrings == new Dictionary<string, string>())
{ return;
var detailStrings = SerializeWithIndentation(AlmanacSelectMenu_Patch.DetailStrings);
File.WriteAllText(Path.Combine(almanacDir, "DetailStringsTranslate.json"), detailStrings); var 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 = ' ') public static string SerializeWithIndentation<T>(T value, int size = 4, char indentChar = ' ')
@ -992,10 +971,8 @@ internal static class FileLoader
File.WriteAllText(Path.Combine(dumpDir, "ZombieStrings.json"), zombieStrings); File.WriteAllText(Path.Combine(dumpDir, "ZombieStrings.json"), zombieStrings);
//File.WriteAllText(Path.Combine(dumpDir, "AbyssBuffData.json"), AbyssBuffData); //File.WriteAllText(Path.Combine(dumpDir, "AbyssBuffData.json"), AbyssBuffData);
// dump iz tips // Dump IZ tips.
var izDump = DumpIZStrings(); var (_, izLevelDataDump) = DumpIZStrings();
var izLevelData = izDump.Item1;
var izLevelDataDump = izDump.Item2;
File.WriteAllText( File.WriteAllText(
Path.Combine(dumpDir, "tips_iz.json"), Path.Combine(dumpDir, "tips_iz.json"),
@ -1009,10 +986,8 @@ internal static class FileLoader
) )
); );
// dump fusion showcase tips // Dump fusion showcase tips.
var fusionShowcaseDump = DumpFSStrings(); var (_, fusionShowcaseDataDump) = DumpFSStrings();
var fusionShowcaseData = fusionShowcaseDump.Item1;
var fusionShowcaseDataDump = fusionShowcaseDump.Item2;
File.WriteAllText( File.WriteAllText(
Path.Combine(dumpDir, "tips_fs.json"), Path.Combine(dumpDir, "tips_fs.json"),
@ -1026,7 +1001,7 @@ internal static class FileLoader
) )
); );
// dump almanac mechanics // Dump almanac mechanics.
var (_, detailStrings) = DumpDetailStrings(); var (_, detailStrings) = DumpDetailStrings();
File.WriteAllText( File.WriteAllText(
@ -1042,7 +1017,7 @@ internal static class FileLoader
); );
} }
public static ValueTuple<Il2CppArrayBase<TextAsset>, Dictionary<string, string>> DumpIZStrings() public static (Il2CppArrayBase<TextAsset>, Dictionary<string, string>) DumpIZStrings()
{ {
var izLevelData = Resources.LoadAll<TextAsset>("izleveldata"); var izLevelData = Resources.LoadAll<TextAsset>("izleveldata");
var izLevelDataDump = new Dictionary<string, string>(); var izLevelDataDump = new Dictionary<string, string>();

View file

@ -9,23 +9,18 @@ public static class ModFeatures
ReloadStrings, ReloadTextures, ExportLevelStrings, ReloadStrings, ReloadTextures, ExportLevelStrings,
} }
private class ModFeature private sealed class ModFeature(string name, ModType modType, KeyCode keyCode, bool defaultValue = false)
{ {
public string Name { get; private set; } // ReSharper disable once UnusedMember.Local
public string Name { get; private set; } = name;
public ModType ModType { get; private set; } // ReSharper disable once MemberCanBePrivate.Local
public ModType ModType { get; } = modType;
public KeyCode KeyCode { get; private set; } public KeyCode KeyCode { get; } = keyCode;
public bool IsActive { get; set; } // ReSharper disable once UnusedMember.Local
public bool IsActive { get; set; } = defaultValue;
public ModFeature(string name, ModType modType, KeyCode keyCode, bool defaultValue = false)
{
Name = name;
ModType = modType;
KeyCode = keyCode;
IsActive = defaultValue;
}
public void ToggleFeature() public void ToggleFeature()
{ {
@ -40,22 +35,20 @@ public static class ModFeatures
Core.ShowToast("Textures Reloaded!"); Core.ShowToast("Textures Reloaded!");
return; return;
case ModType.ExportLevelStrings: case ModType.ExportLevelStrings:
{
var customMenu = UnityEngine.Object.FindObjectOfType<CustomMenu>(); var customMenu = UnityEngine.Object.FindObjectOfType<CustomMenu>();
if (!customMenu) if (!customMenu)
return; return;
if (customMenu.isActiveAndEnabled) if (!customMenu.isActiveAndEnabled)
{ return;
Patches.Modes.Super_Editor.GameLevel.LevelManager_Patch
.ExportLevelStrings(customMenu.LevelData);
Core.ShowToast("Dumped level strings!"); Patches.Modes.Super_Editor.GameLevel.LevelManager_Patch
} .ExportLevelStrings(customMenu.LevelData);
Core.ShowToast("Dumped level strings!");
return; return;
} default: return;
} }
} }
} }
@ -68,7 +61,7 @@ public static class ModFeatures
public static bool IsMultiLanguage { get; } = IsDefined("PVZ_FUSION_TRANSLATOR_MULTI_LANGUAGE", true); public static bool IsMultiLanguage { get; } = IsDefined("PVZ_FUSION_TRANSLATOR_MULTI_LANGUAGE", true);
private static Dictionary<ModType, ModFeature> s_featureLists = new() private static readonly Dictionary<ModType, ModFeature> s_featureLists = new()
{ {
{ ModType.ReloadStrings, new("Reload Strings", ModType.ReloadStrings, KeyCode.Home, true) }, { ModType.ReloadStrings, new("Reload Strings", ModType.ReloadStrings, KeyCode.Home, true) },
{ ModType.ReloadTextures, new("Reload Textures", ModType.ReloadTextures, KeyCode.End, true) }, { ModType.ReloadTextures, new("Reload Textures", ModType.ReloadTextures, KeyCode.End, true) },
@ -80,21 +73,19 @@ public static class ModFeatures
public static void ToggleFeature(ModType modType) public static void ToggleFeature(ModType modType)
{ {
if (!s_featureLists.ContainsKey(modType)) if (s_featureLists.TryGetValue(modType, out var list))
return; list.ToggleFeature();
s_featureLists[modType].ToggleFeature();
} }
public static void OnLateUpdate() public static void OnLateUpdate()
{ {
foreach (var (type, feature) in s_featureLists) foreach (var (_, feature) in s_featureLists)
if (feature.KeyCode != KeyCode.None && Enum.IsDefined(typeof(KeyCode), feature.KeyCode)) if (feature.KeyCode != KeyCode.None && Enum.IsDefined(feature.KeyCode))
if (Input.GetKeyDown(feature.KeyCode)) if (Input.GetKeyDown(feature.KeyCode))
feature.ToggleFeature(); feature.ToggleFeature();
} }
static bool IsDefined(string env, bool fallback = false) private static bool IsDefined(string env, bool fallback = false)
{ {
var ret = var ret =
Environment.GetEnvironmentVariable(env)?.ToUpperInvariant() is not "FALSE" and not "0" and var value && Environment.GetEnvironmentVariable(env)?.ToUpperInvariant() is not "FALSE" and not "0" and var value &&

View file

@ -201,7 +201,7 @@ public static class Utils
.GetComponent<TextMeshProUGUI>(); .GetComponent<TextMeshProUGUI>();
newGoBackText.autoSizeTextContainer = true; newGoBackText.autoSizeTextContainer = true;
newGoBackText.text = StringStore.TranslateText(text, false); newGoBackText.text = StringStore.TranslateText(text);
newGoBackText.font = fontAsset; newGoBackText.font = fontAsset;
newGoBackText.color = color; newGoBackText.color = color;
} }
@ -261,9 +261,6 @@ public static class Utils
public static string GetZombieNameFromAlmanac(ZombieType theZombieType, bool removeTags = false) public static string GetZombieNameFromAlmanac(ZombieType theZombieType, bool removeTags = false)
{ {
var theZombieName = ""; var theZombieName = "";
var currentLanguage = Language.ToString();
var json = AlmanacZombieMenu_Patch.AlmanacJson; var json = AlmanacZombieMenu_Patch.AlmanacJson;
var zombieData = JsonUtility.FromJson<Il2CppAlmanacDataClass>(json); var zombieData = JsonUtility.FromJson<Il2CppAlmanacDataClass>(json);
@ -276,30 +273,26 @@ public static class Utils
return theZombieName; return theZombieName;
} }
#pragma warning disable CA2211
public static Dictionary<int, KeyValuePair<int, string>> PlantIndices = new(); public static Dictionary<int, KeyValuePair<int, string>> PlantIndices = new();
public static Dictionary<string, string> PlantIndiceString = new(); public static Dictionary<string, string> PlantIndiceString = new();
#pragma warning restore CA2211
public static void RegisterPlantIndices() public static void RegisterPlantIndices()
{ {
PlantIndices = new(); PlantIndices = new();
PlantIndiceString = new(); PlantIndiceString = new();
string originalJson;
string translatedJson;
var currentLanguage = Language.ToString();
var almanacDir = FileLoader.GetAssetDir(FileLoader.AssetType.Almanac, Language);
var dumpDir = FileLoader.GetAssetDir(FileLoader.AssetType.Dumps); var dumpDir = FileLoader.GetAssetDir(FileLoader.AssetType.Dumps);
var originalPath = Path.Combine(dumpDir, "LawnStrings.json"); var originalPath = Path.Combine(dumpDir, "LawnStrings.json");
var path = Path.Combine(almanacDir, "LawnStringsTranslate.json");
if (!File.Exists(originalPath)) if (!File.Exists(originalPath))
Log.LogError($"LawnStrings.json file not found at path: {originalPath}"); Log.LogError($"LawnStrings.json file not found at path: {originalPath}");
else else
try try
{ {
originalJson = File.ReadAllText(originalPath); var originalJson = File.ReadAllText(originalPath);
translatedJson = AlmanacPlantMenu_Patch.AlmanacJson; var translatedJson = AlmanacPlantMenu_Patch.AlmanacJson;
var originalPlantData = JsonUtility.FromJson<Il2CppAlmanacDataClass>(originalJson); var originalPlantData = JsonUtility.FromJson<Il2CppAlmanacDataClass>(originalJson);
var translatedPlantData = JsonUtility.FromJson<Il2CppAlmanacDataClass>(translatedJson); var translatedPlantData = JsonUtility.FromJson<Il2CppAlmanacDataClass>(translatedJson);
@ -315,17 +308,12 @@ public static class Utils
if (info.seedType == originalPlantInfo.seedType) if (info.seedType == originalPlantInfo.seedType)
translatedPlantInfo = info; translatedPlantInfo = info;
if (translatedPlantInfo != null) if (translatedPlantInfo is not { name: not null })
if (translatedPlantInfo.name != null) continue;
{
var temp = new KeyValuePair<int, string>(
translatedPlantInfo.seedType,
translatedPlantInfo.name
);
PlantIndices.Add(originalPlantInfo.seedType, temp); KeyValuePair<int, string> temp = new(translatedPlantInfo.seedType, translatedPlantInfo.name);
PlantIndiceString[originalPlantInfo.name] = translatedPlantInfo.name; PlantIndices.Add(originalPlantInfo.seedType, temp);
} PlantIndiceString[originalPlantInfo.name] = translatedPlantInfo.name;
} }
} }
catch (Exception e) catch (Exception e)
@ -334,49 +322,32 @@ public static class Utils
} }
} }
public static void TryAdd<TA, TB>(Dictionary<TA, TB> dict, TA key, TB val) public static void TryAdd<TA, TB>(Dictionary<TA, TB> dict, TA key, TB val) => dict[key] = val;
{
if (dict.ContainsKey(key))
dict[key] = val;
else
dict.Add(key, val);
}
public static void TryAdd<TA, TB>(SortedDictionary<TA, TB> dict, TA key, TB val) public static void TryAdd<TA, TB>(SortedDictionary<TA, TB> dict, TA key, TB val) => dict[key] = val;
{
if (dict.ContainsKey(key))
dict[key] = val;
else
dict.Add(key, val);
}
public static AssetBundle GetAssetBundle(Assembly assembly, string assetBundlePath, bool log = false) public static AssetBundle GetAssetBundle(Assembly assembly, string assetBundlePath, bool log = false)
{ {
try try
{ {
if (assembly != null) if (assembly == null)
{ throw new($"AssetBundle {assetBundlePath} was null.");
var manifestResourceStream =
assembly.GetManifestResourceStream($"PvZ_Fusion_Translator.Resources.{assetBundlePath}");
using (manifestResourceStream) using var manifestResourceStream =
{ assembly.GetManifestResourceStream($"PvZ_Fusion_Translator.Resources.{assetBundlePath}");
if (manifestResourceStream == null)
throw new("Stream was null.");
var array = new byte[manifestResourceStream.Length]; if (manifestResourceStream == null)
_ = manifestResourceStream.Read(array, 0, array.Length); throw new("Stream was null.");
var assetBundle = AssetBundle.LoadFromMemory(array);
ArgumentNullException.ThrowIfNull(assetBundle, "assetBundle");
if (log) var array = new byte[manifestResourceStream.Length];
Log.LogDebug($"AssetBundle {assetBundlePath} has successfully been loaded."); _ = manifestResourceStream.Read(array, 0, array.Length);
var assetBundle = AssetBundle.LoadFromMemory(array);
ArgumentNullException.ThrowIfNull(assetBundle);
return assetBundle; if (log)
} Log.LogDebug($"AssetBundle {assetBundlePath} has successfully been loaded.");
}
throw new($"AssetBundle {assetBundlePath} was null."); return assetBundle;
} }
catch (Exception value) catch (Exception value)
{ {
@ -389,50 +360,45 @@ public static class Utils
var assetBundle = AssetBundle.LoadFromFile(path); var assetBundle = AssetBundle.LoadFromFile(path);
return assetBundle; return assetBundle;
} }
#if false
/*public static Dictionary<int, List<int>> recipeLinks = new Dictionary<int, List<int>>(); public static readonly Dictionary<int, List<int>> recipeLinks = new();
public static void RegisterRecipeLinks() public static void RegisterRecipeLinks()
{ {
recipeLinks.Clear(); recipeLinks.Clear();
Il2CppSystem.Array mixData = MixData.data.Cast<Il2CppSystem.Array>(); Il2CppSystem.Array mixData = MixData.data.Cast<Il2CppSystem.Array>();
int rows = mixData.GetLength(0); var rows = mixData.GetLength(0);
int columns = mixData.GetLength(1); var columns = mixData.GetLength(1);
foreach (PlantType plantType in Enum.GetValues(typeof(PlantType))) foreach (var seedType in from PlantType plantType in Enum.GetValues(typeof(PlantType)) select (int)plantType)
{ {
int seedType = (int)plantType;
recipeLinks.Add(seedType, new()); recipeLinks.Add(seedType, new());
if (seedType > 0) if (seedType > 0)
{ foreach (var checks in Enum.GetValues(typeof(PlantType))
foreach (PlantType checkType in Enum.GetValues(typeof(PlantType))) .Cast<PlantType>()
.Where(checkType => checkType > 0)
.Select(
int[] (checkType) =>
[
mixData.GetValue(seedType, (int)checkType).Unbox<int>(),
mixData.GetValue((int)checkType, seedType).Unbox<int>(),
]
))
{ {
if (checkType > 0) if (checks[0] != 0)
{ recipeLinks[seedType].Add(checks[0]);
int[] checks = [mixData.GetValue(seedType, (int)checkType).Unbox<int>(), mixData.GetValue((int)checkType, seedType).Unbox<int>()];
if (checks[0] != 0) if (checks[1] != 0)
{ recipeLinks[seedType].Add(checks[1]);
recipeLinks[seedType].Add(checks[0]);
}
if (checks[1] != 0)
{
recipeLinks[seedType].Add(checks[1]);
}
}
} }
}
if (recipeLinks[seedType].Count > 0)
{
Log.LogDebug($"Found {recipeLinks[seedType].Count} fusions for {seedType}!");
}
}
}*/
if (recipeLinks[seedType].Count > 0)
Log.LogDebug($"Found {recipeLinks[seedType].Count} fusions for {seedType}!");
}
}
#endif
public static readonly Regex UntranslatedRegex = new("\\p{IsCJKUnifiedIdeographs}+"); public static readonly Regex UntranslatedRegex = new("\\p{IsCJKUnifiedIdeographs}+");
public static bool CheckForUntranslatedText(string text) public static bool CheckForUntranslatedText(string text)
@ -488,11 +454,9 @@ public static class Utils
if (isLog) if (isLog)
Log.LogInfo($"Attempting to read {url}"); Log.LogInfo($"Attempting to read {url}");
var client = new HttpClient();
try try
{ {
var dataRequest = await client.GetAsync(url); var dataRequest = await s_client.GetAsync(url);
if (dataRequest.StatusCode == System.Net.HttpStatusCode.OK) if (dataRequest.StatusCode == System.Net.HttpStatusCode.OK)
{ {
@ -526,11 +490,9 @@ public static class Utils
if (isLog) if (isLog)
Log.LogInfo($"Attempting to read {url}"); Log.LogInfo($"Attempting to read {url}");
var client = new HttpClient();
try try
{ {
var dataRequest = await client.GetAsync(url); var dataRequest = await s_client.GetAsync(url);
if (dataRequest.StatusCode == System.Net.HttpStatusCode.OK) if (dataRequest.StatusCode == System.Net.HttpStatusCode.OK)
{ {
@ -564,19 +526,15 @@ public static class Utils
if (isLog) if (isLog)
Log.LogInfo($"Attempting to read {url}"); Log.LogInfo($"Attempting to read {url}");
var client = new HttpClient(); using var request = new HttpRequestMessage();
request.Method = HttpMethod.Get;
using var request = new HttpRequestMessage request.RequestUri = new(url);
{
Method = HttpMethod.Get,
RequestUri = new(url),
};
request.Headers.Add("Accept", "*/*"); request.Headers.Add("Accept", "*/*");
request.Headers.Add("Accept-Encoding", "gzip, deflate, br"); request.Headers.Add("Accept-Encoding", "gzip, deflate, br");
request.Headers.Add("User-Agent", "TranslatorMod"); request.Headers.Add("User-Agent", "TranslatorMod");
var dataRequest = await client.SendAsync(request); var dataRequest = await s_client.SendAsync(request);
if (dataRequest.StatusCode == System.Net.HttpStatusCode.OK) if (dataRequest.StatusCode == System.Net.HttpStatusCode.OK)
{ {
@ -602,7 +560,7 @@ public static class Utils
var res = 0; var res = 0;
var gameVersionParts = gameVersion.Split('.'); var gameVersionParts = gameVersion.Split('.');
var startingPower = (int)Math.Max(gameVersionParts.Length, 3); var startingPower = Math.Max(gameVersionParts.Length, 3);
for (var i = 0; i < startingPower; i++) for (var i = 0; i < startingPower; i++)
{ {
@ -637,7 +595,7 @@ public static class Utils
RegisterPlantIndices(); RegisterPlantIndices();
Zombie_Patch.LoadHpStrings(); Zombie_Patch.LoadHpStrings();
} }
#pragma warning disable CA2211 // ReSharper disable once NotAccessedField.Global
public static LanguageEnum OldLanguage; public static LanguageEnum OldLanguage;
public static LanguageEnum Language; public static LanguageEnum Language;
@ -698,6 +656,8 @@ public static class Utils
{ ToggleEnum.SwapLocal, "<size=85%>Change Translation\nSource" }, { ToggleEnum.SwapLocal, "<size=85%>Change Translation\nSource" },
}; };
private static readonly HttpClient s_client = new();
#pragma warning restore CA2211
public enum ToggleEnum public enum ToggleEnum
{ {
Textures, Textures,