mirror of
https://github.com/ow-mods/owml.git
synced 2025-12-11 20:15:48 +01:00
commit
1f5b4bdbc5
13
src/OWML.Common/Enums/PatchType.cs
Normal file
13
src/OWML.Common/Enums/PatchType.cs
Normal file
@ -0,0 +1,13 @@
|
||||
namespace OWML.Common
|
||||
{
|
||||
public enum PatchType
|
||||
{
|
||||
All = 0,
|
||||
|
||||
Prefix = 1,
|
||||
|
||||
Postfix = 2,
|
||||
|
||||
Transpiler = 3
|
||||
}
|
||||
}
|
||||
@ -6,15 +6,21 @@ namespace OWML.Common
|
||||
public interface IHarmonyHelper
|
||||
{
|
||||
void AddPrefix<T>(string methodName, Type patchType, string patchMethodName);
|
||||
|
||||
void AddPrefix(MethodBase methodInfo, Type patchType, string patchMethodName);
|
||||
|
||||
void AddPostfix<T>(string methodName, Type patchType, string patchMethodName);
|
||||
|
||||
void AddPostfix(MethodBase methodInfo, Type patchType, string patchMethodName);
|
||||
|
||||
void EmptyMethod<T>(string methodName);
|
||||
|
||||
void EmptyMethod(MethodBase methodInfo);
|
||||
|
||||
void Transpile<T>(string methodName, Type patchType, string patchMethodName);
|
||||
|
||||
void Transpile(MethodBase methodInfo, Type patchType, string patchMethodName);
|
||||
|
||||
void Unpatch<T>(string methodName, PatchType patchType = PatchType.All);
|
||||
}
|
||||
}
|
||||
|
||||
3
src/OWML.Common/OWML.Common.csproj.DotSettings
Normal file
3
src/OWML.Common/OWML.Common.csproj.DotSettings
Normal file
@ -0,0 +1,3 @@
|
||||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=enums/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=interfaces/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
|
||||
@ -2,7 +2,7 @@
|
||||
"author": "Alek",
|
||||
"name": "OWML",
|
||||
"uniqueName": "Alek.OWML",
|
||||
"version": "1.1.4",
|
||||
"version": "1.1.5",
|
||||
"description": "The mod loader and mod framework for Outer Wilds",
|
||||
"minGameVersion": "1.0.7.0",
|
||||
"maxGameVersion": "1.0.7.481"
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Harmony;
|
||||
using OWML.Common;
|
||||
@ -17,7 +19,7 @@ namespace OWML.ModHelper.Events
|
||||
_console = console;
|
||||
_manifest = manifest;
|
||||
_owmlConfig = owmlConfig;
|
||||
|
||||
|
||||
_harmony = CreateInstance();
|
||||
}
|
||||
|
||||
@ -43,30 +45,8 @@ namespace OWML.ModHelper.Events
|
||||
return harmony;
|
||||
}
|
||||
|
||||
private MethodInfo GetMethod<T>(string methodName)
|
||||
{
|
||||
var targetType = typeof(T);
|
||||
MethodInfo result = null;
|
||||
try
|
||||
{
|
||||
_console.WriteLine($"Getting method {methodName} of {targetType.Name}", MessageType.Debug);
|
||||
result = Utils.TypeExtensions.GetAnyMethod(targetType, methodName);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_console.WriteLine($"Exception while getting method {methodName} of {targetType.Name}: {ex}", MessageType.Error);
|
||||
}
|
||||
if (result == null)
|
||||
{
|
||||
_console.WriteLine($"Error - Original method {methodName} of class {targetType} not found.", MessageType.Error);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void AddPrefix<T>(string methodName, Type patchType, string patchMethodName)
|
||||
{
|
||||
public void AddPrefix<T>(string methodName, Type patchType, string patchMethodName) =>
|
||||
AddPrefix(GetMethod<T>(methodName), patchType, patchMethodName);
|
||||
}
|
||||
|
||||
public void AddPrefix(MethodBase original, Type patchType, string patchMethodName)
|
||||
{
|
||||
@ -79,7 +59,7 @@ namespace OWML.ModHelper.Events
|
||||
Patch(original, prefix, null, null);
|
||||
}
|
||||
|
||||
public void AddPostfix<T>(string methodName, Type patchType, string patchMethodName) =>
|
||||
public void AddPostfix<T>(string methodName, Type patchType, string patchMethodName) =>
|
||||
AddPostfix(GetMethod<T>(methodName), patchType, patchMethodName);
|
||||
|
||||
public void AddPostfix(MethodBase original, Type patchType, string patchMethodName)
|
||||
@ -93,13 +73,13 @@ namespace OWML.ModHelper.Events
|
||||
Patch(original, null, postfix, null);
|
||||
}
|
||||
|
||||
public void EmptyMethod<T>(string methodName) =>
|
||||
public void EmptyMethod<T>(string methodName) =>
|
||||
EmptyMethod(GetMethod<T>(methodName));
|
||||
|
||||
public void EmptyMethod(MethodBase methodInfo) =>
|
||||
public void EmptyMethod(MethodBase methodInfo) =>
|
||||
Transpile(methodInfo, typeof(Patches), nameof(Patches.EmptyMethod));
|
||||
|
||||
public void Transpile<T>(string methodName, Type patchType, string patchMethodName) =>
|
||||
public void Transpile<T>(string methodName, Type patchType, string patchMethodName) =>
|
||||
Transpile(GetMethod<T>(methodName), patchType, patchMethodName);
|
||||
|
||||
public void Transpile(MethodBase original, Type patchType, string patchMethodName)
|
||||
@ -113,6 +93,38 @@ namespace OWML.ModHelper.Events
|
||||
Patch(original, null, null, patchMethod);
|
||||
}
|
||||
|
||||
public void Unpatch<T>(string methodName, PatchType patchType = PatchType.All)
|
||||
{
|
||||
_console.WriteLine($"Unpatching {typeof(T).Name}.{methodName}", MessageType.Debug);
|
||||
|
||||
var sharedState = Utils.TypeExtensions.Invoke<Dictionary<MethodBase, byte[]>>(typeof(HarmonySharedState), "GetState");
|
||||
var method = sharedState.Keys.First(m => m.DeclaringType == typeof(T) && m.Name == methodName);
|
||||
var patchInfo = PatchInfoSerialization.Deserialize(sharedState.GetValueSafe(method));
|
||||
|
||||
switch (patchType)
|
||||
{
|
||||
case PatchType.Prefix:
|
||||
patchInfo.RemovePrefix(_manifest.UniqueName);
|
||||
break;
|
||||
case PatchType.Postfix:
|
||||
patchInfo.RemovePostfix(_manifest.UniqueName);
|
||||
break;
|
||||
case PatchType.Transpiler:
|
||||
patchInfo.RemoveTranspiler(_manifest.UniqueName);
|
||||
break;
|
||||
case PatchType.All:
|
||||
patchInfo.RemovePostfix(_manifest.UniqueName);
|
||||
patchInfo.RemovePrefix(_manifest.UniqueName);
|
||||
patchInfo.RemoveTranspiler(_manifest.UniqueName);
|
||||
break;
|
||||
}
|
||||
|
||||
PatchFunctions.UpdateWrapper(method, patchInfo, _manifest.UniqueName);
|
||||
sharedState[method] = patchInfo.Serialize();
|
||||
|
||||
_console.WriteLine($"Unpatched {typeof(T).Name}.{methodName}!", MessageType.Debug);
|
||||
}
|
||||
|
||||
private void Patch(MethodBase original, MethodInfo prefix, MethodInfo postfix, MethodInfo transpiler)
|
||||
{
|
||||
if (original == null)
|
||||
@ -134,5 +146,25 @@ namespace OWML.ModHelper.Events
|
||||
_console.WriteLine($"Exception while patching {fullName}: {ex}", MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private MethodInfo GetMethod<T>(string methodName)
|
||||
{
|
||||
var fullName = $"{typeof(T).Name}.{methodName}";
|
||||
try
|
||||
{
|
||||
_console.WriteLine($"Getting method {fullName}", MessageType.Debug);
|
||||
var result = Utils.TypeExtensions.GetAnyMethod(typeof(T), methodName);
|
||||
if (result == null)
|
||||
{
|
||||
_console.WriteLine($"Error - method {fullName} not found.", MessageType.Error);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_console.WriteLine($"Exception while getting method {fullName}: {ex}", MessageType.Error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -44,5 +44,8 @@ namespace OWML.Utils
|
||||
|
||||
public static T Invoke<T>(this object obj, string name, params object[] parameters) =>
|
||||
(T)obj.GetType().GetAnyMethod(name)?.Invoke(obj, parameters);
|
||||
|
||||
public static T Invoke<T>(this Type type, string name, params object[] parameters) =>
|
||||
(T)type.GetAnyMethod(name).Invoke(null, parameters);
|
||||
}
|
||||
}
|
||||
@ -58,6 +58,13 @@ namespace OWML.EnableDebugMode
|
||||
CycleGUIMode();
|
||||
}
|
||||
|
||||
HandleWarping();
|
||||
|
||||
TestUnpatching();
|
||||
}
|
||||
|
||||
private void HandleWarping()
|
||||
{
|
||||
if (ModHelper.Input.IsNewlyPressed(_inputs["Warp to Interloper"]))
|
||||
{
|
||||
WarpTo(SpawnLocation.Comet);
|
||||
@ -112,5 +119,20 @@ namespace OWML.EnableDebugMode
|
||||
ModHelper.Console.WriteLine($"Warping to {location}!");
|
||||
_playerSpawner.DebugWarp(_playerSpawner.GetSpawnPoint(location));
|
||||
}
|
||||
|
||||
private void TestUnpatching()
|
||||
{
|
||||
if (Input.GetKeyDown(KeyCode.F7))
|
||||
{
|
||||
ModHelper.Console.WriteLine("Removing Jump");
|
||||
ModHelper.HarmonyHelper.EmptyMethod<PlayerCharacterController>("ApplyJump");
|
||||
}
|
||||
|
||||
if (Input.GetKeyDown(KeyCode.F8))
|
||||
{
|
||||
ModHelper.Console.WriteLine("Restoring Jump");
|
||||
ModHelper.HarmonyHelper.Unpatch<PlayerCharacterController>("ApplyJump");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user