actually now its usable

This commit is contained in:
zznty
2023-11-13 23:17:39 +07:00
parent aecc7ee66f
commit ce07a1e86a
41 changed files with 1401 additions and 138 deletions

View File

@@ -8,56 +8,39 @@
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
<EnableWindowsTargeting>true</EnableWindowsTargeting>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
</PropertyGroup>
<PropertyGroup>
<PluginBasePath>$(MSBuildThisFileDirectory)$(BaseIntermediateOutputPath)$(Configuration)\$(TargetFramework)\</PluginBasePath>
<PluginZipPath>$(PluginBasePath)plugin.zip</PluginZipPath>
<PluginZipHashPath>$(PluginBasePath)plugin.zip.sha256</PluginZipHashPath>
<PluginNamePath>$(PluginBasePath)name.txt</PluginNamePath>
<PluginManifestPath>$(PluginBasePath)manifest.xml</PluginManifestPath>
</PropertyGroup>
<ItemGroup>
<EmbeddedResource Include="$(PluginZipPath)" LogicalName="plugin.zip" />
<EmbeddedResource Include="$(PluginZipHashPath)" LogicalName="plugin.zip.sha256" />
<EmbeddedResource Include="$(PluginNamePath)" LogicalName="name.txt" />
<Content Include="$(PluginManifestPath)" Link="manifest.xml" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<DebugSymbols>false</DebugSymbols>
<DebugType>none</DebugType>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Krafs.Publicizer" Version="2.2.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="PolySharp" Version="1.13.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="torch.server.referenceassemblies" Version="1.3.1.260-master" PrivateAssets="all" IncludeAssets="compile" />
</ItemGroup>
<ItemGroup>
<Publicize Include="Torch:Torch.TorchBase.RegisterAuxAssembly" />
<Publicize Include="Torch:Torch.Managers.PluginManager._plugins" />
<Publicize Include="Torch:Torch.TorchPluginBase.Manifest" />
<Publicize Include="Torch:Torch.TorchPluginBase.StoragePath" />
</ItemGroup>
<ItemGroup>
<Content Include="manifest.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>Always</CopyToPublishDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\LuckPerms.Torch\LuckPerms.Torch.csproj" ReferenceOutputAssembly="false" Private="false" />
</ItemGroup>
<ItemGroup>
<Reference Include="System.IO.Compression" />
</ItemGroup>
<Target Name="BuildArchive" BeforeTargets="PreBuildEvent">
<PropertyGroup>
<PluginDir>..\LuckPerms.Torch\bin\$(Configuration)\$(TargetFramework)\win-x64\</PluginDir>
<PluginZipPath>$(BaseIntermediateOutputPath)$(Configuration)\$(TargetFramework)\plugin.zip</PluginZipPath>
</PropertyGroup>
<ZipDirectory DestinationFile="$(PluginZipPath)" SourceDirectory="$(PluginDir)" Overwrite="true" />
<ItemGroup>
<EmbeddedResource Include="$(PluginZipPath)" LogicalName="plugin.zip" />
</ItemGroup>
</Target>
</Project>

View File

@@ -6,67 +6,105 @@ using Torch;
using Torch.API;
using Torch.API.Managers;
using Torch.API.Plugins;
using Torch.Collections;
using Torch.Managers;
using Torch.Utils;
namespace LuckPerms.Loader;
public class Plugin : TorchPluginBase
{
private static readonly ITorchPlugin MainPluginInstance;
private static readonly ILogger Log = LogManager.GetLogger("LuckPerms.Loader");
private static readonly ILogger Log = LogManager.GetLogger("Loader");
static Plugin()
{
string assemblyName;
using (var infoStream = typeof(Plugin).Assembly.GetManifestResourceStream("name.txt")!)
using (var infoStreamReader = new StreamReader(infoStream))
assemblyName = infoStreamReader.ReadLine()!.Trim();
#pragma warning disable CS0618 // Type or member is obsolete
var torch = (ITorchServer)TorchBase.Instance;
#pragma warning restore CS0618 // Type or member is obsolete
var dir = new DirectoryInfo(Path.Combine(torch.InstancePath, "cache", "luckperms.loader"));
var dir = new DirectoryInfo(Path.Combine(torch.InstancePath, "cache", assemblyName));
void ExtractCache()
{
using var currentHashStream = typeof(Plugin).Assembly.GetManifestResourceStream("plugin.zip.sha256")!;
var currentHash = currentHashStream.ReadToEnd();
var hashPath = Path.Combine(dir.FullName, "plugin.zip.sha256");
if (dir.Exists)
{
if (File.Exists(hashPath))
{
Log.Info("Checking cache");
if (dir.Exists)
dir.Delete(true);
var hash = File.ReadAllBytes(hashPath);
if (hash.SequenceEqual(currentHash)) return;
}
dir.Delete(true);
}
Log.Info($"Extracting cache to {dir}");
using (var pluginStream = typeof(Plugin).Assembly.GetManifestResourceStream("plugin.zip")!)
using (var archive = new ZipArchive(pluginStream, ZipArchiveMode.Read))
Log.Info($"Extracting cache to {dir}");
using var pluginStream = typeof(Plugin).Assembly.GetManifestResourceStream("plugin.zip")!;
using var archive = new ZipArchive(pluginStream, ZipArchiveMode.Read);
archive.ExtractToDirectory(dir.FullName);
File.WriteAllBytes(hashPath, currentHash);
}
Log.Info("Injecting LuckPerms");
ExtractCache();
Log.Info($"Injecting {assemblyName}");
AppDomain.CurrentDomain.AssemblyResolve += (_, args) =>
{
var fileName = args.Name[..args.Name.IndexOf(',')];
if (AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(b =>
b.GetName().Name?.Equals(fileName, StringComparison.OrdinalIgnoreCase) is true) is { } assembly)
return assembly;
var path = Path.Combine(dir.FullName, fileName + ".dll");
return File.Exists(path) ? Assembly.LoadFile(path) : null;
};
var mainAssembly = Assembly.LoadFile(Path.Combine(dir.FullName, "LuckPerms.Torch.dll"));
var mainAssembly = Assembly.LoadFile(Path.Combine(dir.FullName, $"{assemblyName}.dll"));
var pluginType = mainAssembly.GetType("LuckPerms.Torch.Plugin", true)!;
var pluginType = mainAssembly.GetType($"{assemblyName}.Plugin", true)!;
// a hacky way to configure JVM
// a hacky way to configure the plugin
RuntimeHelpers.RunClassConstructor(pluginType.TypeHandle);
TorchBase.RegisterAuxAssembly(mainAssembly);
typeof(TorchBase).GetMethod("RegisterAuxAssembly", BindingFlags.NonPublic | BindingFlags.Static)!.Invoke(null, new object[] { mainAssembly });
MainPluginInstance = (ITorchPlugin)Activator.CreateInstance(pluginType)!;
if (MainPluginInstance is not TorchPluginBase pluginBase) return;
pluginBase.Manifest = PluginManifest.Load(Path.Combine(dir.FullName, "manifest.xml"));
pluginBase.StoragePath = torch.InstancePath;
}
public override void Init(ITorchBase torch)
{
if (MainPluginInstance is TorchPluginBase pluginBase)
{
typeof(TorchPluginBase).GetProperty(nameof(Manifest))!.SetValue(pluginBase, Manifest);
typeof(TorchPluginBase).GetProperty(nameof(StoragePath))!.SetValue(pluginBase, StoragePath);
}
var pluginManager = torch.Managers.GetManager<PluginManager>();
var plugins =
(MtObservableSortedDictionary<Guid, ITorchPlugin>)typeof(PluginManager).GetField("_plugins",
BindingFlags.NonPublic | BindingFlags.Instance)!.GetValue(pluginManager);
plugins.Remove(Manifest.Guid);
plugins.Add(Manifest.Guid, MainPluginInstance);
pluginManager._plugins.Remove(Manifest.Guid);
pluginManager._plugins.Add(Manifest.Guid, MainPluginInstance);
MainPluginInstance.Init(torch);
Log.Info("Injected successfully");
}
}

View File

@@ -1,6 +0,0 @@
<?xml version="1.0"?>
<PluginManifest xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Name>LuckPerms.Loader</Name>
<Guid>7E4B3CC8-64FA-416E-8910-AACDF2DA5E2C</Guid>
<Version>v5.4.106.3</Version>
</PluginManifest>

View File

@@ -2,12 +2,6 @@
"version": 1,
"dependencies": {
".NETFramework,Version=v4.8": {
"Krafs.Publicizer": {
"type": "Direct",
"requested": "[2.2.1, )",
"resolved": "2.2.1",
"contentHash": "QGI4nMGQbKsuFUUboixVHu4mv3lHB5RejIa7toIlzTmwLkuCYYEpUBJjmy3OpXYyj5dVSZAXVbr4oeMSloE67Q=="
},
"Microsoft.NETFramework.ReferenceAssemblies": {
"type": "Direct",
"requested": "[1.0.3, )",
@@ -62,6 +56,7 @@
"protobuf-net": "1.0.0"
}
}
}
},
".NETFramework,Version=v4.8/win-x64": {}
}
}