diff --git a/KSPCommunityFixes/Modding/ReflectionTypeLoadExceptionHandler.cs b/KSPCommunityFixes/Modding/ReflectionTypeLoadExceptionHandler.cs index dfedacba..0a86a394 100644 --- a/KSPCommunityFixes/Modding/ReflectionTypeLoadExceptionHandler.cs +++ b/KSPCommunityFixes/Modding/ReflectionTypeLoadExceptionHandler.cs @@ -25,14 +25,13 @@ class ReflectionTypeLoadExceptionHandler : MonoBehaviour private class FailedAssembly { public string errorMessage; - public string guiMessage; + + private readonly string assemblyName; + private readonly string assemblyLocation; + private readonly List missingDependencies = new List(); public FailedAssembly(Assembly assembly) { - string assemblyName; - string assemblyLocation; - List missingDependencies = new List(); - try { assemblyName = assembly.GetName().Name; @@ -70,24 +69,40 @@ public FailedAssembly(Assembly assembly) errorMessage = $"[KSPCF] A ReflectionTypeLoadException thrown by Assembly.GetTypes() has been handled by KSP Community Fixes." + $"\nThis is usually harmless, but indicates that the \"{assemblyName}\" plugin failed to load (location: \"{assemblyLocation}\")"; - guiMessage = Localizer.Format(LOC_F_PluginLoadFailed_name_in_location, $"{assemblyName}", $"\"{assemblyLocation}\""); - if (missingDependencies.Count > 0) { errorMessage += $"\nIt happened because \"{assemblyName}\" is missing the following dependencies : "; - guiMessage += $"\n{LOC_PluginLoadFailed_missingDep} : "; for (int i = 0; i < missingDependencies.Count; i++) { if (i > 0) - { errorMessage += ", "; - guiMessage += ", "; - } errorMessage += "\"" + missingDependencies[i] + "\""; + } + } + } + + // Build the GUI message lazily at render time. The LOC_ fields are only populated by + // LocalizationUtils.ParseLocalization() once KSPCommunityFixes.Start() runs, which can happen + // after a FailedAssembly is constructed during early assembly loading. Formatting here (rather + // than in the constructor) ensures the localized strings are used. See issue #403. + public string GetGuiMessage() + { + string guiMessage = Localizer.Format(LOC_F_PluginLoadFailed_name_in_location, $"{assemblyName}", $"\"{assemblyLocation}\""); + + if (missingDependencies.Count > 0) + { + guiMessage += $"\n{LOC_PluginLoadFailed_missingDep} : "; + for (int i = 0; i < missingDependencies.Count; i++) + { + if (i > 0) + guiMessage += ", "; + guiMessage += "" + missingDependencies[i] + ""; } } + + return guiMessage; } } @@ -139,7 +154,7 @@ private void OnGUI() GUILayout.Label(LOC_PluginsLoadFailed, labelStyle); foreach (FailedAssembly assembly in failedAssemblies.Values) - GUILayout.Label(assembly.guiMessage, labelStyle); + GUILayout.Label(assembly.GetGuiMessage(), labelStyle); GUILayout.EndVertical(); GUILayout.EndArea();