From c45444ee8f460be6dff526f0c66eebb2320db23e Mon Sep 17 00:00:00 2001 From: raphaeIl Date: Fri, 15 Nov 2024 14:59:14 -0500 Subject: [PATCH] Initial Custom GameClient Implementation --- SCHALE.Common/Crypto/FastCRC.cs | 48 ++++ SCHALE.Common/Crypto/PacketCryptManager.cs | 51 ++++ SCHALE.Common/Crypto/XORCryptor.cs | 18 ++ SCHALE.Common/SCHALE.Common.csproj | 1 + .../Controllers/ClientController.cs | 17 ++ SCHALE.GameClient/GameClient.cs | 88 ++++++ SCHALE.GameClient/Models/ErrorViewModel.cs | 9 + .../Properties/launchSettings.json | 38 +++ SCHALE.GameClient/SCHALE.GameClient.csproj | 14 + .../Services/PrivateClientService.cs | 265 ++++++++++++++++++ .../appsettings.Development.json | 8 + SCHALE.GameClient/appsettings.json | 12 + SCHALE.GameServer.sln | 6 + 13 files changed, 575 insertions(+) create mode 100644 SCHALE.Common/Crypto/FastCRC.cs create mode 100644 SCHALE.Common/Crypto/PacketCryptManager.cs create mode 100644 SCHALE.Common/Crypto/XORCryptor.cs create mode 100644 SCHALE.GameClient/Controllers/ClientController.cs create mode 100644 SCHALE.GameClient/GameClient.cs create mode 100644 SCHALE.GameClient/Models/ErrorViewModel.cs create mode 100644 SCHALE.GameClient/Properties/launchSettings.json create mode 100644 SCHALE.GameClient/SCHALE.GameClient.csproj create mode 100644 SCHALE.GameClient/Services/PrivateClientService.cs create mode 100644 SCHALE.GameClient/appsettings.Development.json create mode 100644 SCHALE.GameClient/appsettings.json diff --git a/SCHALE.Common/Crypto/FastCRC.cs b/SCHALE.Common/Crypto/FastCRC.cs new file mode 100644 index 0000000..ccd66ba --- /dev/null +++ b/SCHALE.Common/Crypto/FastCRC.cs @@ -0,0 +1,48 @@ +namespace MX.Core.Crypto +{ + /// Kesunorin + public class FastCRC + { + //public static uint[] crc_table = new uint[256]; + public static uint[] crc_table = [0, 79764919, 159529838, 222504665, 319059676, 398814059, 445009330, 507990021, 638119352, 583659535, 797628118, 726387553, 890018660, 835552979, 1015980042, 944750013, 1276238704, 1221641927, 1167319070, 1095957929, 1595256236, 1540665371, 1452775106, 1381403509, 1780037320, 1859660671, 1671105958, 1733955601, 2031960084, 2111593891, 1889500026, 1952343757, 2552477408, 2632100695, 2443283854, 2506133561, 2334638140, 2414271883, 2191915858, 2254759653, 3190512472, 3135915759, 3081330742, 3009969537, 2905550212, 2850959411, 2762807018, 2691435357, 3560074640, 3505614887, 3719321342, 3648080713, 3342211916, 3287746299, 3467911202, 3396681109, 4063920168, 4143685023, 4223187782, 4286162673, 3779000052, 3858754371, 3904687514, 3967668269, 881225847, 809987520, 1023691545, 969234094, 662832811, 591600412, 771767749, 717299826, 311336399, 374308984, 453813921, 533576470, 25881363, 88864420, 134795389, 214552010, 2023205639, 2086057648, 1897238633, 1976864222, 1804852699, 1867694188, 1645340341, 1724971778, 1587496639, 1516133128, 1461550545, 1406951526, 1302016099, 1230646740, 1142491917, 1087903418, 2896545431, 2825181984, 2770861561, 2716262478, 3215044683, 3143675388, 3055782693, 3001194130, 2326604591, 2389456536, 2200899649, 2280525302, 2578013683, 2640855108, 2418763421, 2498394922, 3769900519, 3832873040, 3912640137, 3992402750, 4088425275, 4151408268, 4197601365, 4277358050, 3334271071, 3263032808, 3476998961, 3422541446, 3585640067, 3514407732, 3694837229, 3640369242, 1762451694, 1842216281, 1619975040, 1682949687, 2047383090, 2127137669, 1938468188, 2001449195, 1325665622, 1271206113, 1183200824, 1111960463, 1543535498, 1489069629, 1434599652, 1363369299, 622672798, 568075817, 748617968, 677256519, 907627842, 853037301, 1067152940, 995781531, 51762726, 131386257, 177728840, 240578815, 269590778, 349224269, 429104020, 491947555, 4046411278, 4126034873, 4172115296, 4234965207, 3794477266, 3874110821, 3953728444, 4016571915, 3609705398, 3555108353, 3735388376, 3664026991, 3290680682, 3236090077, 3449943556, 3378572211, 3174993278, 3120533705, 3032266256, 2961025959, 2923101090, 2868635157, 2813903052, 2742672763, 2604032198, 2683796849, 2461293480, 2524268063, 2284983834, 2364738477, 2175806836, 2238787779, 1569362073, 1498123566, 1409854455, 1355396672, 1317987909, 1246755826, 1192025387, 1137557660, 2072149281, 2135122070, 1912620623, 1992383480, 1753615357, 1816598090, 1627664531, 1707420964, 295390185, 358241886, 404320391, 483945776, 43990325, 106832002, 186451547, 266083308, 932423249, 861060070, 1041341759, 986742920, 613929101, 542559546, 756411363, 701822548, 3316196985, 3244833742, 3425377559, 3370778784, 3601682597, 3530312978, 3744426955, 3689838204, 3819031489, 3881883254, 3928223919, 4007849240, 4037393693, 4100235434, 4180117107, 4259748804, 2310601993, 2373574846, 2151335527, 2231098320, 2596047829, 2659030626, 2470359227, 2550115596, 2947551409, 2876312838, 2788305887, 2733848168, 3165939309, 3094707162, 3040238851, 2985771188]; + + public readonly uint POLYNOMIAL = 79764919; + public readonly uint MASK = 2147483648; + + private void Generate() + { + for (uint i = 0; i < 256; i++) + { + uint crcValue = i << 24; + for (int times = 8; times > 0; times--) + { + if ((MASK & crcValue) != 0) + { + crcValue = POLYNOMIAL ^ (2 * crcValue); + } + else + { + crcValue *= 2; + } + } + crc_table[i] = crcValue; + } + } + + public bool GetCRC(byte[] buffer, int offset, int length, out uint crc) + { + crc = 0; + for (int i = offset; i < offset + length; i++) + { + byte b = buffer[i]; + crc = crc_table[(crc >> 24) ^ b] ^ (crc << 8); + } + return true; + } + + static FastCRC() + { + new FastCRC().Generate(); + } + } +} diff --git a/SCHALE.Common/Crypto/PacketCryptManager.cs b/SCHALE.Common/Crypto/PacketCryptManager.cs new file mode 100644 index 0000000..949bbf8 --- /dev/null +++ b/SCHALE.Common/Crypto/PacketCryptManager.cs @@ -0,0 +1,51 @@ +using System.IO.Compression; +using System.Text; +using SCHALE.Common.NetworkProtocol; +using Serilog; + +namespace MX.Core.Crypto +{ + + /// Kesunorin + public class PacketCryptManager + { + // private static readonly short PROTOCOL_HEAD_RESERVE = 8; + private readonly XORCryptor _cryptor = new(); + private readonly FastCRC _checke = new(); + //private ProtocolConverter _converter = new(); + public static PacketCryptManager Instance = new(); + + public byte[] RequestToBinary(Protocol protocol, string json, int protocolConverter) + { + byte[] compressedData = Compress(json); + _cryptor.Encrypt(compressedData, 0, compressedData.Length); + _checke.GetCRC(compressedData, 0, compressedData.Length, out uint crc); + Log.Information("CRC: " + crc); + //int protocolConverter = _converter.TypeConversion(crc, protocol); + //int protocolConverter = 1797824024; + byte[][] data = + [ + BitConverter.GetBytes(crc), + BitConverter.GetBytes(protocolConverter), + compressedData + ]; + byte[] result = data.SelectMany(_ => _).ToArray(); + return result; + } + + protected byte[] Compress(string text) + { + byte[] inputBytes = Encoding.UTF8.GetBytes(text); + using var memoryStream = new MemoryStream(); + using (var gzipStream = new GZipStream(memoryStream, CompressionMode.Compress, true)) + { + gzipStream.Write(inputBytes, 0, inputBytes.Length); + } + byte[] compressedData = memoryStream.ToArray(); + + byte[][] data = [BitConverter.GetBytes(inputBytes.Length), compressedData]; + byte[] result = data.SelectMany(_ => _).ToArray(); + return result; + } + } +} diff --git a/SCHALE.Common/Crypto/XORCryptor.cs b/SCHALE.Common/Crypto/XORCryptor.cs new file mode 100644 index 0000000..8d06bb9 --- /dev/null +++ b/SCHALE.Common/Crypto/XORCryptor.cs @@ -0,0 +1,18 @@ +namespace MX.Core.Crypto +{ + /// Kesunorin + internal class XORCryptor + { + private readonly uint ENCRYPTION_KEY = 2948064217; + + public bool Encrypt(byte[] data, int offset, int length) + { + for (int i = offset; i < offset + length; i++) + { + data[i] ^= (byte)ENCRYPTION_KEY; + } + + return true; + } + } +} diff --git a/SCHALE.Common/SCHALE.Common.csproj b/SCHALE.Common/SCHALE.Common.csproj index 492cb67..9087f55 100644 --- a/SCHALE.Common/SCHALE.Common.csproj +++ b/SCHALE.Common/SCHALE.Common.csproj @@ -17,6 +17,7 @@ + diff --git a/SCHALE.GameClient/Controllers/ClientController.cs b/SCHALE.GameClient/Controllers/ClientController.cs new file mode 100644 index 0000000..70be39e --- /dev/null +++ b/SCHALE.GameClient/Controllers/ClientController.cs @@ -0,0 +1,17 @@ +using Microsoft.AspNetCore.Mvc; +using SCHALE.GameServer.Services; + +namespace SCHALE.GameClient.Controllers +{ + public class ClientController : Controller + { + private readonly ILogger _logger; + private readonly PrivateClientService _privateClientService; + + public ClientController(ILogger logger, PrivateClientService privateClientService) + { + _logger = logger; + _privateClientService = privateClientService; + } + } +} diff --git a/SCHALE.GameClient/GameClient.cs b/SCHALE.GameClient/GameClient.cs new file mode 100644 index 0000000..67d7157 --- /dev/null +++ b/SCHALE.GameClient/GameClient.cs @@ -0,0 +1,88 @@ +using Microsoft.AspNetCore.Server.Kestrel.Core; +using Microsoft.EntityFrameworkCore; +using SCHALE.GameServer.Services; +using Serilog; +using Serilog.Events; + +namespace SCHALE.GameServer +{ + public class GameServer + { + public static async Task Main(string[] args) + { + var config = new ConfigurationBuilder() + .SetBasePath(Path.GetDirectoryName(AppContext.BaseDirectory)!) + .AddJsonFile("appsettings.json") + .AddJsonFile( + $"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"}.json", + true + ) + .AddJsonFile("appsettings.Local.json", true) + .Build(); + + { + var logFilePath = Path.Combine( + Path.GetDirectoryName(AppContext.BaseDirectory)!, + "logs", + "log.txt" + ); + + if (File.Exists(logFilePath)) + { + var prevLogFilePath = Path.Combine( + Path.GetDirectoryName(logFilePath)!, + "log-prev.txt" + ); + if (File.Exists(prevLogFilePath)) + File.Delete(prevLogFilePath); + + File.Move(logFilePath, prevLogFilePath); + } + + Log.Logger = new LoggerConfiguration() + .WriteTo.Console() + .WriteTo.File( + logFilePath, + restrictedToMinimumLevel: LogEventLevel.Verbose, + shared: true + ) + .ReadFrom.Configuration(config) + .CreateBootstrapLogger(); + } + + Log.Information("Starting..."); + try + { + var builder = WebApplication.CreateBuilder(args); + + builder.Services.Configure(op => + op.AllowSynchronousIO = true + ); + builder.Host.UseSerilog(); + + // Add services to the container. + builder.Services.AddControllers(); + + builder.Services.AddHttpClient(); + builder.Services.AddSingleton(); + builder.Services.AddPrivateClientService(); + + var app = builder.Build(); + + // Configure the HTTP request pipeline. + app.UseAuthorization(); + app.UseSerilogRequestLogging(); + + app.MapControllers(); + + app.Run(); + } catch (Exception ex) + { + Log.Fatal(ex, "An unhandled exception occurred during runtime"); + } finally + { + Log.CloseAndFlush(); + } + } + } +} diff --git a/SCHALE.GameClient/Models/ErrorViewModel.cs b/SCHALE.GameClient/Models/ErrorViewModel.cs new file mode 100644 index 0000000..c93607e --- /dev/null +++ b/SCHALE.GameClient/Models/ErrorViewModel.cs @@ -0,0 +1,9 @@ +namespace SCHALE.GameClient.Models +{ + public class ErrorViewModel + { + public string? RequestId { get; set; } + + public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); + } +} diff --git a/SCHALE.GameClient/Properties/launchSettings.json b/SCHALE.GameClient/Properties/launchSettings.json new file mode 100644 index 0000000..43e710b --- /dev/null +++ b/SCHALE.GameClient/Properties/launchSettings.json @@ -0,0 +1,38 @@ +{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:22994", + "sslPort": 44306 + } + }, + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "http://localhost:5141", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "https://localhost:7267;http://localhost:5141", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/SCHALE.GameClient/SCHALE.GameClient.csproj b/SCHALE.GameClient/SCHALE.GameClient.csproj new file mode 100644 index 0000000..96c7583 --- /dev/null +++ b/SCHALE.GameClient/SCHALE.GameClient.csproj @@ -0,0 +1,14 @@ + + + + net8.0 + enable + enable + + + + + + + + diff --git a/SCHALE.GameClient/Services/PrivateClientService.cs b/SCHALE.GameClient/Services/PrivateClientService.cs new file mode 100644 index 0000000..b0b1c28 --- /dev/null +++ b/SCHALE.GameClient/Services/PrivateClientService.cs @@ -0,0 +1,265 @@ +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc.ModelBinding.Binders; +using MX.Core.Crypto; +using Newtonsoft.Json.Linq; +using SCHALE.Common.Crypto; +using SCHALE.Common.Crypto.XXHash; +using SCHALE.Common.FlatData; +using SCHALE.Common.NetworkProtocol; +using SCHALE.GameServer.Services.Irc; +using Serilog; +using System.IO.Compression; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Reflection.PortableExecutable; +using System.Runtime.InteropServices; +using System.Security.Policy; +using System.Text; +using System.Text.Json; +using System.Threading.Tasks; + +namespace SCHALE.GameServer.Services +{ + public class PrivateClientService : BackgroundService + { + private readonly HttpClient _httpClient; + + public static readonly string API_URL = "http://10.0.0.149/api/gateway"; + public static readonly string MITM_URL = "http://10.0.0.149:8080"; + public static readonly string OFFICIAL_API_URL = "http://prod-gateway.bluearchiveyostar.com:5100/api/"; + // https://prod-game.bluearchiveyostar.com:5000/api/gateway + //public static readonly string OFFICIAL_API_URL = "https://prod-gateway.bluearchiveyostar.com:5100/api/"; + public static readonly string OFFICIAL_API_URL_Test = "ec2-52-68-9-200.ap-northeast-1.compute.amazonaws.com"; + // https://prod-game.bluearchiveyostar.com:5000/api/ + public static readonly string SessionKey = ""; + + public static uint[] crc_table = [0, 79764919, 159529838, 222504665, 319059676, 398814059, 445009330, 507990021, 638119352, 583659535, 797628118, 726387553, 890018660, 835552979, 1015980042, 944750013, 1276238704, 1221641927, 1167319070, 1095957929, 1595256236, 1540665371, 1452775106, 1381403509, 1780037320, 1859660671, 1671105958, 1733955601, 2031960084, 2111593891, 1889500026, 1952343757, 2552477408, 2632100695, 2443283854, 2506133561, 2334638140, 2414271883, 2191915858, 2254759653, 3190512472, 3135915759, 3081330742, 3009969537, 2905550212, 2850959411, 2762807018, 2691435357, 3560074640, 3505614887, 3719321342, 3648080713, 3342211916, 3287746299, 3467911202, 3396681109, 4063920168, 4143685023, 4223187782, 4286162673, 3779000052, 3858754371, 3904687514, 3967668269, 881225847, 809987520, 1023691545, 969234094, 662832811, 591600412, 771767749, 717299826, 311336399, 374308984, 453813921, 533576470, 25881363, 88864420, 134795389, 214552010, 2023205639, 2086057648, 1897238633, 1976864222, 1804852699, 1867694188, 1645340341, 1724971778, 1587496639, 1516133128, 1461550545, 1406951526, 1302016099, 1230646740, 1142491917, 1087903418, 2896545431, 2825181984, 2770861561, 2716262478, 3215044683, 3143675388, 3055782693, 3001194130, 2326604591, 2389456536, 2200899649, 2280525302, 2578013683, 2640855108, 2418763421, 2498394922, 3769900519, 3832873040, 3912640137, 3992402750, 4088425275, 4151408268, 4197601365, 4277358050, 3334271071, 3263032808, 3476998961, 3422541446, 3585640067, 3514407732, 3694837229, 3640369242, 1762451694, 1842216281, 1619975040, 1682949687, 2047383090, 2127137669, 1938468188, 2001449195, 1325665622, 1271206113, 1183200824, 1111960463, 1543535498, 1489069629, 1434599652, 1363369299, 622672798, 568075817, 748617968, 677256519, 907627842, 853037301, 1067152940, 995781531, 51762726, 131386257, 177728840, 240578815, 269590778, 349224269, 429104020, 491947555, 4046411278, 4126034873, 4172115296, 4234965207, 3794477266, 3874110821, 3953728444, 4016571915, 3609705398, 3555108353, 3735388376, 3664026991, 3290680682, 3236090077, 3449943556, 3378572211, 3174993278, 3120533705, 3032266256, 2961025959, 2923101090, 2868635157, 2813903052, 2742672763, 2604032198, 2683796849, 2461293480, 2524268063, 2284983834, 2364738477, 2175806836, 2238787779, 1569362073, 1498123566, 1409854455, 1355396672, 1317987909, 1246755826, 1192025387, 1137557660, 2072149281, 2135122070, 1912620623, 1992383480, 1753615357, 1816598090, 1627664531, 1707420964, 295390185, 358241886, 404320391, 483945776, 43990325, 106832002, 186451547, 266083308, 932423249, 861060070, 1041341759, 986742920, 613929101, 542559546, 756411363, 701822548, 3316196985, 3244833742, 3425377559, 3370778784, 3601682597, 3530312978, 3744426955, 3689838204, 3819031489, 3881883254, 3928223919, 4007849240, 4037393693, 4100235434, 4180117107, 4259748804, 2310601993, 2373574846, 2151335527, 2231098320, 2596047829, 2659030626, 2470359227, 2550115596, 2947551409, 2876312838, 2788305887, 2733848168, 3165939309, 3094707162, 3040238851, 2985771188]; + public readonly uint POLYNOMIAL = 8; + public readonly uint MASK = 0; + + public PrivateClientService(HttpClient httpClient) + { + _httpClient = httpClient; + } + + protected override async Task ExecuteAsync(CancellationToken stoppingToken) + { + //await SendPostRequestAsync(OFFICIAL_API_URL, JsonSerializer.Serialize(new AcademyGetInfoRequest() + //{ + // ClientUpTime = 1, + // Resendable = true, + // Hash = , + // IsTest = false, + // SessionKey = new() + // { + // AccountServerId = , + // MxToken = "" + // }, + //})); + + + await SendPostRequestAsync(OFFICIAL_API_URL, JsonSerializer.Serialize(new ShopBuyGacha3Request() + { + FreeRecruitId = 0, + SessionKey = new() + { + AccountServerId = , + MxToken = SessionKey, + }, + + Cost = new() + { + ParcelInfos = [ + new() + { + Key = new() + { + Type = ParcelType.Currency, + Id = 4, + }, + Amount = 120, + Multiplier = new(10000), + Probability = new(10000) + } + ], + + Currency = new() + { + currencyValue = new() + { + Values = new() + { + { CurrencyTypes.Gem, 120 } + }, + Tickets = new() { }, + Property = new() { }, + Gem = 120, + IsEmpty = false + }, + + Gold = 0, + Gem = 120, + + }, + EquipmentDBs = [], + ItemDBs = [], + FurnitureDBs = [], + ConsumeCondition = 0, + }, + GoodsId = 35838, + ShopUniqueId = 50667, + ClientUpTime = 0, + Resendable = true, + Hash = , + IsTest = false, + })); + } + + public bool GetCRC(byte[] buffer, int offset, int length, out uint crc) + { + if (buffer == null || offset < 0 || length < 0 || offset + length > buffer.Length) + { + crc = 0; + return false; + } + + crc = MASK; + for (int i = offset; i < offset + length; i++) + { + byte index = (byte)((crc ^ buffer[i]) & 0xFF); + crc = (crc >> 8) ^ crc_table[index]; + } + crc ^= MASK; + return true; + } + + + public static byte[] CompressToByteArray(byte[] data) + { + if (data == null || data.Length == 0) + return null; + + using (var output = new MemoryStream()) + { + using (var gzipStream = new GZipStream(output, CompressionMode.Compress)) + { + gzipStream.Write(data, 0, data.Length); + } + // Get the compressed data as a byte array + return output.ToArray(); + } + } + + public static byte[] RequestToBinary(string jsonStr) + { + byte[] jsonPayload = Encoding.UTF8.GetBytes(jsonStr); + byte[] payloadCompressed = CompressToByteArray(jsonPayload); + + XOR.Crypt(payloadCompressed, [0xD9]); + + return payloadCompressed; + } + + + public async Task SendPostRequestAsync(string url, string jsonStr) + { + + //jsonStr = ""; + Log.Information("Sending Post Request to " + url); + Log.Information($"Payload: {jsonStr}"); + byte[] payload = PacketCryptManager.Instance.RequestToBinary(Protocol.Shop_BuyGacha3, jsonStr, ); + + + File.WriteAllBytes("./mx.dat", payload); + Log.Information("Writeen All Bytes"); + + return; + //GetCRC(payload, 0, payload.Length, out uint crc); + + ////using var xxhash = XXHash32.Create(); + ////xxhash.ComputeHash(Encoding.UTF8.GetBytes(name)); + + //Log.Information("CRC: " + crc); + + //SCHALEPacket packet = new SCHALEPacket() + //{ + // CRC = crc, + // Protocol = (ushort)Protocol.Academy_GetInfo, + // PacketSize = payload.Length, + + // Payload = payload + //}; + + //using var memoryStream = new MemoryStream(); + //using var binaryWriter = new BinaryWriter(memoryStream); + + //binaryWriter.Write(packet.CRC); + //binaryWriter.Write(packet.Protocol); + //binaryWriter.Write(packet.PacketSize); + //binaryWriter.Write(payload); + //binaryWriter.BaseStream.Position = 0; + + + using var fileStream = new FileStream("./mx.dat", FileMode.Create, FileAccess.Write); + using var binaryWriterFile = new BinaryWriter(fileStream); + + binaryWriterFile.Write(payload); + + var mxFile = new StreamContent(binaryWriterFile.BaseStream); + + mxFile.Headers.ContentType = MediaTypeHeaderValue.Parse("application/octet-stream"); + + // Add the in-memory content as a file with a name + var boundary = "BestHTTP_HTTPMultiPartForm_3"; + using var content = new MultipartFormDataContent(boundary); + + content.Add(mxFile, "mx", "1"); + + content.Headers.ContentType = new MediaTypeHeaderValue("multipart/form-data"); + content.Headers.ContentType.Parameters.Add(new NameValueHeaderValue("boundary", boundary)); + + // Set up custom headers to match the request shown + _httpClient.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip")); + _httpClient.DefaultRequestHeaders.Add("Bundle-Version", "li3pmyogha"); + _httpClient.DefaultRequestHeaders.Connection.Add("Keep-Alive"); + _httpClient.DefaultRequestHeaders.Connection.Add("TE"); + _httpClient.DefaultRequestHeaders.Add("Keep-Alive", "timeout=21"); + //_httpClient.DefaultRequestHeaders.Add("TE", "identity"); + _httpClient.DefaultRequestHeaders.UserAgent.ParseAdd("BestHTTP/2 v2.4.0"); + + + // Send the POST request + HttpResponseMessage response = await _httpClient.PostAsync(url, content); + + if (response.IsSuccessStatusCode) + { + string responseData = await response.Content.ReadAsStringAsync(); + Log.Information("Success: " + responseData); + } + + else + { + Log.Information($"Error: {response.StatusCode}"); + } + + } + } + + internal static class PrivateClientServiceExtensions + { + public static void AddPrivateClientService(this IServiceCollection services) + { + services.AddHostedService(); + } + } + + public class SCHALEPacket // total 12 bytes header + { + public uint CRC { get; set; } // 4 bytes + public int Protocol { get; set; } // + public int PacketSize { get; set; } // + + public byte[] Payload { get; set; } + + } +} diff --git a/SCHALE.GameClient/appsettings.Development.json b/SCHALE.GameClient/appsettings.Development.json new file mode 100644 index 0000000..0c208ae --- /dev/null +++ b/SCHALE.GameClient/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/SCHALE.GameClient/appsettings.json b/SCHALE.GameClient/appsettings.json new file mode 100644 index 0000000..e8ccb80 --- /dev/null +++ b/SCHALE.GameClient/appsettings.json @@ -0,0 +1,12 @@ +{ + "Serilog": { + "MinimumLevel": { + "Default": "Information", + "Override": { + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + } + }, + "AllowedHosts": "*" +} diff --git a/SCHALE.GameServer.sln b/SCHALE.GameServer.sln index ee9bd08..ac03295 100644 --- a/SCHALE.GameServer.sln +++ b/SCHALE.GameServer.sln @@ -7,6 +7,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SCHALE.GameServer", "SCHALE EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SCHALE.Common", "SCHALE.Common\SCHALE.Common.csproj", "{D8ED8CB5-EA39-46BE-9236-7FC1F46FE15B}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SCHALE.GameClient", "SCHALE.GameClient\SCHALE.GameClient.csproj", "{EBA95AE2-BBCA-4386-ADB3-FC6EC2102E88}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -21,6 +23,10 @@ Global {D8ED8CB5-EA39-46BE-9236-7FC1F46FE15B}.Debug|Any CPU.Build.0 = Debug|Any CPU {D8ED8CB5-EA39-46BE-9236-7FC1F46FE15B}.Release|Any CPU.ActiveCfg = Release|Any CPU {D8ED8CB5-EA39-46BE-9236-7FC1F46FE15B}.Release|Any CPU.Build.0 = Release|Any CPU + {EBA95AE2-BBCA-4386-ADB3-FC6EC2102E88}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EBA95AE2-BBCA-4386-ADB3-FC6EC2102E88}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EBA95AE2-BBCA-4386-ADB3-FC6EC2102E88}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EBA95AE2-BBCA-4386-ADB3-FC6EC2102E88}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE