107 lines
4.0 KiB
C#
107 lines
4.0 KiB
C#
using FastEndpoints;
|
|
using KbinXml.Net;
|
|
using Medusa.Core.Request;
|
|
using Medusa.Core.Services;
|
|
using Medusa.Core.Utils;
|
|
using Microsoft.AspNetCore.DataProtection.KeyManagement;
|
|
using System.Security.Cryptography;
|
|
using System.Text;
|
|
using System.Xml.Linq;
|
|
|
|
namespace Medusa.Core.Endpoints;
|
|
|
|
public class PostCoreEndpoint(IHandlerService handlerService, ILogger<PostCoreEndpoint> logger) : EndpointWithoutRequest
|
|
{
|
|
static readonly byte[] Key =
|
|
Convert.FromHexString("00000000000069D74627D985EE2187161570D08D93B12455035B6DF0D8205DF5");
|
|
private readonly IHandlerService _handlerService = handlerService;
|
|
private readonly ILogger<PostCoreEndpoint> _logger = logger;
|
|
|
|
public override void Configure()
|
|
{
|
|
Post("{**catchAll}");
|
|
AllowAnonymous();
|
|
}
|
|
|
|
public override async Task HandleAsync(CancellationToken ct)
|
|
{
|
|
// Enable buffering to allow multiple reads of the request body
|
|
HttpContext.Request.EnableBuffering();
|
|
|
|
// The body is 932 encoded xml
|
|
using var reader = new StreamReader(HttpContext.Request.Body, Encoding.GetEncoding(932), false, 1024, true);
|
|
var body = await reader.ReadToEndAsync();
|
|
|
|
HttpContext.Request.Body.Position = 0;
|
|
|
|
bool compress = HttpContext.Request.Headers["X-Compress"].ToString().Contains("lz77");
|
|
bool encrypt = HttpContext.Request.Headers["X-Eamuse-Info"].FirstOrDefault() is not null;
|
|
|
|
var amusementRequest = new AmusementRequest() { Method = "", Model = "", Module = "" };
|
|
|
|
//Check if request is query or path type
|
|
if(HttpContext.Request.Query.Count > 0)
|
|
{
|
|
var query = HttpContext.Request.Query;
|
|
var model = query.TryGetValue("model", out var modelValue) ? modelValue.ToString() : "";
|
|
var module = query.TryGetValue("module", out var moduleValue) ? moduleValue.ToString() : "";
|
|
var method = query.TryGetValue("method", out var methodValue) ? methodValue.ToString() : "";
|
|
|
|
amusementRequest.Model = model;
|
|
amusementRequest.Module = module;
|
|
amusementRequest.Method = method;
|
|
}
|
|
else
|
|
{
|
|
// Else get the last 3 values from the path from the end
|
|
var pathValues = HttpContext.Request.Path.ToString().Split('/').Skip(1).ToArray();
|
|
amusementRequest.Model = pathValues[^3];
|
|
amusementRequest.Module = pathValues[^2];
|
|
amusementRequest.Method = pathValues[^1];
|
|
|
|
//remove the last 3 values from the path
|
|
HttpContext.Request.Path = string.Join("/", HttpContext.Request.Path.ToString().Split('/').SkipLast(3).ToArray());
|
|
}
|
|
|
|
|
|
_logger.LogInformation("Handling {Module} {Method}", amusementRequest.Module, amusementRequest.Method);
|
|
|
|
var document = XDocument.Parse(body);
|
|
|
|
var responseXml = await _handlerService.Handle(amusementRequest.Model, amusementRequest.Module, amusementRequest.Method, document);
|
|
|
|
var encoding = HttpContext.Items["Encoding"]?.ToString() ?? "ShiftJIS";
|
|
|
|
switch(encoding)
|
|
{
|
|
case "shift_jis":
|
|
encoding = "ShiftJIS";
|
|
break;
|
|
case "us-ascii":
|
|
encoding = "ASCII";
|
|
break;
|
|
}
|
|
|
|
byte[] encodedBody = KbinConverter.Write(responseXml, (KnownEncodings)Enum.Parse(typeof(KnownEncodings), encoding, true));
|
|
|
|
if(compress)
|
|
{
|
|
encodedBody = LZ77.CompressEmpty(encodedBody);
|
|
}
|
|
|
|
if(encrypt)
|
|
{
|
|
string[] originalInfo = HttpContext.Request.Headers["X-Eamuse-Info"].FirstOrDefault()?.Split('-') ?? [];
|
|
byte[] part = Convert.FromHexString((originalInfo[1] + originalInfo[2]));
|
|
for(int i = 0; i < 6; i++)
|
|
Key[i] = part[i];
|
|
var rc4Key = MD5.HashData(Key);
|
|
encodedBody = RC4.Encrypt(rc4Key, encodedBody);
|
|
|
|
HttpContext.Response.Headers.Append("X-Eamuse-Info", string.Join('-', originalInfo));
|
|
}
|
|
|
|
await SendBytesAsync(encodedBody);
|
|
}
|
|
}
|