Initial commit of MosswartMassacreNG
This commit is contained in:
commit
d4edb67594
13 changed files with 847 additions and 0 deletions
224
MosswartMassacreNG.Loader/LoaderCore.cs
Normal file
224
MosswartMassacreNG.Loader/LoaderCore.cs
Normal file
|
|
@ -0,0 +1,224 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using Decal.Adapter;
|
||||
using Microsoft.Win32;
|
||||
|
||||
namespace MosswartMassacreNG
|
||||
{
|
||||
[FriendlyName("MosswartMassacreNG.Loader")]
|
||||
public class LoaderCore : FilterBase
|
||||
{
|
||||
private Assembly pluginAssembly;
|
||||
private Type pluginType;
|
||||
private object pluginInstance;
|
||||
private FileSystemWatcher pluginWatcher;
|
||||
private bool isSubscribedToRenderFrame = false;
|
||||
private bool needsReload;
|
||||
private int oldCurrentUserValue = -1;
|
||||
|
||||
public static string PluginAssemblyNamespace => typeof(LoaderCore).Namespace.Replace(".Loader", "");
|
||||
public static string PluginAssemblyName => $"{PluginAssemblyNamespace}.dll";
|
||||
public static string PluginAssemblyGuid => "4b1f02bb-9b95-46f0-ad5b-223fea7392fb";
|
||||
|
||||
public static bool IsPluginLoaded { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Assembly directory (contains both loader and plugin dlls)
|
||||
/// </summary>
|
||||
public static string AssemblyDirectory => System.IO.Path.GetDirectoryName(Assembly.GetAssembly(typeof(LoaderCore)).Location);
|
||||
|
||||
public DateTime LastDllChange { get; private set; }
|
||||
|
||||
#region Event Handlers
|
||||
protected override void Startup()
|
||||
{
|
||||
try
|
||||
{
|
||||
Core.PluginInitComplete += Core_PluginInitComplete;
|
||||
Core.PluginTermComplete += Core_PluginTermComplete;
|
||||
Core.FilterInitComplete += Core_FilterInitComplete;
|
||||
|
||||
// watch the AssemblyDirectory for any .dll file changes
|
||||
pluginWatcher = new FileSystemWatcher();
|
||||
pluginWatcher.Path = AssemblyDirectory;
|
||||
pluginWatcher.NotifyFilter = NotifyFilters.LastWrite;
|
||||
pluginWatcher.Filter = "*.dll";
|
||||
pluginWatcher.Changed += PluginWatcher_Changed;
|
||||
pluginWatcher.EnableRaisingEvents = true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void Core_FilterInitComplete(object sender, EventArgs e)
|
||||
{
|
||||
Core.EchoFilter.ClientDispatch += EchoFilter_ClientDispatch;
|
||||
}
|
||||
|
||||
private void EchoFilter_ClientDispatch(object sender, NetworkMessageEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Login_SendEnterWorldRequest
|
||||
if (e.Message.Type == 0xF7C8)
|
||||
{
|
||||
//EnsurePluginIsDisabledInRegistry();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void Core_PluginInitComplete(object sender, EventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
LoadPluginAssembly();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void Core_PluginTermComplete(object sender, EventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
UnloadPluginAssembly();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log(ex);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Shutdown()
|
||||
{
|
||||
try
|
||||
{
|
||||
Core.PluginInitComplete -= Core_PluginInitComplete;
|
||||
Core.PluginTermComplete -= Core_PluginTermComplete;
|
||||
Core.FilterInitComplete -= Core_FilterInitComplete;
|
||||
UnloadPluginAssembly();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void Core_RenderFrame(object sender, EventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (IsPluginLoaded && needsReload && DateTime.UtcNow - LastDllChange > TimeSpan.FromSeconds(1))
|
||||
{
|
||||
needsReload = false;
|
||||
Core.RenderFrame -= Core_RenderFrame;
|
||||
isSubscribedToRenderFrame = false;
|
||||
LoadPluginAssembly();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void PluginWatcher_Changed(object sender, FileSystemEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
LastDllChange = DateTime.UtcNow;
|
||||
needsReload = true;
|
||||
|
||||
if (!isSubscribedToRenderFrame)
|
||||
{
|
||||
isSubscribedToRenderFrame = true;
|
||||
Core.RenderFrame += Core_RenderFrame;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log(ex);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Plugin Loading/Unloading
|
||||
internal void LoadPluginAssembly()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (IsPluginLoaded)
|
||||
{
|
||||
UnloadPluginAssembly();
|
||||
try
|
||||
{
|
||||
CoreManager.Current.Actions.AddChatText($"Reloading {PluginAssemblyName}", 1);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
pluginAssembly = Assembly.Load(File.ReadAllBytes(System.IO.Path.Combine(AssemblyDirectory, PluginAssemblyName)));
|
||||
pluginType = pluginAssembly.GetType($"{PluginAssemblyNamespace}.PluginCore");
|
||||
pluginInstance = Activator.CreateInstance(pluginType);
|
||||
|
||||
var assemblyDirAttr = pluginType.GetProperty("AssemblyDirectory", BindingFlags.Public | BindingFlags.Static);
|
||||
assemblyDirAttr?.SetValue(null, AssemblyDirectory);
|
||||
|
||||
var startupMethod = pluginType.GetMethod("Startup", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
startupMethod.Invoke(pluginInstance, new object[] { });
|
||||
|
||||
IsPluginLoaded = true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void UnloadPluginAssembly()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (pluginInstance != null && pluginType != null)
|
||||
{
|
||||
MethodInfo shutdownMethod = pluginType.GetMethod("Shutdown", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
shutdownMethod.Invoke(pluginInstance, null);
|
||||
pluginInstance = null;
|
||||
pluginType = null;
|
||||
pluginAssembly = null;
|
||||
}
|
||||
IsPluginLoaded = false;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log(ex);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
private void Log(Exception ex)
|
||||
{
|
||||
Log(ex.ToString());
|
||||
}
|
||||
|
||||
private void Log(string message)
|
||||
{
|
||||
File.AppendAllText(System.IO.Path.Combine(AssemblyDirectory, "log.txt"), $"{message}\n");
|
||||
try
|
||||
{
|
||||
CoreManager.Current.Actions.AddChatText(message, 1);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
}
|
||||
32
MosswartMassacreNG.Loader/MosswartMassacreNG.Loader.csproj
Normal file
32
MosswartMassacreNG.Loader/MosswartMassacreNG.Loader.csproj
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net48</TargetFramework>
|
||||
<OutputType>Library</OutputType>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<OutputPath>..\bin\</OutputPath>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<LangVersion>10</LangVersion>
|
||||
<GenerateAssemblyInfo>True</GenerateAssemblyInfo>
|
||||
<RootNamespace>MosswartMassacreNG</RootNamespace>
|
||||
<AssemblyName>MosswartMassacreNG.Loader</AssemblyName>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<None Include="LoaderCore.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Decal.Adapter">
|
||||
<HintPath>.\..\deps\Decal.Adapter.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="Decal.Interop.Core, Version=2.9.8.2, Culture=neutral, PublicKeyToken=481f17d392f1fb65, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<EmbedInteropTypes>True</EmbedInteropTypes>
|
||||
<HintPath>.\..\deps\Decal.Interop.Core.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
|
||||
<PackageReference Include="System.Data.DataSetExtensions" Version="4.5.0" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
Loading…
Add table
Add a link
Reference in a new issue