移除 ClientToken

This commit is contained in:
无聊的小洛
2025-01-25 22:24:56 +08:00
committed by GitHub
parent 70636a9a77
commit 3eed7c5b7f
@@ -1,4 +1,4 @@
Imports System.IO.Compression Imports System.IO.Compression
Public Module ModLaunch Public Module ModLaunch
@@ -236,8 +236,6 @@ NextInner:
'正版购买提示 '正版购买提示
If Not Setup.Get("HintBuy") AndAlso Setup.Get("LoginType") <> McLoginType.Ms Then If Not Setup.Get("HintBuy") AndAlso Setup.Get("LoginType") <> McLoginType.Ms Then
If IsSystemLanguageChinese() Then If IsSystemLanguageChinese() Then
RunInNewThread(
Sub()
Select Case Setup.Get("SystemLaunchCount") Select Case Setup.Get("SystemLaunchCount")
Case 3, 8, 15, 30, 50, 70, 90, 110, 130, 180, 220, 280, 330, 380, 450, 550, 660, 750, 880, 950, 1100, 1300, 1500, 1700, 1900 Case 3, 8, 15, 30, 50, 70, 90, 110, 130, 180, 220, 280, 330, 380, 450, 550, 660, 750, 880, 950, 1100, 1300, 1500, 1700, 1900
If MyMsgBox("你已经启动了 " & Setup.Get("SystemLaunchCount") & " 次 Minecraft 啦!" & vbCrLf & If MyMsgBox("你已经启动了 " & Setup.Get("SystemLaunchCount") & " 次 Minecraft 啦!" & vbCrLf &
@@ -247,7 +245,6 @@ NextInner:
OpenWebsite("https://www.xbox.com/zh-cn/games/store/minecraft-java-bedrock-edition-for-pc/9nxp44l49shj") OpenWebsite("https://www.xbox.com/zh-cn/games/store/minecraft-java-bedrock-edition-for-pc/9nxp44l49shj")
End If End If
End Select End Select
End Sub, "Buy Minecraft")
ElseIf Setup.Get("LoginType") = McLoginType.Legacy Then ElseIf Setup.Get("LoginType") = McLoginType.Legacy Then
Select Case MyMsgBox("你必须先登录正版账号,才能进行离线登录!", "正版验证", "购买正版", "试玩", "返回", Select Case MyMsgBox("你必须先登录正版账号,才能进行离线登录!", "正版验证", "购买正版", "试玩", "返回",
Button1Action:=Sub() OpenWebsite("https://www.xbox.com/zh-cn/games/store/minecraft-java-bedrock-edition-for-pc/9nxp44l49shj")) Button1Action:=Sub() OpenWebsite("https://www.xbox.com/zh-cn/games/store/minecraft-java-bedrock-edition-for-pc/9nxp44l49shj"))
@@ -504,7 +501,7 @@ NextInner:
#Region "分方式登录模块" #Region "分方式登录模块"
'各个登录方式的主对象与输入构造 '各个登录方式的主对象与输入构造
Public McLoginMsLoader As New LoaderTask(Of McLoginMs, McLoginResult)("Loader Login Ms", AddressOf McLoginMsStart) With {.ReloadTimeout = 1} Public McLoginMsLoader As New LoaderTask(Of McLoginMs, McLoginResult)("Loader Login Ms", AddressOf McLoginMsStart)
Public McLoginLegacyLoader As New LoaderTask(Of McLoginLegacy, McLoginResult)("Loader Login Legacy", AddressOf McLoginLegacyStart) Public McLoginLegacyLoader As New LoaderTask(Of McLoginLegacy, McLoginResult)("Loader Login Legacy", AddressOf McLoginLegacyStart)
Public McLoginNideLoader As New LoaderTask(Of McLoginServer, McLoginResult)("Loader Login Nide", AddressOf McLoginServerStart) With {.ReloadTimeout = 1000 * 60 * 10} Public McLoginNideLoader As New LoaderTask(Of McLoginServer, McLoginResult)("Loader Login Nide", AddressOf McLoginServerStart) With {.ReloadTimeout = 1000 * 60 * 10}
Public McLoginAuthLoader As New LoaderTask(Of McLoginServer, McLoginResult)("Loader Login Auth", AddressOf McLoginServerStart) With {.ReloadTimeout = 1000 * 60 * 10} Public McLoginAuthLoader As New LoaderTask(Of McLoginServer, McLoginResult)("Loader Login Auth", AddressOf McLoginServerStart) With {.ReloadTimeout = 1000 * 60 * 10}
@@ -632,6 +629,7 @@ LoginFinish:
Dim Dict As New Dictionary(Of String, String) Dim Dict As New Dictionary(Of String, String)
Dim Emails As New List(Of String) Dim Emails As New List(Of String)
Dim Passwords As New List(Of String) Dim Passwords As New List(Of String)
Try Try
If Not Setup.Get("Login" & Input.Token & "Email") = "" Then Emails.AddRange(Setup.Get("Login" & Input.Token & "Email").ToString.Split("¨")) If Not Setup.Get("Login" & Input.Token & "Email") = "" Then Emails.AddRange(Setup.Get("Login" & Input.Token & "Email").ToString.Split("¨"))
If Not Setup.Get("Login" & Input.Token & "Pass") = "" Then Passwords.AddRange(Setup.Get("Login" & Input.Token & "Pass").ToString.Split("¨")) If Not Setup.Get("Login" & Input.Token & "Pass") = "" Then Passwords.AddRange(Setup.Get("Login" & Input.Token & "Pass").ToString.Split("¨"))
@@ -699,56 +697,205 @@ LoginFinish:
End Sub End Sub
Private Sub McLoginRequestRefresh(ByRef Data As LoaderTask(Of McLoginServer, McLoginResult), RequestUser As Boolean) Private Sub McLoginRequestRefresh(ByRef Data As LoaderTask(Of McLoginServer, McLoginResult), RequestUser As Boolean)
McLaunchLog("刷新登录开始(Refresh, " & Data.Input.Token & ")") McLaunchLog("刷新登录开始(Refresh, " & Data.Input.Token & ")")
Dim LoginJson As JObject = GetJson(NetRequestRetry( Dim LittleSkinAccess = Setup.Get("Cache" & Data.Input.Token & "APIToken")
Dim LittleSkinRefresh = Setup.Get("Cache" & Data.Input.Token & "Refresh")
Dim RefreshData As New JObject()
Dim UserName As String
Dim UUID As String
Dim AccessToken As String
Dim RefreshToken As String
Dim IDToken As String
Dim LoginJson As JObject
'AccessToken 和 RefreshToken 都要有,不然没法刷新
Dim Noth As Boolean = LittleSkinRefresh = ""
Dim Nls As Boolean = LittleSkinAccess = ""
Log(Noth.ToString, LogLevel.Debug)
Log(Nls.ToString, LogLevel.Debug)
If Not LittleSkinAccess = "" AndAlso Not LittleSkinRefresh = "" Then
RefreshData.Add(New JProperty("grant_type", "refresh_token"))
RefreshData.Add(New JProperty("refresh_token", LittleSkinRefresh))
RefreshData.Add(New JProperty("access_token", LittleSkinAccess))
RefreshData.Add(New JProperty("client_id", LittleSkinClientId))
LoginJson = GetJson(NetRequestOnce(
Url:="https://open.littleskin.cn/oauth/token",
Method:="POST",
Data:=RefreshData,
Headers:=New Dictionary(Of String, String) From {{"Accept-Language", "zh_CN"}},
ContentType:="application/json; charset=utf-8"))
AccessToken = LoginJson("access_token").ToString(0)
RefreshToken = LoginJson("refresh_token").ToString(0)
IDToken = LoginJson("id_token").ToString(0)
Dim SelectPrpfile As String = Base64Decode(IDToken.Split(".")(1))
UserName = GetJson(GetJson(SelectPrpfile)("selectedProfile").ToString)("name").ToString
UUID = GetJson(GetJson(SelectPrpfile)("selectedProfile").ToString)("id").ToString
Data.Output.Uuid = UUID
Data.Output.Name = UserName
Setup.Set("Cache" & Data.Input.Token & "Refresh", RefreshToken)
Setup.Set("Cache" & Data.Input.Token & "APIToken", AccessToken)
Else
Throw New Exception("登录信息无效")
End If
Dim RefreshInfo As JObject = New JObject()
RefreshInfo.Add(New JProperty("accessToken", Setup.Get("Cache" & Data.Input.Token & "Access")))
RefreshInfo.Add(New JProperty("requestUser", True))
LoginJson = GetJson(NetRequestRetry(
Url:=Data.Input.BaseUrl & "/refresh", Url:=Data.Input.BaseUrl & "/refresh",
Method:="POST", Method:="POST",
Data:="{" & Data:=RefreshInfo.ToString(0),
If(RequestUser, "
""requestUser"": true,
""selectedProfile"": {
""id"":""" & Setup.Get("Cache" & Data.Input.Token & "Uuid") & """,
""name"":""" & Setup.Get("Cache" & Data.Input.Token & "Name") & """},", "") & "
""accessToken"":""" & Setup.Get("Cache" & Data.Input.Token & "Access") & """,
""clientToken"":""" & Setup.Get("Cache" & Data.Input.Token & "Client") & """}",
Headers:=New Dictionary(Of String, String) From {{"Accept-Language", "zh-CN"}}, Headers:=New Dictionary(Of String, String) From {{"Accept-Language", "zh-CN"}},
ContentType:="application/json; charset=utf-8")) ContentType:="application/json; charset=utf-8"))
'将登录结果输出 '将登录结果输出
If LoginJson("selectedProfile") Is Nothing Then Throw New Exception("选择的角色 " & Setup.Get("Cache" & Data.Input.Token & "Name") & " 无效!") If LoginJson("selectedProfile") Is Nothing Then Throw New Exception("选择的角色 " & Setup.Get("Cache" & Data.Input.Token & "Name") & " 无效!")
Data.Output.AccessToken = LoginJson("accessToken").ToString Data.Output.AccessToken = LoginJson("accessToken").ToString
Data.Output.ClientToken = LoginJson("clientToken").ToString Data.Output.ClientToken = LoginJson("clientToken").ToString
Data.Output.Type = Data.Input.Token
If Data.Output.Uuid = LoginJson("selectedProfile")("id").ToString AndAlso Data.Output.Name = LoginJson("selectedProfile")("name").ToString Then
Else
Data.Output.Uuid = LoginJson("selectedProfile")("id").ToString Data.Output.Uuid = LoginJson("selectedProfile")("id").ToString
Data.Output.Name = LoginJson("selectedProfile")("name").ToString Data.Output.Name = LoginJson("selectedProfile")("name").ToString
Data.Output.Type = Data.Input.Token End If
'保存缓存 '保存缓存
Setup.Set("Cache" & Data.Input.Token & "Access", Data.Output.AccessToken) Setup.Set("Cache" & Data.Input.Token & "Access", Data.Output.AccessToken)
Setup.Set("Cache" & Data.Input.Token & "Client", Data.Output.ClientToken) Setup.Set("Cache" & Data.Input.Token & "Client", Data.Output.ClientToken)
Setup.Set("Cache" & Data.Input.Token & "Uuid", Data.Output.Uuid) Setup.Set("Cache" & Data.Input.Token & "Uuid", Data.Output.Uuid)
Setup.Set("Cache" & Data.Input.Token & "Name", Data.Output.Name) Setup.Set("Cache" & Data.Input.Token & "Name", Data.Output.Name)
Setup.Set("Cache" & Data.Input.Token & "Username", Data.Input.UserName) If Data.Input.UserName Is Nothing Then
Setup.Set("Cache" & Data.Input.Token & "Pass", Data.Input.Password) ' 用一个通用字符模板填充内容
Setup.Set("Cache" & Data.Input.Token & "Username", "LittleSkinOAuth 登录")
Setup.Set("Cache" & Data.Input.Token & "Pass", "LittleSkinOAuth 登录")
End If
McLaunchLog("刷新登录成功(Refresh, " & Data.Input.Token & ")") McLaunchLog("刷新登录成功(Refresh, " & Data.Input.Token & ")")
End Sub End Sub
Private Function McLoginRequestLogin(ByRef Data As LoaderTask(Of McLoginServer, McLoginResult)) As Boolean Private Function McLoginRequestLogin(ByRef Data As LoaderTask(Of McLoginServer, McLoginResult)) As Boolean
Try Try
Dim NeedRefresh As Boolean = False Dim NeedRefresh As Boolean = False
McLaunchLog("登录开始(Login, " & Data.Input.Token & ")") Dim RequestData As New JObject()
Dim RequestData As New JObject( Dim LittleSkinOAuth As Boolean = False
New JProperty("agent", New JObject(New JProperty("name", "Minecraft"), New JProperty("version", 1))), Dim LoginJson
New JProperty("username", Data.Input.UserName), Dim AccessToken As String
New JProperty("password", Data.Input.Password), Dim RefreshToken As String
New JProperty("requestUser", True)) 'LittleSkin OAuth 登录检查
Dim LoginJson As JObject = GetJson(NetRequestRetry(
If Data.Input.BaseUrl.ToLower.Contains("littleskin.cn") And Not LittleSkinClientId = "" Then
'ClientId
RequestData.Add(New JProperty("client_id", LittleSkinClientId))
'一堆权限
RequestData.Add(New JProperty("scope", "offline_access openid Yggdrasil.PlayerProfiles.Select Yggdrasil.MinecraftToken.Create"))
LittleSkinOAuth = True
Else
RequestData.Add(New JProperty("agent", New JObject(New JProperty("name", "Minecraft"), New JProperty("version", 1))))
RequestData.Add(New JProperty("username", Data.Input.UserName))
RequestData.Add(New JProperty("password", Data.Input.Password))
RequestData.Add(New JProperty("requestUser", True))
LittleSkinOAuth = False
End If
' LittleSkin OAuth 登录步骤 1: 获取授权代码
If LittleSkinOAuth Then
McLaunchLog("开始 LittleSkin OAuth 登录步骤 1/3(原始登录)")
LoginJson = GetJson(NetRequestOnce(
Url:="https://open.littleskin.cn/oauth/device_code",
Method:="POST",
Data:=RequestData.ToString(0),
Headers:=New Dictionary(Of String, String) From {{"Accept-Language", "zh_CN"}},
ContentType:="application/json; charset=utf-8"))
Else
LoginJson = GetJson(NetRequestRetry(
Url:=Data.Input.BaseUrl & "/authenticate", Url:=Data.Input.BaseUrl & "/authenticate",
Method:="POST", Method:="POST",
Data:=RequestData.ToString(0), Data:=RequestData.ToString(0),
Headers:=New Dictionary(Of String, String) From {{"Accept-Language", "zh-CN"}}, Headers:=New Dictionary(Of String, String) From {{"Accept-Language", "zh-CN"}},
ContentType:="application/json; charset=utf-8")) ContentType:="application/json; charset=utf-8"))
End If
'检查登录结果 '检查登录结果
' LittleSkin
If LittleSkinOAuth Then
' 轮询验证
'花了点时间改了逻辑。现在按照 OAuth 标准编写的服务端应该都能用这个处理轮询登录
Dim Converter As New MyMsgBoxConverter With {.Content = LoginJson, .ForceWait = True, .Type = MyMsgBoxType.Login, .AuthUrl = "https://open.littleskin.cn/oauth/token"}
WaitingMyMsgBox.Add(Converter)
While Converter.Result Is Nothing
Thread.Sleep(100)
End While
Log(Converter.Result.ToString, LogLevel.Hint)
Log(Converter.Result.ToString, LogLevel.Debug)
'LittleSkin OAuth 登录步骤 2: 获取用户选定档案
McLaunchLog("LittleSkin OAuth 登录步骤 2/3")
'因为还有个 ID Token,硬编码只解析 AccessToken 和 RefreshToken
Dim Result = Converter.Result
Dim IDToken As String
AccessToken = Result("access_token")
RefreshToken = Result("refresh_token")
Dim ProfileData As New JObject()
Dim UserName As String
Dim UUID As String
' IDToken 编码的档案
' 这一行不能用 Try Catch,否则后面解析会抛出 NullReferenceException
IDToken = Result("id_token")
Dim SelectProfile = GetJson(Base64Decode(IDToken.ToString.Split(".")(1)))("selectedProfile").ToString
UserName = GetJson(SelectProfile)("name")
UUID = GetJson(SelectProfile)("id")
'LittleSkin OAuth 登录步骤 3::获取 Minecraft AccessToken 启动令牌
McLaunchLog("LittleSkin OAuth 登录步骤 3/3")
Dim RequestInfo = New JObject()
RequestInfo.Add(New JProperty("uuid", UUID))
'需要 Yggdrasil.MinecraftToken.Create
Result = GetJson(NetRequestOnce(Url:=Data.Input.BaseUrl & "/oauth",
Method:="POST",
Data:=RequestInfo.ToString(0),
Headers:=New Dictionary(Of String, String) From {{"Authorization", "Bearer " & AccessToken}},
ContentType:="application/json; charset=utf-8"))
Dim ClientToken = Result("clientToken").ToString
Dim MCAccessToken = Result("accessToken").ToString
McLaunchLog("LittleSkin OAuth 登录完成")
Data.Output.AccessToken = MCAccessToken
Data.Output.ClientToken = ClientToken
Data.Output.Name = UserName
Data.Output.Uuid = UUID
Data.Output.Type = Data.Input.Token
Setup.Set("Cache" & Data.Input.Token & "Access", Data.Output.AccessToken)
Setup.Set("Cache" & Data.Input.Token & "Refresh", RefreshToken)
Setup.Set("Cache" & Data.Input.Token & "Uuid", Data.Output.Uuid)
Setup.Set("Cache" & Data.Input.Token & "Name", Data.Output.Name)
'刷新需要 AccessToken 和 RefreshToken 配合使用
'Setup.Set("Cache" & Data.Input.Token & "Client", Data.Output.ClientToken)
Setup.Set("Cache" & Data.Input.Token & "APIToken", AccessToken)
If Data.Input.UserName Is Nothing AndAlso Data.Input.Password Is Nothing Then
Setup.Set("Cache" & Data.Input.Token & "Username", "LittleSkinOAuth 登录")
Setup.Set("Cache" & Data.Input.Token & "Pass", "LittleSkinOAuth 登录")
Else
Setup.Set("Cache" & Data.Input.Token & "Username", Data.Input.UserName)
Setup.Set("Cache" & Data.Input.Token & "Pass", Data.Input.Password)
End If
Return True
'原始登录
Else
If LoginJson("availableProfiles").Count = 0 Then If LoginJson("availableProfiles").Count = 0 Then
If Data.Input.ForceReselectProfile Then Hint("你还没有创建角色, 无法更换!", HintType.Critical) If Data.Input.ForceReselectProfile Then Hint("你还没有创建角色, 无法更换!", HintType.Critical)
Throw New Exception("$你还没有创建角色, 请在创建角色后再试!") Throw New Exception("$你还没有创建角色, 请在创建角色后再试!")
ElseIf Data.Input.ForceReselectProfile AndAlso LoginJson("availableProfiles").Count = 1 Then ElseIf Data.Input.ForceReselectProfile AndAlso LoginJson("availableProfiles").Count = 1 Then
Hint("你的账户中只有一个角色, 无法更换!", HintType.Critical) Hint("你的账户中只有一个角色, 无法更换!", HintType.Critical)
End If
End If End If
Dim SelectedName As String = Nothing Dim SelectedName As String = Nothing
Dim SelectedId As String = Nothing Dim SelectedId As String = Nothing
@@ -876,7 +1023,8 @@ Retry:
ElseIf TypeOf Converter.Result Is Exception Then ElseIf TypeOf Converter.Result Is Exception Then
Throw CType(Converter.Result, Exception) Throw CType(Converter.Result, Exception)
Else Else
Return Converter.Result Dim LoginData = Converter.Result
Return {LoginData("access_token"), LoginData("refresh_token")}
End If End If
End Function End Function
'微软登录步骤 1,刷新登录:从 OAuth Code 或 OAuth RefreshToken 获取 {OAuth AccessToken, OAuth RefreshToken} '微软登录步骤 1,刷新登录:从 OAuth Code 或 OAuth RefreshToken 获取 {OAuth AccessToken, OAuth RefreshToken}
@@ -896,7 +1044,10 @@ Retry:
End If End If
End Try End Try
Dim ResultJson As JObject = GetJson(Result) Dim ResultJson As JObject = GetJson(Result)
Dim AccessToken As String = ResultJson("access_token").ToString Dim AccessToken As String = ResultJson("access_token").ToString
Dim RefreshToken As String = ResultJson("refresh_token").ToString Dim RefreshToken As String = ResultJson("refresh_token").ToString
Return {AccessToken, RefreshToken} Return {AccessToken, RefreshToken}
@@ -904,7 +1055,6 @@ Retry:
'微软登录步骤 2:从 OAuth AccessToken 获取 XBLToken '微软登录步骤 2:从 OAuth AccessToken 获取 XBLToken
Private Function MsLoginStep2(AccessToken As String) As String Private Function MsLoginStep2(AccessToken As String) As String
McLaunchLog("开始微软登录步骤 2/6") McLaunchLog("开始微软登录步骤 2/6")
Dim Request As String = "{ Dim Request As String = "{
""Properties"": { ""Properties"": {
""AuthMethod"": ""RPS"", ""AuthMethod"": ""RPS"",
@@ -2048,8 +2198,8 @@ IgnoreCustomSkin:
"@echo off" & vbCrLf & "@echo off" & vbCrLf &
"title 启动 - " & McVersionCurrent.Name & vbCrLf & "title 启动 - " & McVersionCurrent.Name & vbCrLf &
"echo 游戏正在启动,请稍候。" & vbCrLf & "echo 游戏正在启动,请稍候。" & vbCrLf &
"set APPDATA=""" & McVersionCurrent.PathIndie & """" & vbCrLf & "set APPDATA=""" & PathMcFolder & """" & vbCrLf &
"cd /D """ & McVersionCurrent.PathIndie & """" & vbCrLf & "cd /D """ & PathMcFolder & """" & vbCrLf &
CustomCommandGlobal & vbCrLf & CustomCommandGlobal & vbCrLf &
CustomCommandVersion & vbCrLf & CustomCommandVersion & vbCrLf &
"""" & McLaunchJavaSelected.PathJava & """ " & McLaunchArgument & vbCrLf & """" & McLaunchJavaSelected.PathJava & """ " & McLaunchArgument & vbCrLf &