breakpoint
before update unity version
This commit is contained in:
@@ -4,13 +4,16 @@ using System.Collections;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.IO.MemoryMappedFiles;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BITKit.IO;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using Microsoft.CSharp;
|
||||
using UnityEngine.Experimental.Audio;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace BITKit.Mod
|
||||
{
|
||||
@@ -124,6 +127,51 @@ namespace BITKit.Mod
|
||||
|
||||
public class ModService
|
||||
{
|
||||
public static async UniTask<ModPackage[]> SearchPackages()
|
||||
{
|
||||
var list=new List<ModPackage>();
|
||||
var path = Path.Combine(Environment.CurrentDirectory, "Mods");
|
||||
var dir = new DirectoryInfo(path);
|
||||
dir.Create();
|
||||
foreach (var x in dir.GetDirectories())
|
||||
{
|
||||
var file = Path.Combine(x.FullName,ModPackage.DefaultFileName);
|
||||
if(File.Exists(file) is false)continue;
|
||||
var package = JsonConvert.DeserializeObject<ModPackage>(await File.ReadAllTextAsync(file))!;
|
||||
package.PackagePath = file;
|
||||
package.WorkDirectory = x.FullName;
|
||||
list.Add(package);
|
||||
}
|
||||
return list.ToArray();
|
||||
}
|
||||
public static async UniTask Reload()
|
||||
{
|
||||
var mods = Mods;
|
||||
foreach (var x in Mods)
|
||||
{
|
||||
UnLoad(x);
|
||||
UnInstall(x);
|
||||
}
|
||||
|
||||
foreach (var x in await SearchPackages())
|
||||
{
|
||||
var path = x.PackagePath;
|
||||
if (File.Exists(path) is false)
|
||||
{
|
||||
BIT4Log.Warning<ModService>($"未找到{x.PackageName}的描述文件:{path}");
|
||||
continue;
|
||||
}
|
||||
try
|
||||
{
|
||||
await LoadFromPackage(path);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
BIT4Log.LogException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static IMod[] Mods { get; private set; }=Array.Empty<IMod>();
|
||||
|
||||
public static bool IsLocked
|
||||
@@ -158,6 +206,7 @@ namespace BITKit.Mod
|
||||
private static bool _IsRunning;
|
||||
private static bool _IsLocked;
|
||||
private static AppDomain _ModDomain;
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
BIT4Log.Log<ModService>("Mod服务已启动");
|
||||
@@ -165,103 +214,122 @@ namespace BITKit.Mod
|
||||
_CancellationTokenSource = new CancellationTokenSource();
|
||||
_Thread = new Thread(InternalInitialize);
|
||||
_Thread.Start();
|
||||
|
||||
|
||||
return;
|
||||
async void InternalInitialize()
|
||||
|
||||
async void InternalInitialize()
|
||||
{
|
||||
try
|
||||
{
|
||||
_ModDomain = AppDomain.CreateDomain("ModDomain");
|
||||
|
||||
var modPath = Path.Combine(Environment.CurrentDirectory, "Mods\\");
|
||||
PathHelper.EnsureDirectoryCreated(modPath);
|
||||
var directoryInfo = new DirectoryInfo(modPath);
|
||||
foreach (var fileInfo in directoryInfo.GetFiles())
|
||||
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
switch (fileInfo.Extension)
|
||||
_ModDomain = AppDomain.CreateDomain("ModDomain");
|
||||
|
||||
var modPath = Path.Combine(Environment.CurrentDirectory, "Mods\\");
|
||||
PathHelper.EnsureDirectoryCreated(modPath);
|
||||
var directoryInfo = new DirectoryInfo(modPath);
|
||||
foreach (var fileInfo in directoryInfo.GetFiles())
|
||||
{
|
||||
case ".dll":
|
||||
switch (fileInfo.Extension)
|
||||
{
|
||||
var assembly = Assembly.LoadFile(fileInfo.FullName);
|
||||
await Load(assembly);
|
||||
continue;
|
||||
}
|
||||
#if UNITY_64
|
||||
case ".cs":
|
||||
{
|
||||
var code = await File.ReadAllTextAsync(fileInfo.FullName);
|
||||
var assembly = BITSharp.Compile(code);
|
||||
await Load(assembly);
|
||||
continue;
|
||||
}
|
||||
case ".dll":
|
||||
{
|
||||
var assembly = Assembly.LoadFile(fileInfo.FullName);
|
||||
await Load(assembly);
|
||||
continue;
|
||||
}
|
||||
#if UNITY_64
|
||||
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)
|
||||
{
|
||||
_CacheMods.Clear();
|
||||
while (_RegisterQueue.TryDequeue(out var mod))
|
||||
{
|
||||
_CacheMods.Add(mod);
|
||||
mod.OnInitialize();
|
||||
OnModLoad?.Invoke(mod);
|
||||
BIT4Log.Log<ModService>($"加载Mod:{mod.GetType().FullName}");
|
||||
}
|
||||
|
||||
foreach (var mod in _CacheMods)
|
||||
{
|
||||
await mod.OnInitializedAsync(_CancellationTokenSource.Token);
|
||||
foreach (var x in OnModLoadAsync.CastAsFunc())
|
||||
{
|
||||
await x.Invoke(mod);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var mod in _CacheMods)
|
||||
{
|
||||
mod.OnInitialized();
|
||||
OnModLoaded?.Invoke(mod);
|
||||
}
|
||||
|
||||
_CacheMods.Clear();
|
||||
|
||||
while (_UnRegisterQueue.TryDequeue(out var mod))
|
||||
{
|
||||
mod.OnDispose();
|
||||
_CacheMods.Add(mod);
|
||||
OnModUnLoad?.Invoke(mod);
|
||||
}
|
||||
|
||||
foreach (var mod in _CacheMods)
|
||||
{
|
||||
await mod.OnDisposeAsync(_CancellationTokenSource.Token);
|
||||
foreach (var x in OnModUnloadAsync.CastAsFunc())
|
||||
{
|
||||
await x.Invoke(mod);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var mod in _CacheMods)
|
||||
{
|
||||
mod.OnDisposed();
|
||||
OnModUnLoaded?.Invoke(mod);
|
||||
BIT4Log.Log<ModService>($"卸载Mod:{mod.GetType().FullName}");
|
||||
}
|
||||
//Thread.Sleep(1000);
|
||||
#if UNITY_64
|
||||
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服务遇到了错误,已停止");
|
||||
}
|
||||
|
||||
|
||||
while (_IsRunning)
|
||||
{
|
||||
_CacheMods.Clear();
|
||||
while (_RegisterQueue.TryDequeue(out var mod))
|
||||
{
|
||||
_CacheMods.Add(mod);
|
||||
mod.OnInitialize();
|
||||
OnModLoad?.Invoke(mod);
|
||||
BIT4Log.Log<ModService>($"加载Mod:{mod.GetType().FullName}");
|
||||
|
||||
}
|
||||
foreach (var mod in _CacheMods)
|
||||
{
|
||||
await mod.OnInitializedAsync(_CancellationTokenSource.Token);
|
||||
foreach (var x in OnModLoadAsync.CastAsFunc())
|
||||
{
|
||||
await x.Invoke(mod);
|
||||
}
|
||||
}
|
||||
foreach (var mod in _CacheMods)
|
||||
{
|
||||
mod.OnInitialized();
|
||||
OnModLoaded?.Invoke(mod);
|
||||
}
|
||||
_CacheMods.Clear();
|
||||
|
||||
while (_UnRegisterQueue.TryDequeue(out var mod))
|
||||
{
|
||||
mod.OnDispose();
|
||||
_CacheMods.Add(mod);
|
||||
OnModUnLoad?.Invoke(mod);
|
||||
}
|
||||
foreach (var mod in _CacheMods)
|
||||
{
|
||||
await mod.OnDisposeAsync(_CancellationTokenSource.Token);
|
||||
foreach (var x in OnModUnloadAsync.CastAsFunc())
|
||||
{
|
||||
await x.Invoke(mod);
|
||||
}
|
||||
}
|
||||
foreach (var mod in _CacheMods)
|
||||
{
|
||||
mod.OnDisposed();
|
||||
OnModUnLoaded?.Invoke(mod);
|
||||
BIT4Log.Log<ModService>($"卸载Mod:{mod.GetType().FullName}");
|
||||
}
|
||||
//Thread.Sleep(1000);
|
||||
#if UNITY_64
|
||||
await UniTask.Delay(1000);
|
||||
#else
|
||||
await Task.Delay(1000);
|
||||
#endif
|
||||
IsLocked = false;
|
||||
}
|
||||
BIT4Log.Log<ModService>("Mod服务已停止");
|
||||
}
|
||||
}
|
||||
|
||||
public static void Dispose()
|
||||
{_IsRunning = false;
|
||||
_CancellationTokenSource.Cancel();
|
||||
@@ -293,8 +361,20 @@ namespace BITKit.Mod
|
||||
BIT4Log.LogException(e);
|
||||
return UniTask.CompletedTask;
|
||||
}
|
||||
|
||||
foreach (var type in assembly.GetTypes())
|
||||
|
||||
var types = new List<Type>();
|
||||
|
||||
try
|
||||
{
|
||||
types.AddRange(assembly.GetTypes());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
BIT4Log.Warning<ModService>($"{assembly.FullName}遇到了错误");
|
||||
BIT4Log.LogException(e);
|
||||
}
|
||||
|
||||
foreach (var type in types)
|
||||
{
|
||||
//if (type.IsAssignableFrom(typeof(IMod)) is false)
|
||||
if(typeof(IMod).IsAssignableFrom(type) is false)
|
||||
@@ -303,20 +383,53 @@ namespace BITKit.Mod
|
||||
continue;
|
||||
}
|
||||
var mod = Activator.CreateInstance(type).As<IMod>();
|
||||
//mod.FolderPath =$"file://{folderPath}" ;
|
||||
DI.Inject(mod);
|
||||
mod.FolderPath =folderPath;
|
||||
if(_InstalledMods.ContainsKey(mod.PackageName))
|
||||
{
|
||||
BIT4Log.Log<ModService>($"Mod已安装,跳过加载:{mod.PackageName}");
|
||||
continue;
|
||||
}
|
||||
BIT4Log.Log<ModService>($"加载Mod:{mod.GetType().FullName}");
|
||||
BIT4Log.Log<ModService>($"加载Mod:{mod.GetType().FullName},Folder:{folderPath}");
|
||||
|
||||
Install(mod);
|
||||
Load(mod);
|
||||
}
|
||||
|
||||
BIT4Log.Log<ModService>($"<color=green>程序集加载完成:{assembly.FullName}</color>");
|
||||
return UniTask.CompletedTask;
|
||||
}
|
||||
|
||||
public static async UniTask LoadFromPackage(string path)
|
||||
{
|
||||
await UniTask.Yield();
|
||||
if(File.Exists(path) is false) throw new FileNotFoundException(path);
|
||||
var package = JsonConvert.DeserializeObject<ModPackage>(await File.ReadAllTextAsync(path))!;
|
||||
BIT4Log.Log<ModService>($"加载Mod包:{package.PackageName}");
|
||||
if(package.EntryPoint is null) throw new InvalidOperationException("空入口,无法识别类型");
|
||||
path = Path.Combine(Path.GetDirectoryName(path)!, package.EntryPoint);
|
||||
if(File.Exists(path) is false) throw new InvalidOperationException($"未找到入口文件:{path}");
|
||||
var fileInfo = new FileInfo(path);
|
||||
switch (fileInfo.Extension)
|
||||
{
|
||||
case ".dll":
|
||||
{
|
||||
var assembly = Assembly.LoadFile(fileInfo.FullName);
|
||||
await Load(assembly, fileInfo.DirectoryName);
|
||||
break;
|
||||
}
|
||||
#if UNITY_64
|
||||
case ".cs":
|
||||
{
|
||||
var code = await File.ReadAllTextAsync(fileInfo.FullName);
|
||||
var assembly = BITSharp.Compile(code);
|
||||
await Load(assembly, fileInfo.DirectoryName);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
public static void Load(IMod mod)
|
||||
{
|
||||
IsLocked = true;
|
||||
|
Reference in New Issue
Block a user