Initial commit to new repository
This commit is contained in:
195
.decompiledproj/AxCopilot/Core/PluginHost.cs
Normal file
195
.decompiledproj/AxCopilot/Core/PluginHost.cs
Normal file
@@ -0,0 +1,195 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using AxCopilot.Handlers;
|
||||
using AxCopilot.Models;
|
||||
using AxCopilot.SDK;
|
||||
using AxCopilot.Services;
|
||||
|
||||
namespace AxCopilot.Core;
|
||||
|
||||
public class PluginHost
|
||||
{
|
||||
private readonly SettingsService _settings;
|
||||
|
||||
private readonly CommandResolver _resolver;
|
||||
|
||||
private readonly List<IActionHandler> _loadedPlugins = new List<IActionHandler>();
|
||||
|
||||
public IReadOnlyList<IActionHandler> LoadedPlugins => _loadedPlugins;
|
||||
|
||||
public PluginHost(SettingsService settings, CommandResolver resolver)
|
||||
{
|
||||
_settings = settings;
|
||||
_resolver = resolver;
|
||||
}
|
||||
|
||||
public void LoadAll()
|
||||
{
|
||||
_loadedPlugins.Clear();
|
||||
foreach (PluginEntry item in _settings.Settings.Plugins.Where((PluginEntry p) => p.Enabled))
|
||||
{
|
||||
LoadPlugin(item.Path);
|
||||
}
|
||||
string path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "AxCopilot", "skills");
|
||||
if (!Directory.Exists(path))
|
||||
{
|
||||
return;
|
||||
}
|
||||
foreach (string item2 in Directory.EnumerateFiles(path, "*.skill.json"))
|
||||
{
|
||||
LoadJsonSkill(item2);
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadPlugin(string dllPath)
|
||||
{
|
||||
if (!File.Exists(dllPath))
|
||||
{
|
||||
LogService.Warn("플러그인 파일 없음: " + dllPath);
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
Assembly assembly = Assembly.LoadFrom(dllPath);
|
||||
IEnumerable<Type> enumerable = from t in assembly.GetExportedTypes()
|
||||
where typeof(IActionHandler).IsAssignableFrom(t) && !t.IsAbstract
|
||||
select t;
|
||||
foreach (Type item in enumerable)
|
||||
{
|
||||
if (Activator.CreateInstance(item) is IActionHandler actionHandler)
|
||||
{
|
||||
_resolver.RegisterHandler(actionHandler);
|
||||
_loadedPlugins.Add(actionHandler);
|
||||
LogService.Info("플러그인 로드: " + actionHandler.Metadata.Name + " v" + actionHandler.Metadata.Version);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogService.Error("플러그인 로드 실패 (" + dllPath + "): " + ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadJsonSkill(string skillPath)
|
||||
{
|
||||
try
|
||||
{
|
||||
IActionHandler actionHandler = JsonSkillLoader.Load(skillPath);
|
||||
if (actionHandler != null)
|
||||
{
|
||||
_resolver.RegisterHandler(actionHandler);
|
||||
_loadedPlugins.Add(actionHandler);
|
||||
LogService.Info("JSON 스킬 로드: " + actionHandler.Metadata.Name);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogService.Error("JSON 스킬 로드 실패 (" + skillPath + "): " + ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public void Reload()
|
||||
{
|
||||
LogService.Info("플러그인 전체 재로드 시작");
|
||||
LoadAll();
|
||||
}
|
||||
|
||||
public int InstallFromZip(string zipPath)
|
||||
{
|
||||
if (!File.Exists(zipPath))
|
||||
{
|
||||
LogService.Warn("플러그인 zip 파일 없음: " + zipPath);
|
||||
return 0;
|
||||
}
|
||||
string text = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "AxCopilot", "plugins");
|
||||
Directory.CreateDirectory(text);
|
||||
int num = 0;
|
||||
try
|
||||
{
|
||||
using ZipArchive zipArchive = ZipFile.OpenRead(zipPath);
|
||||
string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(zipPath);
|
||||
string text2 = Path.Combine(text, fileNameWithoutExtension);
|
||||
Directory.CreateDirectory(text2);
|
||||
foreach (ZipArchiveEntry entry in zipArchive.Entries)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(entry.Name))
|
||||
{
|
||||
string text3 = Path.Combine(text2, entry.Name);
|
||||
if (!Path.GetFullPath(text3).StartsWith(Path.GetFullPath(text2)))
|
||||
{
|
||||
LogService.Warn("플러그인 zip 경로 위험: " + entry.FullName);
|
||||
}
|
||||
else
|
||||
{
|
||||
entry.ExtractToFile(text3, overwrite: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach (string dllFile in Directory.EnumerateFiles(text2, "*.dll"))
|
||||
{
|
||||
if (!_settings.Settings.Plugins.Any((PluginEntry p) => p.Path == dllFile))
|
||||
{
|
||||
_settings.Settings.Plugins.Add(new PluginEntry
|
||||
{
|
||||
Enabled = true,
|
||||
Path = dllFile
|
||||
});
|
||||
LoadPlugin(dllFile);
|
||||
num++;
|
||||
}
|
||||
}
|
||||
string text4 = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "AxCopilot", "skills");
|
||||
Directory.CreateDirectory(text4);
|
||||
foreach (string item in Directory.EnumerateFiles(text2, "*.skill.json"))
|
||||
{
|
||||
string text5 = Path.Combine(text4, Path.GetFileName(item));
|
||||
File.Copy(item, text5, overwrite: true);
|
||||
LoadJsonSkill(text5);
|
||||
num++;
|
||||
}
|
||||
if (num > 0)
|
||||
{
|
||||
_settings.Save();
|
||||
}
|
||||
LogService.Info($"플러그인 설치 완료: {zipPath} → {num}개 핸들러");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogService.Error("플러그인 zip 설치 실패: " + ex.Message);
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
public bool UninstallPlugin(string dllPath)
|
||||
{
|
||||
try
|
||||
{
|
||||
PluginEntry pluginEntry = _settings.Settings.Plugins.FirstOrDefault((PluginEntry p) => p.Path == dllPath);
|
||||
if (pluginEntry != null)
|
||||
{
|
||||
_settings.Settings.Plugins.Remove(pluginEntry);
|
||||
_settings.Save();
|
||||
}
|
||||
string directoryName = Path.GetDirectoryName(dllPath);
|
||||
if (directoryName != null && Directory.Exists(directoryName))
|
||||
{
|
||||
string path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "AxCopilot", "plugins");
|
||||
if (Path.GetFullPath(directoryName).StartsWith(Path.GetFullPath(path)))
|
||||
{
|
||||
Directory.Delete(directoryName, recursive: true);
|
||||
}
|
||||
}
|
||||
LogService.Info("플러그인 제거 완료: " + dllPath);
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogService.Error("플러그인 제거 실패: " + ex.Message);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user