MyMsgLogin.xaml.vb 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. Public Class MyMsgLogin
  2. Private Data As JObject
  3. Private UserCode As String '需要用户在网页上输入的设备代码
  4. Private DeviceCode As String '用于轮询的设备代码
  5. Private Website As String '验证网页的网址
  6. #Region "弹窗"
  7. Private ReadOnly MyConverter As MyMsgBoxConverter
  8. Private ReadOnly Uuid As Integer = GetUuid()
  9. Public Sub New(Converter As MyMsgBoxConverter)
  10. Try
  11. InitializeComponent()
  12. Btn1.Name = Btn1.Name & GetUuid()
  13. Btn2.Name = Btn2.Name & GetUuid()
  14. Btn3.Name = Btn3.Name & GetUuid()
  15. MyConverter = Converter
  16. ShapeLine.StrokeThickness = GetWPFSize(1)
  17. Data = Converter.Content
  18. Init()
  19. Catch ex As Exception
  20. Logger.Error(ex, "登录弹窗初始化失败", LogBehavior.Toast)
  21. End Try
  22. End Sub
  23. Private Sub Load(sender As Object, e As EventArgs) Handles MyBase.Loaded
  24. Try
  25. '动画
  26. Opacity = 0
  27. AniStart(AaColor(FrmMain.PanMsg, Grid.BackgroundProperty, If(MyConverter.IsWarn, New MyColor(140, 80, 0, 0), New MyColor(90, 0, 0, 0)) - FrmMain.PanMsg.Background, 200), "PanMsg Background")
  28. AniStart({
  29. AaOpacity(Me, 1, 120, 60),
  30. AaDouble(Sub(i) TransformPos.Y += i, -TransformPos.Y, 300, 60, New AniEaseOutBack(AniEasePower.Weak)),
  31. AaDouble(Sub(i) TransformRotate.Angle += i, -TransformRotate.Angle, 300, 60, New AniEaseOutFluent(AniEasePower.Weak))
  32. }, "MyMsgBox " & Uuid)
  33. '记录日志
  34. Logger.Info($"登录弹窗:{LabTitle.Text}{vbCrLf}{LabCaption.Text}")
  35. Catch ex As Exception
  36. Logger.Error(ex, "登录弹窗加载失败", LogBehavior.Toast)
  37. End Try
  38. End Sub
  39. Private Sub Close()
  40. '动画
  41. AniStart({
  42. AaCode(
  43. Sub()
  44. If Not WaitingMyMsgBox.Any() Then
  45. AniStart(AaColor(FrmMain.PanMsg, Grid.BackgroundProperty, New MyColor(0, 0, 0, 0) - FrmMain.PanMsg.Background, 200, Ease:=New AniEaseOutFluent(AniEasePower.Weak)))
  46. End If
  47. End Sub, 30),
  48. AaOpacity(Me, -Opacity, 80, 20),
  49. AaDouble(Sub(i) TransformPos.Y += i, 20 - TransformPos.Y, 150, 0, New AniEaseOutFluent),
  50. AaDouble(Sub(i) TransformRotate.Angle += i, 6 - TransformRotate.Angle, 150, 0, New AniEaseInFluent(AniEasePower.Weak)),
  51. AaCode(Sub() CType(Parent, Grid).Children.Remove(Me), , True)
  52. }, "MyMsgBox " & Uuid)
  53. End Sub
  54. '实现回车和 Esc 的接口(#4857)
  55. Public Sub Btn1_Click() Handles Btn1.Click
  56. End Sub
  57. Public Sub Btn3_Click() Handles Btn3.Click
  58. Finished(New OperationCanceledException)
  59. End Sub
  60. Private Sub Drag(sender As Object, e As MouseButtonEventArgs) Handles PanBorder.MouseLeftButtonDown, LabTitle.MouseLeftButtonDown
  61. On Error Resume Next
  62. If e.GetPosition(ShapeLine).Y <= 2 Then FrmMain.DragMove()
  63. End Sub
  64. #End Region
  65. Private Sub Finished(Result As Object)
  66. If MyConverter.IsExited Then Return
  67. MyConverter.IsExited = True
  68. MyConverter.Result = Result
  69. RunInUi(AddressOf Close)
  70. Thread.Sleep(200)
  71. FrmMain.ShowWindowToTop()
  72. End Sub
  73. Private Sub Init()
  74. UserCode = Data("user_code")
  75. DeviceCode = Data("device_code")
  76. Website = Data("verification_uri")
  77. '设置 UI
  78. LabTitle.Text = "登录 Minecraft"
  79. LabCaption.Text =
  80. $"登录网页将自动开启,请在网页中输入 {UserCode}(已自动复制)。" & vbCrLf & vbCrLf &
  81. $"如果网络环境不佳,网页可能一直加载不出来,届时请使用加速器或 VPN 改善网络环境。" & vbCrLf &
  82. $"你也可以用其他设备打开 {Website} 并输入上述代码。"
  83. CustomEventService.SetEventData(Btn1, Website)
  84. CustomEventService.SetEventData(Btn2, UserCode)
  85. '启动工作线程
  86. RunInNewThread(AddressOf WorkThread, "MyMsgLogin")
  87. End Sub
  88. Private Sub WorkThread()
  89. Thread.Sleep(2000)
  90. If MyConverter.IsExited Then Return
  91. OpenWebsite(Website)
  92. ClipboardSet(UserCode)
  93. Thread.Sleep((Data("interval").ToObject(Of Integer) - 1) * 1000)
  94. '轮询
  95. Dim UnknownFailureCount As Integer = 0
  96. Do While Not MyConverter.IsExited
  97. Try
  98. Dim Result = NetRequestByClient(
  99. "https://login.microsoftonline.com/consumers/oauth2/v2.0/token", HttpMethod.Post,
  100. Content:=
  101. "grant_type=urn:ietf:params:oauth:grant-type:device_code" & "&" &
  102. "client_id=" & OAuthClientId & "&" &
  103. "device_code=" & DeviceCode & "&" &
  104. "scope=XboxLive.signin%20offline_access",
  105. ContentType:="application/x-www-form-urlencoded",
  106. Timeout:=5000 + UnknownFailureCount * 5000,
  107. MakeLog:=False, RequireJson:=True)
  108. '获取结果
  109. Dim ResultJson As JObject = Result.DeserializeJson()
  110. McLaunchLog($"令牌过期时间:{ResultJson("expires_in")} 秒")
  111. Hint("网页登录成功!", HintType.Green)
  112. Finished({ResultJson("access_token").ToString, ResultJson("refresh_token").ToString})
  113. Return
  114. Catch ex As Exception
  115. '修改错误列表时,同时修改 ModLaunch.MsLoginStep1Refresh 中的对应代码
  116. If TypeOf ex Is HttpRequestCodeException Then
  117. Dim Response = CType(ex, HttpRequestCodeException).Response
  118. If Response.Contains("authorization_declined") Then
  119. Finished(New Exception("$你拒绝了 PCL 申请的权限……"))
  120. Return
  121. ElseIf Response.Contains("expired_token") Then
  122. Finished(New Exception("$登录用时太长啦,重新试试吧!"))
  123. Return
  124. ElseIf Response.Contains("Account security interrupt") Then
  125. Finished(New Exception("$该账号由于安全问题无法登陆,请前往微软账户页获取更多信息。"))
  126. Return
  127. ElseIf Response.Contains("service abuse") Then
  128. Finished(New Exception("$非常抱歉,该账号已被微软封禁,无法登录。"))
  129. Return
  130. ElseIf Response.Contains("AADSTS70000") Then '可能不能判 “invalid_grant”,见 #269
  131. Finished(New RestartException)
  132. Return
  133. ElseIf Response.Contains("authorization_pending") Then
  134. Thread.Sleep(2000)
  135. Continue Do
  136. End If
  137. End If
  138. If UnknownFailureCount <= 2 Then
  139. UnknownFailureCount += 1
  140. Logger.Warn(ex, $"登录轮询第 {UnknownFailureCount} 次失败")
  141. Thread.Sleep(2000)
  142. Else
  143. Finished(New Exception("登录轮询失败", ex))
  144. Return
  145. End If
  146. End Try
  147. Loop
  148. End Sub
  149. End Class