|
|
@ -0,0 +1,102 @@ |
|
|
|
using System; |
|
|
|
using System.IO; |
|
|
|
using System.Reflection; |
|
|
|
|
|
|
|
namespace IPA.Loader.Features |
|
|
|
{ |
|
|
|
internal class InitInjectorFeature : Feature |
|
|
|
{ |
|
|
|
protected internal override bool StoreOnPlugin => false; |
|
|
|
|
|
|
|
public override bool Initialize(PluginLoader.PluginMetadata meta, string[] parameters) |
|
|
|
{ // parameters should be (assembly qualified lookup type, [fully qualified type]:[method name])
|
|
|
|
// method should be static
|
|
|
|
if (parameters.Length != 2) |
|
|
|
{ |
|
|
|
InvalidMessage = "Incorrect number of parameters"; |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
RequireLoaded(meta); |
|
|
|
|
|
|
|
var methodParts = parameters[1].Split(':'); |
|
|
|
|
|
|
|
var type = Type.GetType(parameters[0], false); |
|
|
|
if (type == null) |
|
|
|
{ |
|
|
|
InvalidMessage = $"Could not find type {parameters[0]}"; |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
Type getType; |
|
|
|
try |
|
|
|
{ |
|
|
|
getType = meta.Assembly.GetType(methodParts[0]); |
|
|
|
} |
|
|
|
catch (ArgumentException) |
|
|
|
{ |
|
|
|
InvalidMessage = $"Invalid type name {methodParts[0]}"; |
|
|
|
return false; |
|
|
|
} |
|
|
|
catch (Exception e) when (e is FileNotFoundException || e is FileLoadException || e is BadImageFormatException) |
|
|
|
{ |
|
|
|
string filename; |
|
|
|
|
|
|
|
switch (e) |
|
|
|
{ |
|
|
|
case FileNotFoundException fn: |
|
|
|
filename = fn.FileName; |
|
|
|
goto hasFilename; |
|
|
|
case FileLoadException fl: |
|
|
|
filename = fl.FileName; |
|
|
|
goto hasFilename; |
|
|
|
case BadImageFormatException bi: |
|
|
|
filename = bi.FileName; |
|
|
|
hasFilename: |
|
|
|
InvalidMessage = $"Could not find {filename} while loading type"; |
|
|
|
break; |
|
|
|
default: |
|
|
|
InvalidMessage = $"Error while loading type: {e}"; |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
MethodInfo method; |
|
|
|
try |
|
|
|
{ |
|
|
|
method = getType.GetMethod(methodParts[1], BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, |
|
|
|
null, new[] |
|
|
|
{ |
|
|
|
typeof(object), |
|
|
|
typeof(ParameterInfo), |
|
|
|
typeof(PluginLoader.PluginMetadata) |
|
|
|
}, new ParameterModifier[0]); |
|
|
|
} |
|
|
|
catch (Exception e) |
|
|
|
{ |
|
|
|
InvalidMessage = $"Error while loading type: {e}"; |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
if (method == null) |
|
|
|
{ |
|
|
|
InvalidMessage = $"Could not find method {methodParts[1]} in type {methodParts[0]}"; |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
try |
|
|
|
{ |
|
|
|
var del = (PluginInitInjector.InjectParameter)Delegate.CreateDelegate(typeof(PluginInitInjector.InjectParameter), null, method); |
|
|
|
PluginInitInjector.AddInjector(type, del); |
|
|
|
return true; |
|
|
|
} |
|
|
|
catch (Exception e) |
|
|
|
{ |
|
|
|
InvalidMessage = $"Error generated while creating delegate: {e}"; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |