79 lines
2.8 KiB
C#

using AnotherReplayReader.PluginSystem;
using AnotherReplayReader.Utils;
using Microsoft.Win32;
using System;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Security.Cryptography;
using System.Text.Json;
using System.Threading.Tasks;
namespace AnotherReplayReader
{
internal static class Plugin
{
public static Task<bool> LoadPlayerIdentityPlugin(PlayerIdentity playerIdentity)
{
return Task.Run(async () =>
{
var name = $"{nameof(AnotherReplayReader)}.{nameof(PlayerIdentity)}";
var fileName = Path.Combine(App.LibsFolder, $"{name}.dll");
if (File.Exists(fileName))
{
var assembly = await Load(fileName);
var pluginType = assembly.GetType($"{name}.Plugin", true);
var plugin = (IPlugin)Activator.CreateInstance(pluginType);
Auth.LoadPlugin(plugin);
playerIdentity.LoadPlugin(plugin);
return true;
}
return false;
});
}
public static async Task<Assembly> Load(string path)
{
using var file = File.OpenRead(path);
using var metaFile = File.OpenRead($"{path}.meta");
var metaTask = JsonSerializer.DeserializeAsync<VerifierPayload>(metaFile, Network.CommonJsonOptions);
using var memory = new MemoryStream();
await file.CopyToAsync(memory);
var array = memory.ToArray();
using var sha256 = SHA256.Create();
var hash = sha256.ComputeHash(array);
var meta = await metaTask ?? throw new InvalidDataException("Failed to load meta file");
if (!Enumerable.SequenceEqual(hash, meta.ByteData.Value))
{
throw new InvalidDataException($"Hash does not match, might be corrupt {Convert.ToBase64String(hash)} vs {meta.Data}");
}
if (!Verifier.Verify(meta))
{
throw new InvalidDataException("Invalid metadata, might be corrupt");
}
return Assembly.Load(array);
}
public static void Sign()
{
var openFileDialog = new OpenFileDialog
{
Filter = "dll (*.dll)|*.dll|所有文件 (*.*)|*.*",
InitialDirectory = AppContext.BaseDirectory,
};
var result = openFileDialog.ShowDialog();
if (result is true)
{
using var file = openFileDialog.OpenFile();
using var memory = new MemoryStream();
file.CopyTo(memory);
using var sha256 = SHA256.Create();
var hash = sha256.ComputeHash(memory.ToArray());
Verifier.Sign(hash);
}
}
}
}