This commit is contained in:
CortexCore
2025-01-12 11:13:19 +08:00
parent 01e7e4e35e
commit 01b3d1be43
26 changed files with 387 additions and 336 deletions

View File

@@ -21,16 +21,10 @@ namespace BITKit.UX
private const string TemplatePath = "ux_mod_service_template";
public override bool AllowCursor => true;
public UXModService(IUXService uxService) : base(uxService)
{
ModService.OnModInstalled+=OnModInstalled;
ModService.OnModUnInstalled+=OnModUnInstalled;
ModService.OnModLoaded+=OnModLoaded;
ModService.OnModUnLoaded+=OnModUnLoaded;
ModService.OnLocked+=OnLocked;
}
private VisualTreeAsset _modTemplate;
[UXBindPath("open_folder-button")]
private Button _openFolderButton;
[UXBindPath("open-mod-button")]
private Button _openModButton;
[UXBindPath("mods-container")]
@@ -43,22 +37,27 @@ namespace BITKit.UX
private Label _modDescriptionLabel;
[UXBindPath("reload-mod-button",true)]
private Button _reloadModButton;
[UXBindPath("install-roslyn-fill")]
private VisualElement _installRoslynFill;
private readonly ConcurrentDictionary<string,VisualElement> _modContainers=new();
public UXModService(IUXService uxService) : base(uxService)
{
ModService.OnModInstalled+=OnModInstalled;
ModService.OnModUnInstalled+=OnModUnInstalled;
ModService.OnModLoaded+=OnModLoaded;
ModService.OnModUnLoaded+=OnModUnLoaded;
ModService.IsBusy.AddListener(OnLocked);
private void OnLocked(bool obj)
{
RootVisualElement?.SetEnabled(!obj);
OnInitiatedAsync += InitializeAsync;
}
public override async UniTask EntryAsync()
private async UniTask InitializeAsync()
{
await base.EntryAsync();
_installRoslynFill.style.width = 0;
_modTemplate =await ModService.LoadAsset<VisualTreeAsset>(TemplatePath);
UXUtils.Inject(this);
if (_openModButton is not null)
{
_openModButton.clicked += OpenMod;
}
if (_returnButton is not null)
{
@@ -79,7 +78,22 @@ namespace BITKit.UX
await UniTask.SwitchToMainThread();
_reloadModButton.SetEnabled(true);
};
_openFolderButton.clicked += () =>
{
new BITApp.OpenPath()
{
path = Path.Combine(Environment.CurrentDirectory, "Mods")
}.Execute();
};
}
private void OnLocked(bool obj)
{
RootVisualElement?.SetEnabled(!obj);
}
private async void OnModUnInstalled(IMod obj)
{
await UniTask.SwitchToMainThread();
@@ -117,78 +131,6 @@ namespace BITKit.UX
var container = _modContainers.GetOrAdd(obj.Name,_=> Create(obj));
container.Get<Toggle>().SetValueWithoutNotify(true);
}
private static void OpenMod()
{
BIT4Log.Log("正在打开选择文件对话框");
#if UNITY_EDITOR
new Thread(OpenModInternal).Start();
#else
OpenModInternal();
#endif
return;
void OpenModInternal()
{
#if UNITY_5_3_OR_NEWER && UNITY_WINDOW
BIT4Log.Log<UXModService>("已进入文件对话框线程");
new FileBrowser().OpenFileBrowser(new BrowserProperties()
{
//filterIndex = 0,
//filter = "C Sharp files (*.cs)|*.cs |Dll files (*.dll)|*.dll",
}, Filepath);
#else
throw new NotSupportedException($"{Application.platform} 不支持打开文件对话框");
#endif
return;
async void Filepath(string path)
{
BIT4Log.Log<UXModService>("已选择文件:"+path);
await BITApp.SwitchToMainThread();
try
{
var file = new FileInfo(path);
switch (file.Extension)
{
case ".cs":
#if UNITY_5_3_OR_NEWER
var code = await File.ReadAllTextAsync(path);
var assembly = BITSharp.Compile(code);
await ModService.Load(assembly,Path.GetDirectoryName(path));
#else
throw new NotSupportedException($"{Application.platform} 不支持编译C#代码");
#endif
break;
case ".dll":
var bytes = await File.ReadAllBytesAsync(path);
await ModService.Load(Assembly.Load(bytes),Path.GetDirectoryName(path));
break;
case ".json" when file.Name is ModPackage.DefaultFileName:
await ModService.LoadFromPackage(path);
break;
default:
Alert.Print(new AlertMessage()
{
title = "加载失败",
message = "不支持的文件类型"
});
break;
}
}
catch (Exception e)
{
Alert.Print(new AlertMessage()
{
title = "加载失败",
message = e.Message
});
BIT4Log.LogException(e);
}
}
}
}
private VisualElement Create(IMod mod)
{
var container =_modsContainer.Create(_modTemplate);
@@ -219,7 +161,7 @@ namespace BITKit.UX
ModService.OnModUnInstalled-=OnModUnInstalled;
ModService.OnModLoaded-=OnModLoaded;
ModService.OnModUnLoaded-=OnModUnLoaded;
ModService.OnLocked-=OnLocked;
ModService.IsBusy.RemoveListener(OnLocked);
}
}