quantum-space-buddies/QSB/Patches/QSBPatchManager.cs

120 lines
3.3 KiB
C#
Raw Normal View History

2021-12-01 09:10:38 +00:00
using HarmonyLib;
using OWML.Common;
2020-11-03 21:11:10 +00:00
using QSB.Utility;
2021-12-24 01:07:29 +00:00
using System;
using System.Collections.Generic;
using System.Linq;
2020-11-03 21:11:10 +00:00
2022-03-03 03:46:33 +00:00
namespace QSB.Patches;
public static class QSBPatchManager
2020-11-03 21:11:10 +00:00
{
2022-03-03 03:46:33 +00:00
public static event Action<QSBPatchTypes> OnPatchType;
public static event Action<QSBPatchTypes> OnUnpatchType;
private static readonly List<QSBPatch> _patchList = new();
private static readonly List<QSBPatchTypes> _patchedTypes = new();
2020-11-04 20:01:28 +00:00
2022-03-03 03:46:33 +00:00
public static Dictionary<QSBPatchTypes, Harmony> TypeToInstance = new();
2020-12-14 20:41:56 +00:00
2022-12-14 11:47:01 +00:00
private static bool _inited;
2022-03-03 03:46:33 +00:00
public static void Init()
{
2022-12-14 11:47:01 +00:00
if (_inited)
{
2023-07-04 19:24:00 +00:00
var newPatches = new List<QSBPatch>();
2022-12-14 11:47:01 +00:00
foreach (var type in typeof(QSBPatch).GetDerivedTypes())
{
2023-07-04 19:29:10 +00:00
if (!newPatches.Any(x => x.GetType() == type)
&& !_patchList.Any(x => x.GetType() == type))
2023-07-04 19:24:00 +00:00
{
newPatches.Add((QSBPatch)Activator.CreateInstance(type));
}
}
_patchList.AddRange(newPatches);
// could do lots of code to make sure all addon patches are done here,
2023-07-04 19:29:10 +00:00
// but the only patch type that will have been used by this point in the
2023-07-04 19:24:00 +00:00
// mod execution is OnModStart
DebugLog.DebugWrite($"Re-patching block OnModStart for addons", MessageType.Info);
var harmonyInstance = TypeToInstance[QSBPatchTypes.OnModStart];
foreach (var patch in newPatches)
{
if (patch.Type != QSBPatchTypes.OnModStart)
{
continue;
}
DebugLog.DebugWrite($" - Patching in {patch.GetType().Name}", MessageType.Info);
try
{
patch.DoPatches(harmonyInstance);
}
catch (Exception ex)
2022-12-14 11:47:01 +00:00
{
2023-07-04 19:24:00 +00:00
DebugLog.ToConsole($"Error while patching {patch.GetType().Name} :\r\n{ex}", MessageType.Error);
2022-12-14 11:47:01 +00:00
}
}
2023-07-04 19:24:00 +00:00
DebugLog.DebugWrite($"Registered {newPatches.Count()} addon patches.", MessageType.Success);
2022-12-14 11:47:01 +00:00
return;
}
2022-03-03 03:46:33 +00:00
foreach (var type in typeof(QSBPatch).GetDerivedTypes())
{
_patchList.Add((QSBPatch)Activator.CreateInstance(type));
}
foreach (QSBPatchTypes type in Enum.GetValues(typeof(QSBPatchTypes)))
2020-12-02 21:29:53 +00:00
{
TypeToInstance.Add(type, new Harmony(type.ToString()));
}
2020-11-03 21:11:10 +00:00
2022-12-14 11:47:01 +00:00
_inited = true;
2022-03-03 03:46:33 +00:00
DebugLog.DebugWrite("Patch Manager ready.", MessageType.Success);
}
2022-03-03 03:46:33 +00:00
public static void DoPatchType(QSBPatchTypes type)
{
if (_patchedTypes.Contains(type))
{
DebugLog.ToConsole($"Warning - Tried to patch type {type}, when it has already been patched!", MessageType.Warning);
return;
2020-12-02 21:29:53 +00:00
}
2020-11-03 21:11:10 +00:00
2022-03-03 03:46:33 +00:00
OnPatchType?.SafeInvoke(type);
2023-07-04 19:24:00 +00:00
DebugLog.DebugWrite($"Patch block {Enum.GetName(typeof(QSBPatchTypes), type)}", MessageType.Info);
2022-08-07 19:02:45 +00:00
foreach (var patch in _patchList.Where(x => x.Type == type && x.PatchVendor.HasFlag(QSBCore.GameVendor)))
2020-12-02 21:29:53 +00:00
{
2023-07-04 19:24:00 +00:00
DebugLog.DebugWrite($" - Patching in {patch.GetType().Name}", MessageType.Info);
2022-03-03 03:46:33 +00:00
try
{
2022-03-03 03:46:33 +00:00
patch.DoPatches(TypeToInstance[type]);
}
2022-03-03 03:46:33 +00:00
catch (Exception ex)
2020-12-02 21:29:53 +00:00
{
DebugLog.ToConsole($"Error while patching {patch.GetType().Name} :\r\n{ex}", MessageType.Error);
2020-12-02 21:29:53 +00:00
}
}
2022-03-03 03:46:33 +00:00
_patchedTypes.Add(type);
}
2022-03-03 03:46:33 +00:00
public static void DoUnpatchType(QSBPatchTypes type)
{
if (!_patchedTypes.Contains(type))
{
DebugLog.ToConsole($"Warning - Tried to unpatch type {type}, when it is either unpatched or was never patched.", MessageType.Warning);
return;
}
2022-03-03 03:46:33 +00:00
OnUnpatchType?.SafeInvoke(type);
//DebugLog.DebugWrite($"Unpatch block {Enum.GetName(typeof(QSBPatchTypes), type)}", MessageType.Info);
TypeToInstance[type].UnpatchSelf();
_patchedTypes.Remove(type);
2020-12-02 21:29:53 +00:00
}
}