-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathRitsuLibFramework.Diagnostics.cs
More file actions
135 lines (121 loc) · 4.8 KB
/
RitsuLibFramework.Diagnostics.cs
File metadata and controls
135 lines (121 loc) · 4.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
using System.Reflection;
using STS2RitsuLib.Patching.Core;
using STS2RitsuLib.Patching.Models;
namespace STS2RitsuLib
{
public static partial class RitsuLibFramework
{
internal static FrameworkRuntimeSnapshot CaptureRuntimeSnapshot()
{
lock (SyncRoot)
{
var patchers = Enum.GetValues<FrameworkPatcherArea>()
.Select(area =>
{
if (!FrameworkPatchersByArea.TryGetValue(area, out var patcher))
return new(area.ToString(), false, false, 0, 0, 0);
return new FrameworkPatcherSnapshot(
area.ToString(),
true,
patcher.IsApplied,
patcher.RegisteredPatchCount,
patcher.RegisteredDynamicPatchCount,
patcher.AppliedPatchCount);
})
.ToArray();
return new(
IsInitialized,
IsActive,
_profileServicesInitialized,
HasRegisteredModSettings,
_lifecycleObservers.Length,
RegisteredScriptAssemblies.Count,
patchers);
}
}
internal static FrameworkPatchBindingSnapshot[] CapturePatchBindingSnapshot()
{
lock (SyncRoot)
{
return Enum.GetValues<FrameworkPatcherArea>()
.SelectMany(area =>
{
if (!FrameworkPatchersByArea.TryGetValue(area, out var patcher))
return [];
return patcher.RegisteredPatches
.Select(patchInfo => CreatePatchBindingSnapshot(area, patcher, patchInfo))
.ToArray();
})
.ToArray();
}
}
private static FrameworkPatchBindingSnapshot CreatePatchBindingSnapshot(
FrameworkPatcherArea area,
ModPatcher patcher,
ModPatchInfo patchInfo)
{
var originalMethod = ResolveOriginalMethod(patchInfo);
var expectedPatchMethods = ResolvePatchMethods(patchInfo.PatchType);
return new(
area.ToString(),
patcher.PatcherId,
patchInfo.Id,
patchInfo.PatchType.FullName ?? patchInfo.PatchType.Name,
patchInfo.IsCritical,
originalMethod,
expectedPatchMethods);
}
private static MethodInfo? ResolveOriginalMethod(ModPatchInfo patchInfo)
{
if (patchInfo.ParameterTypes != null)
return patchInfo.TargetType.GetMethod(
patchInfo.MethodName,
BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic,
null,
patchInfo.ParameterTypes,
null);
return patchInfo.TargetType.GetMethod(
patchInfo.MethodName,
BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
}
private static MethodInfo[] ResolvePatchMethods(Type patchType)
{
return
[
.. ResolvePatchMethod(patchType, "Prefix"),
.. ResolvePatchMethod(patchType, "Postfix"),
.. ResolvePatchMethod(patchType, "Transpiler"),
.. ResolvePatchMethod(patchType, "Finalizer"),
];
}
private static IEnumerable<MethodInfo> ResolvePatchMethod(Type patchType, string methodName)
{
var method = patchType.GetMethod(methodName,
BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
return method == null ? [] : [method];
}
}
internal readonly record struct FrameworkRuntimeSnapshot(
bool IsInitialized,
bool IsActive,
bool ProfileServicesInitialized,
bool HasRegisteredModSettings,
int LifecycleObserverCount,
int RegisteredScriptAssemblyCount,
FrameworkPatcherSnapshot[] PatcherAreas);
internal readonly record struct FrameworkPatcherSnapshot(
string AreaName,
bool IsRegistered,
bool IsApplied,
int RegisteredPatchCount,
int RegisteredDynamicPatchCount,
int AppliedPatchCount);
internal readonly record struct FrameworkPatchBindingSnapshot(
string AreaName,
string PatcherId,
string PatchId,
string PatchTypeName,
bool IsCritical,
MethodInfo? OriginalMethod,
MethodInfo[] ExpectedPatchMethods);
}