mirror of
https://gitea.tendokyu.moe/Kayori/Medusa.net.git
synced 2026-10-10 00:08:09 +03:00
Clean up and added force encoding option in plugins
This commit is contained in:
+154
-139
@@ -1,24 +1,26 @@
|
||||
using System.Net;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Net.Sockets;
|
||||
using KbinXml.Net;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Server;
|
||||
using Server.Extensions;
|
||||
using Server.Middlewares;
|
||||
using Server.Services;
|
||||
using Server.Utils;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Xml.Linq;
|
||||
using Abstractions.Entities;
|
||||
using Abstractions.Services;
|
||||
using Abstractions.Utils;
|
||||
using KbinXml.Net;
|
||||
using Microsoft.AspNetCore.Hosting.Server;
|
||||
using Microsoft.AspNetCore.Hosting.Server.Features;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Server;
|
||||
using Server.Authentication;
|
||||
using Server.Extensions;
|
||||
using Server.Middlewares;
|
||||
using Server.Models.Request;
|
||||
using Server.Services;
|
||||
using Server.Utils;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Net.Sockets;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Xml.Linq;
|
||||
|
||||
var key =
|
||||
Convert.FromHexString("00000000000069D74627D985EE2187161570D08D93B12455035B6DF0D8205DF5");
|
||||
@@ -98,143 +100,157 @@ app.MapIdentityApi();
|
||||
|
||||
var eamuseGroup = app.MapGroup("eamuse");
|
||||
|
||||
eamuseGroup.MapPost("/{model}/{module}/{method}", (string model, string module, string method,
|
||||
[FromServices] IHttpContextAccessor httpContextAccessor) =>
|
||||
{
|
||||
|
||||
});
|
||||
|
||||
eamuseGroup.MapPost("/{m}", async (string m, [FromQuery] string model, [FromQuery] string? module, [FromQuery] string? method, [FromQuery] string? f,
|
||||
HttpContext httpContext, [FromServices] ILogger<Program> logger, [FromServices] IHandlerService handlerService) =>
|
||||
{
|
||||
// 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;
|
||||
|
||||
var compress = httpContext.Request.Headers["X-Compress"].ToString().Contains("lz77");
|
||||
var encrypt = httpContext.Request.Headers["X-Eamuse-Info"].FirstOrDefault() is not null;
|
||||
|
||||
var amusementRequest = new AmusementRequest() { Model = model, Module = module ?? "", Method = method ?? "" };
|
||||
|
||||
if(!string.IsNullOrEmpty(f))
|
||||
eamuseGroup.MapPost("/{model}/{module}/{method}", async (string model, string module, string method,
|
||||
HttpContext httpContext, [FromServices] ILogger<Program> logger, [FromServices] IHandlerService handlerService, [FromServices] IPluginService pluginService) =>
|
||||
{
|
||||
var fParts = f.Split('.');
|
||||
amusementRequest.Module = fParts[0];
|
||||
amusementRequest.Method = fParts[1];
|
||||
}
|
||||
// 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)
|
||||
{
|
||||
using var reader = new StreamReader(httpContext.Request.Body, Encoding.GetEncoding(932), false, 1024, true);
|
||||
body = await reader.ReadToEndAsync();
|
||||
}
|
||||
|
||||
logger.LogInformation("Handling {Module} {Method}", amusementRequest.Module, amusementRequest.Method);
|
||||
httpContext.Request.Body.Position = 0;
|
||||
|
||||
var compress = httpContext.Request.Headers["X-Compress"].ToString().Contains("lz77");
|
||||
var encrypt = httpContext.Request.Headers["X-Eamuse-Info"].FirstOrDefault() is not null;
|
||||
|
||||
var amusementRequest = new AmusementRequest() { Model = model, Module = module ?? "", Method = method ?? "" };
|
||||
|
||||
var encoding = httpContext.Items["Encoding"]?.ToString() ?? "ShiftJIS";
|
||||
|
||||
httpContext.Request.Headers.TryGetValue("IsEncoded", out var isEncoded);
|
||||
|
||||
var originalInfo = httpContext.Request.Headers["X-Eamuse-Info"].FirstOrDefault() ?? "";
|
||||
|
||||
httpContext.Response.Headers.Append("X-Eamuse-Info", originalInfo);
|
||||
|
||||
var result = await HandleEAmuseRequest(amusementRequest, body, originalInfo, compress, encrypt, isEncoded == "true", encoding, logger, handlerService, pluginService);
|
||||
|
||||
return TypedResults.Bytes(result, "application/octet-stream");
|
||||
});
|
||||
|
||||
eamuseGroup.MapPost("/{m}", async (string m, [FromQuery] string model, [FromQuery] string? module, [FromQuery] string? method, [FromQuery] string? f,
|
||||
HttpContext httpContext, [FromServices] ILogger<Program> logger, [FromServices] IHandlerService handlerService, [FromServices] IPluginService pluginService) =>
|
||||
{
|
||||
// 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)
|
||||
{
|
||||
using var reader = new StreamReader(httpContext.Request.Body, Encoding.GetEncoding(932), false, 1024, true);
|
||||
body = await reader.ReadToEndAsync();
|
||||
}
|
||||
|
||||
httpContext.Request.Body.Position = 0;
|
||||
|
||||
var compress = httpContext.Request.Headers["X-Compress"].ToString().Contains("lz77");
|
||||
var encrypt = httpContext.Request.Headers["X-Eamuse-Info"].FirstOrDefault() is not null;
|
||||
|
||||
var amusementRequest = new AmusementRequest() { Model = model, Module = module ?? "", Method = method ?? "" };
|
||||
|
||||
if(!string.IsNullOrEmpty(f))
|
||||
{
|
||||
var fParts = f.Split('.');
|
||||
amusementRequest.Module = fParts[0];
|
||||
amusementRequest.Method = fParts[1];
|
||||
}
|
||||
|
||||
var encoding = httpContext.Items["Encoding"]?.ToString() ?? "ShiftJIS";
|
||||
|
||||
httpContext.Request.Headers.TryGetValue("IsEncoded", out var isEncoded);
|
||||
|
||||
var originalInfo = httpContext.Request.Headers["X-Eamuse-Info"].FirstOrDefault() ?? "";
|
||||
|
||||
httpContext.Response.Headers.Append("X-Eamuse-Info", originalInfo);
|
||||
|
||||
var result = await HandleEAmuseRequest(amusementRequest, body, originalInfo, compress, encrypt, isEncoded == "true", encoding, logger, handlerService, pluginService);
|
||||
|
||||
return TypedResults.Bytes(result, "application/octet-stream");
|
||||
});
|
||||
|
||||
eamuseGroup.MapPost("/", async ([FromQuery] string model, [FromQuery] string? module, [FromQuery] string? method, [FromQuery] string? f,
|
||||
HttpContext httpContext, [FromServices] ILogger<Program> logger, [FromServices] IHandlerService handlerService, [FromServices] IPluginService pluginService) =>
|
||||
{
|
||||
|
||||
// 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)
|
||||
{
|
||||
using var reader = new StreamReader(httpContext.Request.Body, Encoding.GetEncoding(932), false, 1024, true);
|
||||
body = await reader.ReadToEndAsync();
|
||||
}
|
||||
|
||||
httpContext.Request.Body.Position = 0;
|
||||
|
||||
var compress = httpContext.Request.Headers["X-Compress"].ToString().Contains("lz77");
|
||||
var encrypt = httpContext.Request.Headers["X-Eamuse-Info"].FirstOrDefault() is not null;
|
||||
|
||||
var amusementRequest = new AmusementRequest() { Model = model, Module = module ?? "", Method = method ?? "" };
|
||||
|
||||
if(!string.IsNullOrEmpty(f))
|
||||
{
|
||||
var fParts = f.Split('.');
|
||||
amusementRequest.Module = fParts[0];
|
||||
amusementRequest.Method = fParts[1];
|
||||
}
|
||||
|
||||
var encoding = httpContext.Items["Encoding"]?.ToString() ?? "ShiftJIS";
|
||||
|
||||
httpContext.Request.Headers.TryGetValue("IsEncoded", out var isEncoded);
|
||||
|
||||
var originalInfo = httpContext.Request.Headers["X-Eamuse-Info"].FirstOrDefault() ?? "";
|
||||
|
||||
httpContext.Response.Headers.Append("X-Eamuse-Info", originalInfo);
|
||||
|
||||
var result = await HandleEAmuseRequest(amusementRequest, body, originalInfo, compress, encrypt, isEncoded == "true", encoding, logger, handlerService, pluginService);
|
||||
|
||||
return TypedResults.Bytes(result, "application/octet-stream");
|
||||
});
|
||||
|
||||
async Task<byte[]> HandleEAmuseRequest(AmusementRequest request, string body, string info, bool compress, bool encrypt, bool isEncoded, string encoding, ILogger<Program> logger, IHandlerService handlerService, IPluginService pluginService)
|
||||
{
|
||||
logger.LogInformation("Handling {Module} {Method}", request.Module, request.Method);
|
||||
|
||||
var document = new XDocument();
|
||||
|
||||
if (!string.IsNullOrEmpty(body))
|
||||
document = XDocument.Parse(body);
|
||||
|
||||
var responseXml = await handlerService.Handle(amusementRequest.Model, amusementRequest.Module, amusementRequest.Method, document);
|
||||
|
||||
var encoding = httpContext.Items["Encoding"]?.ToString() ?? "ShiftJIS";
|
||||
|
||||
var encodingEnum = encoding switch
|
||||
{
|
||||
"shift_jis" or "ShiftJIS" or "SHIFT_JIS" => KnownEncodings.ShiftJIS,
|
||||
"us-ascii" => KnownEncodings.ASCII,
|
||||
"utf-8" => KnownEncodings.UTF8,
|
||||
"euc-jp" => KnownEncodings.EUC_JP,
|
||||
"iso-8859-1" => KnownEncodings.ISO_8859_1,
|
||||
_ => throw new ArgumentException($"Unknown encoding: {encoding}")
|
||||
};
|
||||
|
||||
if (amusementRequest.Module == "package")
|
||||
{
|
||||
logger.LogInformation("{xml}", responseXml);
|
||||
}
|
||||
|
||||
var encodedBody = KbinConverter.Write(responseXml, encodingEnum);
|
||||
|
||||
if (amusementRequest.Module == "package")
|
||||
{
|
||||
File.WriteAllBytes("test.bin", encodedBody);
|
||||
}
|
||||
|
||||
if(compress)
|
||||
{
|
||||
encodedBody = LZ77.CompressEmpty(encodedBody);
|
||||
}
|
||||
|
||||
if (!encrypt) return TypedResults.Bytes(encodedBody, "application/octet-stream");
|
||||
var originalInfo = httpContext.Request.Headers["X-Eamuse-Info"].FirstOrDefault()?.Split('-') ?? [];
|
||||
var part = Convert.FromHexString((originalInfo[1] + originalInfo[2]));
|
||||
for(var 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));
|
||||
|
||||
return TypedResults.Bytes(encodedBody, "application/octet-stream");
|
||||
});
|
||||
|
||||
eamuseGroup.MapPost("/", async ([FromQuery] string model, [FromQuery] string? module, [FromQuery] string? method, [FromQuery] string? f,
|
||||
HttpContext httpContext, [FromServices] ILogger<Program> logger, [FromServices] IHandlerService handlerService) =>
|
||||
{
|
||||
// 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)
|
||||
{
|
||||
using var reader = new StreamReader(httpContext.Request.Body, Encoding.GetEncoding(932), false, 1024, true);
|
||||
body = await reader.ReadToEndAsync();
|
||||
}
|
||||
|
||||
httpContext.Request.Body.Position = 0;
|
||||
|
||||
var compress = httpContext.Request.Headers["X-Compress"].ToString().Contains("lz77");
|
||||
var encrypt = httpContext.Request.Headers["X-Eamuse-Info"].FirstOrDefault() is not null;
|
||||
|
||||
var amusementRequest = new AmusementRequest() { Model = model, Module = module ?? "", Method = method ?? ""};
|
||||
|
||||
if (!string.IsNullOrEmpty(f))
|
||||
{
|
||||
var fParts = f.Split('.');
|
||||
amusementRequest.Module = fParts[0];
|
||||
amusementRequest.Method = fParts[1];
|
||||
}
|
||||
|
||||
logger.LogInformation("Handling {Module} {Method}", amusementRequest.Module, amusementRequest.Method);
|
||||
|
||||
var document = new XDocument();
|
||||
|
||||
if(!string.IsNullOrEmpty(body))
|
||||
document = XDocument.Parse(body);
|
||||
|
||||
var responseXml = await handlerService.Handle(amusementRequest.Model, amusementRequest.Module, amusementRequest.Method, document);
|
||||
var responseXml = await handlerService.Handle(request.Model, request.Module, request.Method, document);
|
||||
|
||||
var encoding = httpContext.Items["Encoding"]?.ToString() ?? "ShiftJIS";
|
||||
var plugins = pluginService.GetPlugins();
|
||||
var forcedEncoding = plugins.FirstOrDefault(p => p.GameCode == request.Model)?.ForcedEncoding;
|
||||
|
||||
var encodingEnum = encoding switch
|
||||
{
|
||||
"shift_jis" or "ShiftJIS" or "SHIFT_JIS" => KnownEncodings.ShiftJIS,
|
||||
"us-ascii" => KnownEncodings.ASCII,
|
||||
"utf-8" => KnownEncodings.UTF8,
|
||||
"euc-jp" => KnownEncodings.EUC_JP,
|
||||
"shift_jis" or "ShiftJIS" or "SHIFT_JIS" => KnownEncodings.ShiftJIS,
|
||||
"us-ascii" => KnownEncodings.ASCII,
|
||||
"utf-8" => KnownEncodings.UTF8,
|
||||
"euc-jp" => KnownEncodings.EUC_JP,
|
||||
"iso-8859-1" => KnownEncodings.ISO_8859_1,
|
||||
_ => throw new ArgumentException($"Unknown encoding: {encoding}")
|
||||
};
|
||||
|
||||
if (amusementRequest.Module == "package")
|
||||
if(forcedEncoding is not null)
|
||||
{
|
||||
encodingEnum = forcedEncoding.ToKnownEncoding();
|
||||
}
|
||||
|
||||
if(request.Module == "package")
|
||||
{
|
||||
logger.LogInformation("{xml}", responseXml);
|
||||
}
|
||||
|
||||
|
||||
byte[] encodedBody;
|
||||
|
||||
if (httpContext.Request.Headers.TryGetValue("IsEncoded", out var value) && value == "false")
|
||||
|
||||
if(!isEncoded)
|
||||
{
|
||||
var encoder = Encoding.GetEncoding(encoding);
|
||||
encodedBody = encoder.GetBytes(responseXml.ToString());
|
||||
@@ -242,8 +258,8 @@ eamuseGroup.MapPost("/", async ([FromQuery] string model, [FromQuery] string? mo
|
||||
else
|
||||
{
|
||||
encodedBody = KbinConverter.Write(responseXml, encodingEnum);
|
||||
|
||||
if (amusementRequest.Module == "package")
|
||||
|
||||
if(request.Module == "package")
|
||||
{
|
||||
File.WriteAllBytes("test.bin", encodedBody);
|
||||
}
|
||||
@@ -253,18 +269,17 @@ eamuseGroup.MapPost("/", async ([FromQuery] string model, [FromQuery] string? mo
|
||||
encodedBody = LZ77.CompressEmpty(encodedBody);
|
||||
}
|
||||
|
||||
if (!encrypt) return TypedResults.Bytes(encodedBody, "application/octet-stream");
|
||||
var originalInfo = httpContext.Request.Headers["X-Eamuse-Info"].FirstOrDefault()?.Split('-') ?? [];
|
||||
var originalInfo = info.Split('-');
|
||||
|
||||
if(!encrypt) return encodedBody;
|
||||
var part = Convert.FromHexString((originalInfo[1] + originalInfo[2]));
|
||||
for(var 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));
|
||||
|
||||
return TypedResults.Bytes(encodedBody, "application/octet-stream");
|
||||
});
|
||||
return encodedBody;
|
||||
}
|
||||
|
||||
app.MapFallbackToFile("/index.html");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user