diff --git a/Abstractions/SerializationTypes/XrpcIp4.cs b/Abstractions/SerializationTypes/XrpcIp4.cs new file mode 100644 index 0000000..e2449a1 --- /dev/null +++ b/Abstractions/SerializationTypes/XrpcIp4.cs @@ -0,0 +1,12 @@ +using System.Xml.Serialization; + +namespace Abstractions.SerializationTypes; + +public struct XrpcIp4(string value) +{ + [XmlAttribute("__type")] + public string Type { get; set; } = "ip4"; + + [XmlText] + public string Value { get; set; } = value; +} \ No newline at end of file diff --git a/Abstractions/SerializationTypes/XrpcLong.cs b/Abstractions/SerializationTypes/XrpcLong.cs index 5a52f93..1675325 100644 --- a/Abstractions/SerializationTypes/XrpcLong.cs +++ b/Abstractions/SerializationTypes/XrpcLong.cs @@ -2,11 +2,29 @@ using System.Xml.Serialization; namespace Abstractions.SerializationTypes; -public struct XrpcLong(long value) +public struct XrpcLong { [XmlAttribute("__type")] - public string Type { get; set; } = "s64"; - + public string Type { get; set; } + [XmlText] - public long Value { get; set; } = value; + public long Value { get; set; } + + public XrpcLong(byte value) + { + Value = value; + Type = "s8"; + } + + public XrpcLong(short value) + { + Value = value; + Type = "s16"; + } + + public XrpcLong(long value) + { + Value = value; + Type = "s32"; + } } \ No newline at end of file diff --git a/Abstractions/SerializationTypes/XrpcULong.cs b/Abstractions/SerializationTypes/XrpcULong.cs index f02670c..b9cafb5 100644 --- a/Abstractions/SerializationTypes/XrpcULong.cs +++ b/Abstractions/SerializationTypes/XrpcULong.cs @@ -2,10 +2,29 @@ using System.Xml.Serialization; namespace Abstractions.SerializationTypes; -public struct XrpcULong(ulong value) +public struct XrpcULong { [XmlAttribute("__type")] - public string Type { get; set; } = "u64"; + public string Type { get; set; } - [XmlText] public ulong Value { get; set; } = value; + [XmlText] + public ulong Value { get; set; } + + public XrpcULong(byte value) + { + Value = value; + Type = "u8"; + } + + public XrpcULong(ushort value) + { + Value = value; + Type = "u16"; + } + + public XrpcULong(ulong value) + { + Value = value; + Type = "u32"; + } } \ No newline at end of file diff --git a/Core/Client/package-lock.json b/Core/Client/package-lock.json index e7e5705..544eb69 100644 --- a/Core/Client/package-lock.json +++ b/Core/Client/package-lock.json @@ -1321,7 +1321,6 @@ "integrity": "sha512-0JOXkRyLanfGPE2QRCwgxhzlBAvaRdCNMcvbd7jFfpmD4eEXll7LRwy5ymJmyeZqk7Nh7eD2LeUyQ68BbndmXw==", "devOptional": true, "license": "MIT", - "peer": true, "dependencies": { "undici-types": "~6.19.2" } @@ -1366,7 +1365,6 @@ "integrity": "sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==", "dev": true, "license": "BSD-2-Clause", - "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "7.18.0", "@typescript-eslint/types": "7.18.0", @@ -1849,7 +1847,6 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -2407,7 +2404,6 @@ "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -2464,7 +2460,6 @@ "integrity": "sha512-b/Y05HYmnB/32wqVcjxjHZzNpwxj1onBOvqW89W+V+XNG1dRuaFbNd3vT9CLbr2LXjEoq+3vn8DanWf7XU22Ug==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "globals": "^13.24.0", @@ -4452,8 +4447,7 @@ "version": "4.1.11", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.11.tgz", "integrity": "sha512-2E9TBm6MDD/xKYe+dvJZAmg3yxIEDNRc0jwlNyDg/4Fil2QcSLjFKGVff0lAf1jjeaArlG/M75Ey/EYr/OJtBA==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/tailwindcss-primeui": { "version": "0.6.1", @@ -4566,7 +4560,6 @@ "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", "devOptional": true, "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -4739,7 +4732,6 @@ "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.11.tgz", "integrity": "sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==", "license": "MIT", - "peer": true, "dependencies": { "esbuild": "^0.21.3", "postcss": "^8.4.43", @@ -4821,7 +4813,6 @@ "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.13.tgz", "integrity": "sha512-wmeiSMxkZCSc+PM2w2VRsOYAZC8GdipNFRTsLSfodVqI9mbejKeXEGr8SckuLnrQPGe3oJN5c3K0vpoU9q/wCQ==", "license": "MIT", - "peer": true, "dependencies": { "@vue/compiler-dom": "3.5.13", "@vue/compiler-sfc": "3.5.13", @@ -4868,7 +4859,6 @@ "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.5.1.tgz", "integrity": "sha512-ogAF3P97NPm8fJsE4by9dwSYtDwXIY1nFY9T6DyQnGHd1E2Da94w9JIolpe42LJGIl0DwOHBi8TcRPlPGwbTtw==", "license": "MIT", - "peer": true, "dependencies": { "@vue/devtools-api": "^6.6.4" }, diff --git a/Core/Server/Handlers/Boot/GetServicesHandler.cs b/Core/Server/Handlers/Boot/GetServicesHandler.cs index 4476635..80deed0 100644 --- a/Core/Server/Handlers/Boot/GetServicesHandler.cs +++ b/Core/Server/Handlers/Boot/GetServicesHandler.cs @@ -1,7 +1,6 @@ using Microsoft.AspNetCore.Hosting.Server; using System.Xml.Linq; using Abstractions.Handlers; -using Abstractions.SerializationTypes; using Abstractions.Utils; using Server.Models.Response; @@ -28,7 +27,7 @@ namespace Server.Handlers.Boot private static GetServicesResponse CreateCoreServicesElement() { var services = new GetServicesResponse() - { + { Expire = 3600, Method = "get", Mode = "operation", diff --git a/Core/Server/Handlers/Common/Card/GnInquireCardManagementHandler.cs b/Core/Server/Handlers/Common/Card/GnInquireCardManagementHandler.cs new file mode 100644 index 0000000..df7bc2f --- /dev/null +++ b/Core/Server/Handlers/Common/Card/GnInquireCardManagementHandler.cs @@ -0,0 +1,79 @@ +using Abstractions.Handlers; +using Abstractions.Services; +using Server.Models.Request; +using Server.Models.Response; +using Server.Services; + +namespace Server.Handlers.Common.Card +{ + public class GnInquireCardManagementHandler(IPluginService pluginService, ICardService cardService) : Handler + { + public override void Configure() + { + Module("cardmng"); + Method("gninquire"); + } + + public override async Task HandleAsync(InquireRequest req, string model) + { + var splitModel = model.Split(':'); + var gameCode = splitModel[0]; + + var plugin = pluginService.FindPlugin(gameCode); + + var cardId = req.CardId; + + var inquireResponse = new GnInquireResponse() + { + Status = 0 + }; + + if (string.IsNullOrEmpty(cardId)) + { + inquireResponse.Status = 111; + return inquireResponse; + } + + var konamiId = cardService.ConvertUidToKonamiId(cardId); + + if (string.IsNullOrEmpty(konamiId)) + { + inquireResponse.Status = 111; + return inquireResponse; + } + + var exisitngCard = await cardService.FindByKonamiId(konamiId); + + if (exisitngCard == null) + { + inquireResponse.Status = 112; + return inquireResponse; + } + + if (plugin is null) + { + inquireResponse.Status = 113; + return inquireResponse; + } + + var profileExists = await plugin!.DoesProfileExist(cardId); + + var userIdFlag = profileExists ? "1" : "0"; + var extIdFlag = profileExists ? "1" : "0"; + var newFlag = profileExists ? "0" : "1"; + var isGeniune = profileExists ? "1" : "0"; + + inquireResponse.Binded = 0; + inquireResponse.DataId = konamiId; + inquireResponse.EcFlag = 1; + inquireResponse.Expired = 0; + inquireResponse.NewFlag = newFlag; + inquireResponse.IsGeniune = isGeniune; + inquireResponse.ExtidFlag = extIdFlag; + inquireResponse.RefId = konamiId; + inquireResponse.UserIdFlag = userIdFlag; + + return inquireResponse; + } + } +} diff --git a/Core/Server/Handlers/Common/GetFacilityHandler.cs b/Core/Server/Handlers/Common/GetFacilityHandler.cs index d8b1b10..2d5ecf3 100644 --- a/Core/Server/Handlers/Common/GetFacilityHandler.cs +++ b/Core/Server/Handlers/Common/GetFacilityHandler.cs @@ -20,7 +20,7 @@ public class GetFacilityHandler: HandlerWithoutRequest Location = new FacilityLocation() { Id = new XrpcString("00000000"), - Country = new XrpcString("US"), + Country = new XrpcString("JP"), Region = new XrpcString("NA"), Name = new XrpcString("Medusa"), Type = new XrpcULong(0) @@ -32,7 +32,7 @@ public class GetFacilityHandler: HandlerWithoutRequest }, PortForward = new FacilityPortForward() { - GlobalIp = new XrpcString("127.0.0.1"), + GlobalIp = new XrpcIp4("127.0.0.1"), GlobalPort = new XrpcULong(5246), PrivatePort = new XrpcULong(5246) }, @@ -40,16 +40,16 @@ public class GetFacilityHandler: HandlerWithoutRequest { Flag = new XrpcULong(1), Name = new XrpcString("Medusa"), - Latitude = new XrpcString("0.0"), - Longitude = new XrpcString("0.0") + Latitude = new XrpcString("0"), + Longitude = new XrpcString("0") }, Share = new FacilityShare() { EaCoin = new FacilityEaCoin() { - NotchAmount = new XrpcLong(3000), - NotchCount = new XrpcLong(3), - SupplyLimit = new XrpcLong(100000) + NotchAmount = new XrpcLong((long)3000), + NotchCount = new XrpcLong((long)3), + SupplyLimit = new XrpcLong(1000000) }, Url = new FacilityUrl() { diff --git a/Core/Server/Handlers/Common/OTAUpdates/ListPackageHandler.cs b/Core/Server/Handlers/Common/OTAUpdates/ListPackageHandler.cs index 02b977d..9eafef6 100644 --- a/Core/Server/Handlers/Common/OTAUpdates/ListPackageHandler.cs +++ b/Core/Server/Handlers/Common/OTAUpdates/ListPackageHandler.cs @@ -15,6 +15,7 @@ public class ListPackageHandler: HandlerWithoutRequest { var package = new ListPackageResponse() { + Expire = 1200, Status = 0 }; diff --git a/Core/Server/Models/Response/GetFacilityResponse.cs b/Core/Server/Models/Response/GetFacilityResponse.cs index 30feedb..59ab685 100644 --- a/Core/Server/Models/Response/GetFacilityResponse.cs +++ b/Core/Server/Models/Response/GetFacilityResponse.cs @@ -9,7 +9,7 @@ public class GetFacilityResponse { [XmlAttribute("status")] public required int Status { get; set; } - + [XmlElement("location")] public required FacilityLocation Location { get; set; } @@ -56,7 +56,7 @@ public record FacilityLine public record FacilityPortForward { [XmlElement("globalip")] - public required XrpcString GlobalIp { get; set; } + public required XrpcIp4 GlobalIp { get; set; } [XmlElement("globalport")] public required XrpcULong GlobalPort { get; set; } diff --git a/Core/Server/Models/Response/GetMessageResponse.cs b/Core/Server/Models/Response/GetMessageResponse.cs index 49c69bb..b7fbdbf 100644 --- a/Core/Server/Models/Response/GetMessageResponse.cs +++ b/Core/Server/Models/Response/GetMessageResponse.cs @@ -7,7 +7,7 @@ namespace Server.Models.Response; public class GetMessageResponse { [XmlAttribute("status")] - public required int Status { get; set; } + public required int Status { get; set; } [XmlAttribute("expire")] public required int Expire { get; set; } diff --git a/Core/Server/Models/Response/GetServicesResponse.cs b/Core/Server/Models/Response/GetServicesResponse.cs index 6d91d52..7e0fbe9 100644 --- a/Core/Server/Models/Response/GetServicesResponse.cs +++ b/Core/Server/Models/Response/GetServicesResponse.cs @@ -10,8 +10,8 @@ public class GetServicesResponse public int Expire { get; set; } [XmlAttribute("method")] - public required string Method { get; set; } - + public required string Method { get; set; } + [XmlAttribute("mode")] public required string Mode { get; set; } diff --git a/Core/Server/Models/Response/GnInquireResponse.cs b/Core/Server/Models/Response/GnInquireResponse.cs new file mode 100644 index 0000000..b0122bd --- /dev/null +++ b/Core/Server/Models/Response/GnInquireResponse.cs @@ -0,0 +1,45 @@ +using System.Xml.Serialization; + +namespace Server.Models.Response; + +[XmlRoot("cardmng")] +[Serializable] +public class GnInquireResponse +{ + [XmlAttribute("status")] + public required int Status { get; set; } + + [XmlAttribute("binded")] + public int Binded { get; set; } + + [XmlAttribute("dataid")] + public string DataId { get; set; } = ""; + + [XmlAttribute("ecflag")] + public int EcFlag { get; set; } + + [XmlAttribute("expired")] + public int Expired { get; set; } + + [XmlAttribute("newflag")] + public string NewFlag { get; set; } = ""; + + [XmlAttribute("isgenuine")] + public string IsGeniune { get; set; } = ""; + + + [XmlAttribute("altstatus")] + public string AltStatus { get; set; } = ""; + + [XmlAttribute("articleno")] + public string ArticleNo { get; set; } = ""; + + [XmlAttribute("extidflag")] + public string ExtidFlag { get; set; } = ""; + + [XmlAttribute("refid")] + public string RefId { get; set; } = ""; + + [XmlAttribute("useridflag")] + public string UserIdFlag { get; set; } = ""; +} \ No newline at end of file diff --git a/Core/Server/Models/Response/ListPackageResponse.cs b/Core/Server/Models/Response/ListPackageResponse.cs index 353a805..50f3eeb 100644 --- a/Core/Server/Models/Response/ListPackageResponse.cs +++ b/Core/Server/Models/Response/ListPackageResponse.cs @@ -7,5 +7,8 @@ namespace Server.Models.Response; public class ListPackageResponse { [XmlAttribute("status")] - public required int Status { get; set; } + public required int Status { get; set; } + + [XmlAttribute("expire")] + public required int Expire { get; set; } } \ No newline at end of file diff --git a/Core/Server/Program.cs b/Core/Server/Program.cs index 8d5e263..18658fc 100644 --- a/Core/Server/Program.cs +++ b/Core/Server/Program.cs @@ -21,6 +21,7 @@ using System.Net.NetworkInformation; using System.Net.Sockets; using System.Security.Cryptography; using System.Text; +using System.Xml; using System.Xml.Linq; var key = @@ -115,6 +116,7 @@ var eamuseGroup = app.MapGroup("eamuse"); eamuseGroup.MapPost("/{model}/{module}/{method}", async (string model, string module, string method, HttpContext httpContext, [FromServices] ILogger logger, [FromServices] IHandlerService handlerService, [FromServices] IPluginService pluginService) => { + Console.WriteLine(httpContext.Request.Headers.UserAgent); // Enable buffering to allow multiple reads of the request body httpContext.Request.EnableBuffering(); var body = ""; @@ -132,7 +134,7 @@ var eamuseGroup = app.MapGroup("eamuse"); var amusementRequest = new AmusementRequest() { Model = model, Module = module ?? "", Method = method ?? "" }; - var encoding = httpContext.Items["Encoding"]?.ToString() ?? "ShiftJIS"; + var encoding = httpContext.Items["Encoding"]?.ToString() ?? "SHIFT_JIS"; httpContext.Request.Headers.TryGetValue("IsEncoded", out var isEncoded); @@ -148,6 +150,7 @@ var eamuseGroup = app.MapGroup("eamuse"); eamuseGroup.MapPost("/{m}", async (string m, [FromQuery] string model, [FromQuery] string? module, [FromQuery] string? method, [FromQuery] string? f, HttpContext httpContext, [FromServices] ILogger logger, [FromServices] IHandlerService handlerService, [FromServices] IPluginService pluginService) => { + Console.WriteLine(httpContext.Request.Headers.UserAgent); // Enable buffering to allow multiple reads of the request body httpContext.Request.EnableBuffering(); var body = ""; @@ -172,7 +175,7 @@ var eamuseGroup = app.MapGroup("eamuse"); amusementRequest.Method = fParts[1]; } - var encoding = httpContext.Items["Encoding"]?.ToString() ?? "ShiftJIS"; + var encoding = httpContext.Items["Encoding"]?.ToString() ?? "SHIFT_JIS"; httpContext.Request.Headers.TryGetValue("IsEncoded", out var isEncoded); @@ -188,7 +191,7 @@ var eamuseGroup = app.MapGroup("eamuse"); eamuseGroup.MapPost("/", async ([FromQuery] string model, [FromQuery] string? module, [FromQuery] string? method, [FromQuery] string? f, HttpContext httpContext, [FromServices] ILogger logger, [FromServices] IHandlerService handlerService, [FromServices] IPluginService pluginService) => { - + Console.WriteLine(httpContext.Request.Headers.UserAgent); // Enable buffering to allow multiple reads of the request body httpContext.Request.EnableBuffering(); var body = ""; @@ -213,7 +216,7 @@ var eamuseGroup = app.MapGroup("eamuse"); amusementRequest.Method = fParts[1]; } - var encoding = httpContext.Items["Encoding"]?.ToString() ?? "ShiftJIS"; + var encoding = httpContext.Items["Encoding"]?.ToString() ?? "SHIFT_JIS"; httpContext.Request.Headers.TryGetValue("IsEncoded", out var isEncoded); @@ -226,6 +229,17 @@ var eamuseGroup = app.MapGroup("eamuse"); return TypedResults.Bytes(result, "application/octet-stream"); }); + app.MapFallbackToFile("/index.html"); + +await using var scope = app.Services.CreateAsyncScope(); + +var appDbContext = scope.ServiceProvider.GetRequiredService(); + +await appDbContext.Database.MigrateAsync(); + +app.Run(); +return; + async Task HandleEAmuseRequest(AmusementRequest request, string body, string info, bool compress, bool encrypt, bool isEncoded, string encoding, ILogger logger, IHandlerService handlerService, IPluginService pluginService) { logger.LogInformation("Handling {Module} {Method}", request.Module, request.Method); @@ -238,7 +252,7 @@ async Task HandleEAmuseRequest(AmusementRequest request, string body, st var responseXml = await handlerService.Handle(request.Model, request.Module, request.Method, document); var plugins = pluginService.GetPlugins(); - var forcedEncoding = plugins.FirstOrDefault(p => p.GameCode == request.Model)?.ForcedEncoding; + var forcedEncoding = plugins.FirstOrDefault(p => p.GameCode == request.Model.Split(":")[0])?.ForcedEncoding; var encodingEnum = encoding switch { @@ -293,14 +307,3 @@ async Task HandleEAmuseRequest(AmusementRequest request, string body, st return encodedBody; } -app.MapFallbackToFile("/index.html"); - -await using var scope = app.Services.CreateAsyncScope(); - -var appDbContext = scope.ServiceProvider.GetRequiredService(); - -await appDbContext.Database.MigrateAsync(); - -app.Run(); -return; - diff --git a/Core/Server/Services/HandlerService.cs b/Core/Server/Services/HandlerService.cs index 1b0ff3f..5d21eb7 100644 --- a/Core/Server/Services/HandlerService.cs +++ b/Core/Server/Services/HandlerService.cs @@ -1,4 +1,5 @@ using System.Reflection; +using System.Xml; using Server.Attributes; using System.Xml.Linq; using System.Xml.Serialization; @@ -211,7 +212,8 @@ public class HandlerService(IServiceScopeFactory serviceScopeFactory, ILogger