This commit is contained in:
CortexCore
2025-01-12 11:13:19 +08:00
parent 01e7e4e35e
commit 01b3d1be43
26 changed files with 387 additions and 336 deletions

View File

@@ -130,10 +130,6 @@ namespace BITKit.Mod
{
public static async UniTask<ModPackage[]> SearchPackages()
{
//Todo
IUXWaiting waiting = null;
var handle = waiting?.Get();
handle?.SetMessage("正在搜索Mod包");
var list=new List<ModPackage>();
var path = Path.Combine(Environment.CurrentDirectory, "Mods");
@@ -149,7 +145,6 @@ namespace BITKit.Mod
list.Add(package);
}
waiting?.Release(handle);
return list.ToArray();
}
public static async UniTask Reload()
@@ -184,16 +179,7 @@ namespace BITKit.Mod
public static IMod[] Mods { get; private set; }=Array.Empty<IMod>();
public static bool IsLocked
{
get => _IsLocked;
set
{
if (_IsLocked == value) return;
_IsLocked = value;
OnLocked?.Invoke(value);
}
}
public static readonly ValidHandle IsBusy = new();
public static event Action<ModPackage> OnPackageLoad;
public static event Action<ModPackage> OnPackageLoaded;
@@ -207,179 +193,72 @@ namespace BITKit.Mod
public static event Action OnReload;
public static event Action OnReloaded;
public static event Action<bool> OnLocked;
public static event Func<IMod,UniTask> OnModLoadAsync;
public static event Func<IMod,UniTask> OnModUnloadAsync;
private static CancellationTokenSource _CancellationTokenSource;
private static readonly ConcurrentQueue<IMod> _RegisterQueue=new();
private static readonly ConcurrentQueue<IMod> _UnRegisterQueue = new();
private static readonly List<IMod> _CacheMods = new();
private static readonly ConcurrentDictionary<string,IMod> _InstalledMods=new();
private static Thread _Thread;
private static bool _IsRunning;
private static bool _IsLocked;
public static void Initialize()
public static async UniTask Initialize()
{
BIT4Log.Log<ModService>("Mod服务已启动");
_IsRunning = true;
_CancellationTokenSource = new CancellationTokenSource();
_Thread = new Thread(InternalInitialize);
_Thread.Start();
return;
async void InternalInitialize()
try
{
try
{
try
var modPath = Path.Combine(Environment.CurrentDirectory, "Mods\\");
PathHelper.EnsureDirectoryCreated(modPath);
var directoryInfo = new DirectoryInfo(modPath);
foreach (var fileInfo in directoryInfo.GetFiles())
{
var modPath = Path.Combine(Environment.CurrentDirectory, "Mods\\");
PathHelper.EnsureDirectoryCreated(modPath);
var directoryInfo = new DirectoryInfo(modPath);
foreach (var fileInfo in directoryInfo.GetFiles())
switch (fileInfo.Extension)
{
switch (fileInfo.Extension)
case ".dll":
{
case ".dll":
{
var assembly = Assembly.LoadFile(fileInfo.FullName);
await Load(assembly);
continue;
}
var assembly = Assembly.LoadFile(fileInfo.FullName);
await Load(assembly);
continue;
}
#if UNITY_5_3_OR_NEWER
case ".cs":
{
var code = await File.ReadAllTextAsync(fileInfo.FullName);
var assembly = BITSharp.Compile(code);
await Load(assembly, fileInfo.DirectoryName);
continue;
}
#endif
}
}
}
catch (Exception e)
{
BIT4Log.Warning<ModService>("自动加载Mod失败");
BIT4Log.LogException(e);
}
while (_IsRunning)
{
//todo
IUXWaiting waiting = null;
_CacheMods.Clear();
while (_UnRegisterQueue.TryDequeue(out var mod))
{
var handle = waiting?.Get();
handle?.SetMessage($":正在卸载{mod.PackageName}");
mod.OnDispose();
_CacheMods.Add(mod);
OnModUnLoad?.Invoke(mod);
waiting?.Release(handle);
}
foreach (var mod in _CacheMods)
{
await mod.OnDisposeAsync(_CancellationTokenSource.Token);
foreach (var x in OnModUnloadAsync.CastAsFunc())
case ".cs":
{
await x.Invoke(mod);
var code = await File.ReadAllTextAsync(fileInfo.FullName);
var assembly = BITSharp.Compile(code);
await Load(assembly, fileInfo.DirectoryName);
continue;
}
}
foreach (var mod in _CacheMods)
{
mod.OnDisposed();
OnModUnLoaded?.Invoke(mod);
BIT4Log.Log<ModService>($"卸载Mod:{mod.GetType().FullName}");
}
_CacheMods.Clear();
while (_RegisterQueue.TryDequeue(out var mod))
{
var handle = waiting?.Get();
handle?.SetMessage($"正在加载:{mod.PackageName}");
_CacheMods.Add(mod);
mod.OnInitialize();
OnModLoad?.Invoke(mod);
BIT4Log.Log<ModService>($"加载Mod:{mod.GetType().FullName}");
waiting?.Release(handle);
}
foreach (var mod in _CacheMods)
{
var handle = waiting?.Get();
handle?.SetMessage($"正在初始化:{mod.PackageName}");
await mod.OnInitializedAsync(_CancellationTokenSource.Token);
foreach (var x in OnModLoadAsync.CastAsFunc())
{
await x.Invoke(mod);
}
waiting?.Release(handle);
}
foreach (var mod in _CacheMods)
{
var handle = waiting?.Get();
handle?.SetMessage($":正在完成初始化中{mod.PackageName}");
mod.OnInitialized();
OnModLoaded?.Invoke(mod);
waiting?.Release(handle);
}
_CacheMods.Clear();
//Thread.Sleep(1000);
#if UNITY_5_3_OR_NEWER
await UniTask.Delay(1000);
#else
await Task.Delay(1000);
#endif
IsLocked = false;
}
}
BIT4Log.Log<ModService>("Mod服务已停止");
}
catch (Exception e)
{
BIT4Log.Warning<ModService>("自动加载Mod失败");
BIT4Log.LogException(e);
BIT4Log.Warning<ModService>("Mod服务遇到了错误,已停止");
}
}
catch (Exception e)
{
BIT4Log.LogException(e);
BIT4Log.Warning<ModService>("Mod服务遇到了错误,已停止");
}
}
public static void Dispose()
{_IsRunning = false;
{
_CancellationTokenSource.Cancel();
try
{
_Thread.Join(100);
_RegisterQueue.Clear();
_UnRegisterQueue.Clear();
Mods = Array.Empty<IMod>();
_InstalledMods.Clear();
}
@@ -387,8 +266,9 @@ namespace BITKit.Mod
{
BIT4Log.LogException(e);
}
}
public static UniTask Load(Assembly assembly,string folderPath=null)
{
BIT4Log.Log<ModService>($"加载程序集:{assembly.FullName}");
@@ -480,20 +360,35 @@ namespace BITKit.Mod
}
OnPackageLoaded?.Invoke(package);
}
public static void Load(IMod mod)
public static async UniTask Load(IMod mod)
{
IsLocked = true;
_RegisterQueue.Enqueue(mod);
mod.OnInitialize();
OnModLoad?.Invoke(mod);
BIT4Log.Log<ModService>($"加载Mod:{mod.GetType().FullName}");
}
public static void UnLoad(IMod mod)
public static async UniTask UnLoad(IMod mod)
{
IsLocked = true;
_UnRegisterQueue.Enqueue(mod);
mod.OnDispose();
OnModUnLoad?.Invoke(mod);
await mod.OnDisposeAsync(_CancellationTokenSource.Token);
foreach (var x in OnModUnloadAsync.CastAsFunc())
{
await x.Invoke(mod);
}
mod.OnDisposed();
OnModUnLoaded?.Invoke(mod);
BIT4Log.Log<ModService>($"卸载Mod:{mod.GetType().FullName}");
}
public static void Install(IMod mod)
public static async void Install(IMod mod)
{
await IsBusy;
using var _ = IsBusy.GetHandle();
if (_InstalledMods.ContainsKey(mod.PackageName))
{
throw new ArgumentException("Mod已安装");
@@ -501,9 +396,21 @@ namespace BITKit.Mod
_InstalledMods.TryAdd(mod.PackageName,mod);
Mods = _InstalledMods.Values.ToArray();
OnModInstalled?.Invoke(mod);
await mod.OnInitializedAsync(_CancellationTokenSource.Token);
foreach (var x in OnModLoadAsync.CastAsFunc())
{
await x.Invoke(mod);
}
mod.OnInitialized();
OnModLoaded?.Invoke(mod);
}
public static void UnInstall(IMod mod)
{
using var _ = IsBusy.GetHandle();
if(_InstalledMods.ContainsKey(mod.PackageName) is false) return;
_InstalledMods.TryRemove(mod.PackageName);
Mods = _InstalledMods.Values.ToArray();