0
0
mirror of https://github.com/sp-tarkov/modules.git synced 2025-02-13 09:50:43 -05:00
modules/project/Aki.SinglePlayer/Patches/MainMenu/PluginErrorNotifierPatch.cs
DrakiaXYZ 4b0ebbe597 Send plugin errors to the server console (!35)
- Implement the models/helpers required to send console messages to the server console
- Implement sending plugin errors on startup to the server console
- Remove an unused variable and incorrect comment from PluginErrorNotifierPatch

Example output:
![Example](https://i.imgur.com/c0XBYLm.png)

Depends on changes in SPT-AKI/Server#160

Co-authored-by: DrakiaXYZ <565558+TheDgtl@users.noreply.github.com>
Reviewed-on: SPT-AKI/Modules#35
Reviewed-by: Terkoiz <terkoiz@noreply.dev.sp-tarkov.com>
Co-authored-by: DrakiaXYZ <drakiaxyz@noreply.dev.sp-tarkov.com>
Co-committed-by: DrakiaXYZ <drakiaxyz@noreply.dev.sp-tarkov.com>
2023-10-27 18:46:56 +00:00

79 lines
3.0 KiB
C#

using Aki.Common.Utils;
using Aki.Reflection.Patching;
using Aki.Reflection.Utils;
using BepInEx.Bootstrap;
using EFT.Communications;
using EFT.UI;
using HarmonyLib;
using System.Linq;
using System.Reflection;
using System.Text;
using UnityEngine;
namespace Aki.SinglePlayer.Patches.MainMenu
{
/***
* On the first show of the main menu, check if any BepInEx plugins have failed to load, and inform
* the user. This is done via a toast in the bottom right, with a more detailed console message, as
* well as having the errors forwarded to the server console
**/
internal class PluginErrorNotifierPatch : ModulePatch
{
private static MethodInfo _displayMessageNotificationMethod;
private static bool _messageShown = false;
protected override MethodBase GetTargetMethod()
{
_displayMessageNotificationMethod = AccessTools.Method(typeof(NotificationManagerClass), "DisplayMessageNotification");
var desiredType = typeof(MenuScreen);
var desiredMethod = desiredType.GetMethod("Show", PatchConstants.PrivateFlags);
return desiredMethod;
}
[PatchPostfix]
private static void PatchPostfix()
{
var failedPluginCount = Chainloader.DependencyErrors.Count;
// Skip if we've already shown the message, or there are no errors
if (_messageShown || failedPluginCount == 0)
{
return;
}
// Show a toast in the bottom right of the screen indicating how many plugins failed to load
var consoleHeaderMessage = $"{failedPluginCount} plugin{(failedPluginCount > 1 ? "s" : "")} failed to load due to errors";
var toastMessage = $"{consoleHeaderMessage}. Please check the console for details.";
_displayMessageNotificationMethod.Invoke(null, new object[] { toastMessage, ENotificationDurationType.Infinite, ENotificationIconType.Alert, Color.red });
// Build the error message we'll put in the BepInEx and in-game consoles
var stringBuilder = new StringBuilder();
stringBuilder.AppendLine($"{consoleHeaderMessage}:");
foreach (string error in Chainloader.DependencyErrors)
{
stringBuilder.AppendLine(error);
}
var errorMessage = stringBuilder.ToString();
// Show an error in the BepInEx console/log file
Logger.LogError(errorMessage);
// Show errors in the server console
ServerLog.Error("Aki.Singleplayer", errorMessage);
// Show an error in the in-game console, we have to write this in reverse order because the
// in-game console shows newer messages at the top
foreach (string line in errorMessage.Split('\n').Reverse())
{
if (line.Length > 0)
{
ConsoleScreen.LogError(line);
}
}
_messageShown = true;
}
}
}