login 💀

This commit is contained in:
rafi1212122
2023-05-25 15:28:43 +07:00
parent 106ed39ebd
commit f294d9faa4
11 changed files with 675 additions and 10 deletions

View File

@@ -9,6 +9,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Config.Net" Version="5.1.5" /> <PackageReference Include="Config.Net" Version="5.1.5" />
<PackageReference Include="MongoDB.Driver" Version="2.19.1" /> <PackageReference Include="MongoDB.Driver" Version="2.19.1" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="protobuf-net" Version="3.2.16" /> <PackageReference Include="protobuf-net" Version="3.2.16" />
</ItemGroup> </ItemGroup>

View File

@@ -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<AI> collection = Global.db.GetCollection<AI>("AutoIncrements");
public static int GetNextNumber(string name, int starting = 100)
{
AI AutoIncrement = collection.FindOneAndUpdate(Builders<AI>.Filter.Eq("Name", name), Builders<AI>.Update.SetOnInsert("Count", starting), new FindOneAndUpdateOptions<AI> { IsUpsert = true, ReturnDocument = ReturnDocument.After });
collection.UpdateOne(Builders<AI>.Filter.Eq("Name", AutoIncrement.Name), Builders<AI>.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.
}
}

View File

@@ -14,14 +14,14 @@ namespace Common.Database
UserScheme user = new() UserScheme user = new()
{ {
Name = name, Name = name,
Uid = 1001, Uid = (uint)AutoIncrement.GetNextNumber("UID", 1000),
Nick = "", Nick = "",
Exp = 0, Exp = 0,
Hcoin = 0, Hcoin = 0,
Stamina = 80, Stamina = 80,
SelfDesc = "", SelfDesc = "",
IsFirstLogin = true, IsFirstLogin = true,
Token = Guid.NewGuid(), Token = Guid.NewGuid().ToString(),
WarshipId = 0, WarshipId = 0,
WarshipAvatar = new WarshipAvatarData() WarshipAvatar = new WarshipAvatarData()
{ {
@@ -39,6 +39,18 @@ namespace Common.Database
return user; 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. #pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
public class UserScheme public class UserScheme
{ {
@@ -51,9 +63,7 @@ namespace Common.Database
public int Stamina { get; set; } public int Stamina { get; set; }
public string SelfDesc { get; set; } public string SelfDesc { get; set; }
public bool IsFirstLogin { get; set; } public bool IsFirstLogin { get; set; }
public string Token { get; set; }
[BsonGuidRepresentation(GuidRepresentation.Standard)]
public Guid Token { get; set; }
public int WarshipId { get; set; } public int WarshipId { get; set; }
public WarshipAvatarData WarshipAvatar { get; set; } public WarshipAvatarData WarshipAvatar { get; set; }
public int AssistantAvatarId { get; set; } public int AssistantAvatarId { get; set; }

View File

@@ -19,7 +19,10 @@ namespace Common
[Option(DefaultValue = false)] [Option(DefaultValue = false)]
bool UseLocalCache { get; } bool UseLocalCache { get; }
[Option(DefaultValue = true)]
bool CreateAccountOnLoginAttempt { get; }
[Option(DefaultValue = "mongodb://localhost:27017/PemukulPaku")] [Option(DefaultValue = "mongodb://localhost:27017/PemukulPaku")]
string DatabaseUri { get; } string DatabaseUri { get; }
@@ -32,7 +35,7 @@ namespace Common
public interface IGameserver public interface IGameserver
{ {
[Option(DefaultValue = "127.0.0.1")] [Option(DefaultValue = "127.0.0.1")]
public string Host { get; } public string Host { get; set; }
[Option(DefaultValue = (uint)(16100))] [Option(DefaultValue = (uint)(16100))]
public uint Port { get; } public uint Port { get; }

View File

@@ -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<GranterLoginBody>(Reader.ReadToEndAsync().Result);
GranterLoginBody.GranterLoginBodyData GranterLoginData = JsonConvert.DeserializeObject<GranterLoginBody.GranterLoginBodyData>(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<ShieldVerifyBody>(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<ShieldLoginBody>(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.
}
}
}

View File

@@ -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<object>() } });
});
app.Map("/data_abtest_api/config/experiment/list", (ctx) =>
{
return ctx.Response.WriteAsJsonAsync(new
{
retcode = 0,
success = true,
message = "",
data = Array.Empty<object>()
});
});
app.Map("/account/device/api/listNewerDevices", (ctx) =>
{
return ctx.Response.WriteAsJsonAsync(new
{
data = new {
devices = Array.Empty<object>(),
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<string>(),
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<object>(),
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<CompareProtocolVersionBody>(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.
}
}
}

View File

@@ -24,6 +24,7 @@ namespace HttpServer.Controllers
} }
} }
}; };
ctx.Response.Headers.Add("Content-Type", "application/json");
return ctx.Response.WriteAsync(JsonConvert.SerializeObject(rsp)); return ctx.Response.WriteAsync(JsonConvert.SerializeObject(rsp));
}); });
@@ -59,6 +60,7 @@ namespace HttpServer.Controllers
MihoyoSdkEnv = "2" MihoyoSdkEnv = "2"
} }
}; };
ctx.Response.Headers.Add("Content-Type", "application/json");
return ctx.Response.WriteAsync(JsonConvert.SerializeObject(rsp)); return ctx.Response.WriteAsync(JsonConvert.SerializeObject(rsp));
}); });
} }
@@ -89,7 +91,7 @@ namespace HttpServer.Controllers
BlockErrorDialog = "1", BlockErrorDialog = "1",
ElevatorModelPath = "GameEntry/EVA/StartLoading_Model", ElevatorModelPath = "GameEntry/EVA/StartLoading_Model",
ExResBuffSize = "10485760", ExResBuffSize = "10485760",
IsXxxx = "1", IsXxxx = "0",
MtpSwitch = "0", MtpSwitch = "0",
NetworkFeedbackEnable = "0", NetworkFeedbackEnable = "0",
ShowBulletinButton = "0", ShowBulletinButton = "0",
@@ -188,7 +190,15 @@ namespace HttpServer.Controllers
switch (type) switch (type)
{ {
case "os": 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": case "gf":
if (version.Contains("beta")) if (version.Contains("beta"))
{ {

View File

@@ -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.

View File

@@ -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.

View File

@@ -17,6 +17,8 @@ namespace HttpServer
app.Urls.Add($"https://*:{Global.config.Http.HttpsPort}"); app.Urls.Add($"https://*:{Global.config.Http.HttpsPort}");
DispatchController.AddHandlers(app); DispatchController.AddHandlers(app);
AccountController.AddHandlers(app);
ConfigController.AddHandlers(app);
app.Run(); app.Run();
} }

View File

@@ -1,5 +1,6 @@
using Common.Resources.Proto; using Common.Resources.Proto;
using Common; using Common;
using System.Net.NetworkInformation;
namespace PemukulPaku namespace PemukulPaku
{ {
@@ -12,8 +13,11 @@ namespace PemukulPaku
{ {
Msg = "Hello!" Msg = "Hello!"
}; };
Console.WriteLine(Global.config.Gameserver.Host);
new Thread(HttpServer.Program.Main).Start(); 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); Console.ReadKey(true);
} }
} }