From f294d9faa4919cc9b93e28ff137f777ec377ba9a Mon Sep 17 00:00:00 2001 From: rafi1212122 Date: Thu, 25 May 2023 15:28:43 +0700 Subject: [PATCH] =?UTF-8?q?login=20=F0=9F=92=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Common/Common.csproj | 1 + Common/Database/AutoIncrement.cs | 28 +++ Common/Database/User.cs | 20 +- Common/Program.cs | 7 +- HttpServer/Controllers/AccountController.cs | 170 ++++++++++++++ HttpServer/Controllers/ConfigController.cs | 226 +++++++++++++++++++ HttpServer/Controllers/DispatchController.cs | 14 +- HttpServer/Models/Account.cs | 187 +++++++++++++++ HttpServer/Models/Config.cs | 24 ++ HttpServer/Program.cs | 2 + Program.cs | 6 +- 11 files changed, 675 insertions(+), 10 deletions(-) create mode 100644 Common/Database/AutoIncrement.cs create mode 100644 HttpServer/Controllers/AccountController.cs create mode 100644 HttpServer/Controllers/ConfigController.cs create mode 100644 HttpServer/Models/Account.cs create mode 100644 HttpServer/Models/Config.cs diff --git a/Common/Common.csproj b/Common/Common.csproj index 50d105f..4ccc41d 100644 --- a/Common/Common.csproj +++ b/Common/Common.csproj @@ -9,6 +9,7 @@ + diff --git a/Common/Database/AutoIncrement.cs b/Common/Database/AutoIncrement.cs new file mode 100644 index 0000000..f01dab3 --- /dev/null +++ b/Common/Database/AutoIncrement.cs @@ -0,0 +1,28 @@ +using Common.Resources.Proto; +using MongoDB.Bson.Serialization.Attributes; +using MongoDB.Bson; +using MongoDB.Driver; + +namespace Common.Database +{ + public class AutoIncrement + { + public static readonly IMongoCollection collection = Global.db.GetCollection("AutoIncrements"); + + public static int GetNextNumber(string name, int starting = 100) + { + AI AutoIncrement = collection.FindOneAndUpdate(Builders.Filter.Eq("Name", name), Builders.Update.SetOnInsert("Count", starting), new FindOneAndUpdateOptions { IsUpsert = true, ReturnDocument = ReturnDocument.After }); + collection.UpdateOne(Builders.Filter.Eq("Name", AutoIncrement.Name), Builders.Update.Inc("Count", 1)); + return AutoIncrement.Count + 1; + } + +#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. + public class AI + { + public ObjectId Id { get; set; } + public string Name { get; set; } + public int Count { get; set; } + } +#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. + } +} diff --git a/Common/Database/User.cs b/Common/Database/User.cs index c146adc..52c1b1d 100644 --- a/Common/Database/User.cs +++ b/Common/Database/User.cs @@ -14,14 +14,14 @@ namespace Common.Database UserScheme user = new() { Name = name, - Uid = 1001, + Uid = (uint)AutoIncrement.GetNextNumber("UID", 1000), Nick = "", Exp = 0, Hcoin = 0, Stamina = 80, SelfDesc = "", IsFirstLogin = true, - Token = Guid.NewGuid(), + Token = Guid.NewGuid().ToString(), WarshipId = 0, WarshipAvatar = new WarshipAvatarData() { @@ -39,6 +39,18 @@ namespace Common.Database return user; } + public static UserScheme FromName(string name) + { + UserScheme? user = collection.AsQueryable().Where(d => d.Name == name).FirstOrDefault(); + return user ?? CreateUser(name); + } + + public static UserScheme? FromToken(string token) + { + UserScheme? user = collection.AsQueryable().Where(d => d.Token == token).FirstOrDefault(); + return user; + } + #pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. public class UserScheme { @@ -51,9 +63,7 @@ namespace Common.Database public int Stamina { get; set; } public string SelfDesc { get; set; } public bool IsFirstLogin { get; set; } - - [BsonGuidRepresentation(GuidRepresentation.Standard)] - public Guid Token { get; set; } + public string Token { get; set; } public int WarshipId { get; set; } public WarshipAvatarData WarshipAvatar { get; set; } public int AssistantAvatarId { get; set; } diff --git a/Common/Program.cs b/Common/Program.cs index c6568fc..a367ad5 100644 --- a/Common/Program.cs +++ b/Common/Program.cs @@ -19,7 +19,10 @@ namespace Common [Option(DefaultValue = false)] bool UseLocalCache { get; } - + + [Option(DefaultValue = true)] + bool CreateAccountOnLoginAttempt { get; } + [Option(DefaultValue = "mongodb://localhost:27017/PemukulPaku")] string DatabaseUri { get; } @@ -32,7 +35,7 @@ namespace Common public interface IGameserver { [Option(DefaultValue = "127.0.0.1")] - public string Host { get; } + public string Host { get; set; } [Option(DefaultValue = (uint)(16100))] public uint Port { get; } diff --git a/HttpServer/Controllers/AccountController.cs b/HttpServer/Controllers/AccountController.cs new file mode 100644 index 0000000..ec28b64 --- /dev/null +++ b/HttpServer/Controllers/AccountController.cs @@ -0,0 +1,170 @@ +using Newtonsoft.Json; +using HttpServer.Models; +using Common.Database; +using Newtonsoft.Json.Linq; + +namespace HttpServer.Controllers +{ + public class AccountController + { + public static void AddHandlers(WebApplication app) + { + app.Map("/account/risky/api/check", (HttpContext ctx) => + { + RiskyCheck rsp = new() + { + Retcode = 0, + Message = "", + Data = new RiskyCheck.DataScheme() + { + Id = "", + Action = "ACTION_NONE", + Geetest = null + } + }; + + ctx.Response.Headers.Add("Content-Type", "application/json"); + + return ctx.Response.WriteAsync(JsonConvert.SerializeObject(rsp)); + }); + +#pragma warning disable CS8600, CS8602 // Converting null literal or possible null value to non-nullable type. + app.MapPost("/{game_biz}/combo/granter/login/v2/login", (ctx) => + { + StreamReader Reader = new(ctx.Request.Body); + GranterLoginBody Data = JsonConvert.DeserializeObject(Reader.ReadToEndAsync().Result); + GranterLoginBody.GranterLoginBodyData GranterLoginData = JsonConvert.DeserializeObject(Data.Data); + + + return ctx.Response.WriteAsJsonAsync(new + { + retcode = 0, + message = "OK", + data = new { + combo_id = "0", + open_id = GranterLoginData.Uid, + combo_token = GranterLoginData.Token, + data = JsonConvert.SerializeObject(new + { + guest = GranterLoginData.Guest + }), + heartbeat = false, + account_type = 1, + } + }); + }); + + app.MapPost("/{game_biz}/mdk/shield/api/verify", (ctx) => + { + StreamReader Reader = new(ctx.Request.Body); + ShieldVerifyBody Data = JsonConvert.DeserializeObject(Reader.ReadToEndAsync().Result); + User.UserScheme? user = User.FromToken(Data.Token); + + ShieldLoginResponse rsp = new() + { + Retcode = 0, + Message = "OK", + Data = new() + { + Account = null + } + }; + + if (user != null) + { + rsp.Data = new() + { + Account = new() + { + Uid = user.Uid, + Name = user.Name, + Email = "", + Mobile = "", + IsEmailVerify = "0", + Realname = "", + IdentityCard = "", + Token = user.Token.ToString(), + SafeMobile = "", + FacebookName = "", + GoogleName = "", + TwitterName = "", + GameCenterName = "", + AppleName = "", + SonyName = "", + TapName = "", + Country = "SG", + ReactivateTicket = "", + AreaCode = "**", + DeviceGrantTicket = "", + SteamName = "", + UnmaskedEmail = "", + UnmaskedEmailType = 0 + }, + DeviceGrantRequired = false, + SafeMoblieRequired = false, + RealpersonRequired = false, + ReactivateRequired = false, + RealnameOperation = "None" + }; + } + + ctx.Response.Headers.Add("Content-Type", "application/json"); + + return ctx.Response.WriteAsync(JsonConvert.SerializeObject(rsp)); + }); + + app.MapPost("/{game_biz}/mdk/shield/api/login", (ctx) => + { + StreamReader Reader = new(ctx.Request.Body); + ShieldLoginBody Data = JsonConvert.DeserializeObject(Reader.ReadToEndAsync().Result); + + User.UserScheme user = User.FromName(Data.Account); + + ShieldLoginResponse rsp = new() + { + Retcode = 0, + Message = "OK", + Data = new() + { + Account = new() + { + Uid = user.Uid, + Name = user.Name, + Email = "", + Mobile = "", + IsEmailVerify = "0", + Realname = "", + IdentityCard = "", + Token = user.Token.ToString(), + SafeMobile = "", + FacebookName = "", + GoogleName = "", + TwitterName = "", + GameCenterName = "", + AppleName = "", + SonyName = "", + TapName = "", + Country = "**", + ReactivateTicket = "", + AreaCode = "**", + DeviceGrantTicket = "", + SteamName = "", + UnmaskedEmail = "", + UnmaskedEmailType = 0 + }, + DeviceGrantRequired = false, + SafeMoblieRequired = false, + RealpersonRequired = false, + ReactivateRequired = false, + RealnameOperation = "None" + } + }; + + ctx.Response.Headers.Add("Content-Type", "application/json"); + + return ctx.Response.WriteAsync(JsonConvert.SerializeObject(rsp)); + }); +#pragma warning restore CS8600, CS8602 // Converting null literal or possible null value to non-nullable type. + } + } +} diff --git a/HttpServer/Controllers/ConfigController.cs b/HttpServer/Controllers/ConfigController.cs new file mode 100644 index 0000000..08cf991 --- /dev/null +++ b/HttpServer/Controllers/ConfigController.cs @@ -0,0 +1,226 @@ +using Common; +using HttpServer.Models; +using Newtonsoft.Json; + +namespace HttpServer.Controllers +{ + public class ConfigController + { + public static void AddHandlers(WebApplication app) + { + app.Map("/{game_biz}/mdk/agreement/api/getAgreementInfos", (HttpContext ctx) => + { + return ctx.Response.WriteAsJsonAsync(new { retcode = 0, message = "OK", data = new { marketing_agreements = Array.Empty() } }); + }); + + app.Map("/data_abtest_api/config/experiment/list", (ctx) => + { + return ctx.Response.WriteAsJsonAsync(new + { + retcode = 0, + success = true, + message = "", + data = Array.Empty() + }); + }); + + app.Map("/account/device/api/listNewerDevices", (ctx) => + { + return ctx.Response.WriteAsJsonAsync(new + { + data = new { + devices = Array.Empty(), + latest_id = "0" + }, + message = "OK", + retcode = 0 + }); + }); + + app.Map("/{game_biz}/combo/granter/api/getConfig", (HttpContext ctx) => + { + return ctx.Response.WriteAsJsonAsync(new + { + retcode = 0, + message = "OK", + data = new { + protocol = true, + qr_enabled = false, + log_level = "DEBUG", + announce_url = $"https://{Global.config.Gameserver.Host}/bh3/announcement/", + push_alias_type = 2, + disable_ysdk_guard = false, + enable_announce_pic_popup = false, + app_name = "崩坏3-东南亚", + qr_enabled_apps = new { bbs = false, cloud = false }, + qr_app_icons = new { app = "", bbs = "", cloud = "" }, + qr_cloud_display_name = "" + } + }); + }); + + app.Map("/bh3_os/mdk/shield/api/loadConfig", (HttpContext ctx) => + { + return ctx.Response.WriteAsJsonAsync(new + { + retcode = 0, + message = "OK", + data = new + { + id = 16, + game_key = ctx.Request.Query["game_key"], + client = "PC", + identity = "I_IDENTITY", + guest = false, + ignore_versions = "", + scene = "S_NORMAL", + name = "崩坏3rd-东南亚", + disable_regist = false, + enable_email_captcha = false, + thirdparty = Array.Empty(), + disable_mmt = false, + server_guest = false, + thirdparty_ignore = new { }, + enable_ps_bind_account = false, + thirdparty_login_configs = new { }, + initialize_firebase = false + } + }); + }); + + app.Map("/combo/box/api/config/sdk/combo", (HttpContext ctx) => + { + return ctx.Response.WriteAsJsonAsync(new + { + retcode = 0, + message = "OK", + data = new + { + vals = new + { + list_price_tierv2_enable = "false", + network_report_config = new + { + enable = 0, + status_codes = new int[] { 206 }, + url_paths = new string[] { "dataUpload", "red_dot" }, + }, + kibana_pc_config = new + { + enable = 1, + level = "Debug", + modules = new string[] { "download" } + }, + }, + }, + }); + }); + + app.Map("/device-fp/api/getExtList", (ctx) => + { + return ctx.Response.WriteAsJsonAsync(new + { + retcode = 0, + message = "OK", + data = new + { + code = 200, + msg = "ok", + ext_list = new string[] { + + "cpuName", + "deviceModel", + "deviceName", + "deviceType", + "deviceUID", + "gpuID", + "gpuName", + "gpuAPI", + "gpuVendor", + "gpuVersion", + "gpuMemory", + "osVersion", + "cpuCores", + "cpuFrequency", + "gpuVendorID", + "isGpuMultiTread", + "memorySize", + "screenSize", + "engineName", + "addressMAC" + }, + pkg_list = Array.Empty(), + pkg_str = "/vK5WTh5SS3SAj8Zm0qPWg==" + }, + }); + }); + + app.Map("/device-fp/api/getFp", (ctx) => + { + return ctx.Response.WriteAsJsonAsync(new + { + data = new + { + code = 200, + device_fp = ctx.Request.Query["device_fp"], + msg = "ok", + }, + message = "OK", + retcode = 0, + }); + }); + + app.Map("/report", (ctx) => + { + return ctx.Response.WriteAsync("GET LOG"); + }); + + app.Map("/admin/mi18n/{*remainder}", (ctx) => + { + return ctx.Response.WriteAsJsonAsync(new + { + version = 74 + }); + }); + + app.Map("/sdk/dataUpload", (ctx) => + { + return ctx.Response.WriteAsJsonAsync(new + { + code = 0 + }); + }); + +#pragma warning disable CS8600, CS8602 // Converting null literal or possible null value to non-nullable type. + app.MapPost("/{game_biz}/combo/granter/api/compareProtocolVersion", (ctx) => + { + StreamReader Reader = new(ctx.Request.Body); + CompareProtocolVersionBody Data = JsonConvert.DeserializeObject(Reader.ReadToEndAsync().Result); + + return ctx.Response.WriteAsJsonAsync(new + { + retcode = 0, + message = "OK", + data = new + { + modified = true, + protocol = new + { + id = 0, + app_id = Data.AppId, + language = Data.Language, + user_proto = "", + priv_proto = "", + major = 0, + minimum = 3, + create_time = "0", + teenager_proto = "", + third_proto = "" + } + } + }); + }); +#pragma warning restore CS8600, CS8602 // Converting null literal or possible null value to non-nullable type. + } + } +} diff --git a/HttpServer/Controllers/DispatchController.cs b/HttpServer/Controllers/DispatchController.cs index e028f77..98397fe 100644 --- a/HttpServer/Controllers/DispatchController.cs +++ b/HttpServer/Controllers/DispatchController.cs @@ -24,6 +24,7 @@ namespace HttpServer.Controllers } } }; + ctx.Response.Headers.Add("Content-Type", "application/json"); return ctx.Response.WriteAsync(JsonConvert.SerializeObject(rsp)); }); @@ -59,6 +60,7 @@ namespace HttpServer.Controllers MihoyoSdkEnv = "2" } }; + ctx.Response.Headers.Add("Content-Type", "application/json"); return ctx.Response.WriteAsync(JsonConvert.SerializeObject(rsp)); }); } @@ -89,7 +91,7 @@ namespace HttpServer.Controllers BlockErrorDialog = "1", ElevatorModelPath = "GameEntry/EVA/StartLoading_Model", ExResBuffSize = "10485760", - IsXxxx = "1", + IsXxxx = "0", MtpSwitch = "0", NetworkFeedbackEnable = "0", ShowBulletinButton = "0", @@ -188,7 +190,15 @@ namespace HttpServer.Controllers switch (type) { case "os": - return new string[] { }; + return Global.config.UseLocalCache ? new string[] + { + $"{Global.config.Gameserver.Host}/com.miHoYo.bh3oversea", + $"{Global.config.Gameserver.Host}/com.miHoYo.bh3oversea" + } : new string[] + { + "hk-bigfile-os-mihayo.akamaized.net/com.miHoYo.bh3oversea", + "bigfile-aliyun-os.honkaiimpact3.com/com.miHoYo.bh3oversea" + }; case "gf": if (version.Contains("beta")) { diff --git a/HttpServer/Models/Account.cs b/HttpServer/Models/Account.cs new file mode 100644 index 0000000..ffcbdb2 --- /dev/null +++ b/HttpServer/Models/Account.cs @@ -0,0 +1,187 @@ +using Newtonsoft.Json; + + +#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. +namespace HttpServer.Models +{ + public partial class RiskyCheck + { + [JsonProperty("retcode")] + public int Retcode { get; set; } + + [JsonProperty("message")] + public string Message { get; set; } + + [JsonProperty("data")] + public DataScheme Data { get; set; } + + public partial class DataScheme + { + [JsonProperty("id")] + public string Id { get; set; } + + [JsonProperty("action")] + public string Action { get; set; } + + [JsonProperty("geetest")] + public object? Geetest { get; set; } + } + } + + public partial class GranterLoginBody + { + [JsonProperty("app_id")] + public int AppId { get; set; } + + [JsonProperty("channel_id")] + public int ChannelId { get; set; } + + [JsonProperty("data")] + public string Data { get; set; } + + [JsonProperty("device")] + public string Device { get; set; } + + [JsonProperty("sign")] + public string Sign { get; set; } + + public partial class GranterLoginBodyData + { + [JsonProperty("uid")] + public string Uid { get; set; } + + [JsonProperty("guest")] + public bool Guest { get; set; } + + [JsonProperty("token")] + public string Token { get; set; } + } + } + + public partial class ShieldVerifyBody + { + [JsonProperty("token")] + public string Token { get; set; } + + [JsonProperty("uid")] + public string Uid { get; set; } + } + + public partial class ShieldLoginBody + { + [JsonProperty("account")] + public string Account { get; set; } + + [JsonProperty("is_crypto")] + public bool IsCrypto { get; set; } + + [JsonProperty("password")] + public string Password { get; set; } + } + + public partial class ShieldLoginResponse + { + [JsonProperty("data")] + public ShieldLoginResponseData Data { get; set; } + + [JsonProperty("message")] + public string Message { get; set; } + + [JsonProperty("retcode")] + public long Retcode { get; set; } + + public partial class ShieldLoginResponseData + { + [JsonProperty("account")] + public ShieldLoginResponseDataAccount? Account { get; set; } + + [JsonProperty("device_grant_required")] + public bool DeviceGrantRequired { get; set; } + + [JsonProperty("reactivate_required")] + public bool ReactivateRequired { get; set; } + + [JsonProperty("realname_operation")] + public string RealnameOperation { get; set; } + + [JsonProperty("realperson_required")] + public bool RealpersonRequired { get; set; } + + [JsonProperty("safe_moblie_required")] + public bool SafeMoblieRequired { get; set; } + + public partial class ShieldLoginResponseDataAccount + { + [JsonProperty("apple_name")] + public string AppleName { get; set; } + + [JsonProperty("area_code")] + public string AreaCode { get; set; } + + [JsonProperty("country")] + public string Country { get; set; } + + [JsonProperty("device_grant_ticket")] + public string DeviceGrantTicket { get; set; } + + [JsonProperty("email")] + public string Email { get; set; } + + [JsonProperty("facebook_name")] + public string FacebookName { get; set; } + + [JsonProperty("game_center_name")] + public string GameCenterName { get; set; } + + [JsonProperty("google_name")] + public string GoogleName { get; set; } + + [JsonProperty("identity_card")] + public string IdentityCard { get; set; } + + [JsonProperty("is_email_verify")] + public string IsEmailVerify { get; set; } + + [JsonProperty("mobile")] + public string Mobile { get; set; } + + [JsonProperty("name")] + public string Name { get; set; } + + [JsonProperty("reactivate_ticket")] + public string ReactivateTicket { get; set; } + + [JsonProperty("realname")] + public string Realname { get; set; } + + [JsonProperty("safe_mobile")] + public string SafeMobile { get; set; } + + [JsonProperty("sony_name")] + public string SonyName { get; set; } + + [JsonProperty("steam_name")] + public string SteamName { get; set; } + + [JsonProperty("tap_name")] + public string TapName { get; set; } + + [JsonProperty("token")] + public string Token { get; set; } + + [JsonProperty("twitter_name")] + public string TwitterName { get; set; } + + [JsonProperty("uid")] + public long Uid { get; set; } + + [JsonProperty("unmasked_email")] + public string UnmaskedEmail { get; set; } + + [JsonProperty("unmasked_email_type")] + public long UnmaskedEmailType { get; set; } + } + } + } +} +#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. \ No newline at end of file diff --git a/HttpServer/Models/Config.cs b/HttpServer/Models/Config.cs new file mode 100644 index 0000000..2fa78f3 --- /dev/null +++ b/HttpServer/Models/Config.cs @@ -0,0 +1,24 @@ +using Newtonsoft.Json; + +#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. +namespace HttpServer.Models +{ + public partial class CompareProtocolVersionBody + { + [JsonProperty("app_id")] + public string AppId { get; set; } + + [JsonProperty("channel_id")] + public string ChannelId { get; set; } + + [JsonProperty("language")] + public string Language { get; set; } + + [JsonProperty("major")] + public string Major { get; set; } + + [JsonProperty("minimum")] + public string Minimum { get; set; } + } +} +#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. \ No newline at end of file diff --git a/HttpServer/Program.cs b/HttpServer/Program.cs index 19bb2c3..d458630 100644 --- a/HttpServer/Program.cs +++ b/HttpServer/Program.cs @@ -17,6 +17,8 @@ namespace HttpServer app.Urls.Add($"https://*:{Global.config.Http.HttpsPort}"); DispatchController.AddHandlers(app); + AccountController.AddHandlers(app); + ConfigController.AddHandlers(app); app.Run(); } diff --git a/Program.cs b/Program.cs index b401d15..1314649 100644 --- a/Program.cs +++ b/Program.cs @@ -1,5 +1,6 @@ using Common.Resources.Proto; using Common; +using System.Net.NetworkInformation; namespace PemukulPaku { @@ -12,8 +13,11 @@ namespace PemukulPaku { Msg = "Hello!" }; - Console.WriteLine(Global.config.Gameserver.Host); new Thread(HttpServer.Program.Main).Start(); + + Global.config.Gameserver.Host = NetworkInterface.GetAllNetworkInterfaces().Where(i => i.NetworkInterfaceType != NetworkInterfaceType.Loopback && i.OperationalStatus == OperationalStatus.Up).First().GetIPProperties().UnicastAddresses.Where(a => a.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork).First().Address.ToString(); + Console.WriteLine(Global.config.Gameserver.Host); + Console.ReadKey(true); } }