Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 27 additions & 12 deletions KSPCommunityFixes/Modding/ReflectionTypeLoadExceptionHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<string> missingDependencies = new List<string>();

public FailedAssembly(Assembly assembly)
{
string assemblyName;
string assemblyLocation;
List<string> missingDependencies = new List<string>();

try
{
assemblyName = assembly.GetName().Name;
Expand Down Expand Up @@ -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, $"<b><color=orange>{assemblyName}</color></b>", $"\"{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, $"<b><color=orange>{assemblyName}</color></b>", $"\"{assemblyLocation}\"");

if (missingDependencies.Count > 0)
{
guiMessage += $"\n{LOC_PluginLoadFailed_missingDep} : ";
for (int i = 0; i < missingDependencies.Count; i++)
{
if (i > 0)
guiMessage += ", ";

guiMessage += "<b><color=orange>" + missingDependencies[i] + "</color></b>";
}
}

return guiMessage;
}
}

Expand Down Expand Up @@ -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();
Expand Down