This commit is contained in:
CortexCore
2025-02-24 23:02:43 +08:00
parent 41715e4413
commit 8261a458e2
105 changed files with 2934 additions and 696 deletions

View File

@@ -6,7 +6,6 @@ using System.IO;
using BITKit.IO;
using BITKit.UX;
using Cysharp.Threading.Tasks;
using UnityEditorInternal;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Rendering;
@@ -26,9 +25,11 @@ namespace BITKit
private static void Reload()
{
Stopwatch = new Stopwatch();
#if UNITY_EDITOR
#else
SplashScreen.Stop(SplashScreen.StopBehavior.StopImmediate);
SplashScreen.Stop(SplashScreen.StopBehavior.StopImmediate);
#endif
}

View File

@@ -0,0 +1,65 @@
using System;
using System.Collections;
using System.Collections.Generic;
using BITKit.Entities;
using BITKit.Mod;
using Cysharp.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using UnityEngine;
using ILogger = Microsoft.Extensions.Logging.ILogger;
namespace BITKit.IO
{
public class ScriptableEntitiesService : IDisposable
{
private readonly IEntitiesService _entitiesService;
public string Tags = "scriptable_object";
private readonly List<IEntity> _registeredEntities = new();
public ScriptableEntitiesService(IEntitiesService entitiesService)
{
_entitiesService = entitiesService;
}
public async UniTask InitializeAsync(ILogger logger = null)
{
logger?.LogInformation("正在查找所有ScriptableObject...");
var objs = await ModService.LoadAssets<ScriptableObject>(Tags);
logger?.LogInformation($"找到{objs.Count}个资源,正在加载中...");
for (var index = 0; index < objs.Count; index++)
{
var scriptableObject = objs[index];
var entity = new Entity();
var idComponent = new IdComponent();
entity.ServiceCollection.AddSingleton(idComponent);
var type = scriptableObject.GetType();
entity.ServiceCollection.AddSingleton(type, scriptableObject);
_entitiesService.Register(entity);
logger?.LogInformation($"已加载:{scriptableObject.name}:{type.Name},剩余:{index + 1}/{objs.Count}");
_registeredEntities.Add(entity);
}
logger?.LogInformation("加载完成");
}
public void Dispose()
{
foreach (var x in _registeredEntities)
{
_entitiesService.UnRegister(x);
}
_registeredEntities.Clear();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e1ff18f234ca249459fb3df556f90b11
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,30 +1,165 @@
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Drawing.Printing;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using BITKit.Mod;
using Cysharp.Threading.Tasks;
using Microsoft.Extensions.Logging;
using UnityEditor;
using UnityEngine;
using YooAsset;
using ILogger = Microsoft.Extensions.Logging.ILogger;
using Object = UnityEngine.Object;
namespace BITKit.IO
{
public class YooAssetModHelper : MonoBehaviour
public class YooAssetModHelper
{
private void OnEnable()
public static string Url = "http://server.bitfall.icu:21982/com.project.b/Mods";
public static readonly ConcurrentDictionary<string, HashSet<string>> PackagesManifestDictionary = new();
public static async UniTask LoadMods(ILogger logger=null)
{
ModService.LoadAssetAsyncFactory += LoadAsset;
try
{
var modPath = Path.Combine(Environment.CurrentDirectory, "Mods");
if (Application.platform is RuntimePlatform.Android)
{
modPath = Path.Combine($"/storage/emulated/0/{Application.identifier}/Mods/");
}
foreach (var directoryInfo in new DirectoryInfo(modPath).GetDirectories())
{
var packageName = directoryInfo.Name;
logger?.LogInformation($"开始加载:{packageName}");
var package = YooAssets.CreatePackage(packageName);
var initPars = new HostPlayModeParameters()
{
BuildinQueryServices = new GameQueryServices(),
RemoteServices = new RemoteServices($"{Url}/{directoryInfo.Name}",$"file://{directoryInfo.FullName}")
};
await package.InitializeAsync(initPars);
var update = package.UpdatePackageVersionAsync();
await update.ToUniTask();
var manifest = package.UpdatePackageManifestAsync(update.PackageVersion);
await manifest.ToUniTask();
var downloader = package.CreateResourceDownloader(10, 3);
if (logger is not null)
{
downloader.OnDownloadProgressCallback = (totalDownloadCount, currentDownloadCount,
totalDownloadBytes, currentDownloadBytes) =>
{
//下载进度
var progress = (float)currentDownloadBytes / totalDownloadBytes;
logger.LogInformation($"已下载{(int)(progress*100)}%,资源数量{currentDownloadBytes}/{totalDownloadBytes}");
};
downloader.OnDownloadErrorCallback = (fileName, error) =>
{
logger.LogError($"资源[{fileName}]下载错误::{error}");
};
}
downloader.BeginDownload();
await downloader.ToUniTask();
var mod = new MyMod()
{
FolderPath = directoryInfo.FullName,
PackageName = packageName,
Name = packageName
};
await ModService.Install(mod);
await ModService.Load(mod);
YooAssetUtils.RegisterResourcePackage(package);
logger?.LogInformation($"已加载:{packageName},路径:{directoryInfo.FullName}");
}
return;
}
catch (Exception e)
{
if (logger is not null)
{
logger.LogCritical(e.Message,e);
}
else
{
BIT4Log.LogException(e);
}
}
logger?.LogInformation($"未找到Mod");
}
private void OnDisable()
private static HashSet<string> BuildPackageCache(string obj)
{
ModService.LoadAssetAsyncFactory -= LoadAsset;
var package = YooAssets.GetPackage(obj);
var playMode = package.GetType().GetField("_playModeImpl", ReflectionHelper.Flags)!.GetValue(package);
var manifest = playMode.GetType().GetProperty("ActiveManifest", ReflectionHelper.Flags)!.GetValue(playMode);
var dictionary = manifest.GetType().GetField("AssetDic", ReflectionHelper.Flags)!.GetValue(manifest) as IDictionary;
var hashset = new HashSet<string>();
foreach (var key in dictionary.Keys)
{
hashset.Add(key?.ToString());
}
var assetPathMapping1=manifest.GetType().GetField("AssetPathMapping1", ReflectionHelper.Flags)!.GetValue(manifest) as IDictionary<string,string>;
foreach (var key in assetPathMapping1.Keys)
{
hashset.Add(key);
}
return hashset;
}
private static async UniTask<object> LoadAsset(string arg)
public static async UniTask<IReadOnlyList<object>> LoadAssets( string[] arg)
{
var handle = YooAssets.LoadAssetAsync(arg);
await handle;
return handle.AssetObject;
var list = new List<object>();
foreach (var resourcePackage in YooAssetUtils.RegisteredResourcePackages)
{
foreach (var assetInfo in resourcePackage.GetAssetInfos(arg))
{
var asyncHandle = resourcePackage.LoadAssetAsync(assetInfo);
await asyncHandle;
list.Add(asyncHandle.AssetObject);
}
}
return list;
}
public static async UniTask<object> LoadAsset(string arg)
{
foreach (var resourcePackage in YooAssetUtils.RegisteredResourcePackages.Reverse())
{
if(PackagesManifestDictionary.GetOrAdd(resourcePackage.PackageName,BuildPackageCache).Contains(arg) is false)continue;
var assetInfo = resourcePackage.GetAssetInfo(arg);
if(string.IsNullOrEmpty(assetInfo.Error) is false)continue;
var handle = resourcePackage.LoadAssetAsync(arg);
await handle;
return handle.AssetObject;
}
return null;
}
}
}