Skip to content

Commit

Permalink
Fixed [issue #133](#133) : FastLoader allow the game to launch even w…
Browse files Browse the repository at this point in the history
…hen unrecoverable errors happen during loading.
  • Loading branch information
gotmachine committed Mar 29, 2023
1 parent ad56d8f commit 409a960
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 3 deletions.
2 changes: 1 addition & 1 deletion GameData/KSPCommunityFixes/KSPCommunityFixes.version
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"NAME": "KSPCommunityFixes",
"URL": "https://raw.githubusercontent.com/KSPModdingLibs/KSPCommunityFixes/master/GameData/KSPCommunityFixes/KSPCommunityFixes.version",
"DOWNLOAD": "https://github.com/KSPModdingLibs/KSPCommunityFixes/releases",
"VERSION": {"MAJOR": 1, "MINOR": 25, "PATCH": 3, "BUILD": 0},
"VERSION": {"MAJOR": 1, "MINOR": 25, "PATCH": 4, "BUILD": 0},
"KSP_VERSION": {"MAJOR": 1, "MINOR": 12, "PATCH": 5},
"KSP_VERSION_MIN": {"MAJOR": 1, "MINOR": 8, "PATCH": 0},
"KSP_VERSION_MAX": {"MAJOR": 1, "MINOR": 12, "PATCH": 5}
Expand Down
125 changes: 125 additions & 0 deletions KSPCommunityFixes/Performance/FastLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
using Debug = UnityEngine.Debug;
using UnityEngine.Experimental.Rendering;
using KSP.Localization;
using TMPro;
using UnityEngine.EventSystems;
using UnityEngine.UI;

namespace KSPCommunityFixes.Performance
{
Expand Down Expand Up @@ -1639,11 +1642,14 @@ static object StartCoroutinePassThrough(object instance, IEnumerator enumerator)
/// </summary>
static IEnumerator FrameUnlockedCoroutine(IEnumerator coroutine)
{
LoaderExceptionInfo exceptionInfo = null;
float nextFrameTime = Time.realtimeSinceStartup + minFrameTime;

Stack<IEnumerator> enumerators = new Stack<IEnumerator>();
enumerators.Push(coroutine);



while (enumerators.TryPop(out IEnumerator currentEnumerator))
{
bool moveNext;
Expand All @@ -1656,6 +1662,7 @@ static IEnumerator FrameUnlockedCoroutine(IEnumerator coroutine)
{
Debug.LogException(e);
moveNext = false;
exceptionInfo = new LoaderExceptionInfo(e, coroutine);
}

while (moveNext)
Expand All @@ -1680,11 +1687,23 @@ static IEnumerator FrameUnlockedCoroutine(IEnumerator coroutine)
}
catch (Exception e)
{
object currentObject = currentEnumerator.Current;
Debug.LogException(e);
moveNext = false;
exceptionInfo = new LoaderExceptionInfo(e, coroutine);
}
}
}

if (exceptionInfo != null)
{
exceptionInfo.Show();
while (true)
{
Thread.Sleep(10);
yield return null;
}
}
}

// Fix for issue #114 : Drag cubes are incorrectly calculated with KSPCF 1.24.1
Expand Down Expand Up @@ -2089,6 +2108,112 @@ private static bool GetPngSize(string path, out uint width, out uint height)
}
}

private class LoaderExceptionInfo
{
private string message;
private string stackTrace;
private string loader;
private string origin;
private IEnumerator rootEnumerator;

public LoaderExceptionInfo(Exception e, IEnumerator rootEnumerator)
{
message = $"{e.GetType()}: {e.Message}";
stackTrace = e.StackTrace;

string enumeratorTypeName = rootEnumerator.GetType().Name;

try
{
if (enumeratorTypeName.Contains(nameof(PartLoader.CompileParts)))
{
FieldInfo apField = rootEnumerator.GetType().GetFields(AccessTools.all).FirstOrDefault(p => p.FieldType == typeof(AvailablePart));
if (apField != null)
{
loader = "Part compilation";
origin = "Part";
AvailablePart ap = (AvailablePart)apField.GetValue(rootEnumerator);
if (ap != null)
{
origin += ": ";
if (ap.title != null)
origin += ap.title;

if (ap.partUrl != null)
origin += $" ({ap.partUrl})";
}
}
}
else if (enumeratorTypeName.Contains(nameof(PartLoader.CompileInternalProps)))
{
loader = "Internal props compilation";
FieldInfo[] fields = rootEnumerator.GetType().GetFields(AccessTools.all);
FieldInfo allPropNodesField = fields.FirstOrDefault(p => p.FieldType == typeof(UrlConfig[]));
FieldInfo indexField = fields.FirstOrDefault(p => p.Name.Contains("<i>"));
UrlConfig[] allPropNodes = allPropNodesField?.GetValue(rootEnumerator) as UrlConfig[];

if (indexField != null && allPropNodes != null)
{
int index = (int)indexField.GetValue(rootEnumerator);
if (index >= 0 && index < allPropNodes.Length)
origin = $"Prop: {allPropNodes[index].url}";
}
}
else if (enumeratorTypeName.Contains(nameof(PartLoader.CompileInternalSpaces)))
{
loader = "Internal spaces compilation";
FieldInfo[] fields = rootEnumerator.GetType().GetFields(AccessTools.all);
FieldInfo allSpaceNodesField = fields.FirstOrDefault(p => p.FieldType == typeof(UrlConfig[]));
FieldInfo indexField = fields.FirstOrDefault(p => p.Name.Contains("<i>"));
UrlConfig[] allSpaceNodes = allSpaceNodesField?.GetValue(rootEnumerator) as UrlConfig[];

if (indexField != null && allSpaceNodes != null)
{
int index = (int)indexField.GetValue(rootEnumerator);
if (index >= 0 && index < allSpaceNodes.Length)
origin = $"Space: {allSpaceNodes[index].url}";
}
}
}
catch {}
}

public void Show()
{
string content = "Loading has failed due to an unhandled error\n\n";
if (loader != null)
content += $"Failure in subsystem : {loader}\n";
if (origin != null)
content += $"{origin}\n";

content += $"\n{message}\n{stackTrace}";

DialogGUITextInput input = new DialogGUITextInput(content, true, int.MaxValue, s => s, () => content, TMP_InputField.ContentType.Standard);

MultiOptionDialog dialog = new MultiOptionDialog("loadingFailed",
string.Empty,
"Loading failed",
HighLogic.UISkin, 600f,
input,
new DialogGUIHorizontalLayout(true, false,
new DialogGUIButton("Copy to clipboard", () => GUIUtility.systemCopyBuffer = content, false),
new DialogGUIButton("Quit", Application.Quit)));
PopupDialog.SpawnPopupDialog(dialog, true, HighLogic.UISkin);
input.field.textComponent.enableWordWrapping = false;
input.field.textComponent.overflowMode = TextOverflowModes.Overflow;
input.uiItem.GetComponent<LayoutElement>().minHeight = input.field.textComponent.GetPreferredHeight() + 15f;
}
}


#endregion
}

public class GetInfoThrowModule : PartModule
{
public override string GetInfo()
{
throw new Exception("ExceptionFromGetInfo");
}
}
}
4 changes: 2 additions & 2 deletions KSPCommunityFixes/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
// Revision
//
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.25.3.0")]
[assembly: AssemblyFileVersion("1.25.4.0")]

[assembly: KSPAssembly("KSPCommunityFixes", 1, 25, 3)]
[assembly: KSPAssembly("KSPCommunityFixes", 1, 25, 4)]
[assembly: KSPAssemblyDependency("MultipleModulePartAPI", 1, 0, 0)]
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,9 @@ If doing so in the `Debug` configuration and if your KSP install is modified to

### Changelog

##### 1.25.4
- Fixed [issue #133](https://github.com/KSPModdingLibs/KSPCommunityFixes/issues/133) : FastLoader allow the game to launch even when unrecoverable errors happen during loading.

##### 1.25.3
- Fixed [issue #128](https://github.com/KSPModdingLibs/KSPCommunityFixes/issues/128) : Fairing Expansion disable not retained after revert to hangar from launch
- Fixed [issue #125](https://github.com/KSPModdingLibs/KSPCommunityFixes/issues/125) : Altimeter position was accounting for the AppLauncher width when using the settings slider, but didn't anymore after a scene reload, resulting in a slightly offset position.
Expand Down

0 comments on commit 409a960

Please sign in to comment.