From 9bc440d52687dfe135fe1789b687e5275a94e07f Mon Sep 17 00:00:00 2001 From: awaEric233 Date: Sat, 13 Jun 2026 18:31:53 +0800 Subject: [PATCH 1/2] =?UTF-8?q?Feat:=20=E6=B7=BB=E5=8A=A0=20Microsoft=20?= =?UTF-8?q?=E7=99=BB=E5=BD=95=E5=BC=82=E5=B8=B8=E6=A3=80=E6=B5=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Authentication/MicrosoftAuthentication.cs | 25 +++++++++++++++++++ .../Authentication/GetTokenErrorResponse.cs | 15 +++++++++++ 2 files changed, 40 insertions(+) create mode 100644 Models/Authentication/GetTokenErrorResponse.cs diff --git a/Authentication/MicrosoftAuthentication.cs b/Authentication/MicrosoftAuthentication.cs index 945d28b..d7bf125 100644 --- a/Authentication/MicrosoftAuthentication.cs +++ b/Authentication/MicrosoftAuthentication.cs @@ -104,6 +104,31 @@ public async ValueTask GetTokenResponse(RetrieveDeviceCode dev ClientId = deviceCodeInfo.ClientId }; } + else + { + // 先判断是否正在等待中,直接使用 Contains,避免额外解析开销 + if (!tokenJson.Contains("authorization_pending")) + { + try + { + var errorData = tokenJson.ToJsonEntry(); + switch (errorData.Error) + { + case "authorization_declined": + throw new Exception("用户拒绝了授权"); + case "bad_verification_code": + throw new Exception("提交的 device_code 无效"); + case "expired_token": + throw new TimeoutException("登录已超时,请重试"); // 避免轮询时正好过期导致抓不到异常 + // 实际上还有其他的错误类型,但按理说不会出现,比如 slow_down + } + } + catch (Exception e) + { + throw new Exception("轮询获取 Token 错误:" + e.Message); + } + } + } await Task.Delay(pollingInterval); } diff --git a/Models/Authentication/GetTokenErrorResponse.cs b/Models/Authentication/GetTokenErrorResponse.cs new file mode 100644 index 0000000..d552a33 --- /dev/null +++ b/Models/Authentication/GetTokenErrorResponse.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace StarLight_Core.Models.Authentication; + +/// +/// 令牌错误信息 +/// +public class GetTokenErrorResponse +{ + /// + /// 验证令牌 + /// + [JsonPropertyName("error")] + public string Error { get; set; } +} \ No newline at end of file From 641d444bdc07b3a77f53f18ccb004782168ed03e Mon Sep 17 00:00:00 2001 From: awaEric233 Date: Sat, 13 Jun 2026 20:58:37 +0800 Subject: [PATCH 2/2] =?UTF-8?q?Fix:=20=E4=BF=AE=E5=A4=8D=E6=9C=AA=E7=9F=A5?= =?UTF-8?q?=E9=94=99=E8=AF=AF=E4=B8=8D=E4=BC=9A=E6=8A=9B=E5=87=BA=E5=BC=82?= =?UTF-8?q?=E5=B8=B8=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Skin/Fetchers/YggdrasilSkinFetcher.cs | 44 +++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 Skin/Fetchers/YggdrasilSkinFetcher.cs diff --git a/Skin/Fetchers/YggdrasilSkinFetcher.cs b/Skin/Fetchers/YggdrasilSkinFetcher.cs new file mode 100644 index 0000000..4fffda8 --- /dev/null +++ b/Skin/Fetchers/YggdrasilSkinFetcher.cs @@ -0,0 +1,44 @@ +using StarLight_Core.Models.Authentication; +using StarLight_Core.Models.Skin; +using StarLight_Core.Utilities; +using System.Security.Cryptography.X509Certificates; +using System.Security.Principal; +using System.Text; + +namespace StarLight_Core.Skin.Fetchers; + +/// +/// 外置皮肤获取器 +/// +public class YggdrasilSkinFetcher +{ + /// + /// 获取外置皮肤 + /// + /// 外置账户 + /// 皮肤图片字节信息 + public static async Task GetYggdrasilSkinAsync(YggdrasilAccount account) + { + return await GetYggdrasilSkinAsync(account.ServerUrl, account.Uuid); + } + + /// + /// 获取外置皮肤 + /// + /// 服务器 Url + /// 外置账户 Uuid + /// + public static async Task GetYggdrasilSkinAsync(string serverUrl, string uuid) + { + var baseUrl = serverUrl.TrimEnd("/"); + var skinJson = await HttpUtil.GetStringAsync($"{baseUrl}/sessionserver/session/minecraft/profile/{uuid}"); + var skinUrl = + Encoding.UTF8.GetString( + Convert.FromBase64String( + skinJson.ToJsonEntry().Properties.First().Value)) + .ToJsonEntry() + .Textures.Skin.Url; + using var httpClient = new HttpClient(); + return await httpClient.GetByteArrayAsync(skinUrl); + } +} \ No newline at end of file