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