Changed to use a separate account for each email address.

This commit is contained in:
Kei-Luna
2026-05-13 08:15:33 +09:00
parent 5332d5fe1a
commit 41df375e21
7 changed files with 146 additions and 19 deletions

View File

@@ -26,11 +26,14 @@ public class AccountData : BaseDatabaseDataHelper
AccountData? result = null; AccountData? result = null;
DatabaseHelper.GetAllInstance<AccountData>()?.ForEach(account => DatabaseHelper.GetAllInstance<AccountData>()?.ForEach(account =>
{ {
if (account.Username == username) result = account; if (string.Equals(account.Username, username, StringComparison.OrdinalIgnoreCase)) result = account;
}); });
return result; return result;
} }
public static AccountData? GetAccountByEmail(string email)
=> GetAccountByUserName(email);
public static AccountData? GetAccountByUid(int uid, bool force = false) public static AccountData? GetAccountByUid(int uid, bool force = false)
{ {
var result = DatabaseHelper.GetInstance<AccountData>(uid, force); var result = DatabaseHelper.GetInstance<AccountData>(uid, force);
@@ -61,8 +64,15 @@ public class AccountData : BaseDatabaseDataHelper
#region Account #region Account
public static void CreateAccount(string username, int uid, string password) public static AccountData CreateAccount(string username, int uid, string password)
{ {
if (string.IsNullOrWhiteSpace(username))
throw new ArgumentException("Username cannot be empty.", nameof(username));
if (GetAccountByUserName(username) != null)
throw new InvalidOperationException($"Account '{username}' already exists.");
if (uid != 0 && GetAccountByUid(uid) != null)
throw new InvalidOperationException($"UID '{uid}' is already in use.");
var newUid = uid; var newUid = uid;
if (uid == 0) if (uid == 0)
{ {
@@ -84,6 +94,7 @@ public class AccountData : BaseDatabaseDataHelper
SetPassword(account, password); SetPassword(account, password);
DatabaseHelper.CreateInstance(account); DatabaseHelper.CreateInstance(account);
return account;
} }
public static void DeleteAccount(int uid) public static void DeleteAccount(int uid)

View File

@@ -128,6 +128,7 @@ public class CommandTextCHS
{ {
public NoticeTextCHS Notice { get; } = new(); public NoticeTextCHS Notice { get; } = new();
public HelpTextCHS Help { get; } = new(); public HelpTextCHS Help { get; } = new();
public AccountTextCHS Account { get; } = new();
public GirlTextCHS Girl { get; } = new(); public GirlTextCHS Girl { get; } = new();
public GiveAllTextCHS GiveAll { get; } = new(); public GiveAllTextCHS GiveAll { get; } = new();
public DebugTextCHS Debug { get; } = new(); public DebugTextCHS Debug { get; } = new();
@@ -218,6 +219,14 @@ public class HelpTextCHS
public string CommandAlias => "命令别名: "; public string CommandAlias => "命令别名: ";
} }
public class AccountTextCHS
{
public string Desc => "管理 SDK 登录使用的账号映射";
public string Usage => "用法: /account create <邮箱> <UID>";
public string Created => "已创建账号映射: {0} -> UID {1}";
public string CreateFailed => "创建账号映射失败: {0}";
}
/// <summary> /// <summary>
/// path: Game.Command.Girl /// path: Game.Command.Girl
/// </summary> /// </summary>

View File

@@ -128,6 +128,7 @@ public class CommandTextCHT
{ {
public NoticeTextCHT Notice { get; } = new(); public NoticeTextCHT Notice { get; } = new();
public HelpTextCHT Help { get; } = new(); public HelpTextCHT Help { get; } = new();
public AccountTextCHT Account { get; } = new();
public GirlTextCHT Girl { get; } = new(); public GirlTextCHT Girl { get; } = new();
public GiveAllTextCHT GiveAll { get; } = new(); public GiveAllTextCHT GiveAll { get; } = new();
public DebugTextCHT Debug { get; } = new(); public DebugTextCHT Debug { get; } = new();
@@ -218,6 +219,14 @@ public class HelpTextCHT
public string CommandAlias => "命令別名: "; public string CommandAlias => "命令別名: ";
} }
public class AccountTextCHT
{
public string Desc => "管理 SDK 登入使用的帳號映射";
public string Usage => "用法: /account create <郵箱> <UID>";
public string Created => "已建立帳號映射: {0} -> UID {1}";
public string CreateFailed => "建立帳號映射失敗: {0}";
}
/// <summary> /// <summary>
/// path: Game.Command.Girl /// path: Game.Command.Girl
/// </summary> /// </summary>

View File

@@ -87,6 +87,7 @@ public class CommandTextEN
{ {
public NoticeTextEN Notice { get; } = new(); public NoticeTextEN Notice { get; } = new();
public HelpTextEN Help { get; } = new(); public HelpTextEN Help { get; } = new();
public AccountTextEN Account { get; } = new();
public GirlTextEN Girl { get; } = new(); public GirlTextEN Girl { get; } = new();
public GiveAllTextEN GiveAll { get; } = new(); public GiveAllTextEN GiveAll { get; } = new();
public DebugTextEN Debug { get; } = new(); public DebugTextEN Debug { get; } = new();
@@ -184,6 +185,14 @@ public class HelpTextEN
public string CommandAlias => "Command Alias"; public string CommandAlias => "Command Alias";
} }
public class AccountTextEN
{
public string Desc => "Manage account mappings for SDK logins";
public string Usage => "Usage: /account create <email> <uid>";
public string Created => "Created account mapping: {0} -> UID {1}";
public string CreateFailed => "Failed to create account mapping: {0}";
}
/// <summary> /// <summary>
/// path: Game.Command.Girl /// path: Game.Command.Girl
/// </summary> /// </summary>

View File

@@ -0,0 +1,37 @@
using MikuSB.Database.Account;
using MikuSB.Enums.Player;
using MikuSB.Internationalization;
namespace MikuSB.GameServer.Command.Commands;
[CommandInfo("account", "Game.Command.Account.Desc", "Game.Command.Account.Usage", [], [PermEnum.Admin, PermEnum.Support])]
public class CommandAccount : ICommands
{
[CommandMethod("create")]
public async ValueTask Create(CommandArg arg)
{
if (!await arg.CheckArgCnt(2))
return;
var email = arg.Args[0].Trim();
if (!int.TryParse(arg.Args[1], out var uid) || uid <= 0)
{
await arg.SendMsg(I18NManager.Translate("Game.Command.Notice.InvalidArguments"));
return;
}
try
{
var account = AccountData.CreateAccount(email, uid, "");
await arg.SendMsg(I18NManager.Translate("Game.Command.Account.Created", account.Username, account.Uid.ToString()));
}
catch (InvalidOperationException ex)
{
await arg.SendMsg(I18NManager.Translate("Game.Command.Account.CreateFailed", ex.Message));
}
catch (ArgumentException ex)
{
await arg.SendMsg(I18NManager.Translate("Game.Command.Account.CreateFailed", ex.Message));
}
}
}

View File

@@ -21,11 +21,13 @@ public class HandlerReqLogin : Handler
public override async Task OnHandle(Connection connection, byte[] data, ushort seqNo) public override async Task OnHandle(Connection connection, byte[] data, ushort seqNo)
{ {
var req = ReqLogin.Parser.ParseFrom(data); var req = ReqLogin.Parser.ParseFrom(data);
var account = AccountData.GetAccountByUid(1); var account = AccountData.GetAccountByComboToken(req.Token)
?? AccountData.GetAccountByDispatchToken(req.Token)
?? AccountData.GetAccountByUid(10001)
?? AccountData.GetAccountByUid(1);
if (account == null) if (account == null)
{ {
AccountData.CreateAccount("MIKU", 0, ""); account = AccountData.CreateAccount("default@mikusb.local", 10001, "");
account = AccountData.GetAccountByUid(1);
if (account == null) if (account == null)
{ {
await connection.SendPacket(CmdIds.NtfLogout); await connection.SendPacket(CmdIds.NtfLogout);

View File

@@ -1,5 +1,6 @@
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using MikuSB.Configuration; using MikuSB.Configuration;
using MikuSB.Database.Account;
using MikuSB.SdkServer.Models; using MikuSB.SdkServer.Models;
using MikuSB.Util; using MikuSB.Util;
using System.Text; using System.Text;
@@ -12,6 +13,8 @@ public class RouteController : ControllerBase
{ {
public static ConfigContainer Config = ConfigManager.Config; public static ConfigContainer Config = ConfigManager.Config;
private const int DefaultAccountUid = 10001;
public static object BuildServerList(string version = "") public static object BuildServerList(string version = "")
{ {
return new return new
@@ -126,6 +129,51 @@ public class RouteController : ControllerBase
return Ok(rsp); return Ok(rsp);
} }
private static AccountData EnsureDefaultAccount()
{
var account = AccountData.GetAccountByUid(DefaultAccountUid)
?? AccountData.GetAccountByEmail("default@mikusb.local");
if (account != null)
return account;
return AccountData.CreateAccount("default@mikusb.local", DefaultAccountUid, "");
}
private static AccountData ResolveAccountByUid(string? uid)
{
if (int.TryParse(uid, out var parsedUid))
{
var accountByUid = AccountData.GetAccountByUid(parsedUid);
if (accountByUid != null)
return accountByUid;
}
return EnsureDefaultAccount();
}
private static AccountData ResolveAccountForSdkLogin(string? email, string? uid, string? token)
{
if (!string.IsNullOrWhiteSpace(token))
{
var accountByComboToken = AccountData.GetAccountByComboToken(token);
if (accountByComboToken != null)
return accountByComboToken;
var accountByDispatchToken = AccountData.GetAccountByDispatchToken(token);
if (accountByDispatchToken != null)
return accountByDispatchToken;
}
if (!string.IsNullOrWhiteSpace(email))
{
var accountByEmail = AccountData.GetAccountByEmail(email);
if (accountByEmail != null)
return accountByEmail;
}
return ResolveAccountByUid(uid);
}
[HttpGet("/seasun/loginByToken")] [HttpGet("/seasun/loginByToken")]
[HttpPost("/seasun/loginByToken")] [HttpPost("/seasun/loginByToken")]
public IActionResult LoginByToken( public IActionResult LoginByToken(
@@ -135,9 +183,9 @@ public class RouteController : ControllerBase
[FromForm] string? form_token [FromForm] string? form_token
) )
{ {
string finalUid = uid ?? form_uid ?? "10001"; var account = ResolveAccountForSdkLogin(null, uid ?? form_uid, token ?? form_token);
string finalToken = token ?? form_token ?? Guid.NewGuid().ToString("N"); var finalUid = account.Uid.ToString();
int parsedUid = int.TryParse(finalUid, out var numericUid) ? numericUid : 10001; var finalToken = account.GenerateComboToken();
object rsp = new object rsp = new
{ {
@@ -148,14 +196,14 @@ public class RouteController : ControllerBase
isFirstLogin = false, isFirstLogin = false,
isNeedKoreaSciAuth = false, isNeedKoreaSciAuth = false,
ksOpenId = $"ks_{finalUid}", ksOpenId = $"ks_{finalUid}",
nickname = Config.GameServer.GameServerName, nickname = account.Username,
passportId = finalUid, passportId = finalUid,
playerFillAgeUrl = "", playerFillAgeUrl = "",
status = 0, status = 0,
thirdPartyUid = "", thirdPartyUid = "",
token = finalToken, token = finalToken,
type = "guest", type = "guest",
uid = parsedUid uid = account.Uid
}, },
msg = "操作成功" msg = "操作成功"
}; };
@@ -174,9 +222,10 @@ public class RouteController : ControllerBase
[FromForm] string? form_email [FromForm] string? form_email
) )
{ {
string finalUid = uid ?? form_uid ?? "10001"; var finalEmail = email ?? form_email;
string finalToken = token ?? form_token ?? Guid.NewGuid().ToString("N"); var account = ResolveAccountForSdkLogin(finalEmail, uid ?? form_uid, token ?? form_token);
int parsedUid = int.TryParse(finalUid, out var numericUid) ? numericUid : 10001; var finalUid = account.Uid.ToString();
var finalToken = account.GenerateComboToken();
object rsp = new object rsp = new
{ {
@@ -187,14 +236,14 @@ public class RouteController : ControllerBase
isFirstLogin = false, isFirstLogin = false,
isNeedKoreaSciAuth = false, isNeedKoreaSciAuth = false,
ksOpenId = $"ks_{finalUid}", ksOpenId = $"ks_{finalUid}",
nickname = Config.GameServer.GameServerName, nickname = account.Username,
passportId = finalUid, passportId = finalUid,
playerFillAgeUrl = "", playerFillAgeUrl = "",
status = 0, status = 0,
thirdPartyUid = "", thirdPartyUid = "",
token = finalToken, token = finalToken,
type = "guest", type = "guest",
uid = parsedUid uid = account.Uid
}, },
msg = "操作成功" msg = "操作成功"
}; };
@@ -209,7 +258,8 @@ public class RouteController : ControllerBase
[FromForm] string? form_uid [FromForm] string? form_uid
) )
{ {
string uidString = uid ?? form_uid ?? "10001"; var account = ResolveAccountByUid(uid ?? form_uid);
var uidString = account.Uid.ToString();
object rsp = new object rsp = new
{ {
@@ -219,7 +269,7 @@ public class RouteController : ControllerBase
bindAccountTypes = new[] { "google" }, bindAccountTypes = new[] { "google" },
channelUid = uidString, channelUid = uidString,
loginAccountType = "google", loginAccountType = "google",
nickName = Config.GameServer.GameServerName, nickName = account.Username,
passportId = uidString, passportId = uidString,
uid = $"seasun__{uidString}" uid = $"seasun__{uidString}"
}, },
@@ -288,7 +338,7 @@ public class RouteController : ControllerBase
[HttpGet("/account/query-uid/{appId}")] [HttpGet("/account/query-uid/{appId}")]
public IActionResult QueryUid(string appId, [FromQuery] string authInfo) public IActionResult QueryUid(string appId, [FromQuery] string authInfo)
{ {
var uid = ExtractUid(authInfo) ?? "10001"; var uid = ResolveAccountByUid(ExtractUid(authInfo)).Uid.ToString();
object rsp = new object rsp = new
{ {