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;
|
|
}
|
|
}
|
|
}
|
|
}
|