1
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user