166 lines
6.3 KiB
C#
166 lines
6.3 KiB
C#
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
|
|
{
|
|
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)
|
|
{
|
|
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 static HashSet<string> BuildPackageCache(string obj)
|
|
{
|
|
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;
|
|
}
|
|
|
|
public static async UniTask<IReadOnlyList<object>> LoadAssets( string[] arg)
|
|
{
|
|
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;
|
|
}
|
|
}
|
|
}
|