Skip to content

Commit

Permalink
Fix not patching plugin loading
Browse files Browse the repository at this point in the history
	Corrected to run right before Load is called
	Now patches HacknetChainloader with ILManipulator instead
Actually compile the Pathfinder.Meta.Load namespace
Made EventAttribute able to function on Types as well
	If an EventAttribute is on a type, checks type for any applicable event methods
	Valid methods are static void methods whose only parameter is of type PathfinderEvent
	Can ignore specific events for a auto-register with IgnoreEventAttribute
Renamed Meta.Load.ComputerExecutor to ComputerExecutorAttribute
  • Loading branch information
Spartan322 committed Nov 5, 2021
1 parent d35e48f commit 3cf0f1c
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 11 deletions.
18 changes: 14 additions & 4 deletions PathfinderAPI/Meta/Load/AttributeManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,27 @@
using System.Reflection;
using BepInEx.Hacknet;
using HarmonyLib;
using Mono.Cecil.Cil;
using MonoMod.Cil;

namespace Pathfinder.Meta.Load
{
[HarmonyPatch]
internal static class AttributeManager
{
[HarmonyPrefix]
[HarmonyPatch(typeof(HacknetPlugin), nameof(HacknetPlugin.Load))]
private static void OnPluginLoad(ref HacknetPlugin __instance)
[HarmonyILManipulator]
[HarmonyPatch(typeof(HacknetChainloader), nameof(HacknetChainloader.LoadPlugin))]
private static void OnPluginLoadIL(ILContext il)
{
ReadAttributesFor(__instance);
var c = new ILCursor(il);

c.GotoNext(
x => x.MatchLdloc(1),
x => x.MatchCallvirt(AccessTools.Method(typeof(HacknetPlugin), nameof(HacknetPlugin.Load)))
);

c.Emit(OpCodes.Ldloc, 1);
c.Emit(OpCodes.Call, AccessTools.Method(typeof(AttributeManager), nameof(ReadAttributesFor)));
}

public static void ReadAttributesFor(HacknetPlugin plugin)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Reflection;
using BepInEx.Hacknet;
using Pathfinder.Replacements;
Expand All @@ -7,12 +7,12 @@
namespace Pathfinder.Meta.Load
{
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
public class ComputerExecutor : BaseAttribute
public class ComputerExecutorAttribute : BaseAttribute
{
public string Element { get; }
public ParseOption ParseOptions { get; set; }

public ComputerExecutor(string element, ParseOption parseOptions = ParseOption.None)
public ComputerExecutorAttribute(string element, ParseOption parseOptions = ParseOption.None)
{
Element = element;
ParseOptions = parseOptions;
Expand Down
32 changes: 28 additions & 4 deletions PathfinderAPI/Meta/Load/EventAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

namespace Pathfinder.Meta.Load
{
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = true)]
public class EventAttribute : BaseAttribute
{
private EventHandlerOptions eventHandlerOptions;
Expand Down Expand Up @@ -44,11 +44,35 @@ public EventAttribute(bool continueOnCancel = false, bool continueOnThrow = fals
};
}

private void CallOn(HacknetPlugin plugin, MethodInfo info)
{
var eventType = info.GetParameters().FirstOrDefault()?.ParameterType;
EventManager.AddHandler(eventType, info);
}

private void CallOn(HacknetPlugin plugin, Type type)
{
foreach(var method in type.GetMethods(
BindingFlags.Public
| BindingFlags.NonPublic
| BindingFlags.Static
))
{
if(method.GetCustomAttribute<IgnoreEventAttribute>() != null)
continue;
var parameter = method.GetParameters().FirstOrDefault();
if(method.ReturnType == typeof(void)
&& (parameter?.ParameterType?.IsSubclassOf(typeof(PathfinderEvent)) ?? false))
CallOn(plugin, method);
}
}

protected internal override void CallOn(HacknetPlugin plugin, MemberInfo targettedInfo)
{
var methodInfo = (MethodInfo)targettedInfo;
var eventType = methodInfo.GetParameters().FirstOrDefault()?.ParameterType;
EventManager.AddHandler(eventType, methodInfo);
if(targettedInfo is MethodInfo method)
CallOn(plugin, method);
else
CallOn(plugin, (Type) targettedInfo);
}
}
}
8 changes: 8 additions & 0 deletions PathfinderAPI/Meta/Load/IgnoreEventAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using System;
namespace Pathfinder.Meta.Load
{
[AttributeUsage(AttributeTargets.Method)]
public class IgnoreEventAttribute : System.Attribute
{
}
}
20 changes: 20 additions & 0 deletions PathfinderAPI/PathfinderAPI.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,26 @@
<Compile Include="Executable\ExecutableManager.cs" />
<Compile Include="GUI\ArbitraryCodeWarning.cs" />
<Compile Include="GUI\PFButton.cs" />
<Compile Include="Meta\Load\ActionAttribute.cs" />
<Compile Include="Meta\Load\AdministratorAttribute.cs" />
<Compile Include="Meta\Load\AttributeManager.cs" />
<Compile Include="Meta\Load\BaseAttribute.cs" />
<Compile Include="Meta\Load\CommandAttribute.cs" />
<Compile Include="Meta\Load\ComputerExecutorAttribute.cs" />
<Compile Include="Meta\Load\ConditionAttribute.cs" />
<Compile Include="Meta\Load\DaemonAttribute.cs" />
<Compile Include="Meta\Load\EventAttribute.cs" />
<Compile Include="Meta\Load\ExecutableAttribute.cs" />
<Compile Include="Meta\Load\ExtensionInfoAttribute.cs" />
<Compile Include="Meta\Load\GoalAttribute.cs" />
<Compile Include="Meta\Load\HacknetPluginExtensions.cs" />
<Compile Include="Meta\Load\IgnoreEventAttribute.cs" />
<Compile Include="Meta\Load\IgnorePluginAttribute.cs" />
<Compile Include="Meta\Load\MissionExecutorAttribute.cs" />
<Compile Include="Meta\Load\OptionAttribute.cs" />
<Compile Include="Meta\Load\OptionsTabAttribute.cs" />
<Compile Include="Meta\Load\PortAttribute.cs" />
<Compile Include="Meta\Load\SaveExecutorAttribute.cs" />
<Compile Include="Logger.cs" />
<Compile Include="MiscPatches.cs" />
<Compile Include="Mission\GoalManager.cs" />
Expand Down

0 comments on commit 3cf0f1c

Please # to comment.