diff --git a/.github/workflows/mirror.yml b/.github/workflows/mirror.yml new file mode 100644 index 0000000..e2cc0f1 --- /dev/null +++ b/.github/workflows/mirror.yml @@ -0,0 +1,24 @@ +name: Mirror Repo + +on: + push: + branches: + - "*" + workflow_dispatch: + +jobs: + mirror-repo: + runs-on: ubuntu-latest + + steps: + - name: Mirror + uses: Yikun/hub-mirror-action@master + with: + src: github/Crequency + dst: gitee/Crequency + dst_key: ${{ secrets.GITEE_SYNC_KEY }} + dst_token: ${{ secrets.GITEE_SYNC_TOKEN }} + account_type: org + static_list: "KitX-Plugins" + force_update: true + debug: true diff --git a/.gitignore b/.gitignore index f16e632..cbb72d2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,7 @@ -## Ignore Visual Studio temporary files, build results, and +## Platform ignores +.DS_Store + +## Ignore Visual Studio temporary files, build results, and ## files generated by popular Visual Studio add-ons. ## ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore @@ -348,3 +351,6 @@ MigrationBackup/ # Ionide (cross platform F# VS Code tools) working folder .ionide/ + +# Official Plugins working folder +OfficialPlugins/ diff --git a/TestPlugin.CSharp/Controller.cs b/TestPlugin.CSharp/Controller.cs index 4fd54b0..c7f3df4 100644 --- a/TestPlugin.CSharp/Controller.cs +++ b/TestPlugin.CSharp/Controller.cs @@ -1,13 +1,23 @@ -using KitX.Contract.CSharp; -using KitX.Shared.Plugin; -using KitX.Shared.WebCommand; +using System.Text; using System.Text.Json; +using KitX.Contract.CSharp; +using KitX.Shared.CSharp.Plugin; +using KitX.Shared.CSharp.WebCommand; +using KitX.Shared.CSharp.WebCommand.Details; +using KitX.Shared.CSharp.WebCommand.Infos; namespace TestPlugin.CSharp; public class Controller : IController { - private Action? sendCommandAction; + private Action? sendCommandAction; + + private static readonly JsonSerializerOptions serializerOptions = new() + { + WriteIndented = true, + IncludeFields = true, + PropertyNameCaseInsensitive = true, + }; public void Start() { @@ -27,27 +37,89 @@ public void End() public void Execute(Command cmd) { Console.WriteLine($"Execute: {JsonSerializer.Serialize(cmd)}"); - } - public List GetFunctions() - { - return []; - } + // 从 Tags 中获取 RequestId,用于发送响应 + string? requestId = null; + if (cmd.Tags is not null && cmd.Tags.TryGetValue("RequestId", out var reqId)) + { + requestId = reqId; + } - public void SetSendCommandAction(Action action) => sendCommandAction = action; + if (cmd.FunctionName == "SayHello") + { + // 从参数中获取 name + var name = "World"; // 默认值 - public void SetRootPath(string path) - { - Console.WriteLine($"Root path: {path}"); - } + if (cmd.FunctionArgs is not null && cmd.FunctionArgs.Count > 0) + { + var firstArg = cmd.FunctionArgs[0]; + name = firstArg.Value ?? "World"; + } - public void SetWorkPath(string path) - { - Console.WriteLine($"Work path: {path}"); + var result = $"Hello, {name}!"; + Console.WriteLine($"SayHello result: {result}"); + + // 如果有 RequestId,发送响应 + if (requestId is not null && sendCommandAction is not null) + { + var responseBytes = Encoding.UTF8.GetBytes(result); + + var responseCommand = new Command + { + Request = CommandRequestInfo.ReceiveCommand, + PluginConnectionId = cmd.PluginConnectionId ?? string.Empty, + Body = responseBytes, + BodyLength = responseBytes.Length, + Tags = new Dictionary + { + { "RequestId", requestId } + } + }; + + var responseRequest = new Request + { + Content = JsonSerializer.Serialize(responseCommand, serializerOptions) + }; + + sendCommandAction.Invoke(responseRequest); + } + } } - public void SetCommandsSendBuffer(ref Queue commands) + public List GetFunctions() { - throw new NotImplementedException(); + return [ + new Function() + { + Name = "SayHello", + DisplayNames = new() + { + { "zh-cn", "打招呼" }, + { "zh-tw", "打招呼" }, + { "en-us", "Say Hello" }, + }, + ReturnValueType = "string", + Parameters = [ + new Parameter() + { + Name = "name", + Type = "string", + DisplayNames = new() + { + { "zh-cn", "姓名" }, + { "zh-tw", "姓名" }, + { "en-us", "Name" }, + }, + IsOptional = false, + } + ], + } + ]; } + + public void SetSendCommandAction(Action action) => sendCommandAction = action; + + public void SetWorkingDetail(PluginWorkingDetail workingDetail) => Console.WriteLine( + $"WorkingDetail: {JsonSerializer.Serialize(workingDetail)}" + ); } diff --git a/TestPlugin.CSharp/IdentityInterface.cs b/TestPlugin.CSharp/IdentityInterface.cs index 48c14cc..1dd35d3 100644 --- a/TestPlugin.CSharp/IdentityInterface.cs +++ b/TestPlugin.CSharp/IdentityInterface.cs @@ -1,43 +1,41 @@ using KitX.Contract.CSharp; +using KitX.Shared.CSharp.Plugin; namespace TestPlugin.CSharp; public class IdentityInterface : IIdentityInterface { - public string GetName() => "TestPlugin.CSharp"; + public IController GetController() => new Controller(); - public string GetVersion() => "v0.1.0"; + public IMarketPluginContract GetMarketPluginContract() => null!; - public Dictionary GetDisplayName() => new() + public PluginInfo GetPluginInfo() => new() + { + Name = "TestPlugin.CSharp", + Version = "v0.1.0", + DisplayName = new() { { "zh-cn", "适用于 C# 的 KitX 测试用插件" }, - { "zh-cnt", "適用於 C# 的 KitX 測試用插件" }, + { "zh-tw", "適用於 C# 的 KitX 測試用插件" }, { "en-us", "KitX Testing Plugin for C#" }, - }; - - public string GetAuthorName() => "Dynesshely"; - - public string GetPublisherName() => "Crequency"; - - public string GetAuthorLink() => "https://blog.catrol.cn"; - - public string GetPublisherLink() => "https://catrol.cn"; - - public Dictionary GetSimpleDescription() => new() + }, + AuthorName = "Dynesshely", + AuthorLink = "https://blog.catrol.cn", + PublisherName = "Crequency", + PublisherLink = "https://catrol.cn", + SimpleDescription = new() { { "zh-cn", "KitX 测试用插件" }, - { "zh-cnt", "KitX 測試用插件" }, + { "zh-tw", "KitX 測試用插件" }, { "en-us", "KitX Test Plugin" }, - }; - - public Dictionary GetComplexDescription() => new() + }, + ComplexDescription = new() { { "zh-cn", "KitX 测试用插件, 使用 KitX.Loader.CSharp 作为加载器." }, - { "zh-cnt", "KitX 測試用插件, 使用 KitX.Loader.CSharp 作爲加載器." }, + { "zh-tw", "KitX 測試用插件, 使用 KitX.Loader.CSharp 作爲加載器." }, { "en-us", "KitX Test Plugin, use KitX.Loader.CSharp as loader." }, - }; - - public Dictionary GetTotalDescriptionInMarkdown() => new() + }, + TotalDescriptionInMarkdown = new() { { "zh-cn", @@ -48,7 +46,7 @@ public class IdentityInterface : IIdentityInterface """ }, { - "zh-cnt", + "zh-tw", """ # 關於 這是一個適用於 C# 的 KitX 測試用插件 @@ -63,19 +61,39 @@ public class IdentityInterface : IIdentityInterface Use KitX.Loader.CSharp as loader """ }, - }; - - public string GetIconInBase64() => "图标"; - - public DateTime GetPublishDate() => DateTime.Now; - - public DateTime GetLastUpdateDate() => DateTime.Now; - - public IController GetController() => new Controller(); - - public bool IsMarketVersion() => false; - - public IMarketPluginContract GetMarketPluginContract() => null; - - public string GetRootStartupFileName() => "TestPlugin.CSharp.dll"; + }, + IconInBase64 = "Icon", + PublishDate = DateTime.Now, + LastUpdateDate = DateTime.Now, + IsMarketVersion = false, + RootStartupFileName = "TestPlugin.CSharp.dll", + Tags = [], + Functions = [ + new Function() + { + Name = "SayHello", + DisplayNames = new() + { + { "zh-cn", "打招呼" }, + { "zh-tw", "打招呼" }, + { "en-us", "Say Hello" }, + }, + ReturnValueType = "string", + Parameters = [ + new Parameter() + { + Name = "name", + Type = "string", + DisplayNames = new() + { + { "zh-cn", "姓名" }, + { "zh-tw", "姓名" }, + { "en-us", "Name" }, + }, + IsOptional = false, + } + ], + } + ] + }; } diff --git a/TestPlugin.CSharp/Program.cs b/TestPlugin.CSharp/Program.cs index 15ca0c9..ed9eb4e 100644 --- a/TestPlugin.CSharp/Program.cs +++ b/TestPlugin.CSharp/Program.cs @@ -1,2 +1 @@ - -Console.WriteLine("Hello, World!"); +// 插件入口点 - 不需要顶级语句,Loader 会通过 MEF 加载 IIdentityInterface diff --git a/TestPlugin.CSharp/TestPlugin.CSharp.csproj b/TestPlugin.CSharp/TestPlugin.CSharp.csproj index a533f98..c7c2406 100644 --- a/TestPlugin.CSharp/TestPlugin.CSharp.csproj +++ b/TestPlugin.CSharp/TestPlugin.CSharp.csproj @@ -1,8 +1,8 @@  - Exe - net8.0 + Library + net10.0 enable enable Preview @@ -14,10 +14,6 @@ $(Version) - - - - diff --git a/TestPlugin.WPF.Core/Controller.cs b/TestPlugin.WPF.Core/Controller.cs index d4cab33..5c81d91 100644 --- a/TestPlugin.WPF.Core/Controller.cs +++ b/TestPlugin.WPF.Core/Controller.cs @@ -1,8 +1,10 @@ -using KitX.Contract.CSharp; -using KitX.Shared.WebCommand; -using KitX.Shared.WebCommand.Details; -using System; +using System; +using System.Text; +using System.Text.Json; using System.Windows; +using KitX.Contract.CSharp; +using KitX.Shared.CSharp.WebCommand; +using KitX.Shared.CSharp.WebCommand.Details; namespace TestPlugin.WPF.Core; @@ -10,6 +12,13 @@ public class Controller(MainWindow mainwin) : IController { private readonly MainWindow mainwin = mainwin; + private static readonly JsonSerializerOptions _serializerOptions = new() + { + WriteIndented = false, + IncludeFields = true, + PropertyNameCaseInsensitive = true, + }; + public PluginWorkingDetail? WorkingDetail { get; set; } public void End() @@ -31,7 +40,28 @@ public void Execute(Command command) { if (command.FunctionName.Equals("HelloKitX")) { - MessageBox.Show("Hello KitX !"); + Functions.HelloKitX(); + } + else if (command.FunctionName.Equals("HelloAnything")) + { + var name = command.FunctionArgs != null && command.FunctionArgs.Count > 0 ? command.FunctionArgs[0].Value : "Anything"; + Functions.HelloAnything(name); + } + else if (command.FunctionName.Equals("GetInput")) + { + var inputText = mainwin.GetInputText(); + var bodyBytes = Encoding.UTF8.GetBytes(inputText); + mainwin.sendCommandAction?.Invoke(new Request + { + Type = RequestTypes.Command, + Version = RequestVersions.V1, + Content = JsonSerializer.Serialize(new Command + { + Tags = command.Tags, // 保留 RequestId 用于响应匹配 + Body = bodyBytes, + BodyLength = bodyBytes.Length + }, _serializerOptions) + }); } } diff --git a/TestPlugin.WPF.Core/Functions.cs b/TestPlugin.WPF.Core/Functions.cs new file mode 100644 index 0000000..6b41aca --- /dev/null +++ b/TestPlugin.WPF.Core/Functions.cs @@ -0,0 +1,32 @@ +using System.Windows; +using KitX.Contract.CSharp.Attributes; + +namespace TestPlugin.WPF.Core; + +[EntryClass] +public class Functions +{ + [Function(nameof(HelloKitX))] + public static void HelloKitX() + { + MessageBox.Show("Hello KitX !"); + } + + [Function(nameof(HelloAnything))] + [Translation("DisplayName", "zh-CN", "打个招呼")] + [Translation("DisplayName", "en-US", "Hello Anything")] + public static void HelloAnything( + [Parameter(nameof(name))] + [Translation("DisplayName", "zh-CN", "名称")] + [Translation("DisplayName", "en-US", "Name")] + string name + ) + { + MessageBox.Show($"Hello {name} !"); + } + + [Function(nameof(GetInput))] + [Translation("DisplayName", "zh-CN", "获取输入内容")] + [Translation("DisplayName", "en-US", "Get Input Text")] + public static string GetInput() => string.Empty; // 实际由 Controller.Execute 处理返回值 +} diff --git a/TestPlugin.WPF.Core/MainWindow.xaml b/TestPlugin.WPF.Core/MainWindow.xaml index ba2d5d7..de09bf7 100644 --- a/TestPlugin.WPF.Core/MainWindow.xaml +++ b/TestPlugin.WPF.Core/MainWindow.xaml @@ -9,11 +9,32 @@ SizeToContent="WidthAndHeight" mc:Ignorable="d"> - + + + + + + + +