This commit is contained in:
Developer
2026-06-18 10:06:49 +08:00
parent fdd81aef19
commit ebd5dafa2d
922 changed files with 145347 additions and 297 deletions

View File

@@ -1,21 +1,11 @@
using System;
using System.Text;
using System.Threading.Tasks;
using Cysharp.Threading.Tasks;
using IchniOnline.Online.Network;
using IchniOnline.Online.Network.Models;
using TapSDK.Login;
using UnityEngine;
namespace IchniOnline.Online.Network.Models
{
[Serializable]
public class SessionKeyResponseDto
{
public string SessionKey;
public long ExpiresAt;
}
}
namespace IchniOnline.Online.Logic
{
/// <summary>
@@ -51,7 +41,7 @@ namespace IchniOnline.Online.Logic
/// 使用 TapTap 登录的完整流程:
/// TapTap SDK → 第三方登录 API → JWT → 缓存 → 事件
/// </summary>
public static async void LoginWithTapTap()
public static void LoginWithTapTap()
{
if (IsLoggingIn)
{
@@ -65,51 +55,11 @@ namespace IchniOnline.Online.Logic
Action onCanceled = null;
Action<string> onFailed = null;
onSuccess = async account =>
onSuccess = account =>
{
UnsubscribeTapTapEvents(onSuccess, onCanceled, onFailed);
if (account?.accessToken == null)
{
IsLoggingIn = false;
OnLoginFailed?.Invoke("TapTap 登录成功但 accessToken 为空");
return;
}
var dto = new ThirdPartyLoginRequestDto
{
Token = account.accessToken.kid,
TokenType = account.accessToken.tokenType,
MacKey = account.accessToken.macKey,
MacAlgorithm = account.accessToken.macAlgorithm
};
try
{
var result = await IchniOnlineApiClient.Instance.PostAsync<LoginResponseDto>("/api/auth/third-party/login", dto);
Debug.Log(JsonUtility.ToJson(result.Data));
IsLoggingIn = false;
if (result.IsSuccess)
{
LoginCacheManager.SaveAuthSession(result.Data.Token, result.Data);
IchniOnlineApiClient.Instance.JwtToken = result.Data.Token;
OnLoginSuccess?.Invoke(result.Data);
}
else
{
string errorMessage = $"第三方登录 API 失败: {result.Message}";
if (!string.IsNullOrEmpty(result.ErrorDetail))
errorMessage += $" ({result.ErrorDetail})";
OnLoginFailed?.Invoke(errorMessage);
}
}
catch (Exception ex)
{
IsLoggingIn = false;
Debug.LogError($"[IchniOnlineAuthService] TapTap 登录 API 异常: {ex}");
OnLoginFailed?.Invoke($"TapTap 登录 API 异常: {ex.Message}");
}
CompleteTapTapLoginAsync(account).Forget();
};
onCanceled = () =>
@@ -133,6 +83,55 @@ namespace IchniOnline.Online.Logic
ThirdPartyServiceManager.Instance.StartTapTapLogin();
}
private static async UniTaskVoid CompleteTapTapLoginAsync(TapTapAccount account)
{
if (account?.accessToken == null)
{
IsLoggingIn = false;
OnLoginFailed?.Invoke("TapTap 登录成功但 accessToken 为空");
return;
}
var dto = new ThirdPartyLoginRequestDto
{
token = account.accessToken.kid,
tokenType = account.accessToken.tokenType,
macKey = account.accessToken.macKey,
macAlgorithm = account.accessToken.macAlgorithm
};
try
{
var result = await IchniOnlineApiClient.Instance.PostAsync<LoginResponseDto>("/api/auth/third-party/login", dto);
Debug.Log(JsonUtility.ToJson(result.Data));
IsLoggingIn = false;
if (result.IsSuccess && result.Data != null)
{
LoginCacheManager.SaveAuthSession(result.Data.token, result.Data);
IchniOnlineApiClient.Instance.JwtToken = result.Data.token;
OnLoginSuccess?.Invoke(result.Data);
}
else if (result.IsSuccess && result.Data == null)
{
OnLoginFailed?.Invoke("TapTap login successful but account not bound");
}
else
{
string errorMessage = $"第三方登录 API 失败: {result.Message}";
if (!string.IsNullOrEmpty(result.ErrorDetail))
errorMessage += $" ({result.ErrorDetail})";
OnLoginFailed?.Invoke(errorMessage);
}
}
catch (Exception ex)
{
IsLoggingIn = false;
Debug.LogError($"[IchniOnlineAuthService] TapTap 登录 API 异常: {ex}");
OnLoginFailed?.Invoke($"TapTap 登录 API 异常: {ex.Message}");
}
}
private static void UnsubscribeTapTapEvents(
Action<TapTapAccount> onSuccess,
Action onCanceled,
@@ -154,7 +153,7 @@ namespace IchniOnline.Online.Logic
/// 使用用户名和密码登录的完整流程:
/// 获取 session-key → XOR 加密密码 → 登录 API → JWT → 缓存 → 事件
/// </summary>
public static async void LoginWithPassword(string username, string password)
public static void LoginWithPassword(string username, string password)
{
if (IsLoggingIn)
{
@@ -170,10 +169,15 @@ namespace IchniOnline.Online.Logic
IsLoggingIn = true;
LoginWithPasswordAsync(username, password).Forget();
}
private static async UniTaskVoid LoginWithPasswordAsync(string username, string password)
{
try
{
// 1. 获取 session-key
var sessionResult = await IchniOnlineApiClient.Instance.GetAsync<SessionKeyResponseDto>("/api/auth/session-key");
var sessionResult = await IchniOnlineApiClient.Instance.GetAsync<string>("/api/auth/session-key");
if (!sessionResult.IsSuccess)
{
IsLoggingIn = false;
@@ -184,7 +188,7 @@ namespace IchniOnline.Online.Logic
return;
}
string sessionKey = sessionResult.Data.SessionKey;
string sessionKey = sessionResult.Data;
// 2. XOR 加密密码
string encryptedPassword = EncryptPassword(password, sessionKey);
@@ -192,9 +196,9 @@ namespace IchniOnline.Online.Logic
// 3. 调用登录 API
var loginDto = new LoginRequestDto
{
Username = username,
EncryptedPassword = encryptedPassword,
SessionKey = sessionKey
username = username,
encryptedPassword = encryptedPassword,
sessionKey = sessionKey
};
var loginResult = await IchniOnlineApiClient.Instance.PostAsync<LoginResponseDto>("/api/auth/login", loginDto);
@@ -203,8 +207,8 @@ namespace IchniOnline.Online.Logic
if (loginResult.IsSuccess)
{
LoginCacheManager.SaveAuthSession(loginResult.Data.Token, loginResult.Data);
IchniOnlineApiClient.Instance.JwtToken = loginResult.Data.Token;
LoginCacheManager.SaveAuthSession(loginResult.Data.token, loginResult.Data);
IchniOnlineApiClient.Instance.JwtToken = loginResult.Data.token;
OnLoginSuccess?.Invoke(loginResult.Data);
}
else
@@ -231,7 +235,7 @@ namespace IchniOnline.Online.Logic
/// 用户注册流程POST /api/auth/register
/// 注册成功后触发 OnLoginSuccess(null)(注册不返回 JWT
/// </summary>
public static async void Register(string username, string password, string displayName)
public static void Register(string username, string password, string displayName)
{
if (IsLoggingIn)
{
@@ -247,16 +251,21 @@ namespace IchniOnline.Online.Logic
IsLoggingIn = true;
RegisterAsync(username, password, displayName).Forget();
}
private static async UniTaskVoid RegisterAsync(string username, string password, string displayName)
{
try
{
var registerDto = new RegisterRequestDto
{
Username = username,
Password = password,
DisplayName = displayName
username = username,
password = password,
displayName = displayName
};
var result = await IchniOnlineApiClient.Instance.PostAsync<object>("/api/auth/register", registerDto);
var result = await IchniOnlineApiClient.Instance.PostAsync<UserResponseDto>("/api/auth/register", registerDto);
IsLoggingIn = false;