diff --git a/Abstractions/IMedusaPlugin.cs b/Abstractions/IMedusaPlugin.cs index e498a9b..545bb54 100644 --- a/Abstractions/IMedusaPlugin.cs +++ b/Abstractions/IMedusaPlugin.cs @@ -1,3 +1,4 @@ +using System; using System.Text; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; @@ -16,5 +17,6 @@ public interface IMedusaPlugin Task OnBuilderInitialize(WebApplicationBuilder builder); Task OnAppInitialize(WebApplication app); - Task DoesProfileExist(string cardId); + Delegate DoesProfileExist { get; } + } \ No newline at end of file diff --git a/Abstractions/Services/ICardService.cs b/Abstractions/Services/ICardService.cs index d3fd639..42f04f4 100644 --- a/Abstractions/Services/ICardService.cs +++ b/Abstractions/Services/ICardService.cs @@ -11,6 +11,7 @@ namespace Abstractions.Services string ConvertKonamiIdToUid(string konamiId); Task FindByKonamiId(string konamiId); Task FindByCardId(string cardId); + Task FindById(int parse); Task Exists(string konamiId); Task ValidatePinAsync(string konamiId, string pin); Task IsRegistered(string konamiId, string pin); diff --git a/Core/Client/vite.config.ts.timestamp-1785685443847-31652281ff39.mjs b/Core/Client/vite.config.ts.timestamp-1785685443847-31652281ff39.mjs new file mode 100644 index 0000000..863f630 --- /dev/null +++ b/Core/Client/vite.config.ts.timestamp-1785685443847-31652281ff39.mjs @@ -0,0 +1,56 @@ +// vite.config.ts +import { fileURLToPath, URL } from "node:url"; +import { defineConfig } from "file:///home/thatzokay/Projects/csharp/Medusa.net/Core/Client/node_modules/vite/dist/node/index.js"; +import plugin from "file:///home/thatzokay/Projects/csharp/Medusa.net/Core/Client/node_modules/@vitejs/plugin-vue/dist/index.mjs"; +import fs from "fs"; +import path from "path"; +import child_process from "child_process"; +import { env } from "process"; +import tailwindcss from "file:///home/thatzokay/Projects/csharp/Medusa.net/Core/Client/node_modules/@tailwindcss/vite/dist/index.mjs"; +import Layouts from "file:///home/thatzokay/Projects/csharp/Medusa.net/Core/Client/node_modules/vite-plugin-vue-layouts-next/dist/index.js"; +import VueRouter from "file:///home/thatzokay/Projects/csharp/Medusa.net/Core/Client/node_modules/unplugin-vue-router/dist/vite.js"; +var __vite_injected_original_import_meta_url = "file:///home/thatzokay/Projects/csharp/Medusa.net/Core/Client/vite.config.ts"; +var baseFolder = env.APPDATA !== void 0 && env.APPDATA !== "" ? `${env.APPDATA}/ASP.NET/https` : `${env.HOME}/.aspnet/https`; +fs.mkdirSync(baseFolder, { recursive: true }); +var certificateName = "core2.client"; +var certFilePath = path.join(baseFolder, `${certificateName}.pem`); +var keyFilePath = path.join(baseFolder, `${certificateName}.key`); +if (!fs.existsSync(certFilePath) || !fs.existsSync(keyFilePath)) { + if (0 !== child_process.spawnSync("dotnet", [ + "dev-certs", + "https", + "--export-path", + certFilePath, + "--format", + "Pem", + "--no-password" + ], { stdio: "inherit" }).status) { + throw new Error("Could not create certificate."); + } +} +var target = env.ASPNETCORE_HTTPS_PORT ? `https://localhost:${env.ASPNETCORE_HTTPS_PORT}` : env.ASPNETCORE_URLS ? env.ASPNETCORE_URLS.split(";")[0] : "https://localhost:7059"; +var vite_config_default = defineConfig({ + plugins: [VueRouter({}), tailwindcss(), plugin(), Layouts()], + resolve: { + alias: { + "@": fileURLToPath(new URL("./src", __vite_injected_original_import_meta_url)) + } + }, + server: { + proxy: { + "^/api": { + target, + secure: false + } + }, + port: 5173, + https: { + key: fs.readFileSync(keyFilePath), + cert: fs.readFileSync(certFilePath) + } + } +}); +export { + vite_config_default as default +}; +//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsidml0ZS5jb25maWcudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImNvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9kaXJuYW1lID0gXCIvaG9tZS90aGF0em9rYXkvUHJvamVjdHMvY3NoYXJwL01lZHVzYS5uZXQvQ29yZS9DbGllbnRcIjtjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfZmlsZW5hbWUgPSBcIi9ob21lL3RoYXR6b2theS9Qcm9qZWN0cy9jc2hhcnAvTWVkdXNhLm5ldC9Db3JlL0NsaWVudC92aXRlLmNvbmZpZy50c1wiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9pbXBvcnRfbWV0YV91cmwgPSBcImZpbGU6Ly8vaG9tZS90aGF0em9rYXkvUHJvamVjdHMvY3NoYXJwL01lZHVzYS5uZXQvQ29yZS9DbGllbnQvdml0ZS5jb25maWcudHNcIjtpbXBvcnQgeyBmaWxlVVJMVG9QYXRoLCBVUkwgfSBmcm9tICdub2RlOnVybCc7XG5pbXBvcnQgeyBkZWZpbmVDb25maWcgfSBmcm9tICd2aXRlJztcbmltcG9ydCBwbHVnaW4gZnJvbSAnQHZpdGVqcy9wbHVnaW4tdnVlJztcbmltcG9ydCBmcyBmcm9tICdmcyc7XG5pbXBvcnQgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCBjaGlsZF9wcm9jZXNzIGZyb20gJ2NoaWxkX3Byb2Nlc3MnO1xuaW1wb3J0IHsgZW52IH0gZnJvbSAncHJvY2Vzcyc7XG5pbXBvcnQgdGFpbHdpbmRjc3MgZnJvbSAnQHRhaWx3aW5kY3NzL3ZpdGUnXG5pbXBvcnQgTGF5b3V0cyBmcm9tICd2aXRlLXBsdWdpbi12dWUtbGF5b3V0cy1uZXh0J1xuaW1wb3J0IFZ1ZVJvdXRlciBmcm9tICd1bnBsdWdpbi12dWUtcm91dGVyL3ZpdGUnXG5cbmNvbnN0IGJhc2VGb2xkZXIgPVxuICAgIGVudi5BUFBEQVRBICE9PSB1bmRlZmluZWQgJiYgZW52LkFQUERBVEEgIT09ICcnXG4gICAgICAgID8gYCR7ZW52LkFQUERBVEF9L0FTUC5ORVQvaHR0cHNgXG4gICAgICAgIDogYCR7ZW52LkhPTUV9Ly5hc3BuZXQvaHR0cHNgO1xuXG5mcy5ta2RpclN5bmMoYmFzZUZvbGRlciwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG5cbmNvbnN0IGNlcnRpZmljYXRlTmFtZSA9IFwiY29yZTIuY2xpZW50XCI7XG5jb25zdCBjZXJ0RmlsZVBhdGggPSBwYXRoLmpvaW4oYmFzZUZvbGRlciwgYCR7Y2VydGlmaWNhdGVOYW1lfS5wZW1gKTtcbmNvbnN0IGtleUZpbGVQYXRoID0gcGF0aC5qb2luKGJhc2VGb2xkZXIsIGAke2NlcnRpZmljYXRlTmFtZX0ua2V5YCk7XG5cbmlmICghZnMuZXhpc3RzU3luYyhjZXJ0RmlsZVBhdGgpIHx8ICFmcy5leGlzdHNTeW5jKGtleUZpbGVQYXRoKSkge1xuICAgIGlmICgwICE9PSBjaGlsZF9wcm9jZXNzLnNwYXduU3luYygnZG90bmV0JywgW1xuICAgICAgICAnZGV2LWNlcnRzJyxcbiAgICAgICAgJ2h0dHBzJyxcbiAgICAgICAgJy0tZXhwb3J0LXBhdGgnLFxuICAgICAgICBjZXJ0RmlsZVBhdGgsXG4gICAgICAgICctLWZvcm1hdCcsXG4gICAgICAgICdQZW0nLFxuICAgICAgICAnLS1uby1wYXNzd29yZCcsXG4gICAgXSwgeyBzdGRpbzogJ2luaGVyaXQnLCB9KS5zdGF0dXMpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ291bGQgbm90IGNyZWF0ZSBjZXJ0aWZpY2F0ZS5cIik7XG4gICAgfVxufVxuXG5jb25zdCB0YXJnZXQgPSBlbnYuQVNQTkVUQ09SRV9IVFRQU19QT1JUID8gYGh0dHBzOi8vbG9jYWxob3N0OiR7ZW52LkFTUE5FVENPUkVfSFRUUFNfUE9SVH1gIDpcbiAgICBlbnYuQVNQTkVUQ09SRV9VUkxTID8gZW52LkFTUE5FVENPUkVfVVJMUy5zcGxpdCgnOycpWzBdIDogJ2h0dHBzOi8vbG9jYWxob3N0OjcwNTknO1xuXG4vLyBodHRwczovL3ZpdGVqcy5kZXYvY29uZmlnL1xuZXhwb3J0IGRlZmF1bHQgZGVmaW5lQ29uZmlnKHtcbiAgICBwbHVnaW5zOiBbVnVlUm91dGVyKHt9KSwgdGFpbHdpbmRjc3MoKSwgcGx1Z2luKCksIExheW91dHMoKV0sXG4gICAgcmVzb2x2ZToge1xuICAgICAgICBhbGlhczoge1xuICAgICAgICAgICAgJ0AnOiBmaWxlVVJMVG9QYXRoKG5ldyBVUkwoJy4vc3JjJywgaW1wb3J0Lm1ldGEudXJsKSlcbiAgICAgICAgfVxuICAgIH0sXG4gICAgc2VydmVyOiB7XG4gICAgICAgIHByb3h5OiB7XG4gICAgICAgICAgICAnXi9hcGknOiB7XG4gICAgICAgICAgICAgICAgdGFyZ2V0LFxuICAgICAgICAgICAgICAgIHNlY3VyZTogZmFsc2VcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICAgIHBvcnQ6IDUxNzMsXG4gICAgICAgIGh0dHBzOiB7XG4gICAgICAgICAgICBrZXk6IGZzLnJlYWRGaWxlU3luYyhrZXlGaWxlUGF0aCksXG4gICAgICAgICAgICBjZXJ0OiBmcy5yZWFkRmlsZVN5bmMoY2VydEZpbGVQYXRoKSxcbiAgICAgICAgfVxuICAgIH1cbn0pXG4iXSwKICAibWFwcGluZ3MiOiAiO0FBQW9WLFNBQVMsZUFBZSxXQUFXO0FBQ3ZYLFNBQVMsb0JBQW9CO0FBQzdCLE9BQU8sWUFBWTtBQUNuQixPQUFPLFFBQVE7QUFDZixPQUFPLFVBQVU7QUFDakIsT0FBTyxtQkFBbUI7QUFDMUIsU0FBUyxXQUFXO0FBQ3BCLE9BQU8saUJBQWlCO0FBQ3hCLE9BQU8sYUFBYTtBQUNwQixPQUFPLGVBQWU7QUFUOEwsSUFBTSwyQ0FBMkM7QUFXclEsSUFBTSxhQUNGLElBQUksWUFBWSxVQUFhLElBQUksWUFBWSxLQUN2QyxHQUFHLElBQUksT0FBTyxtQkFDZCxHQUFHLElBQUksSUFBSTtBQUVyQixHQUFHLFVBQVUsWUFBWSxFQUFFLFdBQVcsS0FBSyxDQUFDO0FBRTVDLElBQU0sa0JBQWtCO0FBQ3hCLElBQU0sZUFBZSxLQUFLLEtBQUssWUFBWSxHQUFHLGVBQWUsTUFBTTtBQUNuRSxJQUFNLGNBQWMsS0FBSyxLQUFLLFlBQVksR0FBRyxlQUFlLE1BQU07QUFFbEUsSUFBSSxDQUFDLEdBQUcsV0FBVyxZQUFZLEtBQUssQ0FBQyxHQUFHLFdBQVcsV0FBVyxHQUFHO0FBQzdELE1BQUksTUFBTSxjQUFjLFVBQVUsVUFBVTtBQUFBLElBQ3hDO0FBQUEsSUFDQTtBQUFBLElBQ0E7QUFBQSxJQUNBO0FBQUEsSUFDQTtBQUFBLElBQ0E7QUFBQSxJQUNBO0FBQUEsRUFDSixHQUFHLEVBQUUsT0FBTyxVQUFXLENBQUMsRUFBRSxRQUFRO0FBQzlCLFVBQU0sSUFBSSxNQUFNLCtCQUErQjtBQUFBLEVBQ25EO0FBQ0o7QUFFQSxJQUFNLFNBQVMsSUFBSSx3QkFBd0IscUJBQXFCLElBQUkscUJBQXFCLEtBQ3JGLElBQUksa0JBQWtCLElBQUksZ0JBQWdCLE1BQU0sR0FBRyxFQUFFLENBQUMsSUFBSTtBQUc5RCxJQUFPLHNCQUFRLGFBQWE7QUFBQSxFQUN4QixTQUFTLENBQUMsVUFBVSxDQUFDLENBQUMsR0FBRyxZQUFZLEdBQUcsT0FBTyxHQUFHLFFBQVEsQ0FBQztBQUFBLEVBQzNELFNBQVM7QUFBQSxJQUNMLE9BQU87QUFBQSxNQUNILEtBQUssY0FBYyxJQUFJLElBQUksU0FBUyx3Q0FBZSxDQUFDO0FBQUEsSUFDeEQ7QUFBQSxFQUNKO0FBQUEsRUFDQSxRQUFRO0FBQUEsSUFDSixPQUFPO0FBQUEsTUFDSCxTQUFTO0FBQUEsUUFDTDtBQUFBLFFBQ0EsUUFBUTtBQUFBLE1BQ1o7QUFBQSxJQUNKO0FBQUEsSUFDQSxNQUFNO0FBQUEsSUFDTixPQUFPO0FBQUEsTUFDSCxLQUFLLEdBQUcsYUFBYSxXQUFXO0FBQUEsTUFDaEMsTUFBTSxHQUFHLGFBQWEsWUFBWTtBQUFBLElBQ3RDO0FBQUEsRUFDSjtBQUNKLENBQUM7IiwKICAibmFtZXMiOiBbXQp9Cg== diff --git a/Core/Server/Handlers/Common/Card/AuthPassCardManegementHandler.cs b/Core/Server/Handlers/Common/Card/AuthPassCardManegementHandler.cs index 5afa11e..8354e29 100644 --- a/Core/Server/Handlers/Common/Card/AuthPassCardManegementHandler.cs +++ b/Core/Server/Handlers/Common/Card/AuthPassCardManegementHandler.cs @@ -18,7 +18,9 @@ public class AuthPassCardManegementHandler(ICardService cardService) : Handler HandleAsync(AuthPassRequest req, string model) { var status = 0; - var card = await cardService.FindByKonamiId(req.ReferenceId); + + var id = req.ReferenceId.TrimStart(); + var card = await cardService.FindById(int.Parse(id)!); if (card is null) { diff --git a/Core/Server/Handlers/Common/Card/BindModelCardManagementHandler.cs b/Core/Server/Handlers/Common/Card/BindModelCardManagementHandler.cs index 5d2b0cc..9aa4bde 100644 --- a/Core/Server/Handlers/Common/Card/BindModelCardManagementHandler.cs +++ b/Core/Server/Handlers/Common/Card/BindModelCardManagementHandler.cs @@ -1,21 +1,23 @@ using System.Xml.Linq; using Abstractions.Handlers; +using Server.Models.Request; using Server.Models.Response; namespace Server.Handlers.Common.Card; -public class BindModelCardManagementHandler : HandlerWithoutRequest +public class BindModelCardManagementHandler : Handler { public override void Configure() { Module("cardmng"); Method("bindmodel"); } - public override BindModelResponse Handle(string model) + public override BindModelResponse Handle(BindModelRequest req, string model) { var bindModel = new BindModelResponse() { - Status = 0 + Status = 0, + DataId = req.ReferenceId }; return bindModel; } diff --git a/Core/Server/Handlers/Common/Card/GetRefIdCardManagementHandler.cs b/Core/Server/Handlers/Common/Card/GetRefIdCardManagementHandler.cs index d2d992e..50f51e0 100644 --- a/Core/Server/Handlers/Common/Card/GetRefIdCardManagementHandler.cs +++ b/Core/Server/Handlers/Common/Card/GetRefIdCardManagementHandler.cs @@ -28,8 +28,8 @@ public class GetRefIdCardManagementHandler(ICardService cardService, UserManager var getRefId = new GetRefIdResponse() { Status = 0, - DataId = konamiId, - ReferenceId = konamiId + DataId = card.RawId, + ReferenceId = user.Id.ToString() }; return getRefId; diff --git a/Core/Server/Handlers/Common/Card/GnInquire.cs b/Core/Server/Handlers/Common/Card/GnInquire.cs new file mode 100644 index 0000000..d6d3a7d --- /dev/null +++ b/Core/Server/Handlers/Common/Card/GnInquire.cs @@ -0,0 +1,31 @@ +using Abstractions.Handlers; +using System.Xml.Linq; + +namespace Server.Handlers.Common.Card; + +public class GnInquire : HandlerWithoutRequest +{ + public override void Configure() + { + Module("cardmng"); + Method("gninquire"); + } + + public override XDocument Handle(string model) { + var response = new XDocument( + new XElement("response", + new XElement("status", "0"), + new XElement("data", + new XElement("inquire", + new XElement("card", + new XElement("cardid", "1234567890123456"), + new XElement("konamiid", "KONAMI123456"), + new XElement("profileexists", "1") + ) + ) + ) + ) + ); + return response; + } +} diff --git a/Core/Server/Handlers/Common/Card/GnInquireCardManagementHandler.cs b/Core/Server/Handlers/Common/Card/GnInquireCardManagementHandler.cs index df7bc2f..28b323f 100644 --- a/Core/Server/Handlers/Common/Card/GnInquireCardManagementHandler.cs +++ b/Core/Server/Handlers/Common/Card/GnInquireCardManagementHandler.cs @@ -56,7 +56,7 @@ namespace Server.Handlers.Common.Card return inquireResponse; } - var profileExists = await plugin!.DoesProfileExist(cardId); + var profileExists = await pluginService.DoesProfileExistAsync(plugin, cardId); var userIdFlag = profileExists ? "1" : "0"; var extIdFlag = profileExists ? "1" : "0"; diff --git a/Core/Server/Handlers/Common/Card/InquireCardManagementHandler.cs b/Core/Server/Handlers/Common/Card/InquireCardManagementHandler.cs index a690094..0bf23f4 100644 --- a/Core/Server/Handlers/Common/Card/InquireCardManagementHandler.cs +++ b/Core/Server/Handlers/Common/Card/InquireCardManagementHandler.cs @@ -55,9 +55,9 @@ public class InquireCardManagementHandler(IPluginService pluginService, ICardSer inquireResponse.Status = 113; return inquireResponse; } - - var profileExists = await plugin!.DoesProfileExist(cardId); - + + var profileExists = await pluginService.DoesProfileExistAsync(plugin, cardId); + var userIdFlag = profileExists ? "1" : "0"; var extIdFlag = profileExists ? "1" : "0"; var newFlag = profileExists ? "0" : "1"; @@ -68,8 +68,9 @@ public class InquireCardManagementHandler(IPluginService pluginService, ICardSer inquireResponse.Expired = 0; inquireResponse.NewFlag = newFlag; inquireResponse.ExtidFlag = extIdFlag; - inquireResponse.RefId = konamiId; + inquireResponse.RefId = exisitngCard.Id.ToString().PadLeft(16, '0'); inquireResponse.UserIdFlag = userIdFlag; + inquireResponse.Pcode = konamiId; return inquireResponse; } diff --git a/Core/Server/Models/Request/BindModelRequest.cs b/Core/Server/Models/Request/BindModelRequest.cs new file mode 100644 index 0000000..c759fa9 --- /dev/null +++ b/Core/Server/Models/Request/BindModelRequest.cs @@ -0,0 +1,13 @@ +using System.Xml.Serialization; + +namespace Server.Models.Request; + +[XmlRoot("cardmng")] +public class BindModelRequest +{ + [XmlAttribute("newflag")] + public bool NewFlag { get; set; } + + [XmlAttribute("refid")] + public required string ReferenceId { get; set; } +} \ No newline at end of file diff --git a/Core/Server/Models/Response/BindModelResponse.cs b/Core/Server/Models/Response/BindModelResponse.cs index fe7c433..d6a2589 100644 --- a/Core/Server/Models/Response/BindModelResponse.cs +++ b/Core/Server/Models/Response/BindModelResponse.cs @@ -8,4 +8,7 @@ public class BindModelResponse { [XmlAttribute("status")] public required int Status { get; set; } + + [XmlAttribute("dataid")] + public required string DataId { get; set; } } \ No newline at end of file diff --git a/Core/Server/Models/Response/InquireResponse.cs b/Core/Server/Models/Response/InquireResponse.cs index b729729..052328e 100644 --- a/Core/Server/Models/Response/InquireResponse.cs +++ b/Core/Server/Models/Response/InquireResponse.cs @@ -32,4 +32,7 @@ public class InquireResponse [XmlAttribute("useridflag")] public string UserIdFlag { get; set; } = ""; + + [XmlAttribute("pcode")] + public string Pcode { get; set; } = ""; } \ No newline at end of file diff --git a/Core/Server/Program.cs b/Core/Server/Program.cs index e4958e0..9c69d66 100644 --- a/Core/Server/Program.cs +++ b/Core/Server/Program.cs @@ -75,6 +75,8 @@ builder.Services.AddSingleton(); var app = builder.Build(); +pluginService.SetServiceProvider(app.Services); + app.Lifetime.ApplicationStarted.Register(() => { var serverAddresses = app.Services.GetRequiredService() diff --git a/Core/Server/Services/CardService.cs b/Core/Server/Services/CardService.cs index 65a32b9..41fcb2b 100644 --- a/Core/Server/Services/CardService.cs +++ b/Core/Server/Services/CardService.cs @@ -204,6 +204,11 @@ public class CardService : ICardService return _context.Cards.Include(x => x.User).FirstOrDefaultAsync(c => c.RawId == cardId); } + public Task FindById(int id) + { + return _context.Cards.Include(c => c.User).FirstOrDefaultAsync(x => x.Id == id); + } + public Task Exists(string konamiId) { return _context.Cards.AnyAsync(c => c.KonamiId == konamiId); diff --git a/Core/Server/Services/IPluginService.cs b/Core/Server/Services/IPluginService.cs index 415c85e..525f08a 100644 --- a/Core/Server/Services/IPluginService.cs +++ b/Core/Server/Services/IPluginService.cs @@ -8,4 +8,5 @@ public interface IPluginService void RegisterPlugins(); List GetPlugins(); IMedusaPlugin? FindPlugin(string gameCode, int? minVer = null, int? maxVer = null); + Task DoesProfileExistAsync(IMedusaPlugin plugin, string cardId); } \ No newline at end of file diff --git a/Core/Server/Services/PluginService.cs b/Core/Server/Services/PluginService.cs index 9663523..f8853f7 100644 --- a/Core/Server/Services/PluginService.cs +++ b/Core/Server/Services/PluginService.cs @@ -1,6 +1,7 @@ using System.Diagnostics; using System.Reflection; using Abstractions; +using Microsoft.AspNetCore.Mvc; namespace Server.Services; @@ -8,6 +9,12 @@ public class PluginService(ILogger logger) : IPluginService { private List Plugins { get; } = []; private readonly string _pluginPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "plugins") ; + private IServiceProvider? _serviceProvider; + + public void SetServiceProvider(IServiceProvider serviceProvider) + { + _serviceProvider = serviceProvider; + } public void AddPlugin(IMedusaPlugin plugin) { @@ -79,4 +86,25 @@ public class PluginService(ILogger logger) : IPluginService foundPlugins = foundPlugins.Where(x => x.MaxVer >= maxVer); return foundPlugins.FirstOrDefault(); } + + public async Task DoesProfileExistAsync(IMedusaPlugin plugin, string cardId) + { + if (_serviceProvider is null) + throw new InvalidOperationException("PluginService has not been initialized with a service provider yet."); + + var method = plugin.DoesProfileExist; + var parameters = method.Method.GetParameters(); + + using var scope = _serviceProvider.CreateScope(); + + var args = parameters.Select(p => + { + if (p.Name == "cardId") return (object)cardId; + var isFromServices = p.GetCustomAttribute() != null; + if (isFromServices) return scope.ServiceProvider.GetRequiredService(p.ParameterType); + throw new InvalidOperationException($"Don't know how to resolve parameter '{p.Name}' on plugin delegate DoesProfileExist"); + }).ToArray(); + + return await (Task)method.DynamicInvoke(args)!; + } } \ No newline at end of file