From 8b92d349b2d7ab8237310e76e72eebad5b8437a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9E=97=E8=BD=BB=E8=AF=AD?= Date: Sun, 7 Jun 2026 14:54:54 +0800 Subject: [PATCH 1/6] refactor: profile --- .../Minecraft/Profile/IProfileManagement.cs | 35 ++++++++++++++ .../Autnenrication/IAuthenticateProvider.cs | 8 ++++ .../Autnenrication/MicrosoftProvider.cs | 6 +++ .../Utils/Models/MojangIdentityToken.cs | 9 ++++ .../Utils/Models/MojangResponse.cs | 9 ++++ .../Utils/Models/XSTSProperty.cs | 9 ++++ .../Utils/Models/XboxAuthenticate.cs | 8 ++++ .../Utils/Models/XboxDisplayClaims.cs | 10 ++++ .../Utils/Models/XboxLiveResponse.cs | 10 ++++ .../Utils/Models/XboxProperty.cs | 8 ++++ .../Utils/Models/XboxUserHash.cs | 9 ++++ .../Autnenrication/Utils/MojangUtils.cs | 8 ++++ .../Profile/Autnenrication/Utils/XboxUtils.cs | 20 ++++++++ .../Profile/Profile/IProfileManagement.cs | 35 ++++++++++++++ .../Profile/Profile/Models/OldProfile.cs | 32 +++++++++++++ .../Profile/Profile/Models/Profile.cs | 11 +++++ .../Profile/Profile/Models/ProfileJson.cs | 9 ++++ .../Profile/Profile/Models/ProfileType.cs | 8 ++++ .../Profile/Profile/ProfileManagement.cs | 34 ++++++++++++++ .../Profile/Profile/ProfileService.cs | 47 +++++++++++++++++++ .../Minecraft/Profile/ProfileManagement.cs | 34 ++++++++++++++ PCL.Core/Minecraft/Profile/ProfileService.cs | 47 +++++++++++++++++++ 22 files changed, 406 insertions(+) create mode 100644 PCL.Core/Minecraft/Profile/IProfileManagement.cs create mode 100644 PCL.Core/Minecraft/Profile/Profile/Autnenrication/IAuthenticateProvider.cs create mode 100644 PCL.Core/Minecraft/Profile/Profile/Autnenrication/MicrosoftProvider.cs create mode 100644 PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/Models/MojangIdentityToken.cs create mode 100644 PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/Models/MojangResponse.cs create mode 100644 PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/Models/XSTSProperty.cs create mode 100644 PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/Models/XboxAuthenticate.cs create mode 100644 PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/Models/XboxDisplayClaims.cs create mode 100644 PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/Models/XboxLiveResponse.cs create mode 100644 PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/Models/XboxProperty.cs create mode 100644 PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/Models/XboxUserHash.cs create mode 100644 PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/MojangUtils.cs create mode 100644 PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/XboxUtils.cs create mode 100644 PCL.Core/Minecraft/Profile/Profile/IProfileManagement.cs create mode 100644 PCL.Core/Minecraft/Profile/Profile/Models/OldProfile.cs create mode 100644 PCL.Core/Minecraft/Profile/Profile/Models/Profile.cs create mode 100644 PCL.Core/Minecraft/Profile/Profile/Models/ProfileJson.cs create mode 100644 PCL.Core/Minecraft/Profile/Profile/Models/ProfileType.cs create mode 100644 PCL.Core/Minecraft/Profile/Profile/ProfileManagement.cs create mode 100644 PCL.Core/Minecraft/Profile/Profile/ProfileService.cs create mode 100644 PCL.Core/Minecraft/Profile/ProfileManagement.cs create mode 100644 PCL.Core/Minecraft/Profile/ProfileService.cs diff --git a/PCL.Core/Minecraft/Profile/IProfileManagement.cs b/PCL.Core/Minecraft/Profile/IProfileManagement.cs new file mode 100644 index 000000000..d2a385482 --- /dev/null +++ b/PCL.Core/Minecraft/Profile/IProfileManagement.cs @@ -0,0 +1,35 @@ +namespace PCL.Core.Minecraft.Profile; + +public interface IProfileManagement +{ + /// + /// 创建一个档案 + /// + /// + public T Create(); + /// + /// 删除一个档案 + /// + public void Delete(int index); + /// + /// 更新档案 + /// + /// 档案文件 + public void Update(T profile); + /// + /// 从指定文件加载档案 + /// + /// + public void LoadFromPath(string path); + /// + /// 从指定字符串加载档案信息 + /// + /// 档案信息 + public void LoadFromString(string profiles); + /// + /// 清空档案列表 + /// 是否删除本地档案 + /// + public void Clear(bool deleteLocal = false); + +} \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Profile/Autnenrication/IAuthenticateProvider.cs b/PCL.Core/Minecraft/Profile/Profile/Autnenrication/IAuthenticateProvider.cs new file mode 100644 index 000000000..8c0249d86 --- /dev/null +++ b/PCL.Core/Minecraft/Profile/Profile/Autnenrication/IAuthenticateProvider.cs @@ -0,0 +1,8 @@ +using System.Threading.Tasks; + +namespace PCL.Core.Minecraft.Profile.Autnenrication; + +public interface IAuthenticateProvider +{ + //public Task AuthenticateAsync(); +} \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Profile/Autnenrication/MicrosoftProvider.cs b/PCL.Core/Minecraft/Profile/Profile/Autnenrication/MicrosoftProvider.cs new file mode 100644 index 000000000..79eaed08f --- /dev/null +++ b/PCL.Core/Minecraft/Profile/Profile/Autnenrication/MicrosoftProvider.cs @@ -0,0 +1,6 @@ +namespace PCL.Core.Minecraft.Profile.Autnenrication; + +public class MicrosoftProvider +{ + +} \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/Models/MojangIdentityToken.cs b/PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/Models/MojangIdentityToken.cs new file mode 100644 index 000000000..7364894fd --- /dev/null +++ b/PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/Models/MojangIdentityToken.cs @@ -0,0 +1,9 @@ +using System.Text.Json.Serialization; + +namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils.Models; + +public class MojangIdentityToken +{ + [JsonPropertyName("identityToken")] + public required string IdentityToken { get; set; } +} \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/Models/MojangResponse.cs b/PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/Models/MojangResponse.cs new file mode 100644 index 000000000..228eec816 --- /dev/null +++ b/PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/Models/MojangResponse.cs @@ -0,0 +1,9 @@ +using System.Text.Json.Serialization; + +namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils.Models; + +public record MojangResponse +{ + [JsonPropertyName("username")] + public required string UserName { get; set; } +} \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/Models/XSTSProperty.cs b/PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/Models/XSTSProperty.cs new file mode 100644 index 000000000..b89b020c2 --- /dev/null +++ b/PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/Models/XSTSProperty.cs @@ -0,0 +1,9 @@ +using System.Collections.Generic; + +namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils.Models; + +public record XSTSProperty +{ + public string SandboxId { get; set; } = "RETAIL"; + public List UserTokens { get; set; } = []; +} \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/Models/XboxAuthenticate.cs b/PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/Models/XboxAuthenticate.cs new file mode 100644 index 000000000..ff1bab478 --- /dev/null +++ b/PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/Models/XboxAuthenticate.cs @@ -0,0 +1,8 @@ +namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils.Models; + +public record XboxAuthenticate +{ + public required T Properties { get; set; } + public string RelyingParty { get; set; } = "http://auth.xboxlive.com"; + public required string TokenType { get; set; } +} \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/Models/XboxDisplayClaims.cs b/PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/Models/XboxDisplayClaims.cs new file mode 100644 index 000000000..7db612eb4 --- /dev/null +++ b/PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/Models/XboxDisplayClaims.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils.Models; + +public record XboxDisplayClaims +{ + [JsonPropertyName("xui")] + public required List Xui { get; set; } +} \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/Models/XboxLiveResponse.cs b/PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/Models/XboxLiveResponse.cs new file mode 100644 index 000000000..a2187345b --- /dev/null +++ b/PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/Models/XboxLiveResponse.cs @@ -0,0 +1,10 @@ +using System; + +namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils.Models; + +public record XboxLiveResponse +{ + public required DateTime IssueInstant { get; set; } + public required DateTime NotAfter { get; set; } + public required string Token { get; set; } +} \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/Models/XboxProperty.cs b/PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/Models/XboxProperty.cs new file mode 100644 index 000000000..7f2b27c43 --- /dev/null +++ b/PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/Models/XboxProperty.cs @@ -0,0 +1,8 @@ +namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils.Models; + +public record XboxProperty +{ + public string AuthMethod { get; set; } = "RPS"; + public string SiteName { get; set; } = "user.auth.xboxlive.com"; + public required string RpsTicket { get; set; } +} \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/Models/XboxUserHash.cs b/PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/Models/XboxUserHash.cs new file mode 100644 index 000000000..a03b64182 --- /dev/null +++ b/PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/Models/XboxUserHash.cs @@ -0,0 +1,9 @@ +using System.Text.Json.Serialization; + +namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils.Models; + +public record XboxUserHash +{ + [JsonPropertyName("uhs")] + public required string UserHash { get; set; } +} \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/MojangUtils.cs b/PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/MojangUtils.cs new file mode 100644 index 000000000..aa5422623 --- /dev/null +++ b/PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/MojangUtils.cs @@ -0,0 +1,8 @@ +namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils; + +public static class MojangUtils +{ + private const string MojangAuthServer = "https://api.minecraftservices.com/authentication/login_with_xbox"; + //public static async Task<> AuthenticateAsync(){} + //public static async Task +} \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/XboxUtils.cs b/PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/XboxUtils.cs new file mode 100644 index 000000000..f8329cb71 --- /dev/null +++ b/PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/XboxUtils.cs @@ -0,0 +1,20 @@ +using System.Threading.Tasks; +using PCL.Core.IO.Net.Http; +using PCL.Core.Minecraft.Profile.Autnenrication.Utils.Models; + +namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils; + +public static class XboxUtils +{ + private const string XboxLiveAuthServer = "https://user.auth.xboxlive.com/user/authenticate"; + private const string XstsAuthorizeServer = "https://xsts.auth.xboxlive.com/xsts/authorize"; + public static async Task AuthenticateAsync(XboxAuthenticate authData, bool isXsts) + { + using var response = await HttpRequest.CreatePost( + isXsts ? XstsAuthorizeServer:XboxLiveAuthServer + ).WithJsonContent(authData).SendAsync() + .ConfigureAwait(false); + + return await response.AsJsonAsync(); + } +} \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Profile/IProfileManagement.cs b/PCL.Core/Minecraft/Profile/Profile/IProfileManagement.cs new file mode 100644 index 000000000..d2a385482 --- /dev/null +++ b/PCL.Core/Minecraft/Profile/Profile/IProfileManagement.cs @@ -0,0 +1,35 @@ +namespace PCL.Core.Minecraft.Profile; + +public interface IProfileManagement +{ + /// + /// 创建一个档案 + /// + /// + public T Create(); + /// + /// 删除一个档案 + /// + public void Delete(int index); + /// + /// 更新档案 + /// + /// 档案文件 + public void Update(T profile); + /// + /// 从指定文件加载档案 + /// + /// + public void LoadFromPath(string path); + /// + /// 从指定字符串加载档案信息 + /// + /// 档案信息 + public void LoadFromString(string profiles); + /// + /// 清空档案列表 + /// 是否删除本地档案 + /// + public void Clear(bool deleteLocal = false); + +} \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Profile/Models/OldProfile.cs b/PCL.Core/Minecraft/Profile/Profile/Models/OldProfile.cs new file mode 100644 index 000000000..0be3d4854 --- /dev/null +++ b/PCL.Core/Minecraft/Profile/Profile/Models/OldProfile.cs @@ -0,0 +1,32 @@ +using System.Text.Json.Serialization; + +namespace PCL.Core.Minecraft.Profile.Models; + +public record OldProfile +{ + [JsonPropertyName("type")] + public required string Type { get; set; } + [JsonPropertyName("uuid")] + public required string Uuid { get; set; } + [JsonPropertyName("username")] + public required string UserName { get; set; } + [JsonPropertyName("accessToken")] + public string? AccessToken { get; set; } + [JsonPropertyName("refreshToken")] + public string? RefreshToken { get; set; } + [JsonPropertyName("expires")] + public long? Expires { get; set; } + [JsonPropertyName("desc")] + public required string Description { get; set; } + [JsonPropertyName("skinHeadId")] + public required string SkinHeadId { get; set; } + [JsonPropertyName("serverName")] + public string? ServerName { get; set; } + [JsonPropertyName("server")] + public string? Server { get; set; } + [JsonPropertyName("name")] + public string? Name { get; set; } + [JsonPropertyName("password")] + public string? Password { get; set; } + +} \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Profile/Models/Profile.cs b/PCL.Core/Minecraft/Profile/Profile/Models/Profile.cs new file mode 100644 index 000000000..c7fdca311 --- /dev/null +++ b/PCL.Core/Minecraft/Profile/Profile/Models/Profile.cs @@ -0,0 +1,11 @@ +using PCL.Core.Minecraft.Profile.Autnenrication; + +namespace PCL.Core.Minecraft.Profile.Models; + +public class Profile +{ + public IAuthenticateProvider? CreateAuthenticateServiceProvider() + { + return default; + } +} \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Profile/Models/ProfileJson.cs b/PCL.Core/Minecraft/Profile/Profile/Models/ProfileJson.cs new file mode 100644 index 000000000..33b67e2fc --- /dev/null +++ b/PCL.Core/Minecraft/Profile/Profile/Models/ProfileJson.cs @@ -0,0 +1,9 @@ +using System.Collections.Immutable; + +namespace PCL.Core.Minecraft.Profile.Models; + +public class ProfileJson where T : class +{ + public int LastUsed { get; set; } + public ImmutableArray Profiles { get; private set; } = []; +} \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Profile/Models/ProfileType.cs b/PCL.Core/Minecraft/Profile/Profile/Models/ProfileType.cs new file mode 100644 index 000000000..d55b28a90 --- /dev/null +++ b/PCL.Core/Minecraft/Profile/Profile/Models/ProfileType.cs @@ -0,0 +1,8 @@ +namespace PCL.Core.Minecraft.Profile.Models; + +public enum ProfileType +{ + Microsoft, + Offline, + Authlib +} \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Profile/ProfileManagement.cs b/PCL.Core/Minecraft/Profile/Profile/ProfileManagement.cs new file mode 100644 index 000000000..e59e6f347 --- /dev/null +++ b/PCL.Core/Minecraft/Profile/Profile/ProfileManagement.cs @@ -0,0 +1,34 @@ +namespace PCL.Core.Minecraft.Profile; + +public class ProfileManagement: IProfileManagement where T:class +{ + public T Create() + { + throw new System.NotImplementedException(); + } + + public void Delete(int index) + { + throw new System.NotImplementedException(); + } + + public void Update(T profile) + { + throw new System.NotImplementedException(); + } + + public void LoadFromPath(string path) + { + throw new System.NotImplementedException(); + } + + public void LoadFromString(string profiles) + { + throw new System.NotImplementedException(); + } + + public void Clear(bool deleteLocal = false) + { + throw new System.NotImplementedException(); + } +} \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Profile/ProfileService.cs b/PCL.Core/Minecraft/Profile/Profile/ProfileService.cs new file mode 100644 index 000000000..e65a73afc --- /dev/null +++ b/PCL.Core/Minecraft/Profile/Profile/ProfileService.cs @@ -0,0 +1,47 @@ +using System; +using System.IO; +using System.Threading.Tasks; +using PCL.Core.App; +using PCL.Core.App.IoC; +using PCL.Core.Minecraft.Profile.Models; + +namespace PCL.Core.Minecraft.Profile; + +[LifecycleScope("profile", "档案服务")] +public partial class ProfileService +{ + private static ProfileManagement> _newProfileProvider = new(); + private static ProfileManagement> _oldProfileProvider = new(); + + [LifecycleStart] + private static async Task _Start() + { + } + + private static void _MigrateProfile() + { + + var profileLocation = Path.Combine(Paths.SharedData, "profiles.json"); + var profileMigrateFIle = Path.Combine(Paths.SharedData, "pcl.ce.migrated"); + if (!Path.Exists(profileMigrateFIle)) + { + Context.Debug("已迁移档案信息,跳过检查"); + return; + } + Context.Info("开始迁移旧版本档案信息"); + try + { + + } + catch (UnauthorizedAccessException) + { + Context.Error("读取旧版档案信息失败:权限不足"); + } + catch (Exception ex) + { + Context.Error("迁移档案信息失败", ex); + } + } + + private static void _Import(){} +} \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/ProfileManagement.cs b/PCL.Core/Minecraft/Profile/ProfileManagement.cs new file mode 100644 index 000000000..e59e6f347 --- /dev/null +++ b/PCL.Core/Minecraft/Profile/ProfileManagement.cs @@ -0,0 +1,34 @@ +namespace PCL.Core.Minecraft.Profile; + +public class ProfileManagement: IProfileManagement where T:class +{ + public T Create() + { + throw new System.NotImplementedException(); + } + + public void Delete(int index) + { + throw new System.NotImplementedException(); + } + + public void Update(T profile) + { + throw new System.NotImplementedException(); + } + + public void LoadFromPath(string path) + { + throw new System.NotImplementedException(); + } + + public void LoadFromString(string profiles) + { + throw new System.NotImplementedException(); + } + + public void Clear(bool deleteLocal = false) + { + throw new System.NotImplementedException(); + } +} \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/ProfileService.cs b/PCL.Core/Minecraft/Profile/ProfileService.cs new file mode 100644 index 000000000..e65a73afc --- /dev/null +++ b/PCL.Core/Minecraft/Profile/ProfileService.cs @@ -0,0 +1,47 @@ +using System; +using System.IO; +using System.Threading.Tasks; +using PCL.Core.App; +using PCL.Core.App.IoC; +using PCL.Core.Minecraft.Profile.Models; + +namespace PCL.Core.Minecraft.Profile; + +[LifecycleScope("profile", "档案服务")] +public partial class ProfileService +{ + private static ProfileManagement> _newProfileProvider = new(); + private static ProfileManagement> _oldProfileProvider = new(); + + [LifecycleStart] + private static async Task _Start() + { + } + + private static void _MigrateProfile() + { + + var profileLocation = Path.Combine(Paths.SharedData, "profiles.json"); + var profileMigrateFIle = Path.Combine(Paths.SharedData, "pcl.ce.migrated"); + if (!Path.Exists(profileMigrateFIle)) + { + Context.Debug("已迁移档案信息,跳过检查"); + return; + } + Context.Info("开始迁移旧版本档案信息"); + try + { + + } + catch (UnauthorizedAccessException) + { + Context.Error("读取旧版档案信息失败:权限不足"); + } + catch (Exception ex) + { + Context.Error("迁移档案信息失败", ex); + } + } + + private static void _Import(){} +} \ No newline at end of file From 157aa91733b636fae1d0e8be59fef61bdc421fcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9E=97=E8=BD=BB=E8=AF=AD?= Date: Tue, 9 Jun 2026 13:24:24 +0800 Subject: [PATCH 2/6] fix: duolicate define --- .../Autnenrication/IAuthenticateProvider.cs | 14 ++--- .../Autnenrication/MicrosoftProvider.cs | 10 +-- .../Utils/Models/MojangIdentityToken.cs | 16 ++--- .../Utils/Models/MojangResponse.cs | 16 ++--- .../Utils/Models/XSTSProperty.cs | 16 ++--- .../Utils/Models/XboxAuthenticate.cs | 14 ++--- .../Utils/Models/XboxDisplayClaims.cs | 18 +++--- .../Utils/Models/XboxLiveResponse.cs | 18 +++--- .../Utils/Models/XboxProperty.cs | 14 ++--- .../Utils/Models/XboxUserHash.cs | 16 ++--- .../Autnenrication/Utils/MojangUtils.cs | 14 ++--- .../Autnenrication/Utils/XboxUtils.cs | 38 ++++++------ .../{Profile => }/Models/OldProfile.cs | 62 +++++++++---------- .../Profile/{Profile => }/Models/Profile.cs | 20 +++--- .../{Profile => }/Models/ProfileJson.cs | 16 ++--- .../{Profile => }/Models/ProfileType.cs | 14 ++--- .../Profile/Profile/IProfileManagement.cs | 35 ----------- .../Profile/Profile/ProfileManagement.cs | 34 ---------- .../Profile/Profile/ProfileService.cs | 47 -------------- 19 files changed, 158 insertions(+), 274 deletions(-) rename PCL.Core/Minecraft/Profile/{Profile => }/Autnenrication/IAuthenticateProvider.cs (96%) rename PCL.Core/Minecraft/Profile/{Profile => }/Autnenrication/MicrosoftProvider.cs (95%) rename PCL.Core/Minecraft/Profile/{Profile => }/Autnenrication/Utils/Models/MojangIdentityToken.cs (96%) rename PCL.Core/Minecraft/Profile/{Profile => }/Autnenrication/Utils/Models/MojangResponse.cs (96%) rename PCL.Core/Minecraft/Profile/{Profile => }/Autnenrication/Utils/Models/XSTSProperty.cs (96%) rename PCL.Core/Minecraft/Profile/{Profile => }/Autnenrication/Utils/Models/XboxAuthenticate.cs (97%) rename PCL.Core/Minecraft/Profile/{Profile => }/Autnenrication/Utils/Models/XboxDisplayClaims.cs (96%) rename PCL.Core/Minecraft/Profile/{Profile => }/Autnenrication/Utils/Models/XboxLiveResponse.cs (96%) rename PCL.Core/Minecraft/Profile/{Profile => }/Autnenrication/Utils/Models/XboxProperty.cs (97%) rename PCL.Core/Minecraft/Profile/{Profile => }/Autnenrication/Utils/Models/XboxUserHash.cs (96%) rename PCL.Core/Minecraft/Profile/{Profile => }/Autnenrication/Utils/MojangUtils.cs (97%) rename PCL.Core/Minecraft/Profile/{Profile => }/Autnenrication/Utils/XboxUtils.cs (97%) rename PCL.Core/Minecraft/Profile/{Profile => }/Models/OldProfile.cs (97%) rename PCL.Core/Minecraft/Profile/{Profile => }/Models/Profile.cs (95%) rename PCL.Core/Minecraft/Profile/{Profile => }/Models/ProfileJson.cs (96%) rename PCL.Core/Minecraft/Profile/{Profile => }/Models/ProfileType.cs (94%) delete mode 100644 PCL.Core/Minecraft/Profile/Profile/IProfileManagement.cs delete mode 100644 PCL.Core/Minecraft/Profile/Profile/ProfileManagement.cs delete mode 100644 PCL.Core/Minecraft/Profile/Profile/ProfileService.cs diff --git a/PCL.Core/Minecraft/Profile/Profile/Autnenrication/IAuthenticateProvider.cs b/PCL.Core/Minecraft/Profile/Autnenrication/IAuthenticateProvider.cs similarity index 96% rename from PCL.Core/Minecraft/Profile/Profile/Autnenrication/IAuthenticateProvider.cs rename to PCL.Core/Minecraft/Profile/Autnenrication/IAuthenticateProvider.cs index 8c0249d86..8d6410fa2 100644 --- a/PCL.Core/Minecraft/Profile/Profile/Autnenrication/IAuthenticateProvider.cs +++ b/PCL.Core/Minecraft/Profile/Autnenrication/IAuthenticateProvider.cs @@ -1,8 +1,8 @@ -using System.Threading.Tasks; - -namespace PCL.Core.Minecraft.Profile.Autnenrication; - -public interface IAuthenticateProvider -{ - //public Task AuthenticateAsync(); +using System.Threading.Tasks; + +namespace PCL.Core.Minecraft.Profile.Autnenrication; + +public interface IAuthenticateProvider +{ + //public Task AuthenticateAsync(); } \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Profile/Autnenrication/MicrosoftProvider.cs b/PCL.Core/Minecraft/Profile/Autnenrication/MicrosoftProvider.cs similarity index 95% rename from PCL.Core/Minecraft/Profile/Profile/Autnenrication/MicrosoftProvider.cs rename to PCL.Core/Minecraft/Profile/Autnenrication/MicrosoftProvider.cs index 79eaed08f..f81f593fe 100644 --- a/PCL.Core/Minecraft/Profile/Profile/Autnenrication/MicrosoftProvider.cs +++ b/PCL.Core/Minecraft/Profile/Autnenrication/MicrosoftProvider.cs @@ -1,6 +1,6 @@ -namespace PCL.Core.Minecraft.Profile.Autnenrication; - -public class MicrosoftProvider -{ - +namespace PCL.Core.Minecraft.Profile.Autnenrication; + +public class MicrosoftProvider +{ + } \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/Models/MojangIdentityToken.cs b/PCL.Core/Minecraft/Profile/Autnenrication/Utils/Models/MojangIdentityToken.cs similarity index 96% rename from PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/Models/MojangIdentityToken.cs rename to PCL.Core/Minecraft/Profile/Autnenrication/Utils/Models/MojangIdentityToken.cs index 7364894fd..50de6e689 100644 --- a/PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/Models/MojangIdentityToken.cs +++ b/PCL.Core/Minecraft/Profile/Autnenrication/Utils/Models/MojangIdentityToken.cs @@ -1,9 +1,9 @@ -using System.Text.Json.Serialization; - -namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils.Models; - -public class MojangIdentityToken -{ - [JsonPropertyName("identityToken")] - public required string IdentityToken { get; set; } +using System.Text.Json.Serialization; + +namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils.Models; + +public class MojangIdentityToken +{ + [JsonPropertyName("identityToken")] + public required string IdentityToken { get; set; } } \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/Models/MojangResponse.cs b/PCL.Core/Minecraft/Profile/Autnenrication/Utils/Models/MojangResponse.cs similarity index 96% rename from PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/Models/MojangResponse.cs rename to PCL.Core/Minecraft/Profile/Autnenrication/Utils/Models/MojangResponse.cs index 228eec816..dab469858 100644 --- a/PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/Models/MojangResponse.cs +++ b/PCL.Core/Minecraft/Profile/Autnenrication/Utils/Models/MojangResponse.cs @@ -1,9 +1,9 @@ -using System.Text.Json.Serialization; - -namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils.Models; - -public record MojangResponse -{ - [JsonPropertyName("username")] - public required string UserName { get; set; } +using System.Text.Json.Serialization; + +namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils.Models; + +public record MojangResponse +{ + [JsonPropertyName("username")] + public required string UserName { get; set; } } \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/Models/XSTSProperty.cs b/PCL.Core/Minecraft/Profile/Autnenrication/Utils/Models/XSTSProperty.cs similarity index 96% rename from PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/Models/XSTSProperty.cs rename to PCL.Core/Minecraft/Profile/Autnenrication/Utils/Models/XSTSProperty.cs index b89b020c2..8c1beea52 100644 --- a/PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/Models/XSTSProperty.cs +++ b/PCL.Core/Minecraft/Profile/Autnenrication/Utils/Models/XSTSProperty.cs @@ -1,9 +1,9 @@ -using System.Collections.Generic; - -namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils.Models; - -public record XSTSProperty -{ - public string SandboxId { get; set; } = "RETAIL"; - public List UserTokens { get; set; } = []; +using System.Collections.Generic; + +namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils.Models; + +public record XSTSProperty +{ + public string SandboxId { get; set; } = "RETAIL"; + public List UserTokens { get; set; } = []; } \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/Models/XboxAuthenticate.cs b/PCL.Core/Minecraft/Profile/Autnenrication/Utils/Models/XboxAuthenticate.cs similarity index 97% rename from PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/Models/XboxAuthenticate.cs rename to PCL.Core/Minecraft/Profile/Autnenrication/Utils/Models/XboxAuthenticate.cs index ff1bab478..9edcda0fb 100644 --- a/PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/Models/XboxAuthenticate.cs +++ b/PCL.Core/Minecraft/Profile/Autnenrication/Utils/Models/XboxAuthenticate.cs @@ -1,8 +1,8 @@ -namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils.Models; - -public record XboxAuthenticate -{ - public required T Properties { get; set; } - public string RelyingParty { get; set; } = "http://auth.xboxlive.com"; - public required string TokenType { get; set; } +namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils.Models; + +public record XboxAuthenticate +{ + public required T Properties { get; set; } + public string RelyingParty { get; set; } = "http://auth.xboxlive.com"; + public required string TokenType { get; set; } } \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/Models/XboxDisplayClaims.cs b/PCL.Core/Minecraft/Profile/Autnenrication/Utils/Models/XboxDisplayClaims.cs similarity index 96% rename from PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/Models/XboxDisplayClaims.cs rename to PCL.Core/Minecraft/Profile/Autnenrication/Utils/Models/XboxDisplayClaims.cs index 7db612eb4..c73564c7b 100644 --- a/PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/Models/XboxDisplayClaims.cs +++ b/PCL.Core/Minecraft/Profile/Autnenrication/Utils/Models/XboxDisplayClaims.cs @@ -1,10 +1,10 @@ -using System.Collections.Generic; -using System.Text.Json.Serialization; - -namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils.Models; - -public record XboxDisplayClaims -{ - [JsonPropertyName("xui")] - public required List Xui { get; set; } +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils.Models; + +public record XboxDisplayClaims +{ + [JsonPropertyName("xui")] + public required List Xui { get; set; } } \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/Models/XboxLiveResponse.cs b/PCL.Core/Minecraft/Profile/Autnenrication/Utils/Models/XboxLiveResponse.cs similarity index 96% rename from PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/Models/XboxLiveResponse.cs rename to PCL.Core/Minecraft/Profile/Autnenrication/Utils/Models/XboxLiveResponse.cs index a2187345b..1e0ef8ffb 100644 --- a/PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/Models/XboxLiveResponse.cs +++ b/PCL.Core/Minecraft/Profile/Autnenrication/Utils/Models/XboxLiveResponse.cs @@ -1,10 +1,10 @@ -using System; - -namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils.Models; - -public record XboxLiveResponse -{ - public required DateTime IssueInstant { get; set; } - public required DateTime NotAfter { get; set; } - public required string Token { get; set; } +using System; + +namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils.Models; + +public record XboxLiveResponse +{ + public required DateTime IssueInstant { get; set; } + public required DateTime NotAfter { get; set; } + public required string Token { get; set; } } \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/Models/XboxProperty.cs b/PCL.Core/Minecraft/Profile/Autnenrication/Utils/Models/XboxProperty.cs similarity index 97% rename from PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/Models/XboxProperty.cs rename to PCL.Core/Minecraft/Profile/Autnenrication/Utils/Models/XboxProperty.cs index 7f2b27c43..3558df6e5 100644 --- a/PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/Models/XboxProperty.cs +++ b/PCL.Core/Minecraft/Profile/Autnenrication/Utils/Models/XboxProperty.cs @@ -1,8 +1,8 @@ -namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils.Models; - -public record XboxProperty -{ - public string AuthMethod { get; set; } = "RPS"; - public string SiteName { get; set; } = "user.auth.xboxlive.com"; - public required string RpsTicket { get; set; } +namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils.Models; + +public record XboxProperty +{ + public string AuthMethod { get; set; } = "RPS"; + public string SiteName { get; set; } = "user.auth.xboxlive.com"; + public required string RpsTicket { get; set; } } \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/Models/XboxUserHash.cs b/PCL.Core/Minecraft/Profile/Autnenrication/Utils/Models/XboxUserHash.cs similarity index 96% rename from PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/Models/XboxUserHash.cs rename to PCL.Core/Minecraft/Profile/Autnenrication/Utils/Models/XboxUserHash.cs index a03b64182..e405a1c11 100644 --- a/PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/Models/XboxUserHash.cs +++ b/PCL.Core/Minecraft/Profile/Autnenrication/Utils/Models/XboxUserHash.cs @@ -1,9 +1,9 @@ -using System.Text.Json.Serialization; - -namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils.Models; - -public record XboxUserHash -{ - [JsonPropertyName("uhs")] - public required string UserHash { get; set; } +using System.Text.Json.Serialization; + +namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils.Models; + +public record XboxUserHash +{ + [JsonPropertyName("uhs")] + public required string UserHash { get; set; } } \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/MojangUtils.cs b/PCL.Core/Minecraft/Profile/Autnenrication/Utils/MojangUtils.cs similarity index 97% rename from PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/MojangUtils.cs rename to PCL.Core/Minecraft/Profile/Autnenrication/Utils/MojangUtils.cs index aa5422623..874ce72dd 100644 --- a/PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/MojangUtils.cs +++ b/PCL.Core/Minecraft/Profile/Autnenrication/Utils/MojangUtils.cs @@ -1,8 +1,8 @@ -namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils; - -public static class MojangUtils -{ - private const string MojangAuthServer = "https://api.minecraftservices.com/authentication/login_with_xbox"; - //public static async Task<> AuthenticateAsync(){} - //public static async Task +namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils; + +public static class MojangUtils +{ + private const string MojangAuthServer = "https://api.minecraftservices.com/authentication/login_with_xbox"; + //public static async Task<> AuthenticateAsync(){} + //public static async Task } \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/XboxUtils.cs b/PCL.Core/Minecraft/Profile/Autnenrication/Utils/XboxUtils.cs similarity index 97% rename from PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/XboxUtils.cs rename to PCL.Core/Minecraft/Profile/Autnenrication/Utils/XboxUtils.cs index f8329cb71..d95dd6ef2 100644 --- a/PCL.Core/Minecraft/Profile/Profile/Autnenrication/Utils/XboxUtils.cs +++ b/PCL.Core/Minecraft/Profile/Autnenrication/Utils/XboxUtils.cs @@ -1,20 +1,20 @@ -using System.Threading.Tasks; -using PCL.Core.IO.Net.Http; -using PCL.Core.Minecraft.Profile.Autnenrication.Utils.Models; - -namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils; - -public static class XboxUtils -{ - private const string XboxLiveAuthServer = "https://user.auth.xboxlive.com/user/authenticate"; - private const string XstsAuthorizeServer = "https://xsts.auth.xboxlive.com/xsts/authorize"; - public static async Task AuthenticateAsync(XboxAuthenticate authData, bool isXsts) - { - using var response = await HttpRequest.CreatePost( - isXsts ? XstsAuthorizeServer:XboxLiveAuthServer - ).WithJsonContent(authData).SendAsync() - .ConfigureAwait(false); - - return await response.AsJsonAsync(); - } +using System.Threading.Tasks; +using PCL.Core.IO.Net.Http; +using PCL.Core.Minecraft.Profile.Autnenrication.Utils.Models; + +namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils; + +public static class XboxUtils +{ + private const string XboxLiveAuthServer = "https://user.auth.xboxlive.com/user/authenticate"; + private const string XstsAuthorizeServer = "https://xsts.auth.xboxlive.com/xsts/authorize"; + public static async Task AuthenticateAsync(XboxAuthenticate authData, bool isXsts) + { + using var response = await HttpRequest.CreatePost( + isXsts ? XstsAuthorizeServer:XboxLiveAuthServer + ).WithJsonContent(authData).SendAsync() + .ConfigureAwait(false); + + return await response.AsJsonAsync(); + } } \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Profile/Models/OldProfile.cs b/PCL.Core/Minecraft/Profile/Models/OldProfile.cs similarity index 97% rename from PCL.Core/Minecraft/Profile/Profile/Models/OldProfile.cs rename to PCL.Core/Minecraft/Profile/Models/OldProfile.cs index 0be3d4854..d46df3737 100644 --- a/PCL.Core/Minecraft/Profile/Profile/Models/OldProfile.cs +++ b/PCL.Core/Minecraft/Profile/Models/OldProfile.cs @@ -1,32 +1,32 @@ -using System.Text.Json.Serialization; - -namespace PCL.Core.Minecraft.Profile.Models; - -public record OldProfile -{ - [JsonPropertyName("type")] - public required string Type { get; set; } - [JsonPropertyName("uuid")] - public required string Uuid { get; set; } - [JsonPropertyName("username")] - public required string UserName { get; set; } - [JsonPropertyName("accessToken")] - public string? AccessToken { get; set; } - [JsonPropertyName("refreshToken")] - public string? RefreshToken { get; set; } - [JsonPropertyName("expires")] - public long? Expires { get; set; } - [JsonPropertyName("desc")] - public required string Description { get; set; } - [JsonPropertyName("skinHeadId")] - public required string SkinHeadId { get; set; } - [JsonPropertyName("serverName")] - public string? ServerName { get; set; } - [JsonPropertyName("server")] - public string? Server { get; set; } - [JsonPropertyName("name")] - public string? Name { get; set; } - [JsonPropertyName("password")] - public string? Password { get; set; } - +using System.Text.Json.Serialization; + +namespace PCL.Core.Minecraft.Profile.Models; + +public record OldProfile +{ + [JsonPropertyName("type")] + public required string Type { get; set; } + [JsonPropertyName("uuid")] + public required string Uuid { get; set; } + [JsonPropertyName("username")] + public required string UserName { get; set; } + [JsonPropertyName("accessToken")] + public string? AccessToken { get; set; } + [JsonPropertyName("refreshToken")] + public string? RefreshToken { get; set; } + [JsonPropertyName("expires")] + public long? Expires { get; set; } + [JsonPropertyName("desc")] + public required string Description { get; set; } + [JsonPropertyName("skinHeadId")] + public required string SkinHeadId { get; set; } + [JsonPropertyName("serverName")] + public string? ServerName { get; set; } + [JsonPropertyName("server")] + public string? Server { get; set; } + [JsonPropertyName("name")] + public string? Name { get; set; } + [JsonPropertyName("password")] + public string? Password { get; set; } + } \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Profile/Models/Profile.cs b/PCL.Core/Minecraft/Profile/Models/Profile.cs similarity index 95% rename from PCL.Core/Minecraft/Profile/Profile/Models/Profile.cs rename to PCL.Core/Minecraft/Profile/Models/Profile.cs index c7fdca311..29fcfb1cc 100644 --- a/PCL.Core/Minecraft/Profile/Profile/Models/Profile.cs +++ b/PCL.Core/Minecraft/Profile/Models/Profile.cs @@ -1,11 +1,11 @@ -using PCL.Core.Minecraft.Profile.Autnenrication; - -namespace PCL.Core.Minecraft.Profile.Models; - -public class Profile -{ - public IAuthenticateProvider? CreateAuthenticateServiceProvider() - { - return default; - } +using PCL.Core.Minecraft.Profile.Autnenrication; + +namespace PCL.Core.Minecraft.Profile.Models; + +public class Profile +{ + public IAuthenticateProvider? CreateAuthenticateServiceProvider() + { + return default; + } } \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Profile/Models/ProfileJson.cs b/PCL.Core/Minecraft/Profile/Models/ProfileJson.cs similarity index 96% rename from PCL.Core/Minecraft/Profile/Profile/Models/ProfileJson.cs rename to PCL.Core/Minecraft/Profile/Models/ProfileJson.cs index 33b67e2fc..9b69ed104 100644 --- a/PCL.Core/Minecraft/Profile/Profile/Models/ProfileJson.cs +++ b/PCL.Core/Minecraft/Profile/Models/ProfileJson.cs @@ -1,9 +1,9 @@ -using System.Collections.Immutable; - -namespace PCL.Core.Minecraft.Profile.Models; - -public class ProfileJson where T : class -{ - public int LastUsed { get; set; } - public ImmutableArray Profiles { get; private set; } = []; +using System.Collections.Immutable; + +namespace PCL.Core.Minecraft.Profile.Models; + +public class ProfileJson where T : class +{ + public int LastUsed { get; set; } + public ImmutableArray Profiles { get; private set; } = []; } \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Profile/Models/ProfileType.cs b/PCL.Core/Minecraft/Profile/Models/ProfileType.cs similarity index 94% rename from PCL.Core/Minecraft/Profile/Profile/Models/ProfileType.cs rename to PCL.Core/Minecraft/Profile/Models/ProfileType.cs index d55b28a90..deb77c926 100644 --- a/PCL.Core/Minecraft/Profile/Profile/Models/ProfileType.cs +++ b/PCL.Core/Minecraft/Profile/Models/ProfileType.cs @@ -1,8 +1,8 @@ -namespace PCL.Core.Minecraft.Profile.Models; - -public enum ProfileType -{ - Microsoft, - Offline, - Authlib +namespace PCL.Core.Minecraft.Profile.Models; + +public enum ProfileType +{ + Microsoft, + Offline, + Authlib } \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Profile/IProfileManagement.cs b/PCL.Core/Minecraft/Profile/Profile/IProfileManagement.cs deleted file mode 100644 index d2a385482..000000000 --- a/PCL.Core/Minecraft/Profile/Profile/IProfileManagement.cs +++ /dev/null @@ -1,35 +0,0 @@ -namespace PCL.Core.Minecraft.Profile; - -public interface IProfileManagement -{ - /// - /// 创建一个档案 - /// - /// - public T Create(); - /// - /// 删除一个档案 - /// - public void Delete(int index); - /// - /// 更新档案 - /// - /// 档案文件 - public void Update(T profile); - /// - /// 从指定文件加载档案 - /// - /// - public void LoadFromPath(string path); - /// - /// 从指定字符串加载档案信息 - /// - /// 档案信息 - public void LoadFromString(string profiles); - /// - /// 清空档案列表 - /// 是否删除本地档案 - /// - public void Clear(bool deleteLocal = false); - -} \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Profile/ProfileManagement.cs b/PCL.Core/Minecraft/Profile/Profile/ProfileManagement.cs deleted file mode 100644 index e59e6f347..000000000 --- a/PCL.Core/Minecraft/Profile/Profile/ProfileManagement.cs +++ /dev/null @@ -1,34 +0,0 @@ -namespace PCL.Core.Minecraft.Profile; - -public class ProfileManagement: IProfileManagement where T:class -{ - public T Create() - { - throw new System.NotImplementedException(); - } - - public void Delete(int index) - { - throw new System.NotImplementedException(); - } - - public void Update(T profile) - { - throw new System.NotImplementedException(); - } - - public void LoadFromPath(string path) - { - throw new System.NotImplementedException(); - } - - public void LoadFromString(string profiles) - { - throw new System.NotImplementedException(); - } - - public void Clear(bool deleteLocal = false) - { - throw new System.NotImplementedException(); - } -} \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Profile/ProfileService.cs b/PCL.Core/Minecraft/Profile/Profile/ProfileService.cs deleted file mode 100644 index e65a73afc..000000000 --- a/PCL.Core/Minecraft/Profile/Profile/ProfileService.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System; -using System.IO; -using System.Threading.Tasks; -using PCL.Core.App; -using PCL.Core.App.IoC; -using PCL.Core.Minecraft.Profile.Models; - -namespace PCL.Core.Minecraft.Profile; - -[LifecycleScope("profile", "档案服务")] -public partial class ProfileService -{ - private static ProfileManagement> _newProfileProvider = new(); - private static ProfileManagement> _oldProfileProvider = new(); - - [LifecycleStart] - private static async Task _Start() - { - } - - private static void _MigrateProfile() - { - - var profileLocation = Path.Combine(Paths.SharedData, "profiles.json"); - var profileMigrateFIle = Path.Combine(Paths.SharedData, "pcl.ce.migrated"); - if (!Path.Exists(profileMigrateFIle)) - { - Context.Debug("已迁移档案信息,跳过检查"); - return; - } - Context.Info("开始迁移旧版本档案信息"); - try - { - - } - catch (UnauthorizedAccessException) - { - Context.Error("读取旧版档案信息失败:权限不足"); - } - catch (Exception ex) - { - Context.Error("迁移档案信息失败", ex); - } - } - - private static void _Import(){} -} \ No newline at end of file From 72052254f441ccfff705df4c3595b80015eca1d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9E=97=E8=BD=BB=E8=AF=AD?= Date: Tue, 9 Jun 2026 13:51:19 +0800 Subject: [PATCH 3/6] feat: Profile Model --- PCL.Core/App/Config.cs | 2 ++ .../Autnenrication/MicrosoftProvider.cs | 2 +- .../Profile/Autnenrication/OfflineProvider.cs | 6 ++++ .../Autnenrication/YggdrasilProvider.cs | 6 ++++ PCL.Core/Minecraft/Profile/Models/Profile.cs | 36 ++++++++++++++++--- .../Minecraft/Profile/Models/SafeProfile.cs | 12 +++++++ .../Minecraft/Profile/ProfileManagement.cs | 9 +++-- PCL.Core/Minecraft/Profile/ProfileService.cs | 10 +++--- 8 files changed, 72 insertions(+), 11 deletions(-) create mode 100644 PCL.Core/Minecraft/Profile/Autnenrication/OfflineProvider.cs create mode 100644 PCL.Core/Minecraft/Profile/Autnenrication/YggdrasilProvider.cs create mode 100644 PCL.Core/Minecraft/Profile/Models/SafeProfile.cs diff --git a/PCL.Core/App/Config.cs b/PCL.Core/App/Config.cs index 2a08f2287..a4f358067 100644 --- a/PCL.Core/App/Config.cs +++ b/PCL.Core/App/Config.cs @@ -37,6 +37,8 @@ public static partial class Config /// 动画帧率上限。 /// [ConfigItem("UiAniFPS", 59)] public partial int AnimationFpsLimit { get; set; } + + [ConfigItem("Profile", "{}")] public partial string Profiles { get; set; } } /// diff --git a/PCL.Core/Minecraft/Profile/Autnenrication/MicrosoftProvider.cs b/PCL.Core/Minecraft/Profile/Autnenrication/MicrosoftProvider.cs index f81f593fe..c2e98158a 100644 --- a/PCL.Core/Minecraft/Profile/Autnenrication/MicrosoftProvider.cs +++ b/PCL.Core/Minecraft/Profile/Autnenrication/MicrosoftProvider.cs @@ -1,6 +1,6 @@ namespace PCL.Core.Minecraft.Profile.Autnenrication; -public class MicrosoftProvider +public sealed class MicrosoftProvider(string accessToken, string refreshToken): IAuthenticateProvider { } \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Autnenrication/OfflineProvider.cs b/PCL.Core/Minecraft/Profile/Autnenrication/OfflineProvider.cs new file mode 100644 index 000000000..e4925e16b --- /dev/null +++ b/PCL.Core/Minecraft/Profile/Autnenrication/OfflineProvider.cs @@ -0,0 +1,6 @@ +namespace PCL.Core.Minecraft.Profile.Autnenrication; + +public class OfflineProvider(string accessToken, string refreshToken): IAuthenticateProvider +{ + +} \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Autnenrication/YggdrasilProvider.cs b/PCL.Core/Minecraft/Profile/Autnenrication/YggdrasilProvider.cs new file mode 100644 index 000000000..5077549a2 --- /dev/null +++ b/PCL.Core/Minecraft/Profile/Autnenrication/YggdrasilProvider.cs @@ -0,0 +1,6 @@ +namespace PCL.Core.Minecraft.Profile.Autnenrication; + +public class YggdrasilProvider(string accessToken, string refreshToken): IAuthenticateProvider +{ + +} \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Models/Profile.cs b/PCL.Core/Minecraft/Profile/Models/Profile.cs index 29fcfb1cc..af94b9217 100644 --- a/PCL.Core/Minecraft/Profile/Models/Profile.cs +++ b/PCL.Core/Minecraft/Profile/Models/Profile.cs @@ -1,11 +1,39 @@ -using PCL.Core.Minecraft.Profile.Autnenrication; +using System.Text.Json.Serialization; +using PCL.Core.Minecraft.Profile.Autnenrication; namespace PCL.Core.Minecraft.Profile.Models; -public class Profile +internal class Profile { - public IAuthenticateProvider? CreateAuthenticateServiceProvider() + /// + /// 档案名称 + /// + [JsonPropertyName("name")] + public required string Name { get; set; } + /// + /// UUID + /// + [JsonPropertyName("uuid")] + public required string Uuid { get; set; } + /// + /// 访问令牌 + /// + [JsonPropertyName("accessToken")] + public required string AccessToken { get; set; } + [JsonPropertyName("refreshToken")] + public required string RefreshToken { get; set; } + [JsonPropertyName("propertyJson")] + public required string PropertyJson { get; set; } + [JsonPropertyName("profileDescription")] + public required string ProfileDescription { get; set; } + + [JsonPropertyName("profileType")] + public required ProfileType Type { get; set; } + + public IAuthenticateProvider? CreateAuthenticateServiceProvider() => Type switch { - return default; + ProfileType.Offline => new OfflineProvider(AccessToken, RefreshToken), + ProfileType.Microsoft => new MicrosoftProvider(AccessToken, RefreshToken), + ProfileType.Authlib => new YggdrasilProvider(AccessToken, RefreshToken) } } \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Models/SafeProfile.cs b/PCL.Core/Minecraft/Profile/Models/SafeProfile.cs new file mode 100644 index 000000000..b4681f541 --- /dev/null +++ b/PCL.Core/Minecraft/Profile/Models/SafeProfile.cs @@ -0,0 +1,12 @@ +namespace PCL.Core.Minecraft.Profile.Models; + +/// +/// 供调用方使用的安全 Profile 类 +/// +public class SafeProfile +{ + private SafeProfile(Profile profile) + { + + } +} \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/ProfileManagement.cs b/PCL.Core/Minecraft/Profile/ProfileManagement.cs index e59e6f347..596020e5c 100644 --- a/PCL.Core/Minecraft/Profile/ProfileManagement.cs +++ b/PCL.Core/Minecraft/Profile/ProfileManagement.cs @@ -1,7 +1,12 @@ -namespace PCL.Core.Minecraft.Profile; +using System.IO; +using PCL.Core.Minecraft.Profile.Models; + +namespace PCL.Core.Minecraft.Profile; public class ProfileManagement: IProfileManagement where T:class { + + private ProfileJson? _profiles; public T Create() { throw new System.NotImplementedException(); @@ -19,7 +24,7 @@ public void Update(T profile) public void LoadFromPath(string path) { - throw new System.NotImplementedException(); + LoadFromString(File.ReadAllText(path)); } public void LoadFromString(string profiles) diff --git a/PCL.Core/Minecraft/Profile/ProfileService.cs b/PCL.Core/Minecraft/Profile/ProfileService.cs index e65a73afc..7b5a96d37 100644 --- a/PCL.Core/Minecraft/Profile/ProfileService.cs +++ b/PCL.Core/Minecraft/Profile/ProfileService.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using System.Text.Json; using System.Threading.Tasks; using PCL.Core.App; using PCL.Core.App.IoC; @@ -11,19 +12,20 @@ namespace PCL.Core.Minecraft.Profile; public partial class ProfileService { private static ProfileManagement> _newProfileProvider = new(); - private static ProfileManagement> _oldProfileProvider = new(); + private static ProfileManagement> _oldProfileProvider = new(); [LifecycleStart] private static async Task _Start() { + _newProfileProvider.LoadFromString(Config.System.Profiles); } private static void _MigrateProfile() { var profileLocation = Path.Combine(Paths.SharedData, "profiles.json"); - var profileMigrateFIle = Path.Combine(Paths.SharedData, "pcl.ce.migrated"); - if (!Path.Exists(profileMigrateFIle)) + var profileMigrateFile = Path.Combine(Paths.SharedData, "pcl.ce.migrated"); + if (Path.Exists(profileMigrateFile)) { Context.Debug("已迁移档案信息,跳过检查"); return; @@ -31,7 +33,7 @@ private static void _MigrateProfile() Context.Info("开始迁移旧版本档案信息"); try { - + _oldProfileProvider.LoadFromPath(profileLocation); } catch (UnauthorizedAccessException) { From 7e6ac312351636c16d837e8cab64c8c1a68cc51c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9E=97=E8=BD=BB=E8=AF=AD?= Date: Sun, 14 Jun 2026 13:30:30 +0800 Subject: [PATCH 4/6] impl # Conflicts: # PCL.Core/Minecraft/IdentityModel/Extensions/JsonWebToken/JsonWebKeys.cs # PCL.Core/Minecraft/IdentityModel/Extensions/JsonWebToken/JsonWebToken.cs # PCL.Core/Minecraft/IdentityModel/Extensions/OpenId/OpenIdClient.cs # PCL.Core/Minecraft/IdentityModel/Extensions/OpenId/OpenIdOptions.cs # PCL.Core/Minecraft/IdentityModel/Extensions/YggdrasilConnect/YggdrasilClient.cs # PCL.Core/Minecraft/IdentityModel/Extensions/YggdrasilConnect/YggdrasilOptions.cs # PCL.Core/Minecraft/IdentityModel/IdentityModelException.cs # PCL.Core/Minecraft/IdentityModel/Yggdrasil/Client.cs --- .../Minecraft/IdentityModel/OAuth/Client.cs | 310 +++++++++--------- .../Yggdrasil/YggdrasilCredential.cs | 98 +++--- .../Autnenrication/MicrosoftProvider.cs | 6 - .../Profile/Autnenrication/OfflineProvider.cs | 6 - .../Utils/Models/MojangResponse.cs | 9 - .../Autnenrication/Utils/MojangUtils.cs | 8 - .../Autnenrication/YggdrasilProvider.cs | 6 - .../IAuthenticateProvider.cs | 14 +- .../Autnentication/MicrosoftProvider.cs | 10 + .../MicrosoftProviderBuilder.cs | 20 ++ .../Utils/Models/MojangIdentityToken.cs | 16 +- .../Utils/Models/MojangProfile.cs | 11 + .../Utils/Models/MojangResponse.cs | 18 + .../Utils/Models/XSTSProperty.cs | 16 +- .../Utils/Models/XboxAuthenticate.cs | 14 +- .../Utils/Models/XboxDisplayClaims.cs | 18 +- .../Utils/Models/XboxLiveResponse.cs | 18 +- .../Utils/Models/XboxProperty.cs | 14 +- .../Utils/Models/XboxUserHash.cs | 16 +- .../Autnentication/Utils/MojangUtils.cs | 81 +++++ .../Utils/XboxUtils.cs | 38 +-- .../Minecraft/Profile/Models/OldProfile.cs | 56 ++-- PCL.Core/Minecraft/Profile/Models/Profile.cs | 48 +-- .../Minecraft/Profile/Models/ProfileJson.cs | 16 +- .../Minecraft/Profile/Models/ProfileType.cs | 14 +- .../Minecraft/Profile/Models/SafeProfile.cs | 25 +- .../Minecraft/Profile/ProfileManagement.cs | 9 +- PCL.Core/Minecraft/Profile/ProfileService.cs | 10 +- 28 files changed, 496 insertions(+), 429 deletions(-) delete mode 100644 PCL.Core/Minecraft/Profile/Autnenrication/MicrosoftProvider.cs delete mode 100644 PCL.Core/Minecraft/Profile/Autnenrication/OfflineProvider.cs delete mode 100644 PCL.Core/Minecraft/Profile/Autnenrication/Utils/Models/MojangResponse.cs delete mode 100644 PCL.Core/Minecraft/Profile/Autnenrication/Utils/MojangUtils.cs delete mode 100644 PCL.Core/Minecraft/Profile/Autnenrication/YggdrasilProvider.cs rename PCL.Core/Minecraft/Profile/{Autnenrication => Autnentication}/IAuthenticateProvider.cs (96%) create mode 100644 PCL.Core/Minecraft/Profile/Autnentication/MicrosoftProvider.cs create mode 100644 PCL.Core/Minecraft/Profile/Autnentication/MicrosoftProviderBuilder.cs rename PCL.Core/Minecraft/Profile/{Autnenrication => Autnentication}/Utils/Models/MojangIdentityToken.cs (96%) create mode 100644 PCL.Core/Minecraft/Profile/Autnentication/Utils/Models/MojangProfile.cs create mode 100644 PCL.Core/Minecraft/Profile/Autnentication/Utils/Models/MojangResponse.cs rename PCL.Core/Minecraft/Profile/{Autnenrication => Autnentication}/Utils/Models/XSTSProperty.cs (96%) rename PCL.Core/Minecraft/Profile/{Autnenrication => Autnentication}/Utils/Models/XboxAuthenticate.cs (97%) rename PCL.Core/Minecraft/Profile/{Autnenrication => Autnentication}/Utils/Models/XboxDisplayClaims.cs (96%) rename PCL.Core/Minecraft/Profile/{Autnenrication => Autnentication}/Utils/Models/XboxLiveResponse.cs (96%) rename PCL.Core/Minecraft/Profile/{Autnenrication => Autnentication}/Utils/Models/XboxProperty.cs (97%) rename PCL.Core/Minecraft/Profile/{Autnenrication => Autnentication}/Utils/Models/XboxUserHash.cs (96%) create mode 100644 PCL.Core/Minecraft/Profile/Autnentication/Utils/MojangUtils.cs rename PCL.Core/Minecraft/Profile/{Autnenrication => Autnentication}/Utils/XboxUtils.cs (97%) diff --git a/PCL.Core/Minecraft/IdentityModel/OAuth/Client.cs b/PCL.Core/Minecraft/IdentityModel/OAuth/Client.cs index 1718d5620..7ff19dffd 100644 --- a/PCL.Core/Minecraft/IdentityModel/OAuth/Client.cs +++ b/PCL.Core/Minecraft/IdentityModel/OAuth/Client.cs @@ -1,155 +1,155 @@ -using System; -using System.Text; -using System.Net.Http; -using System.Text.Json; -using System.Threading.Tasks; -using System.Collections.Generic; -using System.Threading; -using PCL.Core.IO.Net.Http; -using PCL.Core.Minecraft.IdentityModel; - -namespace PCL.Core.Minecraft.IdentityModel.OAuth; - -/// -/// OAuth 客户端实现,配合 Polly 食用效果更佳 -/// -/// OAuth 参数 -public sealed class SimpleOAuthClient(OAuthClientOptions options):IOAuthClient -{ - /// - /// 获取授权 Url - /// - /// 访问权限列表 - /// - /// - /// - public string GetAuthorizeUrl(string[] scopes,string state,Dictionary? extData = null) - { - ArgumentException.ThrowIfNullOrWhiteSpace(options.Meta.AuthorizeEndpoint); - var sb = new StringBuilder(); - sb.Append(options.Meta.AuthorizeEndpoint); - sb.Append($"?response_type=code&scope={Uri.EscapeDataString(string.Join(" ", scopes))}"); - sb.Append($"&redirect_uri={Uri.EscapeDataString(options.RedirectUri)}"); - sb.Append($"&client_id={options.ClientId}&state={state}"); - if (extData is null) return sb.ToString(); - foreach (var kvp in extData) - sb.Append($"&{kvp.Key}={Uri.EscapeDataString(kvp.Value)}"); - return sb.ToString(); - } - - /// - /// 使用授权代码获取令牌 - /// - /// 授权代码 - /// 附加属性,不应该包含必须参数和预定义字段 (e.g. client_id、grant_type) - /// - /// - public async Task AuthorizeWithCodeAsync( - string code,CancellationToken token,Dictionary? extData = null - ) - { - extData ??= new Dictionary(); - extData["client_id"] = options.ClientId; - extData["grant_type"] = "authorization_code"; - extData["code"] = code; - var client = options.GetClient.Invoke(); - using var content = new FormUrlEncodedContent(extData); - using var response = await HttpRequest - .CreatePost(options.Meta.TokenEndpoint) - .WithContent(content) - .WithHeaders(options.Headers ?? []) - .SendAsync(client, cancellationToken: token) - .ConfigureAwait(false); - return await response - .AsJsonAsync(cancellationToken: token) - .ConfigureAwait(false); - } - /// - /// 获取设备代码对 - /// - /// - /// - /// - /// - public async Task GetCodePairAsync - (string[] scopes,CancellationToken token, Dictionary? extData = null) - { - ArgumentException.ThrowIfNullOrEmpty(options.Meta.DeviceEndpoint); - var client = options.GetClient.Invoke(); - extData ??= new Dictionary(); - extData["scope"] = string.Join(" ", scopes); - extData["client_id"] = options.ClientId; - var content = new FormUrlEncodedContent(extData); - - using var response = await HttpRequest - .CreatePost(options.Meta.DeviceEndpoint) - .WithContent(content) - .WithHeaders(options.Headers ?? []) - .SendAsync(client, cancellationToken: token) - .ConfigureAwait(false); - - return await response - .AsJsonAsync(cancellationToken: token) - .ConfigureAwait(false); - } - /// - /// 验证用户授权状态
- /// 注:此方法不会检查是否过去了 Interval 秒,请自行处理 - ///
- /// - /// - /// - /// - /// 认证服务器返回设备授权错误 - public async Task AuthorizeWithDeviceAsync - (DeviceCodeData data,CancellationToken token,Dictionary? extData = null) - { - if (data.IsError) throw new IdentityModelAuthenticationException(data.Error, data.ErrorDescription); - var client = options.GetClient.Invoke(); - extData ??= new Dictionary(); - extData["client_id"] = options.ClientId; - extData["grant_type"] = "urn:ietf:params:oauth:grant-type:device_code"; - extData["device_code"] = data.DeviceCode!; - - using var content = new FormUrlEncodedContent(extData); - using var response = await HttpRequest - .CreatePost(options.Meta.TokenEndpoint) - .WithContent(content) - .WithHeaders(options.Headers ?? []) - .SendAsync(client, cancellationToken: token) - .ConfigureAwait(false); - - return await response - .AsJsonAsync(cancellationToken: token) - .ConfigureAwait(false); - } - /// - /// 刷新登录 - /// - /// - /// - /// - /// - /// 认证服务器返回刷新授权错误 - public async Task AuthorizeWithSilentAsync - (AuthorizeResult data,CancellationToken token,Dictionary? extData = null) - { - var client = options.GetClient.Invoke(); - if (data.IsError) throw new IdentityModelAuthenticationException(data.Error, data.ErrorDescription); - extData ??= []; - extData["refresh_token"] = data.RefreshToken!; - extData["grant_type"] = "refresh_token"; - extData["client_id"] = options.ClientId; - using var content = new FormUrlEncodedContent(extData); - using var response = await HttpRequest - .CreatePost(options.Meta.TokenEndpoint) - .WithHeaders(options.Headers ?? []) - .WithContent(content) - .SendAsync(client, cancellationToken: token) - .ConfigureAwait(false); - - return await response - .AsJsonAsync(cancellationToken: token) - .ConfigureAwait(false); - } -} +using System; +using System.Text; +using System.Net.Http; +using System.Text.Json; +using System.Threading.Tasks; +using System.Collections.Generic; +using System.Threading; +using PCL.Core.IO.Net.Http; +using PCL.Core.Minecraft.IdentityModel; + +namespace PCL.Core.Minecraft.IdentityModel.OAuth; + +/// +/// OAuth 客户端实现,配合 Polly 食用效果更佳 +/// +/// OAuth 参数 +public sealed class SimpleOAuthClient(OAuthClientOptions options):IOAuthClient +{ + /// + /// 获取授权 Url + /// + /// 访问权限列表 + /// + /// + /// + public string GetAuthorizeUrl(string[] scopes,string state,Dictionary? extData = null) + { + ArgumentException.ThrowIfNullOrWhiteSpace(options.Meta.AuthorizeEndpoint); + var sb = new StringBuilder(); + sb.Append(options.Meta.AuthorizeEndpoint); + sb.Append($"?response_type=code&scope={Uri.EscapeDataString(string.Join(" ", scopes))}"); + sb.Append($"&redirect_uri={Uri.EscapeDataString(options.RedirectUri)}"); + sb.Append($"&client_id={options.ClientId}&state={state}"); + if (extData is null) return sb.ToString(); + foreach (var kvp in extData) + sb.Append($"&{kvp.Key}={Uri.EscapeDataString(kvp.Value)}"); + return sb.ToString(); + } + + /// + /// 使用授权代码获取令牌 + /// + /// 授权代码 + /// 附加属性,不应该包含必须参数和预定义字段 (e.g. client_id、grant_type) + /// + /// + public async Task AuthorizeWithCodeAsync( + string code,CancellationToken token,Dictionary? extData = null + ) + { + extData ??= new Dictionary(); + extData["client_id"] = options.ClientId; + extData["grant_type"] = "authorization_code"; + extData["code"] = code; + var client = options.GetClient.Invoke(); + using var content = new FormUrlEncodedContent(extData); + using var response = await HttpRequest + .CreatePost(options.Meta.TokenEndpoint) + .WithContent(content) + .WithHeaders(options.Headers ?? []) + .SendAsync(client, cancellationToken: token) + .ConfigureAwait(false); + return await response + .AsJsonAsync(cancellationToken: token) + .ConfigureAwait(false); + } + /// + /// 获取设备代码对 + /// + /// + /// + /// + /// + public async Task GetCodePairAsync + (string[] scopes,CancellationToken token, Dictionary? extData = null) + { + ArgumentException.ThrowIfNullOrEmpty(options.Meta.DeviceEndpoint); + var client = options.GetClient.Invoke(); + extData ??= new Dictionary(); + extData["scope"] = string.Join(" ", scopes); + extData["client_id"] = options.ClientId; + var content = new FormUrlEncodedContent(extData); + + using var response = await HttpRequest + .CreatePost(options.Meta.DeviceEndpoint) + .WithContent(content) + .WithHeaders(options.Headers ?? []) + .SendAsync(client, cancellationToken: token) + .ConfigureAwait(false); + + return await response + .AsJsonAsync(cancellationToken: token) + .ConfigureAwait(false); + } + /// + /// 验证用户授权状态
+ /// 注:此方法不会检查是否过去了 Interval 秒,请自行处理 + ///
+ /// + /// + /// + /// + /// 认证服务器返回设备授权错误 + public async Task AuthorizeWithDeviceAsync + (DeviceCodeData data,CancellationToken token,Dictionary? extData = null) + { + if (data.IsError) throw new IdentityModelAuthenticationException(data.Error, data.ErrorDescription); + var client = options.GetClient.Invoke(); + extData ??= new Dictionary(); + extData["client_id"] = options.ClientId; + extData["grant_type"] = "urn:ietf:params:oauth:grant-type:device_code"; + extData["device_code"] = data.DeviceCode!; + + using var content = new FormUrlEncodedContent(extData); + using var response = await HttpRequest + .CreatePost(options.Meta.TokenEndpoint) + .WithContent(content) + .WithHeaders(options.Headers ?? []) + .SendAsync(client, cancellationToken: token) + .ConfigureAwait(false); + + return await response + .AsJsonAsync(cancellationToken: token) + .ConfigureAwait(false); + } + /// + /// 刷新登录 + /// + /// + /// + /// + /// + /// 认证服务器返回刷新授权错误 + public async Task AuthorizeWithSilentAsync + (AuthorizeResult data,CancellationToken token,Dictionary? extData = null) + { + var client = options.GetClient.Invoke(); + if (data.IsError) throw new IdentityModelAuthenticationException(data.Error, data.ErrorDescription); + extData ??= []; + extData["refresh_token"] = data.RefreshToken!; + extData["grant_type"] = "refresh_token"; + extData["client_id"] = options.ClientId; + using var content = new FormUrlEncodedContent(extData); + using var response = await HttpRequest + .CreatePost(options.Meta.TokenEndpoint) + .WithHeaders(options.Headers ?? []) + .WithContent(content) + .SendAsync(client, cancellationToken: token) + .ConfigureAwait(false); + + return await response + .AsJsonAsync(cancellationToken: token) + .ConfigureAwait(false); + } +} diff --git a/PCL.Core/Minecraft/IdentityModel/Yggdrasil/YggdrasilCredential.cs b/PCL.Core/Minecraft/IdentityModel/Yggdrasil/YggdrasilCredential.cs index fd63e65bc..03530de6b 100644 --- a/PCL.Core/Minecraft/IdentityModel/Yggdrasil/YggdrasilCredential.cs +++ b/PCL.Core/Minecraft/IdentityModel/Yggdrasil/YggdrasilCredential.cs @@ -1,49 +1,49 @@ -using System.Text.Json.Serialization; - -namespace PCL.Core.Minecraft.IdentityModel.Yggdrasil; - -public record YggdrasilCredential -{ - [JsonPropertyName("username")] public required string User { get; init; } - [JsonPropertyName("password")] public required string Password { get; init; } - [JsonPropertyName("agent")] public Agent Agent { get; init; } = new(); - [JsonPropertyName("requestUser")] public bool RequestUser { get; set; } -} - -public record YggdrasilAuthenticateResult -{ - /// - /// 错误类型 - /// - [JsonPropertyName("error")] public string? Error { get; init; } - /// - /// 错误消息 - /// - [JsonPropertyName("errorMessage")] public string? ErrorMessage { get; init; } - /// - /// 访问令牌 - /// - [JsonPropertyName("accessToken")] public string? AccessToken { get; init; } - /// - /// 客户端令牌,基本没用 - /// - [JsonPropertyName("clientToken")] public string? ClientToken { get; init; } - /// - /// 选择的档案 - /// - [JsonPropertyName("selectedProfile")] public Profile? SelectedProfile { get; init; } - /// - /// 可用档案 - /// - [JsonPropertyName("availableProfiles")] public Profile[]? AvailableProfiles { get; init; } - /// - /// 用户信息 - /// - [JsonPropertyName("user")] public Profile? User { get; init; } -} - -public record YggdrasilRefresh -{ - [JsonPropertyName("accessToken")] public required string AccessToken { get; set; } - [JsonPropertyName("selectedProfile")] public Profile? SelectedProfile { get; set; } -} +using System.Text.Json.Serialization; + +namespace PCL.Core.Minecraft.IdentityModel.Yggdrasil; + +public record YggdrasilCredential +{ + [JsonPropertyName("username")] public required string User { get; init; } + [JsonPropertyName("password")] public required string Password { get; init; } + [JsonPropertyName("agent")] public Agent Agent { get; init; } = new(); + [JsonPropertyName("requestUser")] public bool RequestUser { get; set; } +} + +public record YggdrasilAuthenticateResult +{ + /// + /// 错误类型 + /// + [JsonPropertyName("error")] public string? Error { get; init; } + /// + /// 错误消息 + /// + [JsonPropertyName("errorMessage")] public string? ErrorMessage { get; init; } + /// + /// 访问令牌 + /// + [JsonPropertyName("accessToken")] public string? AccessToken { get; init; } + /// + /// 客户端令牌,基本没用 + /// + [JsonPropertyName("clientToken")] public string? ClientToken { get; init; } + /// + /// 选择的档案 + /// + [JsonPropertyName("selectedProfile")] public Profile? SelectedProfile { get; init; } + /// + /// 可用档案 + /// + [JsonPropertyName("availableProfiles")] public Profile[]? AvailableProfiles { get; init; } + /// + /// 用户信息 + /// + [JsonPropertyName("user")] public Profile? User { get; init; } +} + +public record YggdrasilRefresh +{ + [JsonPropertyName("accessToken")] public required string AccessToken { get; set; } + [JsonPropertyName("selectedProfile")] public Profile? SelectedProfile { get; set; } +} diff --git a/PCL.Core/Minecraft/Profile/Autnenrication/MicrosoftProvider.cs b/PCL.Core/Minecraft/Profile/Autnenrication/MicrosoftProvider.cs deleted file mode 100644 index c2e98158a..000000000 --- a/PCL.Core/Minecraft/Profile/Autnenrication/MicrosoftProvider.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace PCL.Core.Minecraft.Profile.Autnenrication; - -public sealed class MicrosoftProvider(string accessToken, string refreshToken): IAuthenticateProvider -{ - -} \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Autnenrication/OfflineProvider.cs b/PCL.Core/Minecraft/Profile/Autnenrication/OfflineProvider.cs deleted file mode 100644 index e4925e16b..000000000 --- a/PCL.Core/Minecraft/Profile/Autnenrication/OfflineProvider.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace PCL.Core.Minecraft.Profile.Autnenrication; - -public class OfflineProvider(string accessToken, string refreshToken): IAuthenticateProvider -{ - -} \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Autnenrication/Utils/Models/MojangResponse.cs b/PCL.Core/Minecraft/Profile/Autnenrication/Utils/Models/MojangResponse.cs deleted file mode 100644 index dab469858..000000000 --- a/PCL.Core/Minecraft/Profile/Autnenrication/Utils/Models/MojangResponse.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.Text.Json.Serialization; - -namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils.Models; - -public record MojangResponse -{ - [JsonPropertyName("username")] - public required string UserName { get; set; } -} \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Autnenrication/Utils/MojangUtils.cs b/PCL.Core/Minecraft/Profile/Autnenrication/Utils/MojangUtils.cs deleted file mode 100644 index 874ce72dd..000000000 --- a/PCL.Core/Minecraft/Profile/Autnenrication/Utils/MojangUtils.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils; - -public static class MojangUtils -{ - private const string MojangAuthServer = "https://api.minecraftservices.com/authentication/login_with_xbox"; - //public static async Task<> AuthenticateAsync(){} - //public static async Task -} \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Autnenrication/YggdrasilProvider.cs b/PCL.Core/Minecraft/Profile/Autnenrication/YggdrasilProvider.cs deleted file mode 100644 index 5077549a2..000000000 --- a/PCL.Core/Minecraft/Profile/Autnenrication/YggdrasilProvider.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace PCL.Core.Minecraft.Profile.Autnenrication; - -public class YggdrasilProvider(string accessToken, string refreshToken): IAuthenticateProvider -{ - -} \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Autnenrication/IAuthenticateProvider.cs b/PCL.Core/Minecraft/Profile/Autnentication/IAuthenticateProvider.cs similarity index 96% rename from PCL.Core/Minecraft/Profile/Autnenrication/IAuthenticateProvider.cs rename to PCL.Core/Minecraft/Profile/Autnentication/IAuthenticateProvider.cs index 8d6410fa2..8c0249d86 100644 --- a/PCL.Core/Minecraft/Profile/Autnenrication/IAuthenticateProvider.cs +++ b/PCL.Core/Minecraft/Profile/Autnentication/IAuthenticateProvider.cs @@ -1,8 +1,8 @@ -using System.Threading.Tasks; - -namespace PCL.Core.Minecraft.Profile.Autnenrication; - -public interface IAuthenticateProvider -{ - //public Task AuthenticateAsync(); +using System.Threading.Tasks; + +namespace PCL.Core.Minecraft.Profile.Autnenrication; + +public interface IAuthenticateProvider +{ + //public Task AuthenticateAsync(); } \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Autnentication/MicrosoftProvider.cs b/PCL.Core/Minecraft/Profile/Autnentication/MicrosoftProvider.cs new file mode 100644 index 000000000..e368db841 --- /dev/null +++ b/PCL.Core/Minecraft/Profile/Autnentication/MicrosoftProvider.cs @@ -0,0 +1,10 @@ +using PCL.Core.IO.Net; +using PCL.Core.Minecraft.IdentityModel.Extensions.OpenId; +using PCL.Core.Minecraft.IdentityModel.OAuth; + +namespace PCL.Core.Minecraft.Profile.Autnenrication; + +public class MicrosoftProvider(OpenIdClient client) +{ + +} \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Autnentication/MicrosoftProviderBuilder.cs b/PCL.Core/Minecraft/Profile/Autnentication/MicrosoftProviderBuilder.cs new file mode 100644 index 000000000..9c27c0adf --- /dev/null +++ b/PCL.Core/Minecraft/Profile/Autnentication/MicrosoftProviderBuilder.cs @@ -0,0 +1,20 @@ +using PCL.Core.Minecraft.IdentityModel.Extensions.OpenId; + +namespace PCL.Core.Minecraft.Profile.Autnenrication; + +public class MicrosoftProviderBuilder +{ + private MicrosoftProviderBuilder(){} + + private OpenIdClient? _client; + + public MicrosoftProviderBuilder Create() => new MicrosoftProviderBuilder(); + + public MicrosoftProviderBuilder SetOptions(OpenIdOptions options) + { + _client = new OpenIdClient(options); + return this; + } + + +} \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Autnenrication/Utils/Models/MojangIdentityToken.cs b/PCL.Core/Minecraft/Profile/Autnentication/Utils/Models/MojangIdentityToken.cs similarity index 96% rename from PCL.Core/Minecraft/Profile/Autnenrication/Utils/Models/MojangIdentityToken.cs rename to PCL.Core/Minecraft/Profile/Autnentication/Utils/Models/MojangIdentityToken.cs index 50de6e689..7364894fd 100644 --- a/PCL.Core/Minecraft/Profile/Autnenrication/Utils/Models/MojangIdentityToken.cs +++ b/PCL.Core/Minecraft/Profile/Autnentication/Utils/Models/MojangIdentityToken.cs @@ -1,9 +1,9 @@ -using System.Text.Json.Serialization; - -namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils.Models; - -public class MojangIdentityToken -{ - [JsonPropertyName("identityToken")] - public required string IdentityToken { get; set; } +using System.Text.Json.Serialization; + +namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils.Models; + +public class MojangIdentityToken +{ + [JsonPropertyName("identityToken")] + public required string IdentityToken { get; set; } } \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Autnentication/Utils/Models/MojangProfile.cs b/PCL.Core/Minecraft/Profile/Autnentication/Utils/Models/MojangProfile.cs new file mode 100644 index 000000000..8219e427f --- /dev/null +++ b/PCL.Core/Minecraft/Profile/Autnentication/Utils/Models/MojangProfile.cs @@ -0,0 +1,11 @@ +using System.Text.Json.Serialization; + +namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils.Models; + +public record MojangProfile +{ + [JsonPropertyName("id")] + public required string Uuid { get; set; } + [JsonPropertyName("name")] + public required string Name { get; set; } +} \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Autnentication/Utils/Models/MojangResponse.cs b/PCL.Core/Minecraft/Profile/Autnentication/Utils/Models/MojangResponse.cs new file mode 100644 index 000000000..937c38794 --- /dev/null +++ b/PCL.Core/Minecraft/Profile/Autnentication/Utils/Models/MojangResponse.cs @@ -0,0 +1,18 @@ +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils.Models; + +public record MojangResponse +{ + [JsonPropertyName("username")] + public required string UserName { get; set; } + [JsonPropertyName("roles")] + public required IEnumerable Roles { get; set; } + [JsonPropertyName("access_token")] + public required string AccessToken { get; set; } + [JsonPropertyName("expires_int")] + public required int ExpiresIn { get; set; } + [JsonPropertyName("token_type")] + public required string TokenType { get; set; } +} \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Autnenrication/Utils/Models/XSTSProperty.cs b/PCL.Core/Minecraft/Profile/Autnentication/Utils/Models/XSTSProperty.cs similarity index 96% rename from PCL.Core/Minecraft/Profile/Autnenrication/Utils/Models/XSTSProperty.cs rename to PCL.Core/Minecraft/Profile/Autnentication/Utils/Models/XSTSProperty.cs index 8c1beea52..b89b020c2 100644 --- a/PCL.Core/Minecraft/Profile/Autnenrication/Utils/Models/XSTSProperty.cs +++ b/PCL.Core/Minecraft/Profile/Autnentication/Utils/Models/XSTSProperty.cs @@ -1,9 +1,9 @@ -using System.Collections.Generic; - -namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils.Models; - -public record XSTSProperty -{ - public string SandboxId { get; set; } = "RETAIL"; - public List UserTokens { get; set; } = []; +using System.Collections.Generic; + +namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils.Models; + +public record XSTSProperty +{ + public string SandboxId { get; set; } = "RETAIL"; + public List UserTokens { get; set; } = []; } \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Autnenrication/Utils/Models/XboxAuthenticate.cs b/PCL.Core/Minecraft/Profile/Autnentication/Utils/Models/XboxAuthenticate.cs similarity index 97% rename from PCL.Core/Minecraft/Profile/Autnenrication/Utils/Models/XboxAuthenticate.cs rename to PCL.Core/Minecraft/Profile/Autnentication/Utils/Models/XboxAuthenticate.cs index 9edcda0fb..ff1bab478 100644 --- a/PCL.Core/Minecraft/Profile/Autnenrication/Utils/Models/XboxAuthenticate.cs +++ b/PCL.Core/Minecraft/Profile/Autnentication/Utils/Models/XboxAuthenticate.cs @@ -1,8 +1,8 @@ -namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils.Models; - -public record XboxAuthenticate -{ - public required T Properties { get; set; } - public string RelyingParty { get; set; } = "http://auth.xboxlive.com"; - public required string TokenType { get; set; } +namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils.Models; + +public record XboxAuthenticate +{ + public required T Properties { get; set; } + public string RelyingParty { get; set; } = "http://auth.xboxlive.com"; + public required string TokenType { get; set; } } \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Autnenrication/Utils/Models/XboxDisplayClaims.cs b/PCL.Core/Minecraft/Profile/Autnentication/Utils/Models/XboxDisplayClaims.cs similarity index 96% rename from PCL.Core/Minecraft/Profile/Autnenrication/Utils/Models/XboxDisplayClaims.cs rename to PCL.Core/Minecraft/Profile/Autnentication/Utils/Models/XboxDisplayClaims.cs index c73564c7b..7db612eb4 100644 --- a/PCL.Core/Minecraft/Profile/Autnenrication/Utils/Models/XboxDisplayClaims.cs +++ b/PCL.Core/Minecraft/Profile/Autnentication/Utils/Models/XboxDisplayClaims.cs @@ -1,10 +1,10 @@ -using System.Collections.Generic; -using System.Text.Json.Serialization; - -namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils.Models; - -public record XboxDisplayClaims -{ - [JsonPropertyName("xui")] - public required List Xui { get; set; } +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils.Models; + +public record XboxDisplayClaims +{ + [JsonPropertyName("xui")] + public required List Xui { get; set; } } \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Autnenrication/Utils/Models/XboxLiveResponse.cs b/PCL.Core/Minecraft/Profile/Autnentication/Utils/Models/XboxLiveResponse.cs similarity index 96% rename from PCL.Core/Minecraft/Profile/Autnenrication/Utils/Models/XboxLiveResponse.cs rename to PCL.Core/Minecraft/Profile/Autnentication/Utils/Models/XboxLiveResponse.cs index 1e0ef8ffb..a2187345b 100644 --- a/PCL.Core/Minecraft/Profile/Autnenrication/Utils/Models/XboxLiveResponse.cs +++ b/PCL.Core/Minecraft/Profile/Autnentication/Utils/Models/XboxLiveResponse.cs @@ -1,10 +1,10 @@ -using System; - -namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils.Models; - -public record XboxLiveResponse -{ - public required DateTime IssueInstant { get; set; } - public required DateTime NotAfter { get; set; } - public required string Token { get; set; } +using System; + +namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils.Models; + +public record XboxLiveResponse +{ + public required DateTime IssueInstant { get; set; } + public required DateTime NotAfter { get; set; } + public required string Token { get; set; } } \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Autnenrication/Utils/Models/XboxProperty.cs b/PCL.Core/Minecraft/Profile/Autnentication/Utils/Models/XboxProperty.cs similarity index 97% rename from PCL.Core/Minecraft/Profile/Autnenrication/Utils/Models/XboxProperty.cs rename to PCL.Core/Minecraft/Profile/Autnentication/Utils/Models/XboxProperty.cs index 3558df6e5..7f2b27c43 100644 --- a/PCL.Core/Minecraft/Profile/Autnenrication/Utils/Models/XboxProperty.cs +++ b/PCL.Core/Minecraft/Profile/Autnentication/Utils/Models/XboxProperty.cs @@ -1,8 +1,8 @@ -namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils.Models; - -public record XboxProperty -{ - public string AuthMethod { get; set; } = "RPS"; - public string SiteName { get; set; } = "user.auth.xboxlive.com"; - public required string RpsTicket { get; set; } +namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils.Models; + +public record XboxProperty +{ + public string AuthMethod { get; set; } = "RPS"; + public string SiteName { get; set; } = "user.auth.xboxlive.com"; + public required string RpsTicket { get; set; } } \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Autnenrication/Utils/Models/XboxUserHash.cs b/PCL.Core/Minecraft/Profile/Autnentication/Utils/Models/XboxUserHash.cs similarity index 96% rename from PCL.Core/Minecraft/Profile/Autnenrication/Utils/Models/XboxUserHash.cs rename to PCL.Core/Minecraft/Profile/Autnentication/Utils/Models/XboxUserHash.cs index e405a1c11..a03b64182 100644 --- a/PCL.Core/Minecraft/Profile/Autnenrication/Utils/Models/XboxUserHash.cs +++ b/PCL.Core/Minecraft/Profile/Autnentication/Utils/Models/XboxUserHash.cs @@ -1,9 +1,9 @@ -using System.Text.Json.Serialization; - -namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils.Models; - -public record XboxUserHash -{ - [JsonPropertyName("uhs")] - public required string UserHash { get; set; } +using System.Text.Json.Serialization; + +namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils.Models; + +public record XboxUserHash +{ + [JsonPropertyName("uhs")] + public required string UserHash { get; set; } } \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Autnentication/Utils/MojangUtils.cs b/PCL.Core/Minecraft/Profile/Autnentication/Utils/MojangUtils.cs new file mode 100644 index 000000000..57685df15 --- /dev/null +++ b/PCL.Core/Minecraft/Profile/Autnentication/Utils/MojangUtils.cs @@ -0,0 +1,81 @@ +using System; +using System.Net.Http; +using System.Net.Http.Json; +using System.Text.Json; +using System.Text.Json.Nodes; +using System.Threading.Tasks; +using PCL.Core.IO.Net.Http; +using PCL.Core.Minecraft.Profile.Autnenrication.Utils.Models; +using PCL.Core.Minecraft.Profile.Models; + +namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils; + +public static class MojangUtils +{ + #region "API 定义" + + private const string MojangAuthenticateEndpoint = "https://api.minecraftservices.com/authentication/login_with_xbox"; + private const string LicenseEndpoint = "https://api.minecraftservices.com/entitlements/mcstore"; + private const string ProfileEndpont = "https://api.minecraftservices.com/minecraft/profile"; + private const string SessionServerProfileEndpoint = "https://sessionserver.mojang.com/session/minecraft/profile/"; + private const string NameProfileEndpoint = "https://api.minecraftservices.com/users/profiles/minecraft/"; + private const string SkinServiceChangeEndpoint = "https://api.minecraftservices.com/minecraft/profile/skins"; + private const string SkinServiceResetEndpoint = "https://api.minecraftservices.com/user/profile/skin/active"; + + #endregion + + /// + /// 发送一次登录请求 + /// + /// XSTS 令牌 + /// Xbox User Hash + /// + public static async Task AuthenticateAsync(string xstsToken, string userHash) + { + using var response = await HttpRequest.CreatePost(MojangAuthenticateEndpoint) + .WithContent(new StringContent( + JsonSerializer.Serialize(new MojangIdentityToken + { + IdentityToken = $"XBL3.0 x={userHash};{xstsToken}" + } + )) + ).SendAsync().ConfigureAwait(false); + return await response.AsJsonAsync().ConfigureAwait(false); + } + /// + /// 检查玩家是否持有许可 + /// + /// + /// 如果没有有效许可,返回 false + public static async Task CheckLicenseAsync(SafeProfile profile) + { + using var response = await HttpRequest.Create(LicenseEndpoint) + .WithAuthentication(profile.TokenType, profile.AccessToken) + .SendAsync().ConfigureAwait(false); + return response.IsSuccess; + } + /// + /// 获取玩家的完整档案 + /// + /// 档案信息 + public static async Task GetProfileAsync(SafeProfile profile) + { + throw new NotImplementedException(); + } + + /// + /// 通过玩家名称获取档案信息
+ /// NOTE: 由于 Mojang API 限制,此方法仅能获取精简版档案信息
+ /// 如果需要完整信息,请调用 。 + ///
+ /// + public static async Task GetSimpleProfileWithNameAsync(string name) + { + + } + + public static async Task GetFullProfileWithUuidAsync() + { + + } +} \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Autnenrication/Utils/XboxUtils.cs b/PCL.Core/Minecraft/Profile/Autnentication/Utils/XboxUtils.cs similarity index 97% rename from PCL.Core/Minecraft/Profile/Autnenrication/Utils/XboxUtils.cs rename to PCL.Core/Minecraft/Profile/Autnentication/Utils/XboxUtils.cs index d95dd6ef2..f8329cb71 100644 --- a/PCL.Core/Minecraft/Profile/Autnenrication/Utils/XboxUtils.cs +++ b/PCL.Core/Minecraft/Profile/Autnentication/Utils/XboxUtils.cs @@ -1,20 +1,20 @@ -using System.Threading.Tasks; -using PCL.Core.IO.Net.Http; -using PCL.Core.Minecraft.Profile.Autnenrication.Utils.Models; - -namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils; - -public static class XboxUtils -{ - private const string XboxLiveAuthServer = "https://user.auth.xboxlive.com/user/authenticate"; - private const string XstsAuthorizeServer = "https://xsts.auth.xboxlive.com/xsts/authorize"; - public static async Task AuthenticateAsync(XboxAuthenticate authData, bool isXsts) - { - using var response = await HttpRequest.CreatePost( - isXsts ? XstsAuthorizeServer:XboxLiveAuthServer - ).WithJsonContent(authData).SendAsync() - .ConfigureAwait(false); - - return await response.AsJsonAsync(); - } +using System.Threading.Tasks; +using PCL.Core.IO.Net.Http; +using PCL.Core.Minecraft.Profile.Autnenrication.Utils.Models; + +namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils; + +public static class XboxUtils +{ + private const string XboxLiveAuthServer = "https://user.auth.xboxlive.com/user/authenticate"; + private const string XstsAuthorizeServer = "https://xsts.auth.xboxlive.com/xsts/authorize"; + public static async Task AuthenticateAsync(XboxAuthenticate authData, bool isXsts) + { + using var response = await HttpRequest.CreatePost( + isXsts ? XstsAuthorizeServer:XboxLiveAuthServer + ).WithJsonContent(authData).SendAsync() + .ConfigureAwait(false); + + return await response.AsJsonAsync(); + } } \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Models/OldProfile.cs b/PCL.Core/Minecraft/Profile/Models/OldProfile.cs index d46df3737..e2ae9b603 100644 --- a/PCL.Core/Minecraft/Profile/Models/OldProfile.cs +++ b/PCL.Core/Minecraft/Profile/Models/OldProfile.cs @@ -1,32 +1,26 @@ -using System.Text.Json.Serialization; - -namespace PCL.Core.Minecraft.Profile.Models; - -public record OldProfile -{ - [JsonPropertyName("type")] - public required string Type { get; set; } - [JsonPropertyName("uuid")] - public required string Uuid { get; set; } - [JsonPropertyName("username")] - public required string UserName { get; set; } - [JsonPropertyName("accessToken")] - public string? AccessToken { get; set; } - [JsonPropertyName("refreshToken")] - public string? RefreshToken { get; set; } - [JsonPropertyName("expires")] - public long? Expires { get; set; } - [JsonPropertyName("desc")] - public required string Description { get; set; } - [JsonPropertyName("skinHeadId")] - public required string SkinHeadId { get; set; } - [JsonPropertyName("serverName")] - public string? ServerName { get; set; } - [JsonPropertyName("server")] - public string? Server { get; set; } - [JsonPropertyName("name")] - public string? Name { get; set; } - [JsonPropertyName("password")] - public string? Password { get; set; } - +using System.Text.Json.Serialization; + +namespace PCL.Core.Minecraft.Profile.Models; + +public record OldProfile: SafeProfile +{ + [JsonPropertyName("type")] + public required string Type { get; set; } + [JsonPropertyName("refreshToken")] + public string? RefreshToken { get; set; } + [JsonPropertyName("expires")] + public long? Expires { get; set; } + [JsonPropertyName("desc")] + public required string Description { get; set; } + [JsonPropertyName("skinHeadId")] + public required string SkinHeadId { get; set; } + [JsonPropertyName("serverName")] + public string? ServerName { get; set; } + [JsonPropertyName("server")] + public string? Server { get; set; } + [JsonPropertyName("name")] + public string? Name { get; set; } + [JsonPropertyName("password")] + public string? Password { get; set; } + } \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Models/Profile.cs b/PCL.Core/Minecraft/Profile/Models/Profile.cs index af94b9217..eb5ad1c38 100644 --- a/PCL.Core/Minecraft/Profile/Models/Profile.cs +++ b/PCL.Core/Minecraft/Profile/Models/Profile.cs @@ -1,39 +1,11 @@ -using System.Text.Json.Serialization; -using PCL.Core.Minecraft.Profile.Autnenrication; - -namespace PCL.Core.Minecraft.Profile.Models; - -internal class Profile -{ - /// - /// 档案名称 - /// - [JsonPropertyName("name")] - public required string Name { get; set; } - /// - /// UUID - /// - [JsonPropertyName("uuid")] - public required string Uuid { get; set; } - /// - /// 访问令牌 - /// - [JsonPropertyName("accessToken")] - public required string AccessToken { get; set; } - [JsonPropertyName("refreshToken")] - public required string RefreshToken { get; set; } - [JsonPropertyName("propertyJson")] - public required string PropertyJson { get; set; } - [JsonPropertyName("profileDescription")] - public required string ProfileDescription { get; set; } - - [JsonPropertyName("profileType")] - public required ProfileType Type { get; set; } - - public IAuthenticateProvider? CreateAuthenticateServiceProvider() => Type switch - { - ProfileType.Offline => new OfflineProvider(AccessToken, RefreshToken), - ProfileType.Microsoft => new MicrosoftProvider(AccessToken, RefreshToken), - ProfileType.Authlib => new YggdrasilProvider(AccessToken, RefreshToken) - } +using PCL.Core.Minecraft.Profile.Autnenrication; + +namespace PCL.Core.Minecraft.Profile.Models; + +internal record Profile: SafeProfile +{ + public IAuthenticateProvider? CreateAuthenticateServiceProvider() + { + return default; + } } \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Models/ProfileJson.cs b/PCL.Core/Minecraft/Profile/Models/ProfileJson.cs index 9b69ed104..33b67e2fc 100644 --- a/PCL.Core/Minecraft/Profile/Models/ProfileJson.cs +++ b/PCL.Core/Minecraft/Profile/Models/ProfileJson.cs @@ -1,9 +1,9 @@ -using System.Collections.Immutable; - -namespace PCL.Core.Minecraft.Profile.Models; - -public class ProfileJson where T : class -{ - public int LastUsed { get; set; } - public ImmutableArray Profiles { get; private set; } = []; +using System.Collections.Immutable; + +namespace PCL.Core.Minecraft.Profile.Models; + +public class ProfileJson where T : class +{ + public int LastUsed { get; set; } + public ImmutableArray Profiles { get; private set; } = []; } \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Models/ProfileType.cs b/PCL.Core/Minecraft/Profile/Models/ProfileType.cs index deb77c926..d55b28a90 100644 --- a/PCL.Core/Minecraft/Profile/Models/ProfileType.cs +++ b/PCL.Core/Minecraft/Profile/Models/ProfileType.cs @@ -1,8 +1,8 @@ -namespace PCL.Core.Minecraft.Profile.Models; - -public enum ProfileType -{ - Microsoft, - Offline, - Authlib +namespace PCL.Core.Minecraft.Profile.Models; + +public enum ProfileType +{ + Microsoft, + Offline, + Authlib } \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Models/SafeProfile.cs b/PCL.Core/Minecraft/Profile/Models/SafeProfile.cs index b4681f541..538e648c8 100644 --- a/PCL.Core/Minecraft/Profile/Models/SafeProfile.cs +++ b/PCL.Core/Minecraft/Profile/Models/SafeProfile.cs @@ -1,12 +1,15 @@ -namespace PCL.Core.Minecraft.Profile.Models; - -/// -/// 供调用方使用的安全 Profile 类 -/// -public class SafeProfile -{ - private SafeProfile(Profile profile) - { - - } +using System.Text.Json.Serialization; + +namespace PCL.Core.Minecraft.Profile.Models; + +public record SafeProfile +{ + [JsonPropertyName("username")] + public required string UserName { get; set; } + [JsonPropertyName("accessToken")] + public required string AccessToken { get; set; } + [JsonPropertyName("uuid")] + public required string Uuid { get; set; } + [JsonPropertyName("tokenType")] + public required string TokenType { get; set; } } \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/ProfileManagement.cs b/PCL.Core/Minecraft/Profile/ProfileManagement.cs index 596020e5c..e59e6f347 100644 --- a/PCL.Core/Minecraft/Profile/ProfileManagement.cs +++ b/PCL.Core/Minecraft/Profile/ProfileManagement.cs @@ -1,12 +1,7 @@ -using System.IO; -using PCL.Core.Minecraft.Profile.Models; - -namespace PCL.Core.Minecraft.Profile; +namespace PCL.Core.Minecraft.Profile; public class ProfileManagement: IProfileManagement where T:class { - - private ProfileJson? _profiles; public T Create() { throw new System.NotImplementedException(); @@ -24,7 +19,7 @@ public void Update(T profile) public void LoadFromPath(string path) { - LoadFromString(File.ReadAllText(path)); + throw new System.NotImplementedException(); } public void LoadFromString(string profiles) diff --git a/PCL.Core/Minecraft/Profile/ProfileService.cs b/PCL.Core/Minecraft/Profile/ProfileService.cs index 7b5a96d37..e65a73afc 100644 --- a/PCL.Core/Minecraft/Profile/ProfileService.cs +++ b/PCL.Core/Minecraft/Profile/ProfileService.cs @@ -1,6 +1,5 @@ using System; using System.IO; -using System.Text.Json; using System.Threading.Tasks; using PCL.Core.App; using PCL.Core.App.IoC; @@ -12,20 +11,19 @@ namespace PCL.Core.Minecraft.Profile; public partial class ProfileService { private static ProfileManagement> _newProfileProvider = new(); - private static ProfileManagement> _oldProfileProvider = new(); + private static ProfileManagement> _oldProfileProvider = new(); [LifecycleStart] private static async Task _Start() { - _newProfileProvider.LoadFromString(Config.System.Profiles); } private static void _MigrateProfile() { var profileLocation = Path.Combine(Paths.SharedData, "profiles.json"); - var profileMigrateFile = Path.Combine(Paths.SharedData, "pcl.ce.migrated"); - if (Path.Exists(profileMigrateFile)) + var profileMigrateFIle = Path.Combine(Paths.SharedData, "pcl.ce.migrated"); + if (!Path.Exists(profileMigrateFIle)) { Context.Debug("已迁移档案信息,跳过检查"); return; @@ -33,7 +31,7 @@ private static void _MigrateProfile() Context.Info("开始迁移旧版本档案信息"); try { - _oldProfileProvider.LoadFromPath(profileLocation); + } catch (UnauthorizedAccessException) { From 7450389cbbde9bc6dc4204196270436ed2062b2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9E=97=E8=BD=BB=E8=AF=AD?= Date: Tue, 16 Jun 2026 13:52:55 +0800 Subject: [PATCH 5/6] impl [SKIP CI] --- .../IAuthenticateProvider.cs | 16 +- .../MicrosoftProvider.cs | 18 +- .../Utils/Models/MojangIdentityToken.cs | 16 +- .../Utils/Models/MojangProfile.cs | 20 +-- .../Utils/Models/MojangResponse.cs | 34 ++-- .../Utils/Models/XSTSProperty.cs | 16 +- .../Utils/Models/XboxAuthenticate.cs | 14 +- .../Utils/Models/XboxDisplayClaims.cs | 18 +- .../Utils/Models/XboxLiveResponse.cs | 18 +- .../Utils/Models/XboxProperty.cs | 14 +- .../Utils/Models/XboxUserHash.cs | 16 +- .../Utils/MojangUtils.cs | 161 +++++++++--------- .../Utils/XboxUtils.cs | 38 ++--- .../MicrosoftProviderBuilder.cs | 20 --- .../Minecraft/Profile/IProfileManagement.cs | 2 +- .../Models/{Profile.cs => McProfile.cs} | 21 +-- .../Minecraft/Profile/Models/OldProfile.cs | 2 +- .../Minecraft/Profile/Models/ProfileJson.cs | 4 +- .../Minecraft/Profile/Models/SafeProfile.cs | 7 + .../Minecraft/Profile/ProfileManagement.cs | 24 ++- PCL.Core/Minecraft/Profile/ProfileService.cs | 4 +- 21 files changed, 241 insertions(+), 242 deletions(-) rename PCL.Core/Minecraft/Profile/{Autnentication => Authentication}/IAuthenticateProvider.cs (57%) rename PCL.Core/Minecraft/Profile/{Autnentication => Authentication}/MicrosoftProvider.cs (75%) rename PCL.Core/Minecraft/Profile/{Autnentication => Authentication}/Utils/Models/MojangIdentityToken.cs (70%) rename PCL.Core/Minecraft/Profile/{Autnentication => Authentication}/Utils/Models/MojangProfile.cs (75%) rename PCL.Core/Minecraft/Profile/{Autnentication => Authentication}/Utils/Models/MojangResponse.cs (87%) rename PCL.Core/Minecraft/Profile/{Autnentication => Authentication}/Utils/Models/XSTSProperty.cs (71%) rename PCL.Core/Minecraft/Profile/{Autnentication => Authentication}/Utils/Models/XboxAuthenticate.cs (75%) rename PCL.Core/Minecraft/Profile/{Autnentication => Authentication}/Utils/Models/XboxDisplayClaims.cs (73%) rename PCL.Core/Minecraft/Profile/{Autnentication => Authentication}/Utils/Models/XboxLiveResponse.cs (74%) rename PCL.Core/Minecraft/Profile/{Autnentication => Authentication}/Utils/Models/XboxProperty.cs (74%) rename PCL.Core/Minecraft/Profile/{Autnentication => Authentication}/Utils/Models/XboxUserHash.cs (68%) rename PCL.Core/Minecraft/Profile/{Autnentication => Authentication}/Utils/MojangUtils.cs (93%) rename PCL.Core/Minecraft/Profile/{Autnentication => Authentication}/Utils/XboxUtils.cs (83%) delete mode 100644 PCL.Core/Minecraft/Profile/Autnentication/MicrosoftProviderBuilder.cs rename PCL.Core/Minecraft/Profile/Models/{Profile.cs => McProfile.cs} (53%) diff --git a/PCL.Core/Minecraft/Profile/Autnentication/IAuthenticateProvider.cs b/PCL.Core/Minecraft/Profile/Authentication/IAuthenticateProvider.cs similarity index 57% rename from PCL.Core/Minecraft/Profile/Autnentication/IAuthenticateProvider.cs rename to PCL.Core/Minecraft/Profile/Authentication/IAuthenticateProvider.cs index 8c0249d86..c9778dfbe 100644 --- a/PCL.Core/Minecraft/Profile/Autnentication/IAuthenticateProvider.cs +++ b/PCL.Core/Minecraft/Profile/Authentication/IAuthenticateProvider.cs @@ -1,8 +1,10 @@ -using System.Threading.Tasks; - -namespace PCL.Core.Minecraft.Profile.Autnenrication; - -public interface IAuthenticateProvider -{ - //public Task AuthenticateAsync(); +using System.Threading.Tasks; + +namespace PCL.Core.Minecraft.Profile.Authentication; + +public interface IAuthenticateProvider +{ + //public Task AuthenticateAsync(); + + public void RefreshInfo(); } \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Autnentication/MicrosoftProvider.cs b/PCL.Core/Minecraft/Profile/Authentication/MicrosoftProvider.cs similarity index 75% rename from PCL.Core/Minecraft/Profile/Autnentication/MicrosoftProvider.cs rename to PCL.Core/Minecraft/Profile/Authentication/MicrosoftProvider.cs index e368db841..0a78b4c22 100644 --- a/PCL.Core/Minecraft/Profile/Autnentication/MicrosoftProvider.cs +++ b/PCL.Core/Minecraft/Profile/Authentication/MicrosoftProvider.cs @@ -1,10 +1,10 @@ -using PCL.Core.IO.Net; -using PCL.Core.Minecraft.IdentityModel.Extensions.OpenId; -using PCL.Core.Minecraft.IdentityModel.OAuth; - -namespace PCL.Core.Minecraft.Profile.Autnenrication; - -public class MicrosoftProvider(OpenIdClient client) -{ - +using PCL.Core.IO.Net; +using PCL.Core.Minecraft.IdentityModel.Extensions.OpenId; +using PCL.Core.Minecraft.IdentityModel.OAuth; + +namespace PCL.Core.Minecraft.Profile.Authentication; + +public class MicrosoftProvider(OpenIdClient client) +{ + } \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Autnentication/Utils/Models/MojangIdentityToken.cs b/PCL.Core/Minecraft/Profile/Authentication/Utils/Models/MojangIdentityToken.cs similarity index 70% rename from PCL.Core/Minecraft/Profile/Autnentication/Utils/Models/MojangIdentityToken.cs rename to PCL.Core/Minecraft/Profile/Authentication/Utils/Models/MojangIdentityToken.cs index 7364894fd..cb65d985c 100644 --- a/PCL.Core/Minecraft/Profile/Autnentication/Utils/Models/MojangIdentityToken.cs +++ b/PCL.Core/Minecraft/Profile/Authentication/Utils/Models/MojangIdentityToken.cs @@ -1,9 +1,9 @@ -using System.Text.Json.Serialization; - -namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils.Models; - -public class MojangIdentityToken -{ - [JsonPropertyName("identityToken")] - public required string IdentityToken { get; set; } +using System.Text.Json.Serialization; + +namespace PCL.Core.Minecraft.Profile.Authentication.Utils.Models; + +public class MojangIdentityToken +{ + [JsonPropertyName("identityToken")] + public required string IdentityToken { get; set; } } \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Autnentication/Utils/Models/MojangProfile.cs b/PCL.Core/Minecraft/Profile/Authentication/Utils/Models/MojangProfile.cs similarity index 75% rename from PCL.Core/Minecraft/Profile/Autnentication/Utils/Models/MojangProfile.cs rename to PCL.Core/Minecraft/Profile/Authentication/Utils/Models/MojangProfile.cs index 8219e427f..8f7f03b62 100644 --- a/PCL.Core/Minecraft/Profile/Autnentication/Utils/Models/MojangProfile.cs +++ b/PCL.Core/Minecraft/Profile/Authentication/Utils/Models/MojangProfile.cs @@ -1,11 +1,11 @@ -using System.Text.Json.Serialization; - -namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils.Models; - -public record MojangProfile -{ - [JsonPropertyName("id")] - public required string Uuid { get; set; } - [JsonPropertyName("name")] - public required string Name { get; set; } +using System.Text.Json.Serialization; + +namespace PCL.Core.Minecraft.Profile.Authentication.Utils.Models; + +public record MojangProfile +{ + [JsonPropertyName("id")] + public required string Uuid { get; set; } + [JsonPropertyName("name")] + public required string Name { get; set; } } \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Autnentication/Utils/Models/MojangResponse.cs b/PCL.Core/Minecraft/Profile/Authentication/Utils/Models/MojangResponse.cs similarity index 87% rename from PCL.Core/Minecraft/Profile/Autnentication/Utils/Models/MojangResponse.cs rename to PCL.Core/Minecraft/Profile/Authentication/Utils/Models/MojangResponse.cs index 937c38794..3d4ab32fe 100644 --- a/PCL.Core/Minecraft/Profile/Autnentication/Utils/Models/MojangResponse.cs +++ b/PCL.Core/Minecraft/Profile/Authentication/Utils/Models/MojangResponse.cs @@ -1,18 +1,18 @@ -using System.Collections.Generic; -using System.Text.Json.Serialization; - -namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils.Models; - -public record MojangResponse -{ - [JsonPropertyName("username")] - public required string UserName { get; set; } - [JsonPropertyName("roles")] - public required IEnumerable Roles { get; set; } - [JsonPropertyName("access_token")] - public required string AccessToken { get; set; } - [JsonPropertyName("expires_int")] - public required int ExpiresIn { get; set; } - [JsonPropertyName("token_type")] - public required string TokenType { get; set; } +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace PCL.Core.Minecraft.Profile.Authentication.Utils.Models; + +public record MojangResponse +{ + [JsonPropertyName("username")] + public required string UserName { get; set; } + [JsonPropertyName("roles")] + public required IEnumerable Roles { get; set; } + [JsonPropertyName("access_token")] + public required string AccessToken { get; set; } + [JsonPropertyName("expires_int")] + public required int ExpiresIn { get; set; } + [JsonPropertyName("token_type")] + public required string TokenType { get; set; } } \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Autnentication/Utils/Models/XSTSProperty.cs b/PCL.Core/Minecraft/Profile/Authentication/Utils/Models/XSTSProperty.cs similarity index 71% rename from PCL.Core/Minecraft/Profile/Autnentication/Utils/Models/XSTSProperty.cs rename to PCL.Core/Minecraft/Profile/Authentication/Utils/Models/XSTSProperty.cs index b89b020c2..17b456ce2 100644 --- a/PCL.Core/Minecraft/Profile/Autnentication/Utils/Models/XSTSProperty.cs +++ b/PCL.Core/Minecraft/Profile/Authentication/Utils/Models/XSTSProperty.cs @@ -1,9 +1,9 @@ -using System.Collections.Generic; - -namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils.Models; - -public record XSTSProperty -{ - public string SandboxId { get; set; } = "RETAIL"; - public List UserTokens { get; set; } = []; +using System.Collections.Generic; + +namespace PCL.Core.Minecraft.Profile.Authentication.Utils.Models; + +public record XSTSProperty +{ + public string SandboxId { get; set; } = "RETAIL"; + public List UserTokens { get; set; } = []; } \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Autnentication/Utils/Models/XboxAuthenticate.cs b/PCL.Core/Minecraft/Profile/Authentication/Utils/Models/XboxAuthenticate.cs similarity index 75% rename from PCL.Core/Minecraft/Profile/Autnentication/Utils/Models/XboxAuthenticate.cs rename to PCL.Core/Minecraft/Profile/Authentication/Utils/Models/XboxAuthenticate.cs index ff1bab478..1f2f8788e 100644 --- a/PCL.Core/Minecraft/Profile/Autnentication/Utils/Models/XboxAuthenticate.cs +++ b/PCL.Core/Minecraft/Profile/Authentication/Utils/Models/XboxAuthenticate.cs @@ -1,8 +1,8 @@ -namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils.Models; - -public record XboxAuthenticate -{ - public required T Properties { get; set; } - public string RelyingParty { get; set; } = "http://auth.xboxlive.com"; - public required string TokenType { get; set; } +namespace PCL.Core.Minecraft.Profile.Authentication.Utils.Models; + +public record XboxAuthenticate +{ + public required T Properties { get; set; } + public string RelyingParty { get; set; } = "http://auth.xboxlive.com"; + public required string TokenType { get; set; } } \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Autnentication/Utils/Models/XboxDisplayClaims.cs b/PCL.Core/Minecraft/Profile/Authentication/Utils/Models/XboxDisplayClaims.cs similarity index 73% rename from PCL.Core/Minecraft/Profile/Autnentication/Utils/Models/XboxDisplayClaims.cs rename to PCL.Core/Minecraft/Profile/Authentication/Utils/Models/XboxDisplayClaims.cs index 7db612eb4..f19d2f2cf 100644 --- a/PCL.Core/Minecraft/Profile/Autnentication/Utils/Models/XboxDisplayClaims.cs +++ b/PCL.Core/Minecraft/Profile/Authentication/Utils/Models/XboxDisplayClaims.cs @@ -1,10 +1,10 @@ -using System.Collections.Generic; -using System.Text.Json.Serialization; - -namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils.Models; - -public record XboxDisplayClaims -{ - [JsonPropertyName("xui")] - public required List Xui { get; set; } +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace PCL.Core.Minecraft.Profile.Authentication.Utils.Models; + +public record XboxDisplayClaims +{ + [JsonPropertyName("xui")] + public required List Xui { get; set; } } \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Autnentication/Utils/Models/XboxLiveResponse.cs b/PCL.Core/Minecraft/Profile/Authentication/Utils/Models/XboxLiveResponse.cs similarity index 74% rename from PCL.Core/Minecraft/Profile/Autnentication/Utils/Models/XboxLiveResponse.cs rename to PCL.Core/Minecraft/Profile/Authentication/Utils/Models/XboxLiveResponse.cs index a2187345b..bbf3203cb 100644 --- a/PCL.Core/Minecraft/Profile/Autnentication/Utils/Models/XboxLiveResponse.cs +++ b/PCL.Core/Minecraft/Profile/Authentication/Utils/Models/XboxLiveResponse.cs @@ -1,10 +1,10 @@ -using System; - -namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils.Models; - -public record XboxLiveResponse -{ - public required DateTime IssueInstant { get; set; } - public required DateTime NotAfter { get; set; } - public required string Token { get; set; } +using System; + +namespace PCL.Core.Minecraft.Profile.Authentication.Utils.Models; + +public record XboxLiveResponse +{ + public required DateTime IssueInstant { get; set; } + public required DateTime NotAfter { get; set; } + public required string Token { get; set; } } \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Autnentication/Utils/Models/XboxProperty.cs b/PCL.Core/Minecraft/Profile/Authentication/Utils/Models/XboxProperty.cs similarity index 74% rename from PCL.Core/Minecraft/Profile/Autnentication/Utils/Models/XboxProperty.cs rename to PCL.Core/Minecraft/Profile/Authentication/Utils/Models/XboxProperty.cs index 7f2b27c43..db844e092 100644 --- a/PCL.Core/Minecraft/Profile/Autnentication/Utils/Models/XboxProperty.cs +++ b/PCL.Core/Minecraft/Profile/Authentication/Utils/Models/XboxProperty.cs @@ -1,8 +1,8 @@ -namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils.Models; - -public record XboxProperty -{ - public string AuthMethod { get; set; } = "RPS"; - public string SiteName { get; set; } = "user.auth.xboxlive.com"; - public required string RpsTicket { get; set; } +namespace PCL.Core.Minecraft.Profile.Authentication.Utils.Models; + +public record XboxProperty +{ + public string AuthMethod { get; set; } = "RPS"; + public string SiteName { get; set; } = "user.auth.xboxlive.com"; + public required string RpsTicket { get; set; } } \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Autnentication/Utils/Models/XboxUserHash.cs b/PCL.Core/Minecraft/Profile/Authentication/Utils/Models/XboxUserHash.cs similarity index 68% rename from PCL.Core/Minecraft/Profile/Autnentication/Utils/Models/XboxUserHash.cs rename to PCL.Core/Minecraft/Profile/Authentication/Utils/Models/XboxUserHash.cs index a03b64182..4505352b5 100644 --- a/PCL.Core/Minecraft/Profile/Autnentication/Utils/Models/XboxUserHash.cs +++ b/PCL.Core/Minecraft/Profile/Authentication/Utils/Models/XboxUserHash.cs @@ -1,9 +1,9 @@ -using System.Text.Json.Serialization; - -namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils.Models; - -public record XboxUserHash -{ - [JsonPropertyName("uhs")] - public required string UserHash { get; set; } +using System.Text.Json.Serialization; + +namespace PCL.Core.Minecraft.Profile.Authentication.Utils.Models; + +public record XboxUserHash +{ + [JsonPropertyName("uhs")] + public required string UserHash { get; set; } } \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Autnentication/Utils/MojangUtils.cs b/PCL.Core/Minecraft/Profile/Authentication/Utils/MojangUtils.cs similarity index 93% rename from PCL.Core/Minecraft/Profile/Autnentication/Utils/MojangUtils.cs rename to PCL.Core/Minecraft/Profile/Authentication/Utils/MojangUtils.cs index 57685df15..d5bbff238 100644 --- a/PCL.Core/Minecraft/Profile/Autnentication/Utils/MojangUtils.cs +++ b/PCL.Core/Minecraft/Profile/Authentication/Utils/MojangUtils.cs @@ -1,81 +1,82 @@ -using System; -using System.Net.Http; -using System.Net.Http.Json; -using System.Text.Json; -using System.Text.Json.Nodes; -using System.Threading.Tasks; -using PCL.Core.IO.Net.Http; -using PCL.Core.Minecraft.Profile.Autnenrication.Utils.Models; -using PCL.Core.Minecraft.Profile.Models; - -namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils; - -public static class MojangUtils -{ - #region "API 定义" - - private const string MojangAuthenticateEndpoint = "https://api.minecraftservices.com/authentication/login_with_xbox"; - private const string LicenseEndpoint = "https://api.minecraftservices.com/entitlements/mcstore"; - private const string ProfileEndpont = "https://api.minecraftservices.com/minecraft/profile"; - private const string SessionServerProfileEndpoint = "https://sessionserver.mojang.com/session/minecraft/profile/"; - private const string NameProfileEndpoint = "https://api.minecraftservices.com/users/profiles/minecraft/"; - private const string SkinServiceChangeEndpoint = "https://api.minecraftservices.com/minecraft/profile/skins"; - private const string SkinServiceResetEndpoint = "https://api.minecraftservices.com/user/profile/skin/active"; - - #endregion - - /// - /// 发送一次登录请求 - /// - /// XSTS 令牌 - /// Xbox User Hash - /// - public static async Task AuthenticateAsync(string xstsToken, string userHash) - { - using var response = await HttpRequest.CreatePost(MojangAuthenticateEndpoint) - .WithContent(new StringContent( - JsonSerializer.Serialize(new MojangIdentityToken - { - IdentityToken = $"XBL3.0 x={userHash};{xstsToken}" - } - )) - ).SendAsync().ConfigureAwait(false); - return await response.AsJsonAsync().ConfigureAwait(false); - } - /// - /// 检查玩家是否持有许可 - /// - /// - /// 如果没有有效许可,返回 false - public static async Task CheckLicenseAsync(SafeProfile profile) - { - using var response = await HttpRequest.Create(LicenseEndpoint) - .WithAuthentication(profile.TokenType, profile.AccessToken) - .SendAsync().ConfigureAwait(false); - return response.IsSuccess; - } - /// - /// 获取玩家的完整档案 - /// - /// 档案信息 - public static async Task GetProfileAsync(SafeProfile profile) - { - throw new NotImplementedException(); - } - - /// - /// 通过玩家名称获取档案信息
- /// NOTE: 由于 Mojang API 限制,此方法仅能获取精简版档案信息
- /// 如果需要完整信息,请调用 。 - ///
- /// - public static async Task GetSimpleProfileWithNameAsync(string name) - { - - } - - public static async Task GetFullProfileWithUuidAsync() - { - - } +using System; +using System.Net.Http; +using System.Net.Http.Json; +using System.Text.Json; +using System.Text.Json.Nodes; +using System.Threading.Tasks; +using PCL.Core.IO.Net.Http; +using PCL.Core.Minecraft.Profile.Authentication.Utils.Models; +using PCL.Core.Minecraft.Profile.Models; + +namespace PCL.Core.Minecraft.Profile.Authentication.Utils; + +public static class MojangUtils +{ + #region "API 定义" + + private const string MojangAuthenticateEndpoint = "https://api.minecraftservices.com/authentication/login_with_xbox"; + private const string LicenseEndpoint = "https://api.minecraftservices.com/entitlements/mcstore"; + private const string ProfileEndpont = "https://api.minecraftservices.com/minecraft/profile"; + private const string SessionServerProfileEndpoint = "https://sessionserver.mojang.com/session/minecraft/profile/"; + private const string NameProfileEndpoint = "https://api.minecraftservices.com/users/profiles/minecraft/"; + private const string SkinServiceChangeEndpoint = "https://api.minecraftservices.com/minecraft/profile/skins"; + private const string SkinServiceResetEndpoint = "https://api.minecraftservices.com/user/profile/skin/active"; + + #endregion + + /// + /// 发送一次登录请求 + /// + /// XSTS 令牌 + /// Xbox User Hash + /// + public static async Task AuthenticateAsync(string xstsToken, string userHash) + { + using var response = await HttpRequest.CreatePost(MojangAuthenticateEndpoint) + .WithContent(new StringContent( + JsonSerializer.Serialize(new MojangIdentityToken + { + IdentityToken = $"XBL3.0 x={userHash};{xstsToken}" + } + )) + ).SendAsync().ConfigureAwait(false); + return await response.AsJsonAsync().ConfigureAwait(false); + } + + /// + /// 检查玩家是否持有许可 + /// + /// + /// 如果没有有效许可,返回 false + public static async Task CheckLicenseAsync(SafeProfile profile) + { + using var response = await HttpRequest.Create(LicenseEndpoint) + .WithAuthentication(profile.TokenType, profile.AccessToken) + .SendAsync().ConfigureAwait(false); + return response.IsSuccess; + } + /// + /// 获取玩家的完整档案 + /// + /// 档案信息 + public static async Task GetProfileAsync(SafeProfile profile) + { + throw new NotImplementedException(); + } + + /// + /// 通过玩家名称获取档案信息
+ /// NOTE: 由于 Mojang API 限制,此方法仅能获取精简版档案信息
+ /// 如果需要完整信息,请调用 。 + ///
+ /// + public static async Task GetSimpleProfileWithNameAsync(string name) + { + + } + + public static async Task GetFullProfileWithUuidAsync() + { + + } } \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Autnentication/Utils/XboxUtils.cs b/PCL.Core/Minecraft/Profile/Authentication/Utils/XboxUtils.cs similarity index 83% rename from PCL.Core/Minecraft/Profile/Autnentication/Utils/XboxUtils.cs rename to PCL.Core/Minecraft/Profile/Authentication/Utils/XboxUtils.cs index f8329cb71..6815e749c 100644 --- a/PCL.Core/Minecraft/Profile/Autnentication/Utils/XboxUtils.cs +++ b/PCL.Core/Minecraft/Profile/Authentication/Utils/XboxUtils.cs @@ -1,20 +1,20 @@ -using System.Threading.Tasks; -using PCL.Core.IO.Net.Http; -using PCL.Core.Minecraft.Profile.Autnenrication.Utils.Models; - -namespace PCL.Core.Minecraft.Profile.Autnenrication.Utils; - -public static class XboxUtils -{ - private const string XboxLiveAuthServer = "https://user.auth.xboxlive.com/user/authenticate"; - private const string XstsAuthorizeServer = "https://xsts.auth.xboxlive.com/xsts/authorize"; - public static async Task AuthenticateAsync(XboxAuthenticate authData, bool isXsts) - { - using var response = await HttpRequest.CreatePost( - isXsts ? XstsAuthorizeServer:XboxLiveAuthServer - ).WithJsonContent(authData).SendAsync() - .ConfigureAwait(false); - - return await response.AsJsonAsync(); - } +using System.Threading.Tasks; +using PCL.Core.IO.Net.Http; +using PCL.Core.Minecraft.Profile.Authentication.Utils.Models; + +namespace PCL.Core.Minecraft.Profile.Authentication.Utils; + +public static class XboxUtils +{ + private const string XboxLiveAuthServer = "https://user.auth.xboxlive.com/user/authenticate"; + private const string XstsAuthorizeServer = "https://xsts.auth.xboxlive.com/xsts/authorize"; + public static async Task AuthenticateAsync(XboxAuthenticate authData, bool isXsts) + { + using var response = await HttpRequest.CreatePost( + isXsts ? XstsAuthorizeServer:XboxLiveAuthServer + ).WithJsonContent(authData).SendAsync() + .ConfigureAwait(false); + + return await response.AsJsonAsync(); + } } \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Autnentication/MicrosoftProviderBuilder.cs b/PCL.Core/Minecraft/Profile/Autnentication/MicrosoftProviderBuilder.cs deleted file mode 100644 index 9c27c0adf..000000000 --- a/PCL.Core/Minecraft/Profile/Autnentication/MicrosoftProviderBuilder.cs +++ /dev/null @@ -1,20 +0,0 @@ -using PCL.Core.Minecraft.IdentityModel.Extensions.OpenId; - -namespace PCL.Core.Minecraft.Profile.Autnenrication; - -public class MicrosoftProviderBuilder -{ - private MicrosoftProviderBuilder(){} - - private OpenIdClient? _client; - - public MicrosoftProviderBuilder Create() => new MicrosoftProviderBuilder(); - - public MicrosoftProviderBuilder SetOptions(OpenIdOptions options) - { - _client = new OpenIdClient(options); - return this; - } - - -} \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/IProfileManagement.cs b/PCL.Core/Minecraft/Profile/IProfileManagement.cs index d2a385482..89ddf9f67 100644 --- a/PCL.Core/Minecraft/Profile/IProfileManagement.cs +++ b/PCL.Core/Minecraft/Profile/IProfileManagement.cs @@ -6,7 +6,7 @@ public interface IProfileManagement /// 创建一个档案 /// /// - public T Create(); + public void Add(T profile); /// /// 删除一个档案 /// diff --git a/PCL.Core/Minecraft/Profile/Models/Profile.cs b/PCL.Core/Minecraft/Profile/Models/McProfile.cs similarity index 53% rename from PCL.Core/Minecraft/Profile/Models/Profile.cs rename to PCL.Core/Minecraft/Profile/Models/McProfile.cs index eb5ad1c38..fe3a3b04d 100644 --- a/PCL.Core/Minecraft/Profile/Models/Profile.cs +++ b/PCL.Core/Minecraft/Profile/Models/McProfile.cs @@ -1,11 +1,12 @@ -using PCL.Core.Minecraft.Profile.Autnenrication; - -namespace PCL.Core.Minecraft.Profile.Models; - -internal record Profile: SafeProfile -{ - public IAuthenticateProvider? CreateAuthenticateServiceProvider() - { - return default; - } +using PCL.Core.Minecraft.Profile.Autnenrication; + +namespace PCL.Core.Minecraft.Profile.Models; + +internal record McProfile: SafeProfile +{ + + public static IAuthenticateProvider? CreateAuthenticateServiceProvider() + { + return default; + } } \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Models/OldProfile.cs b/PCL.Core/Minecraft/Profile/Models/OldProfile.cs index e2ae9b603..d958307d7 100644 --- a/PCL.Core/Minecraft/Profile/Models/OldProfile.cs +++ b/PCL.Core/Minecraft/Profile/Models/OldProfile.cs @@ -2,7 +2,7 @@ namespace PCL.Core.Minecraft.Profile.Models; -public record OldProfile: SafeProfile +internal record OldProfile: SafeProfile { [JsonPropertyName("type")] public required string Type { get; set; } diff --git a/PCL.Core/Minecraft/Profile/Models/ProfileJson.cs b/PCL.Core/Minecraft/Profile/Models/ProfileJson.cs index 33b67e2fc..b0e9e6d66 100644 --- a/PCL.Core/Minecraft/Profile/Models/ProfileJson.cs +++ b/PCL.Core/Minecraft/Profile/Models/ProfileJson.cs @@ -2,8 +2,8 @@ namespace PCL.Core.Minecraft.Profile.Models; -public class ProfileJson where T : class +public class ProfileJson { public int LastUsed { get; set; } - public ImmutableArray Profiles { get; private set; } = []; + public ImmutableArray Profiles { get; internal set; } = []; } \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Models/SafeProfile.cs b/PCL.Core/Minecraft/Profile/Models/SafeProfile.cs index 538e648c8..43276ed2d 100644 --- a/PCL.Core/Minecraft/Profile/Models/SafeProfile.cs +++ b/PCL.Core/Minecraft/Profile/Models/SafeProfile.cs @@ -2,6 +2,9 @@ namespace PCL.Core.Minecraft.Profile.Models; +/// +/// 适用于外部使用的安全档案类 +/// public record SafeProfile { [JsonPropertyName("username")] @@ -12,4 +15,8 @@ public record SafeProfile public required string Uuid { get; set; } [JsonPropertyName("tokenType")] public required string TokenType { get; set; } + [JsonPropertyName("profileType")] + public ProfileType? ProfileType { get; set; } + + private McProfile? _innerProfile; } \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/ProfileManagement.cs b/PCL.Core/Minecraft/Profile/ProfileManagement.cs index e59e6f347..cf707dbc4 100644 --- a/PCL.Core/Minecraft/Profile/ProfileManagement.cs +++ b/PCL.Core/Minecraft/Profile/ProfileManagement.cs @@ -1,20 +1,28 @@ -namespace PCL.Core.Minecraft.Profile; +using PCL.Core.Minecraft.Profile.Models; -public class ProfileManagement: IProfileManagement where T:class +namespace PCL.Core.Minecraft.Profile; + +public class ProfileManagement: IProfileManagement + where TProfileModel:SafeProfile { - public T Create() + private ProfileJson _profiles = new(); + + public SafeProfile Current { get; set; } + + public void Add(TProfileModel profile) { - throw new System.NotImplementedException(); + _profiles.Profiles = _profiles.Profiles.Add(profile); } - public void Delete(int index) + public void Delete(TProfileModel profile) { - throw new System.NotImplementedException(); + _profiles.Profiles = _profiles.Profiles.Remove(profile); } - public void Update(T profile) + public void Update(TProfileModel origin ,TProfileModel current) { - throw new System.NotImplementedException(); + if (origin == Current) Current = current; + } public void LoadFromPath(string path) diff --git a/PCL.Core/Minecraft/Profile/ProfileService.cs b/PCL.Core/Minecraft/Profile/ProfileService.cs index e65a73afc..0e07c3027 100644 --- a/PCL.Core/Minecraft/Profile/ProfileService.cs +++ b/PCL.Core/Minecraft/Profile/ProfileService.cs @@ -10,8 +10,8 @@ namespace PCL.Core.Minecraft.Profile; [LifecycleScope("profile", "档案服务")] public partial class ProfileService { - private static ProfileManagement> _newProfileProvider = new(); - private static ProfileManagement> _oldProfileProvider = new(); + private static ProfileManagement _newProfileProvider = new(); + private static ProfileManagement _oldProfileProvider = new(); [LifecycleStart] private static async Task _Start() From e6cb12942f7730702f9a68da447e4fbb57c38684 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9E=97=E8=BD=BB=E8=AF=AD?= Date: Wed, 17 Jun 2026 13:53:58 +0800 Subject: [PATCH 6/6] impl [SKIP CI] --- .../Minecraft/Profile/IProfileManagement.cs | 16 ++++--- .../Minecraft/Profile/Models/McProfile.cs | 19 +++++++- .../Minecraft/Profile/Models/SafeProfile.cs | 2 +- .../Minecraft/Profile/ProfileManagement.cs | 43 +++++++++++++++---- PCL.Core/Minecraft/Profile/ProfileService.cs | 38 +++++++++++++++- 5 files changed, 101 insertions(+), 17 deletions(-) diff --git a/PCL.Core/Minecraft/Profile/IProfileManagement.cs b/PCL.Core/Minecraft/Profile/IProfileManagement.cs index 89ddf9f67..1a2703334 100644 --- a/PCL.Core/Minecraft/Profile/IProfileManagement.cs +++ b/PCL.Core/Minecraft/Profile/IProfileManagement.cs @@ -1,4 +1,6 @@ -namespace PCL.Core.Minecraft.Profile; +using System.Collections.Generic; + +namespace PCL.Core.Minecraft.Profile; public interface IProfileManagement { @@ -10,12 +12,13 @@ public interface IProfileManagement /// /// 删除一个档案 /// - public void Delete(int index); + public void Delete(T profile); /// /// 更新档案 /// - /// 档案文件 - public void Update(T profile); + /// 原档案文件 + /// 新档案文件 + public void Update(T origin, T newProfile); /// /// 从指定文件加载档案 /// @@ -28,8 +31,9 @@ public interface IProfileManagement public void LoadFromString(string profiles); /// /// 清空档案列表 - /// 是否删除本地档案 /// - public void Clear(bool deleteLocal = false); + public void Clear(); + + public IEnumerable GetAll(); } \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/Models/McProfile.cs b/PCL.Core/Minecraft/Profile/Models/McProfile.cs index fe3a3b04d..78a7722c5 100644 --- a/PCL.Core/Minecraft/Profile/Models/McProfile.cs +++ b/PCL.Core/Minecraft/Profile/Models/McProfile.cs @@ -1,9 +1,26 @@ -using PCL.Core.Minecraft.Profile.Autnenrication; +using System; +using System.Text.Json.Serialization; +using PCL.Core.Minecraft.Profile.Authentication; namespace PCL.Core.Minecraft.Profile.Models; internal record McProfile: SafeProfile { + [JsonPropertyName("refreshToken")] + public required string RefreshToken { get; set; } + [JsonPropertyName("skinPath")] + public required string SkinPath { get; set; } + [JsonPropertyName("expires")] + public required DateTime ExpiredAt { get; set; } + [JsonPropertyName("profileDetails")] + public object? ProfileDetails { get; set; } + + // Yggdrasil + + [JsonPropertyName("server")] + public string? YggdrasilApiServerAddress { get; set; } + + // public static IAuthenticateProvider? CreateAuthenticateServiceProvider() { diff --git a/PCL.Core/Minecraft/Profile/Models/SafeProfile.cs b/PCL.Core/Minecraft/Profile/Models/SafeProfile.cs index 43276ed2d..6b83e45be 100644 --- a/PCL.Core/Minecraft/Profile/Models/SafeProfile.cs +++ b/PCL.Core/Minecraft/Profile/Models/SafeProfile.cs @@ -14,7 +14,7 @@ public record SafeProfile [JsonPropertyName("uuid")] public required string Uuid { get; set; } [JsonPropertyName("tokenType")] - public required string TokenType { get; set; } + public string? TokenType { get; set; } [JsonPropertyName("profileType")] public ProfileType? ProfileType { get; set; } diff --git a/PCL.Core/Minecraft/Profile/ProfileManagement.cs b/PCL.Core/Minecraft/Profile/ProfileManagement.cs index cf707dbc4..3c759b7f2 100644 --- a/PCL.Core/Minecraft/Profile/ProfileManagement.cs +++ b/PCL.Core/Minecraft/Profile/ProfileManagement.cs @@ -1,42 +1,69 @@ -using PCL.Core.Minecraft.Profile.Models; +using System; +using System.Collections.Generic; +using System.IO; +using System.Text.Json; +using PCL.Core.Minecraft.Profile.Models; namespace PCL.Core.Minecraft.Profile; public class ProfileManagement: IProfileManagement where TProfileModel:SafeProfile { - private ProfileJson _profiles = new(); - public SafeProfile Current { get; set; } + private ProfileJson? _profiles; + private object _syncLock = new(); + /// + /// 当前档案 + /// + public SafeProfile? Current { get; private set; } public void Add(TProfileModel profile) { + if (_profiles is null) throw new InvalidOperationException("Must load the profile list before modifying it."); _profiles.Profiles = _profiles.Profiles.Add(profile); } public void Delete(TProfileModel profile) { + if (_profiles is null) throw new InvalidOperationException("Must load the profile list before modifying it."); _profiles.Profiles = _profiles.Profiles.Remove(profile); } public void Update(TProfileModel origin ,TProfileModel current) { + if (_profiles is null) throw new InvalidOperationException("Must load the profile list before modifying it."); if (origin == Current) Current = current; - + var index = _profiles.Profiles.IndexOf(origin); + _profiles.Profiles = _profiles.Profiles.SetItem(index, current); } public void LoadFromPath(string path) { - throw new System.NotImplementedException(); + lock(_syncLock) + { + if (Current is not null) return; + _profiles = JsonSerializer.Deserialize>(File.ReadAllText(path)); + + } } public void LoadFromString(string profiles) { - throw new System.NotImplementedException(); + lock (_syncLock) + { + if (Current is not null) return; + _profiles = JsonSerializer.Deserialize>(profiles); + } + } + + public void Clear() + { + _profiles?.Profiles = _profiles.Profiles.Clear(); } - public void Clear(bool deleteLocal = false) + public IEnumerable GetAll() { - throw new System.NotImplementedException(); + if (_profiles is null) throw new InvalidOperationException("Profile list was not loaded."); + return _profiles.Profiles; } } \ No newline at end of file diff --git a/PCL.Core/Minecraft/Profile/ProfileService.cs b/PCL.Core/Minecraft/Profile/ProfileService.cs index 0e07c3027..08a7b8497 100644 --- a/PCL.Core/Minecraft/Profile/ProfileService.cs +++ b/PCL.Core/Minecraft/Profile/ProfileService.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using System.Linq; using System.Threading.Tasks; using PCL.Core.App; using PCL.Core.App.IoC; @@ -8,6 +9,7 @@ namespace PCL.Core.Minecraft.Profile; [LifecycleScope("profile", "档案服务")] +[LifecycleService(LifecycleState.Loaded)] public partial class ProfileService { private static ProfileManagement _newProfileProvider = new(); @@ -16,6 +18,7 @@ public partial class ProfileService [LifecycleStart] private static async Task _Start() { + _newProfileProvider.LoadFromString(Config.System.Profiles); } private static void _MigrateProfile() @@ -31,7 +34,27 @@ private static void _MigrateProfile() Context.Info("开始迁移旧版本档案信息"); try { - + _oldProfileProvider.LoadFromPath(profileLocation); + foreach (var profile in _oldProfileProvider.GetAll()) + { + var newProfile = new McProfile + { + UserName = profile.UserName, + Uuid = profile.Uuid, + SkinPath = "", + ExpiredAt = default, + AccessToken = profile.AccessToken, + RefreshToken = profile.RefreshToken ?? string.Empty, + TokenType = profile.TokenType, + ProfileType = profile.Type switch + { + "microsoft" => ProfileType.Microsoft, + "authlib" => ProfileType.Authlib, + _ => ProfileType.Offline + } + }; + _newProfileProvider.Add(newProfile); + } } catch (UnauthorizedAccessException) { @@ -44,4 +67,17 @@ private static void _MigrateProfile() } private static void _Import(){} + + private static bool _isCheckedLicense; + + public static bool HasValidLicense + { + get + { + if (!_isCheckedLicense) + field = _newProfileProvider.GetAll().Any(p => p.ProfileType == ProfileType.Microsoft); + return field; + } + private set; + } } \ No newline at end of file