using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; using BITKit.UX; #if UNITY_EDITOR using UnityEditor; #endif using UnityEngine; namespace BITKit.Mod { public class UnityModService : MonoBehaviour { [SerializeReference,SubclassSelector] private IReference[] referencedAssemblies; private async void Start() { //DI.TryGet(out var waiting); IUXWaiting waiting = null; var handle = waiting?.Get(); handle?.SetMessage("正在初始化Mod服务"); if (Application.isEditor is false) { BIT4Log.Log($"UnityPlayer所在位置:{Application.dataPath}"); BIT4Log.Log($"{nameof(System.Linq)}位于{typeof(Enumerable).Assembly.Location}"); } foreach (var x in referencedAssemblies) { var dllName = x.Value.Contains(".dll") ? x.Value : $"{x.Value}.dll"; if (SearchDll(dllName,out var dll) is false) { BIT4Log.Warning($"未找到:{dll}"); continue; } BITSharp.ReferencedAssemblies.Add(@$"""{dll}"""); } try { ModService.Initialize(); } catch (Exception e) { BIT4Log.Warning("初始化失败"); BIT4Log.LogException(e); return; } destroyCancellationToken.Register(ModService.Dispose); ModService.OnPackageLoad+=OnPackageLoad; var packages = await ModService.SearchPackages(); if (destroyCancellationToken.IsCancellationRequested) return; foreach (var package in packages) { await ModService.LoadFromPackage(package.PackagePath); if (destroyCancellationToken.IsCancellationRequested) return; } destroyCancellationToken.Register(() => { ModService.OnPackageLoad-=OnPackageLoad; }); waiting?.Release(handle); } private void OnPackageLoad(ModPackage obj) { var loadedDlls = referencedAssemblies.Cast(); var reportBuilder = new System.Text.StringBuilder(); //对比已加载的dll和当前引用的dll foreach (var x in obj.Dlls.Except(loadedDlls)) { if (SearchDll(x, out var dll) is false) { BIT4Log.Warning($"未找到:{dll}"); continue; } BITSharp.ReferencedAssemblies.Add(@$"""{dll}"""); reportBuilder.AppendLine($"加载:{dll}"); } BIT4Log.Log(reportBuilder.ToString()); } private bool SearchDll(string dllName,out string dll,params string[] moreFolder) { #if UNITY_EDITOR dll = System.IO.Path.Combine(Environment.CurrentDirectory, "Library", "ScriptAssemblies", dllName); var folder = EditorApplication.applicationPath; folder = Path.GetDirectoryName(folder); if(File.Exists(dll) is false) { dll = Path.Combine(folder,"Data", "MonoBleedingEdge", "lib","mono","unityjit-win32",dllName); } if (File.Exists(dll) is false) { dll = Path.Combine(folder,"Data", "MonoBleedingEdge", "lib","mono","unityjit-win32","Facades",dllName); } #else dll = System.IO.Path.Combine(Environment.CurrentDirectory,$"{Application.productName}_Data", "Managed", dllName); #endif return File.Exists(dll); } } }