You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

107 lines
3.2 KiB

#nullable enable
using IPA.Logging;
using System;
using System.IO;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;
namespace IPA.Loader.Features
{
internal class DefineFeature : Feature
{
public static bool NewFeature = true;
private class DataModel
{
[JsonPropertyName("type")]
[JsonRequired]
public string TypeName { get; init; } = "";
[JsonPropertyName("name")]
// TODO: Originally DisallowNull
public string? ActualName { get; init; }
public string Name => ActualName ?? TypeName;
}
private DataModel data = null!;
protected override bool Initialize(PluginMetadata meta, JsonObject featureData)
{
Logger.Features.Debug("Executing DefineFeature Init");
try
{
data = featureData.Deserialize<DataModel>() ?? throw new InvalidOperationException("Feature data is null");
}
catch (Exception e)
{
InvalidMessage = $"Invalid data: {e}";
return false;
}
InvalidMessage = $"Feature {data.Name} already exists";
return PreregisterFeature(meta, data.Name);
}
public override void BeforeInit(PluginMetadata meta)
{
Logger.Features.Debug("Executing DefineFeature AfterInit");
Type type;
try
{
type = meta.Assembly.GetType(data.TypeName);
}
catch (ArgumentException)
{
Logger.Features.Error($"Invalid type name {data.TypeName}");
return;
}
catch (Exception e) when (e is FileNotFoundException or FileLoadException or BadImageFormatException)
{
var filename = "";
switch (e)
{
case FileNotFoundException fn:
filename = fn.FileName;
break;
case FileLoadException fl:
filename = fl.FileName;
break;
case BadImageFormatException bi:
filename = bi.FileName;
break;
}
Logger.Features.Error($"Could not find {filename} while loading type");
return;
}
if (type == null)
{
Logger.Features.Error($"Invalid type name {data.TypeName}");
return;
}
try
{
if (RegisterFeature(meta, data.Name, type))
{
NewFeature = true;
return;
}
Logger.Features.Error($"Feature with name {data.Name} already exists");
return;
}
catch (ArgumentException)
{
Logger.Features.Error($"{type.FullName} not a subclass of {nameof(Feature)}");
return;
}
}
}
}