Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file.
78 changes: 30 additions & 48 deletions PCL.Neo.Core/Service/Accounts/AccountService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,6 @@
private readonly string _selectedAccountFilePath;
private readonly JsonSerializerOptions _jsonOptions;

// TODO: 配置Yggdrasil服务API密钥
// fix: yggdrasil doesn't have any access key ( from: whitecat346)
// /cc @BL077
private readonly string _yggdrasilApiKey = "";

// TODO: 配置默认的Yggdrasil API超时时间(毫秒)
private readonly int _yggdrasilApiTimeoutMs = 10000;

private List<BaseAccount> _cachedAccounts = [];
private string? _selectedAccountUuid;
private bool _isLoaded;
Expand Down Expand Up @@ -437,54 +429,44 @@
return account;
}

this.LogAccountInfo($"开始刷新微软账户令牌: {account.UserName}");

var refreshResult = await _microsoftAuthService.RefreshTokenAsync(account.OAuthToken.RefreshToken);
if (refreshResult.IsFailure)
{
this.LogAccountError($"刷新微软账户令牌失败: {account.UserName}", refreshResult.Error);
throw refreshResult.Error!;
}

var tokenInfo = refreshResult.Value;
this.LogAccountDebug("获取到新的OAuth令牌");

// 获取Minecraft令牌
var mcTokenResult = await _microsoftAuthService.GetUserMinecraftAccessTokenAsync(tokenInfo.AccessToken);
if (mcTokenResult.IsFailure)
try
{
this.LogAccountError($"获取Minecraft令牌失败: {account.UserName}", mcTokenResult.Error);
throw mcTokenResult.Error;
}
this.LogAccountInfo($"开始刷新微软账户令牌: {account.UserName}");

this.LogAccountDebug("获取到新的Minecraft令牌");
var refreshResult = await _microsoftAuthService.RefreshTokenAsync(account.OAuthToken.RefreshToken);

// 获取用户信息
var accountInfoResult = await _microsoftAuthService.GetUserAccountInfoAsync(mcTokenResult.Value);
if (accountInfoResult.IsFailure)
{
this.LogAccountError($"获取账户信息失败: {account.UserName}", accountInfoResult.Error);
throw accountInfoResult.Error!;
}
this.LogAccountDebug("获取到新的OAuth令牌");

var accountInfo = accountInfoResult.Value;
// 获取Minecraft令牌
var mcTokenResult =
await _microsoftAuthService.GetUserMinecraftAccessTokenAsync(refreshResult.AccessToken);

// 创建更新后的账户
var updatedAccount = account with
{
OAuthToken = tokenInfo,
McAccessToken = mcTokenResult.Value,
UserName = accountInfo.UserName,
Skins = accountInfo.Skins,
Capes = accountInfo.Capes
};
this.LogAccountDebug("获取到新的Minecraft令牌");

this.LogAccountInfo($"微软账户令牌刷新成功: {updatedAccount.UserName}");
// 获取用户信息
var accountInfoResult = await _microsoftAuthService.GetUserAccountInfoAsync(mcTokenResult);

// 保存更新后的账户
await SaveAccountAsync(updatedAccount);
// 创建更新后的账户
var updatedAccount = account with
{
OAuthToken = refreshResult,
McAccessToken = mcTokenResult,
UserName = accountInfoResult.UserName,
Skins = accountInfoResult.Skins,
Capes = accountInfoResult.Capes
};
this.LogAccountInfo($"微软账户令牌刷新成功: {updatedAccount.UserName}");

// 保存更新后的账户
await SaveAccountAsync(updatedAccount);

return updatedAccount;
return updatedAccount;
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
catch (Exception ex) when (ex is not ArgumentNullException)
{
Expand All @@ -494,7 +476,7 @@
}

/// <inheritdoc />
public async Task<YggdrasilAccount> ValidateYggdrasilAccountAsync(string serverUrl, string username,

Check warning on line 479 in PCL.Neo.Core/Service/Accounts/AccountService.cs

View workflow job for this annotation

GitHub Actions / build-MacOsApp

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 479 in PCL.Neo.Core/Service/Accounts/AccountService.cs

View workflow job for this annotation

GitHub Actions / build-AppImage

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.
string password)
{
try
Expand Down Expand Up @@ -596,7 +578,7 @@
}

/// <inheritdoc />
public async Task<YggdrasilAccount> RefreshYggdrasilAccountAsync(YggdrasilAccount account)

Check warning on line 581 in PCL.Neo.Core/Service/Accounts/AccountService.cs

View workflow job for this annotation

GitHub Actions / build-MacOsApp

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 581 in PCL.Neo.Core/Service/Accounts/AccountService.cs

View workflow job for this annotation

GitHub Actions / build-AppImage

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.
{
try
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ public class DeviceFlowAwaitUser(string userCode, string verificationUri) : Devi

public class DeviceFlowPolling : DeviceFlowState;

public class DeviceFlowDeclined : DeviceFlowState;
public class DeviceFlowDeclined : Exception;

public class DeviceFlowExpired : DeviceFlowState;
public class DeviceFlowExpired : Exception;

public class DeviceFlowBadVerificationCode : DeviceFlowState;
public class DeviceFlowBadVerificationCode : Exception;

public class DeviceFlowGetAccountInfo : DeviceFlowState;

Expand All @@ -26,7 +26,7 @@ public class DeviceFlowSucceeded(MsaAccount account) : DeviceFlowState
public MsaAccount Account { get; } = account;
}

public class DeviceFlowUnkonw : DeviceFlowState;
public class DeviceFlowUnkonw : Exception;

public class DeviceFlowInternetError : DeviceFlowState;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,35 +17,35 @@ public interface IMicrosoftAuthService
/// 获取设备码
/// </summary>
/// <returns>获取到的设备码信息,会在失败的时候返回异常</returns>
Task<Result<DeviceCodeData.DeviceCodeInfo, HttpError>> RequestDeviceCodeAsync();
Task<DeviceCodeData.DeviceCodeInfo> RequestDeviceCodeAsync();

/// <summary>
/// 开始轮询服务器
/// </summary>
/// <param name="deviceCode">设备码</param>
/// <param name="interval">轮询间隔</param>
/// <returns>轮询结果</returns>
Task<Result<DeviceCodeData.DeviceCodeAccessToken, DeviceFlowError>> PollForTokenAsync(string deviceCode,
Task<DeviceCodeData.DeviceCodeAccessToken> PollForTokenAsync(string deviceCode,
int interval);

/// <summary>
/// 获取玩家全部信息
/// </summary>
/// <param name="accessToken">通行Token</param>
/// <returns>玩家信息</returns>
Task<Result<string, NotHaveGameException>> GetUserMinecraftAccessTokenAsync(string accessToken);
Task<string> GetUserMinecraftAccessTokenAsync(string accessToken);

/// <summary>
/// 获取玩家的账户信息
/// </summary>
/// <param name="accessToken">需要的Token</param>
/// <returns>账户信息</returns>
Task<Result<DeviceCodeData.McAccountInfo, Exception>> GetUserAccountInfoAsync(string accessToken);
Task<DeviceCodeData.McAccountInfo> GetUserAccountInfoAsync(string accessToken);

/// <summary>
/// 刷新玩家的OAuth2 Token
/// </summary>
/// <param name="refreshToken">OAuth2的刷新Token</param>
/// <returns>新的Token</returns>
Task<Result<OAuthTokenData, Exception>> RefreshTokenAsync(string refreshToken);
Task<OAuthTokenData> RefreshTokenAsync(string refreshToken);
}
Loading
Loading