mirror of
https://gitea.tendokyu.moe/Kayori/Medusa.net.git
synced 2026-10-02 03:38:03 +03:00
Fix Sppass which uses GET instead of POST
This commit is contained in:
@@ -40,11 +40,7 @@ export class AuthenticationService {
|
||||
store.setRefreshToken(tokenResponse.refreshToken);
|
||||
store.setLoggedIn(true);
|
||||
|
||||
if (await UserService.GetUserClaims()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return await UserService.GetUserClaims();
|
||||
}
|
||||
|
||||
static async login(
|
||||
|
||||
@@ -45,17 +45,10 @@ public static class CardlessApi
|
||||
return TypedResults.BadRequest(new ApproveSessionResponse { Success = false, Message = "No card registered on this account yet." });
|
||||
}
|
||||
|
||||
// `cardType` has no value confirmed directly from sppass itself -
|
||||
// decompiling SOUND VOLTEX's sppass module only shows the client
|
||||
// requiring it be non-empty and parse as base-10, never comparing it
|
||||
// against a real value. "4" is borrowed from KAMUNITY.AvsTypes.CardType
|
||||
// (MCARD=0, ICCARD=1, FELICA=2, VIRTUAL=4), KONAMI's shared platform
|
||||
// card-type enum used identically by two other arcade titles' decompiled
|
||||
// C# (Polaris Chord, Chase Chase Jokers) - VIRTUAL is the platform's own
|
||||
// name for "no physical card," an exact semantic match for cardless
|
||||
// login. Not proven that sppass reuses this enum, so if the cabinet
|
||||
// rejects it, that's the first assumption to revisit.
|
||||
var approved = sessionService.TryApprove(token, "4", card.RawId);
|
||||
// Confirmed against decompiled Assembly-CSharp: CardEntryScene casts
|
||||
// sppass.lookup's card_type straight into (MCARD=0,
|
||||
// ICCARD=1, FELICA=2, VIRTUAL=4, CARDLESS=5) and sets Account.IsCardless=true
|
||||
var approved = sessionService.TryApprove(token, "5", card.RawId);
|
||||
|
||||
if (!approved)
|
||||
{
|
||||
|
||||
@@ -32,12 +32,12 @@ namespace Server.Handlers.Boot
|
||||
Mode = "operation",
|
||||
Status = 0
|
||||
};
|
||||
|
||||
|
||||
var coreServices = new string[]{
|
||||
"cardmng", "facility", "message", "numbering", "package", "pcbevent", "pcbtracker", "pkglist",
|
||||
"posevent", "userdata", "userid", "eacoin", "dlstatus", "netlog", "info", "reference", "sidmgr",
|
||||
"local", "local2", "lobby", "slocal", "slocal2", "sglocal", "sglocal2", "lab", "globby",
|
||||
"slobby", "sglobby", "eacharge"
|
||||
"slobby", "sglobby", "eacharge", "sppass"
|
||||
};
|
||||
|
||||
foreach(var service in coreServices)
|
||||
@@ -48,7 +48,7 @@ namespace Server.Handlers.Boot
|
||||
Url = $"{CommonUrl}/{service}"
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
services.Items.Add(new ServiceItem()
|
||||
{
|
||||
Name = "ntp",
|
||||
@@ -60,7 +60,7 @@ namespace Server.Handlers.Boot
|
||||
Name = "keepalive",
|
||||
Url = "http://127.0.0.1:8083/keepalive?pa=127.0.0.1&ia=127.0.0.1&ga=127.0.0.1&ma=127.0.0.1&t1=2&t2=10"
|
||||
});
|
||||
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
using Abstractions.Handlers;
|
||||
using Server.Models.Response;
|
||||
|
||||
namespace Server.Handlers.Common;
|
||||
|
||||
public class KeepAlivePcbTrackerHandler : HandlerWithoutRequest<KeepAlivePcbTrackerResponse>
|
||||
{
|
||||
public override void Configure()
|
||||
{
|
||||
Module("pcbtracker");
|
||||
Method("keepalive");
|
||||
}
|
||||
|
||||
public override KeepAlivePcbTrackerResponse Handle(GameModel model)
|
||||
{
|
||||
var pcbEvent = new KeepAlivePcbTrackerResponse()
|
||||
{
|
||||
Status = 0
|
||||
};
|
||||
|
||||
return pcbEvent;
|
||||
}
|
||||
}
|
||||
@@ -16,13 +16,22 @@ public class BodyParsingMiddleware(RequestDelegate next)
|
||||
|
||||
public async Task Invoke(HttpContext context)
|
||||
{
|
||||
if(context.Request.Method == "GET" || !context.Request.Path.ToString().Contains("eamuse", StringComparison.CurrentCultureIgnoreCase))
|
||||
var method = context.Request.Method;
|
||||
var path = context.Request.Path.ToString();
|
||||
|
||||
if (!(
|
||||
(method == "GET" && path.Contains("sppass", StringComparison.InvariantCultureIgnoreCase)) ||
|
||||
(method == "POST" && path.Contains("eamuse", StringComparison.InvariantCultureIgnoreCase))
|
||||
))
|
||||
{
|
||||
await _next(context);
|
||||
return;
|
||||
}
|
||||
|
||||
var body = await ParseRequest(context);
|
||||
var token = context.Request.Query["token"].ToString();
|
||||
var body = method == "GET" && !string.IsNullOrEmpty(token)
|
||||
? new XDocument(new XElement("call", new XElement("sppass", new XAttribute("token", token))))
|
||||
: await ParseRequest(context);
|
||||
|
||||
context.Items["Encoding"] = body.Declaration?.Encoding;
|
||||
var bodyString = body.ToString();
|
||||
@@ -41,10 +50,10 @@ public class BodyParsingMiddleware(RequestDelegate next)
|
||||
{
|
||||
var isCompressed = context.Request.Headers["X-Compress"].ToString().Contains("lz77");
|
||||
var info = context.Request.Headers["X-Eamuse-Info"].FirstOrDefault();
|
||||
var contentLength = context.Request.Headers.ContentLength ?? 0;
|
||||
var data = new byte[(int)contentLength];
|
||||
|
||||
await context.Request.Body.ReadExactlyAsync(data.AsMemory(0, (int)contentLength));
|
||||
using var bodyStream = new MemoryStream();
|
||||
await context.Request.Body.CopyToAsync(bodyStream);
|
||||
var data = bodyStream.ToArray();
|
||||
|
||||
if(info is not null)
|
||||
{
|
||||
@@ -73,7 +82,7 @@ public class BodyParsingMiddleware(RequestDelegate next)
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
//Console.WriteLine(e);
|
||||
//Console.WriteLine(e);
|
||||
var testData = Encoding.ASCII.GetString(data);
|
||||
|
||||
if (!string.IsNullOrEmpty(testData))
|
||||
@@ -83,7 +92,6 @@ public class BodyParsingMiddleware(RequestDelegate next)
|
||||
context.Request.Headers.Append("IsEncoded", "false");
|
||||
}
|
||||
}
|
||||
//Data is now xml in konami binary form
|
||||
return returnData;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace Server.Models.Response;
|
||||
|
||||
[XmlRoot("pcbtracker")]
|
||||
public class KeepAlivePcbTrackerResponse
|
||||
{
|
||||
[XmlAttribute("status")]
|
||||
public required int Status { get; set; }
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Xml.Serialization;
|
||||
using Abstractions.SerializationTypes;
|
||||
|
||||
namespace Server.Models.Response;
|
||||
|
||||
@@ -8,15 +9,15 @@ public class SppassLookupResponse
|
||||
[XmlAttribute("status")]
|
||||
public required int Status { get; set; }
|
||||
|
||||
[XmlAttribute("url")]
|
||||
public required string Url { get; set; }
|
||||
[XmlElement("url")]
|
||||
public required XrpcString Url { get; set; }
|
||||
|
||||
[XmlAttribute("interval")]
|
||||
public required int Interval { get; set; }
|
||||
[XmlElement("interval")]
|
||||
public required XrpcInt Interval { get; set; }
|
||||
|
||||
[XmlAttribute("card_type")]
|
||||
public string CardType { get; set; } = "";
|
||||
[XmlElement("card_type")]
|
||||
public XrpcString CardType { get; set; } = "";
|
||||
|
||||
[XmlAttribute("card_id")]
|
||||
public string CardId { get; set; } = "";
|
||||
[XmlElement("card_id")]
|
||||
public XrpcString CardId { get; set; } = "";
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Xml.Serialization;
|
||||
using Abstractions.SerializationTypes;
|
||||
|
||||
namespace Server.Models.Response;
|
||||
|
||||
@@ -8,15 +9,15 @@ public class SppassOpenResponse
|
||||
[XmlAttribute("status")]
|
||||
public required int Status { get; set; }
|
||||
|
||||
[XmlAttribute("token")]
|
||||
public required string Token { get; set; }
|
||||
[XmlElement("token")]
|
||||
public required XrpcString Token { get; set; }
|
||||
|
||||
[XmlAttribute("expire_datetime")]
|
||||
public required string ExpireDatetime { get; set; }
|
||||
[XmlElement("expire_datetime")]
|
||||
public required XrpcString ExpireDatetime { get; set; }
|
||||
|
||||
[XmlAttribute("url")]
|
||||
public required string Url { get; set; }
|
||||
[XmlElement("url")]
|
||||
public required XrpcString Url { get; set; }
|
||||
|
||||
[XmlAttribute("interval")]
|
||||
public required int Interval { get; set; }
|
||||
[XmlElement("interval")]
|
||||
public required XrpcInt Interval { get; set; }
|
||||
}
|
||||
|
||||
+11
-3
@@ -195,6 +195,15 @@ eamuseGroup.MapPost("/", ([FromQuery] string model, [FromQuery] string? module,
|
||||
return HandleEAmuseRoute(amusementRequest, httpContext, logger, handlerService, pluginService);
|
||||
});
|
||||
|
||||
eamuseGroup.MapGet("/{module}/{model}/{module2}/{method}", (string module, string model, string module2, string method,
|
||||
HttpContext httpContext, [FromServices] ILogger<Program> logger, [FromServices] IHandlerService handlerService,
|
||||
[FromServices] IPluginService pluginService) =>
|
||||
{
|
||||
var amusementRequest = new AmusementRequest() { Model = model, Module = module ?? "", Method = method ?? "" };
|
||||
|
||||
return HandleEAmuseRoute(amusementRequest, httpContext, logger, handlerService, pluginService);
|
||||
});
|
||||
|
||||
var graphqlMap = app.MapGraphQL();
|
||||
|
||||
app.MapFallbackToFile("/index.html");
|
||||
@@ -230,11 +239,10 @@ async Task<IResult> HandleEAmuseRoute(AmusementRequest amusementRequest, HttpCon
|
||||
Console.WriteLine(httpContext.Request.Headers.UserAgent);
|
||||
// Enable buffering to allow multiple reads of the request body
|
||||
httpContext.Request.EnableBuffering();
|
||||
var body = "";
|
||||
// The body is 932 encoded xml
|
||||
if (httpContext.Request.Body.Length != 0)
|
||||
string body;
|
||||
using (var reader = new StreamReader(httpContext.Request.Body, Encoding.GetEncoding(932), false, 1024, true))
|
||||
{
|
||||
using var reader = new StreamReader(httpContext.Request.Body, Encoding.GetEncoding(932), false, 1024, true);
|
||||
body = await reader.ReadToEndAsync();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user