龙腾猫跃 %!s(int64=3) %!d(string=hai) anos
pai
achega
fd7049ceed
Modificáronse 26 ficheiros con 249 adicións e 539 borrados
  1. 0 4
      Plain Craft Launcher 2/Application.xaml.vb
  2. 1 1
      Plain Craft Launcher 2/Controls/MyIconButton.xaml.vb
  3. 8 2
      Plain Craft Launcher 2/Controls/MyScrollViewer.vb
  4. 7 1
      Plain Craft Launcher 2/FormMain.xaml.vb
  5. 21 5
      Plain Craft Launcher 2/Modules/Base/ModBase.vb
  6. 10 4
      Plain Craft Launcher 2/Modules/Base/MyBitmap.vb
  7. 1 1
      Plain Craft Launcher 2/Modules/Minecraft/ModComp.vb
  8. 1 1
      Plain Craft Launcher 2/Modules/Minecraft/ModCrash.vb
  9. 39 75
      Plain Craft Launcher 2/Modules/Minecraft/ModLaunch.vb
  10. 4 2
      Plain Craft Launcher 2/Modules/Minecraft/ModMinecraft.vb
  11. 2 2
      Plain Craft Launcher 2/My Project/AssemblyInfo.vb
  12. 26 18
      Plain Craft Launcher 2/Pages/PageDownload/ModDownloadLib.vb
  13. 10 12
      Plain Craft Launcher 2/Pages/PageLaunch/MySkin.xaml.vb
  14. 4 6
      Plain Craft Launcher 2/Pages/PageLaunch/PageLaunchLeft.xaml
  15. 14 88
      Plain Craft Launcher 2/Pages/PageLaunch/PageLaunchLeft.xaml.vb
  16. 0 6
      Plain Craft Launcher 2/Pages/PageLaunch/PageLaunchRight.xaml.vb
  17. 0 26
      Plain Craft Launcher 2/Pages/PageLaunch/PageLoginMojang.xaml
  18. 0 84
      Plain Craft Launcher 2/Pages/PageLaunch/PageLoginMojang.xaml.vb
  19. 0 29
      Plain Craft Launcher 2/Pages/PageLaunch/PageLoginMojangSkin.xaml
  20. 0 117
      Plain Craft Launcher 2/Pages/PageLaunch/PageLoginMojangSkin.xaml.vb
  21. 9 5
      Plain Craft Launcher 2/Pages/PageLaunch/PageLoginMs.xaml
  22. 6 1
      Plain Craft Launcher 2/Pages/PageLaunch/PageLoginMs.xaml.vb
  23. 35 12
      Plain Craft Launcher 2/Pages/PageLaunch/PageLoginMsSkin.xaml
  24. 47 19
      Plain Craft Launcher 2/Pages/PageLaunch/PageLoginMsSkin.xaml.vb
  25. 4 4
      Plain Craft Launcher 2/Pages/PageVersion/PageVersionLeft.xaml.vb
  26. 0 14
      Plain Craft Launcher 2/Plain Craft Launcher 2.vbproj

+ 0 - 4
Plain Craft Launcher 2/Application.xaml.vb

@@ -205,10 +205,6 @@ Public Class Application
             Setup.Set("Login" & Token & "Email", Join(Dict.Keys.ToArray, "¨"))
             Setup.Set("Login" & Token & "Pass", Join(Dict.Values.ToArray, "¨"))
             Select Case Token
-                Case "Mojang"
-                    FrmLoginMojang.ComboName.ItemsSource = Dict.Keys
-                    FrmLoginMojang.ComboName.Text = If(Dict.Keys.Count > 0, Dict.Keys(0), "")
-                    FrmLoginMojang.TextPass.Password = If(Dict.Values.Count > 0, Dict.Values(0), "")
                 Case "Nide"
                     FrmLoginNide.ComboName.ItemsSource = Dict.Keys
                     FrmLoginNide.ComboName.Text = If(Dict.Keys.Count > 0, Dict.Keys(0), "")

+ 1 - 1
Plain Craft Launcher 2/Controls/MyIconButton.xaml.vb

@@ -115,7 +115,7 @@
                     Dim AnimList As New List(Of AniData)
                     Select Case Theme
                         Case Themes.Color
-                            AnimList.Add(AaColor(Path, Shape.FillProperty, "ColorBrush4", AnimationColorOut))
+                            AnimList.Add(AaColor(Path, Shape.FillProperty, "ColorBrush5", AnimationColorOut))
                             PanBack.Background = New MyColor(0, 255, 255, 255)
                         Case Themes.White
                             AnimList.Add(AaColor(Path, Shape.FillProperty, "ColorBrush8", AnimationColorOut))

+ 8 - 2
Plain Craft Launcher 2/Controls/MyScrollViewer.vb

@@ -5,8 +5,14 @@
     Private RealOffset As Double
     Private Sub MyScrollViewer_PreviewMouseWheel(sender As Object, e As MouseWheelEventArgs) Handles Me.PreviewMouseWheel
         If e.Delta = 0 OrElse ActualHeight = 0 OrElse ScrollableHeight = 0 Then Exit Sub
-        Dim SourceTypeName As String = e.Source.GetType.Name
-        If Content.TemplatedParent Is Nothing AndAlso (SourceTypeName.Contains("Combo") OrElse SourceTypeName = "MyTextBox") Then Exit Sub '确定可视树,防止滚动问题
+        Dim SourceType = e.Source.GetType
+        If Content.TemplatedParent Is Nothing AndAlso
+            ((GetType(ComboBox).IsAssignableFrom(SourceType) AndAlso CType(e.Source, ComboBox).IsDropDownOpen) OrElse
+            (GetType(TextBox).IsAssignableFrom(SourceType) AndAlso CType(e.Source, TextBox).AcceptsReturn) OrElse
+            GetType(ComboBoxItem).IsAssignableFrom(SourceType)) Then
+            '如果当前是在对有滚动条的下拉框或文本框执行,则不接管操作
+            Exit Sub
+        End If
         PerformVerticalOffsetDelta(-e.Delta)
         e.Handled = True
     End Sub

+ 7 - 1
Plain Craft Launcher 2/FormMain.xaml.vb

@@ -95,7 +95,13 @@ Public Class FormMain
         '3:BUG+ IMP* FEAT-
         '2:BUG* IMP-
         '1:BUG-
-        If LastVersion < 287 Then 'Snapshot 2.5.3
+        If LastVersion < 289 Then 'Snapshot 2.5.4
+            FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "重新制作正版登录页面"))
+            FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "彻底移除 Mojang 登录"))
+            FeatureCount += 6
+            BugCount += 14
+        End If
+        If LastVersion < 288 Then 'Snapshot 2.5.3
             FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "在缺少 Java 时会自动下载所需的 Java"))
             FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "添加 CurseForge / Modrinth 来源筛选"))
             FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "为下载管理和音乐播放按钮添加进度条"))

+ 21 - 5
Plain Craft Launcher 2/Modules/Base/ModBase.vb

@@ -11,12 +11,12 @@ Public Module ModBase
 #Region "声明"
 
     '下列版本信息由更新器自动修改
-    Public Const VersionBaseName As String = "2.5.3" '不含分支前缀的显示用版本名
-    Public Const VersionStandardCode As String = "2.5.3." & VersionBranchCode '标准格式的四段式版本号
+    Public Const VersionBaseName As String = "2.5.4" '不含分支前缀的显示用版本名
+    Public Const VersionStandardCode As String = "2.5.4." & VersionBranchCode '标准格式的四段式版本号
 #If BETA Then
     Public Const VersionCode As Integer = 286 'Release
 #Else
-    Public Const VersionCode As Integer = 288 'Snapshot
+    Public Const VersionCode As Integer = 289 'Snapshot
 #End If
     '自动生成的版本信息
     Public Const VersionDisplayName As String = VersionBranchName & " " & VersionBaseName
@@ -158,6 +158,10 @@ Public Module ModBase
         ''' </summary>
         Public Const IconButtonUser As String = "M660.338 528.065c63.61-46.825 105.131-121.964 105.131-206.83 0-141.7-115.29-256.987-256.997-256.987-141.706 0-256.998 115.288-256.998 256.987 0 85.901 42.52 161.887 107.456 208.562-152.1 59.92-260.185 207.961-260.185 381.077 0 21.276 17.253 38.53 38.53 38.53 21.278 0 38.53-17.254 38.53-38.53 0-183.426 149.232-332.671 332.667-332.671 1.589 0 3.113-0.207 4.694-0.244 0.8 0.056 1.553 0.244 2.362 0.244 183.434 0 332.664 149.245 332.664 332.671 0 21.276 17.255 38.53 38.533 38.53 21.277 0 38.53-17.254 38.53-38.53 0-174.885-110.354-324.13-264.917-382.809z m-331.803-206.83c0-99.22 80.72-179.927 179.935-179.927s179.937 80.708 179.937 179.927c0 99.203-80.721 179.91-179.937 179.91s-179.935-80.708-179.935-179.91z"
         ''' <summary>
+        ''' 图标按钮,微软,0.9x
+        ''' </summary>
+        Public Const IconButtonMs As String = "M0,0h5v5h-5ZM6,0h5v5h-5v-5ZM0,6h5v5h-5v-5ZM6,6h5v5h-5v-5Z"
+        ''' <summary>
         ''' 图标,音符,1x
         ''' </summary>
         Public Const IconMusic As String = "M348.293565 716.53287V254.797913c0-41.672348 28.004174-78.358261 68.919652-90.37913L815.994435 40.826435c62.775652-18.610087 125.907478 26.579478 125.907478 89.933913v539.158261c8.013913 42.25113-8.94887 89.177043-47.014956 127.109565a232.848696 232.848696 0 0 1-170.785392 65.758609c-61.885217-2.938435-111.081739-33.435826-129.113043-80.050087-18.031304-46.614261-2.137043-102.177391 41.672348-145.853218a232.848696 232.848696 0 0 1 170.785391-65.80313c21.014261 1.024 40.514783 5.164522 57.878261 12.065391V233.338435c0-12.109913-10.551652-20.034783-20.569044-20.034783a24.620522 24.620522 0 0 0-5.787826 0.934957L439.785739 338.18713a19.545043 19.545043 0 0 0-14.825739 19.144348v438.984348H423.846957c11.53113 43.987478-5.164522 94.208-45.412174 134.322087a232.848696 232.848696 0 0 1-170.785392 65.758609c-61.885217-2.938435-111.081739-33.435826-129.113043-80.050087-18.031304-46.614261-2.137043-102.177391 41.672348-145.853218a232.848696 232.848696 0 0 1 170.785391-65.80313c20.791652 1.024 40.069565 5.075478 57.299478 11.842783z"
@@ -784,7 +788,7 @@ Public Module ModBase
             '复制文件
             File.Copy(FromPath, ToPath, True)
         Catch ex As Exception
-            Throw New Exception("复制文件出错:" & FromPath & " -> " & ToPath, ex)
+            Throw New Exception("复制文件出错:" & FromPath & " → " & ToPath, ex)
         End Try
     End Sub
     ''' <summary>
@@ -1240,7 +1244,19 @@ Re:
             Directory.CreateDirectory(DestDirectory)
             If CompressFilePath.EndsWith(".zip") OrElse CompressFilePath.EndsWith(".jar") OrElse CompressFilePath.EndsWith(".mrpack") Then
                 '以 zip 方式解压
-                ZipFile.ExtractToDirectory(CompressFilePath, DestDirectory, If(Encode, Encoding.GetEncoding("GB18030")))
+                Using stream As New FileStream(CompressFilePath, FileMode.Open)
+                    Using archive As New ZipArchive(stream, ZipArchiveMode.Read, False, If(Encode, Encoding.GetEncoding("GB18030")))
+                        For Each entry As ZipArchiveEntry In archive.Entries
+                            Dim destinationPath As String = IO.Path.Combine(DestDirectory, entry.FullName)
+                            If destinationPath.EndsWith("\") OrElse destinationPath.EndsWith("/") Then
+                                Directory.CreateDirectory(destinationPath)
+                            Else
+                                If File.Exists(destinationPath) Then File.Delete(destinationPath)
+                                entry.ExtractToFile(destinationPath, True)
+                            End If
+                        Next
+                    End Using
+                End Using
                 Return True
             ElseIf CompressFilePath.EndsWith(".gz") Then
                 '以 gz 方式解压

+ 10 - 4
Plain Craft Launcher 2/Modules/Base/MyBitmap.vb

@@ -1,5 +1,7 @@
 '一个万能的自动图片类型转换工具类
 
+Imports System.Drawing.Imaging
+
 Public Class MyBitmap
 
     ''' <summary>
@@ -29,7 +31,7 @@ Public Class MyBitmap
         Dim bitmapData = Bitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format32bppArgb)
         Try
             Dim size = rect.Width * rect.Height * 4
-            Return BitmapSource.Create(Bitmap.Width, Bitmap.Height, DPI, DPI, PixelFormats.Bgra32, Nothing, bitmapData.Scan0, size, bitmapData.Stride)
+            Return BitmapSource.Create(Bitmap.Width, Bitmap.Height, Bitmap.HorizontalResolution, Bitmap.VerticalResolution, PixelFormats.Bgra32, Nothing, bitmapData.Scan0, size, bitmapData.Stride)
         Finally
             Bitmap.UnlockBits(bitmapData)
         End Try
@@ -109,8 +111,10 @@ Public Class MyBitmap
     Public Function Rotation(angle As Double) As System.Drawing.Bitmap
         Dim img As System.Drawing.Image = Me.Pic
         Dim bitSize As Single = img.Width
-        Dim bmp As New System.Drawing.Bitmap(CInt(bitSize), CInt(bitSize))
+        Dim bmp As New System.Drawing.Bitmap(CInt(bitSize), CInt(bitSize), img.PixelFormat)
+        bmp.SetResolution(img.HorizontalResolution, img.VerticalResolution)
         Using g As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(bmp)
+            g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor
             g.TranslateTransform(bitSize / 2, bitSize / 2)
             g.RotateTransform(angle)
             g.TranslateTransform(-bitSize / 2, -bitSize / 2)
@@ -124,9 +128,11 @@ Public Class MyBitmap
     ''' </summary>
     Public Function Clip(rect As System.Drawing.Rectangle) As System.Drawing.Bitmap
         Dim img As System.Drawing.Image = Pic
-        Dim bmp As New System.Drawing.Bitmap(rect.Width, rect.Height)
+        Dim bmp As New System.Drawing.Bitmap(rect.Width, rect.Height, img.PixelFormat)
+        bmp.SetResolution(img.HorizontalResolution, img.VerticalResolution)
         Using g As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(bmp)
-            g.DrawImageUnscaled(img, rect)
+            g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor
+            g.DrawImageUnscaled(img, rect.X, rect.Y)
         End Using
         Return bmp
     End Function

+ 1 - 1
Plain Craft Launcher 2/Modules/Minecraft/ModComp.vb

@@ -181,7 +181,7 @@
             Get
                 If Not LoadedDatabase Then
                     LoadedDatabase = True
-                    _DatabaseEntry = CompDatabase.FirstOrDefault(Function(c) If(FromCurseForge, c.CurseForgeSlug, c.ModrinthSlug) = Slug)
+                    If Type = CompType.Mod Then _DatabaseEntry = CompDatabase.FirstOrDefault(Function(c) If(FromCurseForge, c.CurseForgeSlug, c.ModrinthSlug) = Slug)
                 End If
                 Return _DatabaseEntry
             End Get

+ 1 - 1
Plain Craft Launcher 2/Modules/Minecraft/ModCrash.vb

@@ -505,7 +505,7 @@ Done:
                 If ModId Is Nothing Then ModId = RegexSeek(LogMc, "(?<= in config \[)[^./ ]+(?=.mixins.json\] FAILED during )")
                 If ModId Is Nothing Then ModId = RegexSeek(LogMc, "(?<= in config \[mixins.)[^./ ]+(?=.json\] FAILED during )")
                 If ModId Is Nothing Then ModId = RegexSeek(LogMc, "(?<= in callback )[^./ ]+(?=.mixins.json:)")
-                If ModId Is Nothing Then ModId = RegexSeek(LogMc, "(?<= in callback mixins.)[^./ ]+(?=.json:)")
+                If ModId Is Nothing Then ModId = RegexSeek(LogMc, "(?<=from mod )[^\] ]+(?=\] from phase)")
                 AppendReason(CrashReason.ModMixin失败, TryAnalyzeModName(If(ModId, "").TrimEnd((vbCrLf & " ").ToCharArray)))
             End If
             If LogMc.Contains("Caught exception from ") Then AppendReason(CrashReason.确定Mod导致游戏崩溃, TryAnalyzeModName(RegexSeek(LogMc, "(?<=Caught exception from )[^\n]+?")?.TrimEnd((vbCrLf & " ").ToCharArray)))

+ 39 - 75
Plain Craft Launcher 2/Modules/Minecraft/ModLaunch.vb

@@ -181,20 +181,32 @@ NextInner:
                         CheckResult = McLoginAble(LoginInput)
                     End Sub)
         If CheckResult <> "" Then Throw New ArgumentException(CheckResult)
-        '求赞助
 #If BETA Then
+        '求赞助
         RunInNewThread(Sub()
                            Select Case Setup.Get("SystemLaunchCount")
-                               Case 20, 50, 100, 150, 200, 250, 300, 350, 400, 450, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500, 1600, 1700, 1800, 1900, 2000
+                               Case 20, 50, 100, 150, 200, 250, 300, 350, 400, 450, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500, 1700, 1900, 2100, 2300, 2500
                                    If MyMsgBox("PCL 已经为你启动了 " & Setup.Get("SystemLaunchCount") & " 次游戏啦!" & vbCrLf &
-                                               "如果觉得 PCL 还算好用的话,也可以考虑小小地赞助一下作者呢 qwq……" & vbCrLf &
-                                               "毕竟一个人开发也不容易(小声)……",
+                                               "如果觉得 PCL 还算好用的话,也可以考虑赞助一下作者……一点心意也行……" & vbCrLf &
+                                               "毕竟一个人开发也不容易(悲)……",
                                                "求赞助啦……", "这就赞助!", "但是我拒绝") = 1 Then
-                                       OpenWebsite("https://afdian.net/a/LTCat/plan")
+                                       OpenWebsite("https://afdian.net/a/LTCat")
                                    End If
                            End Select
                        End Sub, "Donate")
 #End If
+        '正版购买提示
+        If Not Setup.Get("HintBuy") AndAlso Setup.Get("LoginType") <> McLoginType.Ms Then
+            Select Case Setup.Get("SystemLaunchCount")
+                Case 10, 35, 75, 125, 175, 225, 275, 325, 375, 425, 475, 550, 650, 750, 850, 950, 1050, 1150, 1250, 1350, 1450, 1600, 1800, 2000, 2200, 2400
+                    If MyMsgBox("你已经启动了 " & Setup.Get("SystemLaunchCount") & " 次 Minecraft 啦!" & vbCrLf &
+                                "如果觉得 Minecraft 还不错,也可以考虑购买正版支持一下,毕竟开发游戏也很不容易……" & vbCrLf &
+                                "在你登录一次正版账号后,就不会再出现这个提示了。",
+                                "考虑一下正版?", "购买正版游戏", "下次一定") = 1 Then
+                        OpenWebsite("https://www.minecraft.net/store/checkout/minecraft-java-bedrock-edition-pc")
+                    End If
+            End Select
+        End If
     End Sub
 
 #End Region
@@ -204,7 +216,6 @@ NextInner:
     '登录方式
     Public Enum McLoginType
         Legacy = 0
-        Mojang = 1
         Nide = 2
         Auth = 3
         Ms = 5
@@ -304,15 +315,8 @@ NextInner:
         Public Uuid As String
         Public AccessToken As String
         Public Type As String
-        ''' <summary>
-        ''' 仅用于登录方式为 Mojang 正版时的 Refresh Login,其余时间为一个无意义的 ID(一般为玩家的 UUID)。
-        ''' </summary>
         Public ClientToken As String
         ''' <summary>
-        ''' 用于登录的邮箱。仅用于登录方式为 Mojang 正版时的 launcher_profile 更新。
-        ''' </summary>
-        Public Email As String
-        ''' <summary>
         ''' 进行微软登录时返回的 profile 信息。
         ''' </summary>
         Public ProfileJson As String
@@ -324,8 +328,6 @@ NextInner:
     Public Function McLoginName() As String
         '根据当前登录方式优先返回
         Select Case Setup.Get("LoginType")
-            Case McLoginType.Mojang
-                If Setup.Get("CacheMojangName") <> "" Then Return Setup.Get("CacheMojangName")
             Case McLoginType.Ms
                 If Setup.Get("CacheMsName") <> "" Then Return Setup.Get("CacheMsName")
             Case McLoginType.Legacy
@@ -337,7 +339,6 @@ NextInner:
         End Select
         '查找所有可能的项
         If Setup.Get("CacheMsName") <> "" Then Return Setup.Get("CacheMsName")
-        If Setup.Get("CacheMojangName") <> "" Then Return Setup.Get("CacheMojangName")
         If Setup.Get("CacheNideName") <> "" Then Return Setup.Get("CacheNideName")
         If Setup.Get("CacheAuthName") <> "" Then Return Setup.Get("CacheAuthName")
         If Setup.Get("LoginLegacyName") <> "" Then Return Setup.Get("LoginLegacyName").ToString.Split("¨")(0)
@@ -348,12 +349,6 @@ NextInner:
     ''' </summary>
     Public Function McLoginAble() As String
         Select Case Setup.Get("LoginType")
-            Case McLoginType.Mojang
-                If Setup.Get("CacheMojangAccess") = "" Then
-                    Return FrmLoginMojang.IsVaild()
-                Else
-                    Return ""
-                End If
             Case McLoginType.Ms
                 If Setup.Get("CacheMsOAuthRefresh") = "" Then
                     Return FrmLoginMs.IsVaild()
@@ -383,8 +378,6 @@ NextInner:
     ''' </summary>
     Public Function McLoginAble(LoginData As McLoginData) As String
         Select Case LoginData.Type
-            Case McLoginType.Mojang
-                Return PageLoginMojang.IsVaild(LoginData)
             Case McLoginType.Ms
                 Return PageLoginMs.IsVaild(LoginData)
             Case McLoginType.Legacy
@@ -407,12 +400,6 @@ NextInner:
             Select Case LoginType
                 Case McLoginType.Legacy
                     LoginData = PageLoginLegacy.GetLoginData()
-                Case McLoginType.Mojang
-                    If Setup.Get("CacheMojangAccess") = "" Then
-                        LoginData = PageLoginMojang.GetLoginData()
-                    Else
-                        LoginData = PageLoginMojangSkin.GetLoginData()
-                    End If
                 Case McLoginType.Ms
                     If Setup.Get("CacheMsOAuthRefresh") = "" Then
                         LoginData = PageLoginMs.GetLoginData()
@@ -445,8 +432,6 @@ NextInner:
         '获取对应加载器
         Dim Loader As LoaderBase = Nothing
         Select Case Data.Input.Type
-            Case McLoginType.Mojang
-                Loader = McLoginMojangLoader
             Case McLoginType.Ms
                 Loader = McLoginMsLoader
             Case McLoginType.Legacy
@@ -473,7 +458,6 @@ NextInner:
 #Region "分方式登录模块"
 
     '各个登录方式的主对象与输入构造
-    Public McLoginMojangLoader As New LoaderTask(Of McLoginServer, McLoginResult)("Loader Login Mojang", AddressOf McLoginServerStart) With {.ReloadTimeout = 60000}
     Public McLoginMsLoader As New LoaderTask(Of McLoginMs, McLoginResult)("Loader Login Ms", AddressOf McLoginMsStart) With {.ReloadTimeout = 300000}
     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 = 60000}
@@ -484,7 +468,7 @@ NextInner:
     Private Sub McLoginMsStart(Data As LoaderTask(Of McLoginMs, McLoginResult))
         Dim Input As McLoginMs = Data.Input
         Dim LogUsername As String = Input.UserName
-        McLaunchLog("登录方式:微软正版(" & If(LogUsername = "", "尚未登录", LogUsername) & ")")
+        McLaunchLog("登录方式:正版(" & If(LogUsername = "", "尚未登录", LogUsername) & ")")
         Data.Progress = 0.05
         '检查是否已经登录完成
         If Input.AccessToken <> "" AndAlso Not Data.IsForceRestarting Then
@@ -531,6 +515,7 @@ Relogin:
         '解锁主题
 SkipLogin:
         McLaunchLog("微软登录完成")
+        Setup.Set("HintBuy", True) '关闭正版购买提示
         Data.Progress = 0.95
         If ThemeUnlock(10, False) Then MyMsgBox("感谢你对正版游戏的支持!" & vbCrLf & "隐藏主题 跳票红 已解锁!", "提示")
     End Sub
@@ -617,11 +602,7 @@ LoginFinish:
             .Type = "Legacy"
         End With
         '将结果扩展到所有项目中
-        'Data.Output.AccessToken = Setup.Get("CacheMojangAccess") '不能优先使用缓存的 AccessToken,这会导致离线用户名设置失效
-        'If Data.Output.AccessToken.Length < 300 Then
         Data.Output.AccessToken = Data.Output.Uuid
-        'Data.Output.ClientToken = Setup.Get("CacheMojangClient")
-        'If Data.Output.AccessToken.Length <> 32 Then
         Data.Output.ClientToken = Data.Output.Uuid
         '保存启动记录
         Dim Names As New List(Of String)
@@ -649,7 +630,6 @@ LoginFinish:
             Data.Output.Name = LoginJson("selectedProfile")("name").ToString
             Data.Output.Uuid = LoginJson("selectedProfile")("id").ToString
             Data.Output.Type = "Auth"
-            Data.Output.Email = Data.Input.UserName
             McLaunchLog("登录成功(Login, HiPer)")
             '保存启动记录
             Dim Names As New List(Of String)
@@ -691,7 +671,6 @@ LoginFinish:
         Data.Output.Uuid = Uuid
         Data.Output.Name = Name
         Data.Output.Type = Data.Input.Token
-        Data.Output.Email = Data.Input.UserName
         '不更改缓存,直接结束
         McLaunchLog("验证登录成功(Validate, " & Data.Input.Token & ")")
     End Sub
@@ -716,7 +695,6 @@ LoginFinish:
         Data.Output.Uuid = LoginJson("selectedProfile")("id").ToString
         Data.Output.Name = LoginJson("selectedProfile")("name").ToString
         Data.Output.Type = Data.Input.Token
-        Data.Output.Email = Data.Input.UserName
         '保存缓存
         Setup.Set("Cache" & Data.Input.Token & "Access", Data.Output.AccessToken)
         Setup.Set("Cache" & Data.Input.Token & "Client", Data.Output.ClientToken)
@@ -737,12 +715,8 @@ LoginFinish:
                    ContentType:="application/json; charset=utf-8"))
             '检查登录结果
             If LoginJson("availableProfiles").Count = 0 Then
-                If Data.Input.Type = McLoginType.Auth Then
-                    If Data.Input.ForceReselectProfile Then Hint("你还没有创建角色,无法更换!", HintType.Critical)
-                    Throw New Exception("$你还没有创建角色,请在创建角色后再试!")
-                Else
-                    Throw New Exception("$你还没有购买 Minecraft 正版,请在购买后再试!")
-                End If
+                If Data.Input.ForceReselectProfile Then Hint("你还没有创建角色,无法更换!", HintType.Critical)
+                Throw New Exception("$你还没有创建角色,请在创建角色后再试!")
             ElseIf Data.Input.ForceReselectProfile AndAlso LoginJson("availableProfiles").Count = 1 Then
                 Hint("你的账户中只有一个角色,无法更换!", HintType.Critical)
             End If
@@ -785,7 +759,6 @@ LoginFinish:
             Data.Output.Name = SelectedName
             Data.Output.Uuid = SelectedId
             Data.Output.Type = Data.Input.Token
-            Data.Output.Email = Data.Input.UserName
             '保存缓存
             Setup.Set("Cache" & Data.Input.Token & "Access", Data.Output.AccessToken)
             Setup.Set("Cache" & Data.Input.Token & "Client", Data.Output.ClientToken)
@@ -798,27 +771,13 @@ LoginFinish:
         Catch ex As Exception
             Dim AllMessage As String = GetExceptionSummary(ex)
             Log(ex, "登录失败原始错误信息", LogLevel.Normal)
-            If AllMessage.Contains("410") AndAlso AllMessage.Contains("Migrated") Then
-                Throw New Exception("$登录失败:该 Mojang 账号已迁移至微软账号,请在上方的登录方式中选择 微软 并再次尝试登录!")
-            ElseIf AllMessage.Contains("403") Then
+            If AllMessage.Contains("403") Then
                 Select Case Data.Input.Type
                     Case McLoginType.Auth
                         Throw New Exception("$登录失败,以下为可能的原因:" & vbCrLf &
                                             " - 输入的账号或密码错误。" & vbCrLf &
                                             " - 登录尝试过于频繁,导致被暂时屏蔽。请不要操作,等待 10 分钟后再试。" & vbCrLf &
                                             " - 只注册了账号,但没有在皮肤站新建角色。")
-                    Case McLoginType.Legacy
-                        Throw
-                    Case McLoginType.Mojang
-                        If AllMessage.Contains("Invalid username or password") Then
-                            Throw New Exception("$登录失败:输入的账号或密码有误。")
-                        Else
-                            Throw New Exception("$登录尝试过于频繁,导致被 Mojang 暂时屏蔽。请不要操作,等待 10 分钟后再试。")
-                        End If
-                    Case McLoginType.Ms
-                        Throw New Exception("$登录失败,以下为可能的原因:" & vbCrLf &
-                                            " - 登录尝试过于频繁,导致被暂时屏蔽。请不要操作,等待 10 分钟后再试。" & vbCrLf &
-                                            " - 账号类别错误。如果你在使用 Mojang 账号,请将登录方式切换为 Mojang。")
                     Case McLoginType.Nide
                         Throw New Exception("$登录失败,以下为可能的原因:" & vbCrLf &
                                             " - 输入的账号或密码错误。" & vbCrLf &
@@ -1037,8 +996,8 @@ SystemBrowser:
             ElseIf Message.Contains("(404)") Then
                 Log(ex, "微软登录第 6 步汇报 404")
                 RunInNewThread(Sub()
-                                   Select Case MyMsgBox("你可能没有在 Minecraft 官网创建档案,或者没有购买 Minecraft。" & vbCrLf &
-                                            "如果你已经购买了游戏,请在官网上创建档案后再试。", "登录失败", "创建档案", "购买 Minecraft", "取消")
+                                   Select Case MyMsgBox("你可能没有在 Minecraft 官网创建档案,XBox Game Pass 已到期,或者还没有购买 Minecraft。" & vbCrLf &
+                                            "如果你确认拥有 Minecraft,请在官网上创建档案后再试。", "登录失败", "创建档案", "购买 Minecraft", "取消")
                                        Case 1
                                            OpenWebsite("https://www.minecraft.net/zh-hans/msaprofile/mygames/editprofile")
                                        Case 2
@@ -1180,6 +1139,9 @@ SystemBrowser:
             ElseIf McVersionCurrent.Version.McCodeMain >= 18 AndAlso McVersionCurrent.Version.McCodeMain < 99 AndAlso McVersionCurrent.Version.HasOptiFine Then '#305
                 '1.18+:若安装了 OptiFine,最高 Java 18
                 MaxVer = New Version(1, 18, 999, 999)
+            ElseIf McVersionCurrent.Version.McCodeMain >= 19 AndAlso McVersionCurrent.Version.McCodeMain < 99 Then
+                '1.19+:最高 Java 19
+                MaxVer = New Version(1, 19, 999, 999)
             End If
         End If
 
@@ -1708,7 +1670,7 @@ NextVersion:
         '更新 launcher_profiles.json
         Try
             '确保可用
-            If Not (McLoginLoader.Output.Type = "Mojang" OrElse McLoginLoader.Output.Type = "Microsoft") Then Exit Try
+            If Not McLoginLoader.Output.Type = "Microsoft" Then Exit Try
             McFolderLauncherProfilesJsonCreate(PathMcFolder)
             '构建需要替换的 Json 对象
             Dim ReplaceJsonString As String = "
@@ -1716,7 +1678,7 @@ NextVersion:
               ""authenticationDatabase"": {
                 ""00000111112222233333444445555566"": {
                   ""accessToken"": """ & McLoginLoader.Output.AccessToken & """,
-                  ""username"": """ & If(McLoginLoader.Output.Email, McLoginLoader.Output.Name).Replace("""", "-") & """,
+                  ""username"": """ & McLoginLoader.Output.Name.Replace("""", "-") & """,
                   ""profiles"": {
                     ""66666555554444433333222221111100"": {
                         ""displayName"": """ & McLoginLoader.Output.Name & """
@@ -1747,7 +1709,7 @@ NextVersion:
                       ""authenticationDatabase"": {
                         ""00000111112222233333444445555566"": {
                           ""accessToken"": """ & McLoginLoader.Output.AccessToken & """,
-                          ""username"": """ & If(McLoginLoader.Output.Email, McLoginLoader.Output.Name).Replace("""", "-") & """,
+                          ""username"": """ & McLoginLoader.Output.Name.Replace("""", "-") & """,
                           ""profiles"": {
                             ""66666555554444433333222221111100"": {
                                 ""displayName"": """ & McLoginLoader.Output.Name & """
@@ -1851,7 +1813,7 @@ NextVersion:
                         End If
                     Case 19
                         If McVersionCurrent.Version.McCodeSub <= 3 Then
-                            PackFormat = 10
+                            PackFormat = 9
                         Else
                             PackFormat = 12
                         End If
@@ -1989,7 +1951,7 @@ IgnoreCustomSkin:
             Try
                 CustomProcess.StartInfo.FileName = "cmd.exe"
                 CustomProcess.StartInfo.Arguments = "/c """ & CustomCommandGlobal & """"
-                CustomProcess.StartInfo.WorkingDirectory = Path
+                CustomProcess.StartInfo.WorkingDirectory = PathMcFolder
                 CustomProcess.StartInfo.UseShellExecute = False
                 CustomProcess.StartInfo.CreateNoWindow = True
                 CustomProcess.Start()
@@ -2013,7 +1975,7 @@ IgnoreCustomSkin:
             Try
                 CustomProcess.StartInfo.FileName = "cmd.exe"
                 CustomProcess.StartInfo.Arguments = "/c """ & CustomCommandVersion & """"
-                CustomProcess.StartInfo.WorkingDirectory = Path
+                CustomProcess.StartInfo.WorkingDirectory = PathMcFolder
                 CustomProcess.StartInfo.UseShellExecute = False
                 CustomProcess.StartInfo.CreateNoWindow = True
                 CustomProcess.Start()
@@ -2061,12 +2023,16 @@ IgnoreCustomSkin:
         '开始进程
         GameProcess.Start()
         McLaunchLog("已启动游戏进程:" & McLaunchJavaSelected.PathJavaw)
+        If Loader.IsAborted Then
+            McLaunchLog("由于取消启动,已强制结束游戏进程") '#1631
+            GameProcess.Kill()
+            Exit Sub
+        End If
         Loader.Output = GameProcess
         McLaunchProcess = GameProcess
 
         '进程优先级处理
         Try
-            If GameProcess.HasExited Then Exit Try '可能在启动游戏进程的同时刚好取消了启动
             GameProcess.PriorityBoostEnabled = True
             Select Case Setup.Get("LaunchArgumentPriority")
                 Case 0 '高
@@ -2177,10 +2143,8 @@ IgnoreCustomSkin:
                 Else
                     Raw = Raw.Replace("{login}", "离线")
                 End If
-            Case McLoginType.Mojang
-                Raw = Raw.Replace("{login}", "Mojang 正版")
             Case McLoginType.Ms
-                Raw = Raw.Replace("{login}", "微软正版")
+                Raw = Raw.Replace("{login}", "正版")
             Case McLoginType.Nide
                 Raw = Raw.Replace("{login}", "统一通行证")
             Case McLoginType.Auth

+ 4 - 2
Plain Craft Launcher 2/Modules/Minecraft/ModMinecraft.vb

@@ -147,7 +147,7 @@ Public Module ModMinecraft
 
 #Region "版本处理"
 
-    Public Const McVersionCacheVersion As Integer = 25
+    Public Const McVersionCacheVersion As Integer = 26
 
     Private _McVersionCurrent As McVersion
     Private _McVersionLast = 0 '为 0 以保证与 Nothing 不相同,使得 UI 显示可以正常初始化
@@ -742,8 +742,10 @@ ExitDataLoad:
                 If CustomInfo = "" Then
                     Select Case State
                         Case McVersionState.Snapshot
-                            If Version.McName.ToLower.Contains("pre") OrElse Version.McName.ToLower.Contains("rc") Then
+                            If Version.McName.ToLower.Contains("pre") Then
                                 Info = "预发布版 " & Version.McName
+                            ElseIf Version.McName.ToLower.Contains("rc") Then
+                                Info = "发布候选 " & Version.McName
                             ElseIf Version.McName.Contains("experimental") OrElse Version.McName = "pending" Then
                                 Info = "实验性快照"
                             Else

+ 2 - 2
Plain Craft Launcher 2/My Project/AssemblyInfo.vb

@@ -51,6 +51,6 @@ Imports System.Runtime.InteropServices
 ' 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
 ' 方法是按如下所示使用“*”
 
-<Assembly: AssemblyVersion("2.5.3.0")>
-<Assembly: AssemblyFileVersion("2.5.3.0")>
+<Assembly: AssemblyVersion("2.5.4.0")>
+<Assembly: AssemblyFileVersion("2.5.4.0")>
 <Assembly: NeutralResourcesLanguage("")>

+ 26 - 18
Plain Craft Launcher 2/Pages/PageDownload/ModDownloadLib.vb

@@ -3,10 +3,14 @@
 Public Module ModDownloadLib
 
     ''' <summary>
-    ''' 如果 OptiFine 与 Forge 同时开始安装,就会导致 Forge 安装失败,所以在这里添加一个锁。
+    ''' 如果 OptiFine 与 Forge 同时开始安装,就会导致 Forge 安装失败。
     ''' </summary>
     Private InstallSyncLock As New Object
     ''' <summary>
+    ''' 如果 OptiFine 与 Forge 同时复制原版 Jar,就会导致复制文件时冲突。
+    ''' </summary>
+    Private VanillaSyncLock As New Object
+    ''' <summary>
     ''' 最高的 Minecraft 大版本号,-1 代表尚未获取。
     ''' </summary>
     Public McVersionHighest As Integer = -1
@@ -548,16 +552,18 @@ Public Module ModDownloadLib
                                                                              If Task.IsAborted Then Exit Sub
                                                                              '拷贝原版文件
                                                                              If Not IsCustomFolder Then Exit Sub
-                                                                             Dim ClientName As String = New DirectoryInfo(ClientDownloadLoader.Input).Name
-                                                                             Directory.CreateDirectory(McFolder & "versions\" & DownloadInfo.Inherit)
-                                                                             If Not File.Exists(McFolder & "versions\" & DownloadInfo.Inherit & "\" & DownloadInfo.Inherit & ".json") Then
-                                                                                 CopyFile(ClientDownloadLoader.Input & ClientName & ".json",
+                                                                             SyncLock VanillaSyncLock
+                                                                                 Dim ClientName As String = New DirectoryInfo(ClientDownloadLoader.Input).Name
+                                                                                 Directory.CreateDirectory(McFolder & "versions\" & DownloadInfo.Inherit)
+                                                                                 If Not File.Exists(McFolder & "versions\" & DownloadInfo.Inherit & "\" & DownloadInfo.Inherit & ".json") Then
+                                                                                     CopyFile(ClientDownloadLoader.Input & ClientName & ".json",
                                                                                           McFolder & "versions\" & DownloadInfo.Inherit & "\" & DownloadInfo.Inherit & ".json")
-                                                                             End If
-                                                                             If Not File.Exists(McFolder & "versions\" & DownloadInfo.Inherit & "\" & DownloadInfo.Inherit & ".jar") Then
-                                                                                 CopyFile(ClientDownloadLoader.Input & ClientName & ".jar",
-                                                                                          McFolder & "versions\" & DownloadInfo.Inherit & "\" & DownloadInfo.Inherit & ".jar")
-                                                                             End If
+                                                                                 End If
+                                                                                 If Not File.Exists(McFolder & "versions\" & DownloadInfo.Inherit & "\" & DownloadInfo.Inherit & ".jar") Then
+                                                                                     CopyFile(ClientDownloadLoader.Input & ClientName & ".jar",
+                                                                                              McFolder & "versions\" & DownloadInfo.Inherit & "\" & DownloadInfo.Inherit & ".jar")
+                                                                                 End If
+                                                                             End SyncLock
                                                                          End Sub) With {.ProgressWeight = 0.1, .Show = False})
 
         '安装(新旧方式均需要原版 Jar 和 Json)
@@ -1379,14 +1385,16 @@ Public Module ModDownloadLib
                                                                              If Task.IsAborted Then Exit Sub
                                                                              '拷贝原版文件
                                                                              If Not IsCustomFolder Then Exit Sub
-                                                                             Dim ClientName As String = New DirectoryInfo(ClientDownloadLoader.Input).Name
-                                                                             Directory.CreateDirectory(McFolder & "versions\" & Inherit)
-                                                                             If Not File.Exists(McFolder & "versions\" & Inherit & "\" & Inherit & ".json") Then
-                                                                                 CopyFile(ClientDownloadLoader.Input & ClientName & ".json", McFolder & "versions\" & Inherit & "\" & Inherit & ".json")
-                                                                             End If
-                                                                             If Not File.Exists(McFolder & "versions\" & Inherit & "\" & Inherit & ".jar") Then
-                                                                                 CopyFile(ClientDownloadLoader.Input & ClientName & ".jar", McFolder & "versions\" & Inherit & "\" & Inherit & ".jar")
-                                                                             End If
+                                                                             SyncLock VanillaSyncLock
+                                                                                 Dim ClientName As String = New DirectoryInfo(ClientDownloadLoader.Input).Name
+                                                                                 Directory.CreateDirectory(McFolder & "versions\" & Inherit)
+                                                                                 If Not File.Exists(McFolder & "versions\" & Inherit & "\" & Inherit & ".json") Then
+                                                                                     CopyFile(ClientDownloadLoader.Input & ClientName & ".json", McFolder & "versions\" & Inherit & "\" & Inherit & ".json")
+                                                                                 End If
+                                                                                 If Not File.Exists(McFolder & "versions\" & Inherit & "\" & Inherit & ".jar") Then
+                                                                                     CopyFile(ClientDownloadLoader.Input & ClientName & ".jar", McFolder & "versions\" & Inherit & "\" & Inherit & ".jar")
+                                                                                 End If
+                                                                             End SyncLock
 #End Region
                                                                          End Sub) With {.ProgressWeight = 0.1, .Show = False})
             Loaders.Add(New LoaderTask(Of Boolean, Boolean)("安装 Mod 加载器(方式 A)",

+ 10 - 12
Plain Craft Launcher 2/Pages/PageLaunch/MySkin.xaml.vb

@@ -41,7 +41,7 @@
     End Sub
 
     '保存皮肤
-    Private Sub BtnSkinSave_Click(sender As Object, e As RoutedEventArgs) Handles BtnSkinSave.Click
+    Public Sub BtnSkinSave_Click() Handles BtnSkinSave.Click
         Save(Loader)
     End Sub
     Public Shared Sub Save(Loader As LoaderTask(Of EqualableList(Of String), String))
@@ -121,7 +121,7 @@
     End Sub
 
     '刷新缓存
-    Private Sub RefreshClick(sender As MyMenuItem, e As EventArgs) Handles BtnSkinRefresh.Click
+    Public Sub RefreshClick() Handles BtnSkinRefresh.Click
         RefreshCache(Loader)
     End Sub
     ''' <summary>
@@ -140,21 +140,20 @@
         Else
             RunInThread(Sub()
                             Try
-                                Hint("正在刷新皮肤……")
+                                Hint("正在刷新头像……")
                                 '清空缓存
                                 Log("[Skin] 正在清空皮肤缓存")
                                 If Directory.Exists(PathTemp & "Cache\Skin") Then DeleteDirectory(PathTemp & "Cache\Skin")
                                 If Directory.Exists(PathTemp & "Cache\Uuid") Then DeleteDirectory(PathTemp & "Cache\Uuid")
-                                IniClearCache(PathTemp & "Cache\Skin\IndexMojang.ini")
                                 IniClearCache(PathTemp & "Cache\Skin\IndexMs.ini")
                                 IniClearCache(PathTemp & "Cache\Skin\IndexNide.ini")
                                 IniClearCache(PathTemp & "Cache\Skin\IndexAuth.ini")
                                 IniClearCache(PathTemp & "Cache\Uuid\Mojang.ini")
                                 '刷新控件
-                                For Each SkinLoader In If(sender IsNot Nothing, {sender}, {PageLaunchLeft.SkinMojang, PageLaunchLeft.SkinLegacy, PageLaunchLeft.SkinMs})
+                                For Each SkinLoader In If(sender IsNot Nothing, {sender}, {PageLaunchLeft.SkinLegacy, PageLaunchLeft.SkinMs})
                                     SkinLoader.WaitForExit(IsForceRestart:=True)
                                 Next
-                                Hint("已刷新皮肤!", HintType.Finish)
+                                Hint("已刷新头像!", HintType.Finish)
                             Catch ex As Exception
                                 Log(ex, "刷新皮肤缓存失败", LogLevel.Msgbox)
                             End Try
@@ -165,15 +164,14 @@
     ''' 在更换正版皮肤后,刷新正版皮肤。
     ''' </summary>
     ''' <param name="SkinAddress">新的正版皮肤完整地址。</param>
-    Public Shared Sub ReloadCache(SkinAddress As String, IsMsLogin As Boolean)
+    Public Shared Sub ReloadCache(SkinAddress As String)
         RunInThread(Sub()
                         Try
                             '更新缓存
-                            Dim LoginType As String = If(IsMsLogin, "Ms", "Mojang")
-                            WriteIni(PathTemp & "Cache\Skin\Index" & LoginType & ".ini", Setup.Get("Cache" & LoginType & "Uuid"), SkinAddress)
-                            Log(String.Format("[Skin] 已写入皮肤地址缓存 {0} -> {1}", Setup.Get("Cache" & LoginType & "Uuid"), SkinAddress))
+                            WriteIni(PathTemp & "Cache\Skin\IndexMs.ini", Setup.Get("CacheMsUuid"), SkinAddress)
+                            Log(String.Format("[Skin] 已写入皮肤地址缓存 {0} -> {1}", Setup.Get("CacheMsUuid"), SkinAddress))
                             '刷新控件
-                            For Each SkinLoader In If(IsMsLogin, {PageLaunchLeft.SkinMs, PageLaunchLeft.SkinLegacy}, {PageLaunchLeft.SkinMojang, PageLaunchLeft.SkinLegacy})
+                            For Each SkinLoader In {PageLaunchLeft.SkinMs, PageLaunchLeft.SkinLegacy}
                                 SkinLoader.WaitForExit(IsForceRestart:=True)
                             Next
                             '完成提示
@@ -198,7 +196,7 @@
         End Set
     End Property
     Private IsChanging As Boolean = False
-    Private Sub BtnSkinCape_Click(sender As Object, e As RoutedEventArgs) Handles BtnSkinCape.Click
+    Public Sub BtnSkinCape_Click() Handles BtnSkinCape.Click
         '检查条件,获取新披风
         If IsChanging Then
             Hint("正在更改披风中,请稍候!")

+ 4 - 6
Plain Craft Launcher 2/Pages/PageLaunch/PageLaunchLeft.xaml

@@ -33,7 +33,7 @@
                     <Path Name="PathTypeOne" HorizontalAlignment="Left" RenderTransformOrigin="0.5,0.5" Margin="12,0,0,0" Stretch="Uniform" Fill="{DynamicResource ColorBrush3}" MaxHeight="16" MaxWidth="16" VerticalAlignment="Center"
                           Data="">
                         <Path.RenderTransform>
-                            <ScaleTransform ScaleX="1.4" ScaleY="1.4" />
+                            <ScaleTransform ScaleX="1.2" ScaleY="1.2" />
                         </Path.RenderTransform>
                     </Path>
                     <TextBlock Name="LabTypeOne" Text="" FontSize="14" VerticalAlignment="Center" Grid.Column="1" Foreground="{DynamicResource ColorBrush3}" Margin="15,0,12,0" Grid.ColumnSpan="2" SnapsToDevicePixels="False" UseLayoutRounding="False" />
@@ -48,12 +48,10 @@
                 <ColumnDefinition Width="Auto" />
                 <ColumnDefinition Width="1*" />
             </Grid.ColumnDefinitions>
-            <local:MyRadioButton x:Name="RadioLoginType1" Tag="LoginType/1" Grid.Column="1" Grid.ColumnSpan="1" ColorType="Highlight" Text="Mojang" Margin="4,0"
-                             LogoScale="1.1" Logo="M9.183,18.967c-0.109-2.239,1.336-5.119,3.92-4.96c3.657-0.027,7.319-0.044,10.977,0.005	c3.712,0.214,6.596,2.759,9.652,4.533c0.181-1.697-0.197-3.717,1.237-4.982c1.899,2.091,3.143,4.894,5.677,6.334	c1.577,0.805,2.973-0.668,4.221-1.44c1.55,2.305,2.108,5.075,2.622,7.752c0.657,3.438,0.947,6.925,1.111,10.413	c-1.734-0.733-3.355-1.708-4.971-2.671c-1.396-4.933-5.349-8.656-9.723-11.059c-3.46-1.817-7.752-2.185-11.338-0.52	c-3.761,1.593-6.285,5.666-5.891,9.75c0.121,4.577,3.17,8.765,7.391,10.456c7.746,3.285,16.407,2.234,24.521,1.243	c0.454,2.315-1.511,4.527-3.695,4.889c-10.577,0.038-21.148-0.011-31.725,0.022c-2.217,0.279-4.079-1.879-3.964-4.008	C9.167,36.141,9.216,27.556,9.183,18.967z M40.114,8.09c0.294-0.801,0.872-1.417,1.542-1.924c1.379,2.589,2.742,5.482,2.311,8.491	c-0.332,2.54-4.42,2.507-5.052,0.163C38.349,12.527,39.209,10.178,40.114,8.09z M0,53 l0.1,0 z" Checked="True" />
-            <local:MyRadioButton x:Name="RadioLoginType5" Tag="LoginType/5" Grid.Column="2" Grid.ColumnSpan="1" ColorType="Highlight" Text="微软" Margin="4,0"
-                             LogoScale="0.9" Logo="M481.882353 826.428235V527.661176l402.371765 2.409412v356.592941l-402.371765-60.235294z m0-628.85647l402.371765-60.235294v330.089411H481.882353V197.571765zM137.336471 525.251765h289.129411v293.948235l-289.129411-45.778824V525.251765z m0-55.416471V248.169412l289.129411-45.778824v265.035294h-289.129411z" />
+            <local:MyRadioButton x:Name="RadioLoginType5" Tag="LoginType/5" Grid.Column="2" Grid.ColumnSpan="1" ColorType="Highlight" Text="正版" Margin="4,0"
+                             LogoScale="1" Logo="M511.488256 95.184408c35.310345 22.516742 95.184408 55.78011 167.34033 84.437781 75.738131 29.681159 148.405797 40.93953 191.392304 45.033483v353.615193c0 73.691154-50.662669 164.781609-136.123938 244.101949C649.65917 901.181409 558.568716 942.12094 512 942.12094c-46.568716 0-137.65917-40.93953-222.096952-119.748126C204.441779 742.54073 153.77911 651.450275 153.77911 577.247376v-353.103448c42.474763-4.093953 116.165917-15.352324 191.904048-45.545227 75.226387-30.192904 133.565217-63.456272 165.805098-83.414293M512 0c-4.093953 0-8.187906 1.535232-11.258371 3.582209l-14.84058 10.234882c-1.023488 0.511744-67.550225 47.592204-170.410794 88.531735-100.813593 39.916042-198.556722 41.963018-199.58021 41.963018l-25.075462 0.511744c-10.746627 0.511744-18.934533 8.187906-18.934533 18.422789v414.000999c0 216.97951 286.064968 446.24088 440.09995 446.24088s440.09995-229.261369 440.09995-445.729136V163.758121c0-10.234883-8.69965-18.422789-18.934533-18.422789l-24.563718-0.511744c-1.023488 0-98.766617-2.046977-199.58021-41.963018-103.372314-40.93953-170.410795-88.01999-170.922538-88.531734L523.258371 3.582209c-3.070465-2.558721-7.164418-3.582209-11.258371-3.582209z M743.308346 410.930535l-260.477761 260.477761c-15.864068 15.864068-41.963018 15.864068-57.827087 0l-144.823588-144.823588c-15.864068-15.864068-15.864068-41.963018 0-57.827087 8.187906-8.187906 18.422789-11.770115 29.169415-11.770115 10.234883 0 20.981509 4.093953 29.169416 11.770115l115.654173 115.654173L685.993003 352.591704c15.864068-15.864068 41.963018-15.864068 57.827087 0 15.352324 16.375812 15.352324 42.474763-0.511744 58.338831z" />
             <local:MyRadioButton x:Name="RadioLoginType0" Tag="LoginType/0" Grid.Column="3" Grid.ColumnSpan="1" ColorType="Highlight" Text="离线"  Margin="4,0"
-                             LogoScale="0.95" Logo="M660.338 528.065c63.61-46.825 105.131-121.964 105.131-206.83 0-141.7-115.29-256.987-256.997-256.987-141.706 0-256.998 115.288-256.998 256.987 0 85.901 42.52 161.887 107.456 208.562-152.1 59.92-260.185 207.961-260.185 381.077 0 21.276 17.253 38.53 38.53 38.53 21.278 0 38.53-17.254 38.53-38.53 0-183.426 149.232-332.671 332.667-332.671 1.589 0 3.113-0.207 4.694-0.244 0.8 0.056 1.553 0.244 2.362 0.244 183.434 0 332.664 149.245 332.664 332.671 0 21.276 17.255 38.53 38.533 38.53 21.277 0 38.53-17.254 38.53-38.53 0-174.885-110.354-324.13-264.917-382.809z m-331.803-206.83c0-99.22 80.72-179.927 179.935-179.927s179.937 80.708 179.937 179.927c0 99.203-80.721 179.91-179.937 179.91s-179.935-80.708-179.935-179.91z" />
+                             LogoScale="0.85" Logo="M533.293176 788.841412a60.235294 60.235294 0 1 1 85.202824 85.202823l-42.616471 42.586353c-129.355294 129.385412-339.124706 129.385412-468.510117 0-129.385412-129.385412-129.385412-339.124706 0-468.510117l42.586353-42.616471a60.235294 60.235294 0 1 1 85.202823 85.202824l-42.61647 42.586352a210.823529 210.823529 0 1 0 298.164706 298.164706l42.586352-42.61647z m255.548236-255.548236l42.61647-42.586352a210.823529 210.823529 0 1 0-298.164706-298.164706l-42.586352 42.61647a60.235294 60.235294 0 1 1-85.202824-85.202823l42.616471-42.586353c129.355294-129.385412 339.124706-129.385412 468.510117 0 129.385412 129.385412 129.385412 339.124706 0 468.510117l-42.586353 42.616471a60.235294 60.235294 0 1 1-85.202823-85.202824zM192.542118 192.542118a60.235294 60.235294 0 0 1 85.202823 0l553.712941 553.712941a60.235294 60.235294 0 0 1-85.202823 85.202823L192.542118 277.744941a60.235294 60.235294 0 0 1 0-85.202823z" />
             <!--<local:MyRadioButton x:Name="RadioLoginType2" Tag="LoginType/2" Grid.Column="4" ColorType="Highlight" Text="统一通行证" Visibility="Collapsed"
                              LogoScale="1.1" Logo="M834.5 684.1c-31.2-70.4-98.9-120.9-179.1-127.3 63.5-8.5 112.6-63 112.6-128.8 0-71.8-58.2-130-130-130s-130 58.2-130 130c0 65.9 49 120.3 112.6 128.8-80.2 6.4-148 57-179.1 127.3-8.7 19.7 6 42 27.6 42 12.1 0 22.7-7.5 27.7-18.5 24.3-53.9 78.5-91.5 141.3-91.5s117 37.6 141.3 91.5c5 11.1 15.6 18.5 27.7 18.5 21.4 0 36.1-22.3 27.4-42zM567.9 427.9c0-38.6 31.4-70 70-70s70 31.4 70 70-31.4 70-70 70-70-31.4-70-70zM460.3 347.9H216.9c-16.6 0-30 13.4-30 30s13.4 30 30 30h243.3c16.6 0 30-13.4 30-30 0.1-16.5-13.4-30-29.9-30zM367.4 459.6H216.9c-16.6 0-30 13.4-30 30s13.4 30 30 30h150.4c16.6 0 30-13.4 30-30 0.1-16.6-13.4-30-29.9-30zM297.4 571.2H217c-16.6 0-30 13.4-30 30s13.4 30 30 30h80.4c16.6 0 30-13.4 30-30 0-16.5-13.5-30-30-30zM900 236v552H124V236h776m0-60H124c-33.1 0-60 26.9-60 60v552c0 33.1 26.9 60 60 60h776c33.1 0 60-26.9 60-60V236c0-33.1-26.9-60-60-60z" />-->
         </Grid>

+ 14 - 88
Plain Craft Launcher 2/Pages/PageLaunch/PageLaunchLeft.xaml.vb

@@ -67,7 +67,7 @@
 
         '改变页面
         Dim LoginType As McLoginType = Setup.Get("LoginType")
-        If LoginType = McLoginType.Legacy OrElse LoginType = McLoginType.Mojang OrElse LoginType = McLoginType.Ms Then CType(FindName("RadioLoginType" & LoginType), MyRadioButton).Checked = True
+        If LoginType = McLoginType.Legacy OrElse LoginType = McLoginType.Ms Then CType(FindName("RadioLoginType" & LoginType), MyRadioButton).Checked = True
         RefreshPage(False, False)
 
         AniControlEnabled -= 1
@@ -117,8 +117,6 @@
 
     Private Enum PageType
         None
-        Mojang
-        MojangSkin
         Legacy
         Nide
         NideSkin
@@ -134,12 +132,6 @@
 
     Private Function PageGet(Type As PageType)
         Select Case Type
-            Case PageType.Mojang
-                If IsNothing(FrmLoginMojang) Then FrmLoginMojang = New PageLoginMojang
-                Return FrmLoginMojang
-            Case PageType.MojangSkin
-                If IsNothing(FrmLoginMojangSkin) Then FrmLoginMojangSkin = New PageLoginMojangSkin
-                Return FrmLoginMojangSkin
             Case PageType.Legacy
                 If IsNothing(FrmLoginLegacy) Then FrmLoginLegacy = New PageLoginLegacy
                 Return FrmLoginLegacy
@@ -171,7 +163,7 @@
     ''' <param name="Type">新页面的种类。</param>
     ''' <param name="Anim">是否显示动画。</param>
     Private Function PageChange(Type As PageType, Anim As Boolean)
-        Dim PageNew As Object = FrmLoginMojang '初始化一个东西,避免在执行时出现异常导致雪崩
+        Dim PageNew As Object = FrmLoginMs '初始化一个东西,避免在执行时出现异常导致雪崩
         Try
 
 #Region "确定更改的页面实例并实例化"
@@ -232,14 +224,7 @@
         Select Case LoginPageType
             Case 0 '正版或离线
 UnknownType:
-                If RadioLoginType1.Checked Then
-                    If Setup.Get("CacheMojangAccess") = "" Then
-                        Type = PageType.Mojang
-                    Else
-                        Type = PageType.MojangSkin
-                    End If
-                    Setup.Set("LoginType", McLoginType.Mojang)
-                ElseIf RadioLoginType5.Checked Then
+                If RadioLoginType5.Checked Then
                     If Setup.Get("CacheMsAccess") = "" Then
                         Type = PageType.Ms
                     Else
@@ -252,28 +237,19 @@ UnknownType:
                 End If
                 PanType.Visibility = Visibility.Visible
                 PanTypeOne.Visibility = Visibility.Collapsed
-                RadioLoginType1.Visibility = Visibility.Visible
                 RadioLoginType5.Visibility = Visibility.Visible
                 RadioLoginType0.Visibility = Visibility.Visible
             Case 1 '仅正版
-                If RadioLoginType1.Checked Then
-                    If Setup.Get("CacheMojangAccess") = "" Then
-                        Type = PageType.Mojang
-                    Else
-                        Type = PageType.MojangSkin
-                    End If
-                    Setup.Set("LoginType", McLoginType.Mojang)
+                If Setup.Get("CacheMsAccess") = "" Then
+                    Type = PageType.Ms
                 Else
-                    If Setup.Get("CacheMsAccess") = "" Then
-                        Type = PageType.Ms
-                    Else
-                        Type = PageType.MsSkin
-                    End If
-                    Setup.Set("LoginType", McLoginType.Ms)
+                    Type = PageType.MsSkin
                 End If
-                PanType.Visibility = Visibility.Visible
-                PanTypeOne.Visibility = Visibility.Collapsed
-                RadioLoginType1.Visibility = Visibility.Visible
+                Setup.Set("LoginType", McLoginType.Ms)
+                PanType.Visibility = Visibility.Collapsed
+                PanTypeOne.Visibility = Visibility.Visible
+                PathTypeOne.Data = (New GeometryConverter).ConvertFromString(Logo.IconButtonMs)
+                LabTypeOne.Text = "正版登录"
                 RadioLoginType5.Visibility = Visibility.Visible
                 RadioLoginType0.Visibility = Visibility.Collapsed
             Case 2 '仅离线
@@ -316,7 +292,7 @@ UnknownType:
         Dim Control As MyRadioButton = FindName("RadioLoginType" & Setup.Get("LoginType"))
         If Control IsNot Nothing Then Control.Checked = True
     End Sub
-    Private Sub RadioLoginType_Change(sender As Object, raiseByMouse As Boolean) Handles RadioLoginType0.Check, RadioLoginType1.Check, RadioLoginType5.Check
+    Private Sub RadioLoginType_Change(sender As Object, raiseByMouse As Boolean) Handles RadioLoginType0.Check, RadioLoginType5.Check
         If raiseByMouse Then RefreshPage(True, True)
     End Sub
 
@@ -324,54 +300,6 @@ UnknownType:
 
 #Region "皮肤"
 
-    'Mojang 正版皮肤
-    Public Shared SkinMojang As New LoaderTask(Of EqualableList(Of String), String)("Loader Skin Mojang", AddressOf SkinMojangLoad, AddressOf SkinMojangInput, ThreadPriority.AboveNormal)
-    Private Shared Function SkinMojangInput() As EqualableList(Of String)
-        '获取名称
-        Return New EqualableList(Of String) From {Setup.Get("CacheMojangName"), Setup.Get("CacheMojangUuid")}
-    End Function
-    Private Shared Sub SkinMojangLoad(Data As LoaderTask(Of EqualableList(Of String), String))
-        '清空已有皮肤
-        '如果在输入时清空皮肤,若输入内容一样则不会执行 Load 方法,导致皮肤不被加载
-        RunInUi(Sub() If FrmLoginMojangSkin IsNot Nothing AndAlso FrmLoginMojangSkin.Skin IsNot Nothing Then FrmLoginMojangSkin.Skin.Clear())
-        '获取 Url
-        Dim UserName As String = Data.Input(0)
-        Dim Uuid As String = Data.Input(1)
-        If UserName = "" Then
-            Data.Output = PathImage & "Skins/" & McSkinSex(McLoginLegacyUuid(UserName)) & ".png"
-            Log("[Minecraft] 获取正版皮肤失败,ID 为空")
-            GoTo Finish
-        End If
-        Try
-            Dim Result As String = McSkinGetAddress(Uuid, "Mojang")
-            If Data.IsAborted Then Throw New ThreadInterruptedException("当前任务已取消:" & UserName)
-            Result = McSkinDownload(Result)
-            If Data.IsAborted Then Throw New ThreadInterruptedException("当前任务已取消:" & UserName)
-            Data.Output = Result
-        Catch ex As Exception
-            If ex.GetType.Name = "ThreadInterruptedException" Then
-                Data.Output = ""
-                Exit Sub
-            ElseIf GetExceptionSummary(ex).Contains("429") Then
-                Data.Output = PathImage & "Skins/" & McSkinSex(McLoginLegacyUuid(UserName)) & ".png"
-                Log("[Minecraft] 获取正版皮肤失败(" & UserName & "):获取皮肤太过频繁,请 5 分钟后再试!", LogLevel.Hint)
-            ElseIf GetExceptionSummary(ex).Contains("未设置自定义皮肤") Then
-                Data.Output = PathImage & "Skins/" & McSkinSex(McLoginLegacyUuid(UserName)) & ".png"
-                Log("[Minecraft] 用户未设置自定义皮肤,跳过皮肤加载")
-            Else
-                Data.Output = PathImage & "Skins/" & McSkinSex(McLoginLegacyUuid(UserName)) & ".png"
-                Log(ex, "获取正版皮肤失败(" & UserName & ")", LogLevel.Hint)
-            End If
-        End Try
-Finish:
-        '刷新显示
-        If FrmLoginMojangSkin IsNot Nothing Then
-            RunInUi(AddressOf FrmLoginMojangSkin.Skin.Load)
-        ElseIf Not Data.IsAborted Then '如果已经中断,Input 也被清空,就不会再次刷新
-            Data.Input = Nothing '清空输入,因为皮肤实际上没有被渲染,如果不清空切换到页面的 Start 会由于输入相同而不渲染
-        End If
-    End Sub
-
     '微软正版皮肤
     Public Shared SkinMs As New LoaderTask(Of EqualableList(Of String), String)("Loader Skin Ms", AddressOf SkinMsLoad, AddressOf SkinMsInput, ThreadPriority.AboveNormal)
     Private Shared Function SkinMsInput() As EqualableList(Of String)
@@ -592,7 +520,7 @@ Finish:
 
     '全部皮肤加载器
     '需要放在其中元素的后面,否则会因为它提前被加载而莫名其妙变成 Nothing
-    Public Shared SkinLoaders As New List(Of LoaderTask(Of EqualableList(Of String), String)) From {SkinMojang, SkinMs, SkinLegacy, SkinNide, SkinAuth}
+    Public Shared SkinLoaders As New List(Of LoaderTask(Of EqualableList(Of String), String)) From {SkinMs, SkinLegacy, SkinNide, SkinAuth}
 
 #End Region
 
@@ -713,10 +641,8 @@ ExitRefresh:
                 Else
                     LabLaunchingMethod.Text = "离线登录"
                 End If
-            Case McLoginType.Mojang
-                LabLaunchingMethod.Text = "Mojang 正版登录"
             Case McLoginType.Ms
-                LabLaunchingMethod.Text = "微软正版登录"
+                LabLaunchingMethod.Text = "正版登录"
             Case McLoginType.Nide
                 LabLaunchingMethod.Text = "统一通行证"
             Case McLoginType.Auth

+ 0 - 6
Plain Craft Launcher 2/Pages/PageLaunch/PageLaunchRight.xaml.vb

@@ -99,10 +99,4 @@
         Init()
     End Sub
 
-    Public Shared Sub StartMigration()
-        MyMsgBox("在迁移过程中,你可能需要设置你的档案信息,此时请注意让年龄大于 18 岁,否则可能导致无法登录!" & vbCrLf &
-                 "在迁移完成后,请在上方选择 微软 登录方式而非 Mojang。", "迁移提示", "继续", ForceWait:=True)
-        OpenWebsite("https://www.minecraft.net/zh-hans/account-security")
-    End Sub
-
 End Class

+ 0 - 26
Plain Craft Launcher 2/Pages/PageLaunch/PageLoginMojang.xaml

@@ -1,26 +0,0 @@
-<Grid x:Class="PageLoginMojang" Tag="False"
-      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
-      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
-      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
-      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
-      xmlns:local="clr-namespace:PCL"
-      mc:Ignorable="d" d:DesignWidth="302.4" Margin="0,0,0,-2">
-    <Grid.RowDefinitions>
-        <RowDefinition Height="Auto" />
-        <RowDefinition Height="Auto" />
-        <RowDefinition Height="10" />
-        <RowDefinition Height="Auto" />
-        <RowDefinition Height="Auto" />
-    </Grid.RowDefinitions>
-    <Grid.ColumnDefinitions>
-        <ColumnDefinition />
-        <ColumnDefinition Width="224" />
-    </Grid.ColumnDefinitions>
-    <local:MyHint Text="Mojang 账号现已无法进入正版服务器,请点击此处开始账号迁移!" Grid.ColumnSpan="2" Margin="0,0,0,15" x:Name="HintMigration" />
-    <local:MyComboBox Grid.Row="1" Grid.Column="1" IsEditable="True" Height="28" x:Name="ComboName" />
-    <TextBlock Grid.Row="1" Text="邮箱" VerticalAlignment="Center" />
-    <PasswordBox Grid.Row="3" Grid.Column="1" x:Name="TextPass" />
-    <TextBlock Text="密码" Grid.Row="3" VerticalAlignment="Center" />
-    <local:MyCheckBox x:Name="CheckRemember" Tag="LoginRemember" Height="20" Margin="-1,12,80,0" Text="记住密码" Grid.Row="4" Grid.Column="1" Grid.ColumnSpan="2" />
-    <local:MyTextButton Margin="0,12,2,0" x:Name="BtnLink" Content="购买正版" Grid.Row="4" HorizontalAlignment="Right" Grid.Column="1" Padding="20,0,0,0" HorizontalContentAlignment="Right" VerticalContentAlignment="Center" FontSize="13" />
-</Grid>

+ 0 - 84
Plain Craft Launcher 2/Pages/PageLaunch/PageLoginMojang.xaml.vb

@@ -1,84 +0,0 @@
-Public Class PageLoginMojang
-
-    Private IsFirstLoad As Boolean = True
-    ''' <summary>
-    ''' 刷新页面显示的所有信息。
-    ''' </summary>
-    Public Sub Reload(KeepInput As Boolean)
-        '记住密码
-        CheckRemember.Checked = Setup.Get("LoginRemember")
-        If KeepInput AndAlso Not IsFirstLoad Then '避免第一次就以 KeepInput 的方式加载,导致文本框里没东西
-            '保留输入,只刷新下拉框列表
-            Dim Input As String = ComboName.Text
-            ComboName.ItemsSource = If(Setup.Get("LoginMojangEmail") = "", Nothing, Setup.Get("LoginMojangEmail").ToString.Split("¨"))
-            ComboName.Text = Input
-        Else
-            '不保留输入,刷新列表后自动选择第一项
-            If Setup.Get("LoginMojangEmail") = "" Then
-                ComboName.ItemsSource = Nothing
-            Else
-                ComboName.ItemsSource = Setup.Get("LoginMojangEmail").ToString.Split("¨")
-                ComboName.Text = Setup.Get("LoginMojangEmail").ToString.Split("¨")(0)
-                If Setup.Get("LoginRemember") Then TextPass.Password = Setup.Get("LoginMojangPass").ToString.Split("¨")(0).Trim
-            End If
-        End If
-        IsFirstLoad = False
-    End Sub
-    ''' <summary>
-    ''' 获取当前页面的登录信息。
-    ''' </summary>
-    Public Shared Function GetLoginData() As McLoginServer
-        If FrmLoginMojang Is Nothing Then
-            Return New McLoginServer(McLoginType.Mojang) With {.BaseUrl = "https://authserver.mojang.com", .Token = "Mojang", .UserName = "", .Password = "", .Type = McLoginType.Mojang, .Description = "Mojang 正版"}
-        Else
-            Return New McLoginServer(McLoginType.Mojang) With {.BaseUrl = "https://authserver.mojang.com", .Token = "Mojang", .UserName = If(FrmLoginMojang.ComboName.Text, "").Replace("¨", "").Trim(), .Password = If(FrmLoginMojang.TextPass.Password, "").Replace("¨", "").Trim(), .Type = McLoginType.Mojang, .Description = "Mojang 正版"}
-        End If
-    End Function
-    ''' <summary>
-    ''' 当前页面的登录信息是否有效。
-    ''' </summary>
-    Public Shared Function IsVaild(LoginData As McLoginServer) As String
-        If LoginData.UserName = "" Then Return "邮箱不能为空!"
-        If Not LoginData.UserName.Contains("@") Then Return "邮箱格式错误!"
-        If LoginData.Password = "" Then Return "密码不能为空!"
-        Return ""
-    End Function
-    Public Function IsVaild() As String
-        Return IsVaild(GetLoginData())
-    End Function
-
-    '保存输入信息
-    Private Sub ComboMojangName_TextChanged(sender As Object, e As TextChangedEventArgs) Handles ComboName.TextChanged
-        If sender.Text = "" Then TextPass.Password = ""
-        If AniControlEnabled = 0 Then Setup.Set("CacheMojangAccess", "") '迫使其不进行 Validate
-    End Sub
-    Private Sub TextMojangPass_PasswordChanged(sender As Object, e As RoutedEventArgs) Handles TextPass.PasswordChanged
-        If AniControlEnabled = 0 Then Setup.Set("CacheMojangAccess", "")
-    End Sub
-    Private Sub ComboMojangName_SelectionChanged(sender As MyComboBox, e As SelectionChangedEventArgs) Handles ComboName.SelectionChanged
-        If sender.SelectedIndex = -1 OrElse Not Setup.Get("LoginRemember") Then
-            TextPass.Password = ""
-        Else
-            TextPass.Password = Setup.Get("LoginMojangPass").ToString.Split("¨")(sender.SelectedIndex).Trim
-        End If
-    End Sub
-    Private Sub CheckRememberChange(sender As MyCheckBox, e As Object) Handles CheckRemember.Change
-        If AniControlEnabled = 0 Then Setup.Set(sender.Tag, sender.Checked)
-    End Sub
-
-    '链接处理
-    Private Sub InputChanged() Handles ComboName.TextChanged, TextPass.PasswordChanged
-        BtnLink.Content = If(ComboName.Text = "" AndAlso TextPass.Password = "", "购买正版", "找回密码")
-    End Sub
-    Private Sub BtnMojang_Click(sender As Object, e As EventArgs) Handles BtnLink.Click
-        If BtnLink.Content = "购买正版" Then
-            OpenWebsite("https://www.minecraft.net/zh-hans/store/checkout/minecraft-java-bedrock-edition-pc")
-        Else
-            OpenWebsite("https://www.minecraft.net/zh-hans/password/forgot")
-        End If
-    End Sub
-    Private Sub HintMigration_Click() Handles HintMigration.MouseLeftButtonUp
-        PageLaunchRight.StartMigration()
-    End Sub
-
-End Class

+ 0 - 29
Plain Craft Launcher 2/Pages/PageLaunch/PageLoginMojangSkin.xaml

@@ -1,29 +0,0 @@
-<Grid x:Class="PageLoginMojangSkin" Tag="True"
-      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
-      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
-      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
-      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
-      xmlns:local="clr-namespace:PCL"
-      mc:Ignorable="d" d:DesignWidth="297.6" Margin="0,19,0,5">
-    <Grid Margin="0,56,0,0" Background="{StaticResource ColorBrushSemiTransparent}" Name="PanData">
-        <Grid.ColumnDefinitions>
-            <ColumnDefinition Width="34" />
-            <ColumnDefinition />
-            <ColumnDefinition Width="34" />
-        </Grid.ColumnDefinitions>
-        <Grid.RowDefinitions>
-            <RowDefinition Height="Auto" />
-            <RowDefinition Height="19" />
-            <RowDefinition Height="Auto" MinHeight="30" />
-            <RowDefinition Height="19" />
-        </Grid.RowDefinitions>
-        <local:MyHint Text="Mojang 账号现已无法进入正版服务器,请点击此处开始账号迁移!" Grid.ColumnSpan="3" Margin="0,0,0,15" x:Name="HintMigration" />
-        <StackPanel Grid.Column="1" Grid.Row="2" VerticalAlignment="Center">
-            <TextBlock Name="TextName" Text="加载中" Margin="8,0" FontSize="14" HorizontalAlignment="Center" TextTrimming="CharacterEllipsis" />
-            <TextBlock Name="TextEmail" Text="加载中" Margin="8,4,8,0" FontSize="12" HorizontalAlignment="Center" TextTrimming="CharacterEllipsis" Foreground="{DynamicResource ColorBrushGray3}" />
-        </StackPanel>
-        <local:MyIconButton ToolTip="更改密码" Grid.Row="2" Height="14" Opacity="0" x:Name="BtnEdit" ToolTipService.Placement="Center" ToolTipService.VerticalOffset="32" ToolTipService.InitialShowDelay="50" ToolTipService.ShowDuration="1000000" Grid.Column="0" HorizontalAlignment="Center" Logo="F1 M 53.2929,21.2929L 54.7071,22.7071C 56.4645,24.4645 56.4645,27.3137 54.7071,29.0711L 52.2323,31.5459L 44.4541,23.7677L 46.9289,21.2929C 48.6863,19.5355 51.5355,19.5355 53.2929,21.2929 Z M 31.7262,52.052L 23.948,44.2738L 43.0399,25.182L 50.818,32.9601L 31.7262,52.052 Z M 23.2409,47.1023L 28.8977,52.7591L 21.0463,54.9537L 23.2409,47.1023 Z" Margin="8,0,0,0" VerticalAlignment="Center" />
-        <local:MyIconButton ToolTip="退出登录" Grid.Row="2" Height="14" Opacity="0" x:Name="BtnExit" ToolTipService.Placement="Center" ToolTipService.VerticalOffset="32" ToolTipService.InitialShowDelay="50" ToolTipService.ShowDuration="1000000" Grid.Column="2" HorizontalAlignment="Center" Logo="F1 M 51.0071,19.0027L 51.0071,27.0038L 48.0067,27.0038L 48.0067,22.0031L 25.0035,22.0031L 25.0035,54.0075L 48.0067,54.0075L 48.0067,49.0068L 51.0071,49.0068L 51.0071,57.008L 22.1698,57.008L 22.0031,19.0027L 51.0071,19.0027 Z M 30.0042,35.0049L 45.2563,35.0049L 37.005,28.0039L 47.0066,28.0039L 58.5082,38.0053L 47.0066,48.0067L 37.005,48.0067L 45.2563,41.0057L 30.0042,41.0057L 30.0042,35.0049 Z" Margin="0,0,8,0" VerticalAlignment="Center" />
-    </Grid>
-    <local:MySkin HorizontalAlignment="Center" VerticalAlignment="Top" x:Name="Skin" HasCape="False" />
-</Grid>

+ 0 - 117
Plain Craft Launcher 2/Pages/PageLaunch/PageLoginMojangSkin.xaml.vb

@@ -1,117 +0,0 @@
-Public Class PageLoginMojangSkin
-
-    Public Sub New()
-        InitializeComponent()
-        Skin.Loader = PageLaunchLeft.SkinMojang
-    End Sub
-    Private Sub PageLoginLegacy_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
-        Skin.Loader.Start()
-    End Sub
-
-    ''' <summary>
-    ''' 刷新页面显示的所有信息。
-    ''' </summary>
-    Public Sub Reload(KeepInput As Boolean)
-        TextName.Text = Setup.Get("CacheMojangName")
-        TextEmail.Text = Setup.Get("CacheMojangUsername")
-        TextEmail.Visibility = If(Setup.Get("UiLauncherEmail"), Visibility.Collapsed, Visibility.Visible)
-        '皮肤在 Loaded 加载
-    End Sub
-    ''' <summary>
-    ''' 获取当前页面的登录信息。
-    ''' </summary>
-    Public Shared Function GetLoginData() As McLoginServer
-        Return New McLoginServer(McLoginType.Mojang) With {.BaseUrl = "https://authserver.mojang.com", .Token = "Mojang", .UserName = Setup.Get("CacheMojangUsername"), .Password = Setup.Get("CacheMojangPass"), .Description = "Mojang 正版", .Type = McLoginType.Mojang}
-    End Function
-
-    Private Sub PageLoginMojangSkin_MouseEnter(sender As Object, e As MouseEventArgs) Handles PanData.MouseEnter
-        AniStart({
-                 AaOpacity(BtnEdit, 1 - BtnEdit.Opacity, 80),
-                 AaHeight(BtnEdit, 25.5 - BtnEdit.Height, 140,, New AniEaseOutFluent),
-                 AaHeight(BtnEdit, -1.5, 50, 140, New AniEaseInFluent),
-                 AaOpacity(BtnExit, 1 - BtnExit.Opacity, 80),
-                 AaHeight(BtnExit, 25.5 - BtnExit.Height, 140,, New AniEaseOutFluent),
-                 AaHeight(BtnExit, -1.5, 50, 140, New AniEaseInFluent)
-        }, "PageLoginMojangSkin Button")
-    End Sub
-    Private Sub PageLoginMojangSkin_MouseLeave(sender As Object, e As MouseEventArgs) Handles PanData.MouseLeave
-        AniStart({
-                 AaOpacity(BtnEdit, -BtnEdit.Opacity, 120,, New AniEaseOutFluent),
-                 AaHeight(BtnEdit, 14 - BtnEdit.Height, 120,, New AniEaseInFluent),
-                 AaOpacity(BtnExit, -BtnExit.Opacity, 120,, New AniEaseOutFluent),
-                 AaHeight(BtnExit, 14 - BtnExit.Height, 120,, New AniEaseInFluent)
-        }, "PageLoginMojangSkin Button")
-    End Sub
-
-    Private Sub BtnEdit_Click(sender As Object, e As EventArgs) Handles BtnEdit.Click
-        Select Case MyMsgBox("你希望通过哪种途径更改密码?" & vbCrLf & "首次通过个人档案修改密码可能需要验证你的密保问题。", "更改密码", "个人档案", "密保邮箱", "取消")
-            Case 1
-                '个人档案
-                OpenWebsite("https://www.minecraft.net/zh-hans/msaprofile")
-            Case 2
-                '密保邮箱
-                OpenWebsite("https://account.mojang.com/password")
-            Case 3
-                '取消
-        End Select
-    End Sub
-    Private Sub BtnExit_Click() Handles BtnExit.Click
-        Setup.Set("CacheMojangAccess", "")
-        FrmLaunchLeft.RefreshPage(False, True)
-    End Sub
-
-    Private Sub Skin_Click(sender As Object, e As MouseButtonEventArgs) Handles Skin.Click
-        If McLoginLoader.State = LoadState.Failed Then
-            Hint("登录失败,无法更改皮肤!", HintType.Critical)
-            Exit Sub
-        End If
-        Dim SkinInfo As McSkinInfo = McSkinSelect()
-        If Not SkinInfo.IsVaild Then Exit Sub
-        Hint("正在更改皮肤……")
-        RunInNewThread(Async Sub()
-                           Try
-
-                               If McLoginLoader.State = LoadState.Loading Then McLoginLoader.WaitForExit() '等待登录结束
-                               Dim AccessToken As String = Setup.Get("CacheMojangAccess")
-                               Dim Uuid As String = Setup.Get("CacheMojangUuid")
-
-                               Dim Client As New Net.Http.HttpClient With {.Timeout = New TimeSpan(0, 0, 10)}
-                               Client.DefaultRequestHeaders.Authorization = New Net.Http.Headers.AuthenticationHeaderValue("Bearer", AccessToken)
-                               Client.DefaultRequestHeaders.Accept.Add(New Net.Http.Headers.MediaTypeWithQualityHeaderValue("*/*"))
-                               Client.DefaultRequestHeaders.UserAgent.Add(New Net.Http.Headers.ProductInfoHeaderValue("MojangSharp", "0.1"))
-                               Dim Contents As New Net.Http.MultipartFormDataContent From {
-                                      {New Net.Http.StringContent(If(SkinInfo.IsSlim, "slim", "")), "model"},
-                                      {New Net.Http.ByteArrayContent(File.ReadAllBytes(SkinInfo.LocalFile)), "file", GetFileNameFromPath(SkinInfo.LocalFile)}
-                                  }
-                               Dim Result As String = Await (Await Client.PutAsync(New Uri("https://api.mojang.com/user/profile/" & Uuid & "/skin"), Contents)).Content.ReadAsStringAsync
-                               If RegexCheck(Result, "^[0-9a-f]{59,64}$") Then
-                                   MySkin.ReloadCache("http://textures.minecraft.net/texture/" & Result, False)
-                               ElseIf Result.ToLower.Contains("ip not secured") Then
-                                   If MyMsgBox("首次操作需要在官网验证密保问题。" & vbCrLf & "验证完成后,你即可使用 PCL 更改皮肤,且无需再次验证。", "验证密保问题", "开始验证", "取消") = 1 Then
-                                       OpenWebsite("https://www.minecraft.net/zh-hans/profile/skin")
-                                   End If
-                               ElseIf Result.Contains("request requires user authentication") Then
-                                   Hint("正在重新登录,请稍后再次尝试更改皮肤!")
-                                   RunInUi(Sub()
-                                               BtnExit_Click()
-                                               If String.IsNullOrEmpty(McLoginAble()) Then McLoginLoader.Start()
-                                           End Sub)
-                               ElseIf Result.Contains("""errorMessage""") Then
-                                   Hint("更改皮肤失败:" & GetJson(Result)("errorMessage"), HintType.Critical)
-                               Else
-                                   Throw New Exception("未知错误(" & Result & ")")
-                               End If
-                           Catch ex As Exception
-                               If ex.GetType.Equals(GetType(Tasks.TaskCanceledException)) Then
-                                   Hint("更改皮肤失败:与 Mojang 皮肤服务器的连接超时,请检查你的网络是否通畅!", HintType.Critical)
-                               Else
-                                   Log(ex, "更改皮肤失败", LogLevel.Hint)
-                               End If
-                           End Try
-                       End Sub, "Mojang Skin Upload")
-    End Sub
-    Private Sub HintMigration_Click() Handles HintMigration.MouseLeftButtonUp
-        PageLaunchRight.StartMigration()
-    End Sub
-
-End Class

+ 9 - 5
Plain Craft Launcher 2/Pages/PageLaunch/PageLoginMs.xaml

@@ -6,11 +6,15 @@
       xmlns:local="clr-namespace:PCL"
       mc:Ignorable="d" d:DesignWidth="302.4" Margin="0,0,0,-2">
     <StackPanel x:Name="PanEmpty">
-        <Path Data="M535.94 571.76l291.060 0.36v286.020l-291.060-39.24v-247.14M499.94 535.76v314.64l363.060 48.96v-363.060l-363.060-0.54zM197 571.4l218.52 0.36v226.98l-218.52-30.42v-196.92M161 535.4v264.42l290.52 40.32v-304.2l-290.52-0.54zM827 166.76v285.12l-291.060-0.36v-239.76l291.060-45M863 124.64l-363.060 56.16v306.54l363.060 0.54v-363.24zM415.52 231.2v219.96l-218.52-0.18v-189.36l218.52-30.42M451.52 189.8l-290.52 40.5v256.68l290.52 0.36v-297.54z"
-          Fill="{DynamicResource ColorBrush1}" Opacity="0.7"
+        <Path Data="M660.338 528.065c63.61-46.825 105.131-121.964 105.131-206.83 0-141.7-115.29-256.987-256.997-256.987-141.706 0-256.998 115.288-256.998 256.987 0 85.901 42.52 161.887 107.456 208.562-152.1 59.92-260.185 207.961-260.185 381.077 0 21.276 17.253 38.53 38.53 38.53 21.278 0 38.53-17.254 38.53-38.53 0-183.426 149.232-332.671 332.667-332.671 1.589 0 3.113-0.207 4.694-0.244 0.8 0.056 1.553 0.244 2.362 0.244 183.434 0 332.664 149.245 332.664 332.671 0 21.276 17.255 38.53 38.533 38.53 21.277 0 38.53-17.254 38.53-38.53 0-174.885-110.354-324.13-264.917-382.809z m-331.803-206.83c0-99.22 80.72-179.927 179.935-179.927s179.937 80.708 179.937 179.927c0 99.203-80.721 179.91-179.937 179.91s-179.935-80.708-179.935-179.91z"
+          Fill="{DynamicResource ColorBrush1}" Opacity="0.3"
           Width="40" Stretch="Uniform"/>
-        <TextBlock Text="    无账号信息&#xa;点击 添加账号 按钮以登录" HorizontalAlignment="Center" Margin="0,15,0,25"
-               Foreground="{DynamicResource ColorBrush1}" Opacity="0.7" />
-        <local:MyButton Text="添加账号" x:Name="BtnLogin" ColorType="Highlight" Height="35" HorizontalAlignment="Center" Width="150" />
+        <TextBlock Text="没有已登录的账号" HorizontalAlignment="Center" Margin="0,15,0,40"
+               Foreground="{DynamicResource ColorBrush1}" Opacity="0.5" />
+        <local:MyButton Text="登录" x:Name="BtnLogin" ColorType="Highlight" Height="35" HorizontalAlignment="Center" Width="150" />
+        <StackPanel Orientation="Horizontal" Margin="0,16,0,0" HorizontalAlignment="Center" Opacity="0.7">
+            <local:MyTextButton Text="购买正版" Margin="0,0,15,0" EventType="打开网页" EventData="https://www.minecraft.net/store/checkout/minecraft-java-bedrock-edition-pc" />
+            <local:MyTextButton Text="老账号迁移" Margin="15,0,0,0" x:Name="BtnMigration" />
+        </StackPanel>
     </StackPanel>
 </StackPanel>

+ 6 - 1
Plain Craft Launcher 2/Pages/PageLaunch/PageLoginMs.xaml.vb

@@ -16,7 +16,7 @@
     ''' </summary>
     Public Shared Function IsVaild(LoginData As McLoginMs) As String
         If LoginData.OAuthRefreshToken = "" Then
-            Return "请在登录账号后再继续!"
+            Return "请在登录账号后再启动游戏!"
         Else
             Return ""
         End If
@@ -61,5 +61,10 @@
                            End Try
                        End Sub, "Ms Login")
     End Sub
+    '账号迁移入口
+    Private Sub BtnMigration_Click(sender As Object, e As EventArgs) Handles BtnMigration.Click
+        MyMsgBox("在迁移过程中,你可能需要设置你的档案信息,此时请注意让年龄大于 18 岁,否则可能导致无法登录!", "迁移提示", "继续", ForceWait:=True)
+        OpenWebsite("https://www.minecraft.net/zh-hans/account-security")
+    End Sub
 
 End Class

+ 35 - 12
Plain Craft Launcher 2/Pages/PageLaunch/PageLoginMsSkin.xaml

@@ -4,21 +4,44 @@
       xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
       xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
       xmlns:local="clr-namespace:PCL"
-      mc:Ignorable="d" d:DesignWidth="297.6" Margin="0,19,0,5">
-    <Grid Margin="0,56,0,0" Background="{StaticResource ColorBrushSemiTransparent}" Name="PanData">
-        <Grid.ColumnDefinitions>
-            <ColumnDefinition Width="34" />
-            <ColumnDefinition />
-            <ColumnDefinition Width="34" />
-        </Grid.ColumnDefinitions>
+      mc:Ignorable="d" d:DesignWidth="297.6" Margin="0,60,0,5">
+    <Grid Background="{StaticResource ColorBrushSemiTransparent}" Name="PanData">
         <Grid.RowDefinitions>
-            <RowDefinition Height="19" />
+            <RowDefinition Height="75" />
             <RowDefinition Height="Auto" MinHeight="30" />
             <RowDefinition Height="19" />
+            <RowDefinition Height="24" />
+            <RowDefinition Height="19" />
         </Grid.RowDefinitions>
-        <TextBlock Grid.Column="1" Grid.Row="1" VerticalAlignment="Center" Name="TextName" Text="加载中" Margin="8,0" FontSize="14" HorizontalAlignment="Center" TextTrimming="CharacterEllipsis" />
-        <local:MyIconButton ToolTip="更改密码" Grid.Row="1" Height="14" Opacity="0" x:Name="BtnEdit" ToolTipService.Placement="Center" ToolTipService.VerticalOffset="32" ToolTipService.InitialShowDelay="50" ToolTipService.ShowDuration="1000000" Grid.Column="0" HorizontalAlignment="Center" Logo="F1 M 53.2929,21.2929L 54.7071,22.7071C 56.4645,24.4645 56.4645,27.3137 54.7071,29.0711L 52.2323,31.5459L 44.4541,23.7677L 46.9289,21.2929C 48.6863,19.5355 51.5355,19.5355 53.2929,21.2929 Z M 31.7262,52.052L 23.948,44.2738L 43.0399,25.182L 50.818,32.9601L 31.7262,52.052 Z M 23.2409,47.1023L 28.8977,52.7591L 21.0463,54.9537L 23.2409,47.1023 Z" Margin="8,0,0,0" VerticalAlignment="Center" />
-        <local:MyIconButton ToolTip="退出登录" Grid.Row="1" Height="14" Opacity="0" x:Name="BtnExit" ToolTipService.Placement="Center" ToolTipService.VerticalOffset="32" ToolTipService.InitialShowDelay="50" ToolTipService.ShowDuration="1000000" Grid.Column="2" HorizontalAlignment="Center" Logo="F1 M 51.0071,19.0027L 51.0071,27.0038L 48.0067,27.0038L 48.0067,22.0031L 25.0035,22.0031L 25.0035,54.0075L 48.0067,54.0075L 48.0067,49.0068L 51.0071,49.0068L 51.0071,57.008L 22.1698,57.008L 22.0031,19.0027L 51.0071,19.0027 Z M 30.0042,35.0049L 45.2563,35.0049L 37.005,28.0039L 47.0066,28.0039L 58.5082,38.0053L 47.0066,48.0067L 37.005,48.0067L 45.2563,41.0057L 30.0042,41.0057L 30.0042,35.0049 Z" Margin="0,0,8,0" VerticalAlignment="Center" />
+        <TextBlock Grid.Row="1" VerticalAlignment="Center" Name="TextName" Text="加载中" Margin="8,0" FontSize="17" HorizontalAlignment="Center" TextTrimming="CharacterEllipsis" />
+        <StackPanel Orientation="Horizontal" Grid.Row="3" HorizontalAlignment="Center" x:Name="PanButtons" Opacity="0">
+            <local:MyIconButton Height="24" Margin="0,0.5,15,0"  x:Name="BtnSkin"
+                                ToolTip="皮肤/披风" ToolTipService.Placement="Center" ToolTipService.VerticalOffset="40" ToolTipService.InitialShowDelay="50" ToolTipService.ShowDuration="1000000" 
+                                LogoScale="1.08" Logo="M764.0003 0.076794a215.433442 215.433442 0 0 0-76.282279 13.950954l-9.06172 3.686123c-49.148314 20.734445-88.518161 30.53851-115.498538 30.53851-27.031573 0-66.478214-9.855261-116.676049-31.050471a217.583681 217.583681 0 0 0-72.186586-16.766743l-9.138515-0.307177-3.839712-0.051196-8.626553 0.307177-4.223683 0.281579A160.755943 160.755943 0 0 0 250.477214 45.385396l-219.32435 212.438467a102.392321 102.392321 0 0 0-11.263156 134.210734l106.360023 144.552359 3.378947 4.351674a102.469115 102.469115 0 0 0 112.810739 31.690423l5.657176-2.175837V883.210559a140.789441 140.789441 0 0 0 140.789441 140.789441h372.170487l5.657175-0.102392a140.789441 140.789441 0 0 0 135.132266-140.687049l-0.025599-318.6705 1.177512 0.716747a102.392321 102.392321 0 0 0 141.941355-44.233483l70.906682-144.39877a102.392321 102.392321 0 0 0-20.657651-118.647101L875.86391 45.385396A160.730345 160.730345 0 0 0 764.0003 0.076794z m-357.349199 111.454041C468.444867 137.615279 520.562558 150.644702 563.157763 150.644702c42.492813 0 94.584906-12.978227 156.199485-38.985876A112.580356 112.580356 0 0 1 764.0003 102.469115c15.154063 0 29.693773 5.887558 40.598555 16.433967L1023.923206 331.495138l-70.906682 144.39877-93.023423-65.684674a38.39712 38.39712 0 0 0-60.53946 31.383247V883.210559a38.39712 38.39712 0 0 1-38.39712 38.39712H388.886034a38.39712 38.39712 0 0 1-38.397121-38.39712V445.176212a38.39712 38.39712 0 0 0-61.691373-30.487314l-80.070795 61.20501L102.392321 331.341549l219.32435-212.438467a58.363623 58.363623 0 0 1 35.581332-16.229183L362.110442 102.469115l6.322726 0.179186a115.191361 115.191361 0 0 1 38.217933 8.882534z">
+                <local:MyIconButton.ContextMenu>
+                    <ContextMenu Closed="HidePanel" HorizontalOffset="10" VerticalOffset="18">
+                        <local:MyMenuItem Click="BtnSkinEdit_Click" Header="修改皮肤"/>
+                        <local:MyMenuItem Click="BtnSkinSave_Click" Header="保存皮肤"/>
+                        <local:MyMenuItem Click="BtnSkinRefresh_Click" Header="刷新头像"/>
+                        <Separator />
+                        <local:MyMenuItem Click="BtnSkinCape_Click" Header="修改披风"/>
+                    </ContextMenu>
+                </local:MyIconButton.ContextMenu>
+            </local:MyIconButton>
+            <local:MyIconButton Height="24" Margin="0,0,16,0" x:Name="BtnEdit"
+                                ToolTip="账号信息" ToolTipService.Placement="Center" ToolTipService.VerticalOffset="40" ToolTipService.InitialShowDelay="50" ToolTipService.ShowDuration="1000000" 
+                                LogoScale="1.1" Logo="M462.336 924.891429L73.142857 950.857143l25.965714-389.193143 467.017143-467.017143a73.398857 73.398857 0 0 1 103.789715 0l259.437714 259.437714a73.398857 73.398857 0 0 1 0 103.789715l-467.017143 467.017143z m155.684571-778.349715L202.861714 561.664l259.474286 259.474286L877.458286 405.942857 618.057143 146.541714zM151.003429 873.033143l233.508571-25.965714-207.579429-207.579429-25.965714 233.545143z m544.841142-492.982857l51.894858 51.894857-233.508572 233.508571-51.931428-51.894857 233.545142-233.508571z">
+                <local:MyIconButton.ContextMenu>
+                    <ContextMenu Closed="HidePanel" HorizontalOffset="10" VerticalOffset="18">
+                        <local:MyMenuItem Click="BtnEditPassword_Click" Header="修改密码" />
+                        <local:MyMenuItem Click="BtnEditName_Click" Header="修改玩家名" />
+                    </ContextMenu>
+                </local:MyIconButton.ContextMenu>
+            </local:MyIconButton>
+            <local:MyIconButton Height="24" x:Name="BtnExit" Margin="0,0,0,0"
+                                ToolTip="退出登录" ToolTipService.Placement="Center" ToolTipService.VerticalOffset="40" ToolTipService.InitialShowDelay="50" ToolTipService.ShowDuration="1000000" 
+                                Logo="M533.333333 64a21.333333 21.333333 0 0 1 21.333334 21.333333v42.666667a21.333333 21.333333 0 0 1-21.333334 21.333333H170.666667v725.333334h362.666666a21.333333 21.333333 0 0 1 21.333334 21.333333v42.666667a21.333333 21.333333 0 0 1-21.333334 21.333333H170.666667a85.333333 85.333333 0 0 1-85.226667-81.066667L85.333333 874.666667V149.333333a85.333333 85.333333 0 0 1 81.066667-85.226666L170.666667 64h362.666666z m194.581334 219.584l183.168 183.168a64 64 0 0 1 2.88 87.424l-2.88 3.072-183.168 183.168a21.333333 21.333333 0 0 1-30.165334 0l-30.165333-30.165333a21.333333 21.333333 0 0 1 0-30.165334L792.96 554.666667H362.666667a21.333333 21.333333 0 0 1-21.333334-21.333334v-42.666666a21.333333 21.333333 0 0 1 21.333334-21.333334h430.293333l-125.376-125.418666a21.333333 21.333333 0 0 1 0-30.165334l30.165333-30.165333a21.333333 21.333333 0 0 1 30.165334 0z" />
+        </StackPanel>
     </Grid>
-    <local:MySkin HorizontalAlignment="Center" VerticalAlignment="Top" x:Name="Skin" HasCape="True" />
+    <local:MySkin HorizontalAlignment="Center" VerticalAlignment="Top" x:Name="Skin" HasCape="True" IsHitTestVisible="False" />
 </Grid>

+ 47 - 19
Plain Craft Launcher 2/Pages/PageLaunch/PageLoginMsSkin.xaml.vb

@@ -26,28 +26,29 @@
         End If
     End Function
 
-    Private Sub PageLoginMsSkin_MouseEnter(sender As Object, e As MouseEventArgs) Handles PanData.MouseEnter
-        AniStart({
-                 AaOpacity(BtnEdit, 1 - BtnEdit.Opacity, 80),
-                 AaHeight(BtnEdit, 25.5 - BtnEdit.Height, 140,, New AniEaseOutFluent),
-                 AaHeight(BtnEdit, -1.5, 50, 140, New AniEaseInFluent),
-                 AaOpacity(BtnExit, 1 - BtnExit.Opacity, 80),
-                 AaHeight(BtnExit, 25.5 - BtnExit.Height, 140,, New AniEaseOutFluent),
-                 AaHeight(BtnExit, -1.5, 50, 140, New AniEaseInFluent)
-        }, "PageLoginMsSkin Button")
+#Region "下边栏其他内容"
+
+    '显示/隐藏控制
+    Private Sub ShowPanel(sender As Object, e As MouseEventArgs) Handles PanData.MouseEnter
+        AniStart(AaOpacity(PanButtons, 1 - PanButtons.Opacity, 120), "PageLoginMsSkin Button")
     End Sub
-    Private Sub PageLoginMsSkin_MouseLeave(sender As Object, e As MouseEventArgs) Handles PanData.MouseLeave
-        AniStart({
-                 AaOpacity(BtnEdit, -BtnEdit.Opacity, 120,, New AniEaseOutFluent),
-                 AaHeight(BtnEdit, 14 - BtnEdit.Height, 120,, New AniEaseInFluent),
-                 AaOpacity(BtnExit, -BtnExit.Opacity, 120,, New AniEaseOutFluent),
-                 AaHeight(BtnExit, 14 - BtnExit.Height, 120,, New AniEaseInFluent)
-        }, "PageLoginMsSkin Button")
+    Public Sub HidePanel() Handles PanData.MouseLeave
+        If BtnEdit.ContextMenu.IsOpen OrElse BtnSkin.ContextMenu.IsOpen OrElse PanData.IsMouseOver Then Exit Sub
+        AniStart(AaOpacity(PanButtons, -PanButtons.Opacity, 120), "PageLoginMsSkin Button")
     End Sub
 
+    '修改账号信息
     Private Sub BtnEdit_Click(sender As Object, e As EventArgs) Handles BtnEdit.Click
-        OpenWebsite("https://account.microsoft.com/security")
+        BtnEdit.ContextMenu.IsOpen = True
+    End Sub
+    Public Sub BtnEditPassword_Click(sender As Object, e As RoutedEventArgs)
+        OpenWebsite("https://account.live.com/password/Change")
     End Sub
+    Public Sub BtnEditName_Click(sender As Object, e As RoutedEventArgs)
+        OpenWebsite("https://www.minecraft.net/en-us/msaprofile/mygames/editprofile")
+    End Sub
+
+    '退出登录
     Private Sub BtnExit_Click() Handles BtnExit.Click
         Setup.Set("CacheMsOAuthRefresh", "")
         Setup.Set("CacheMsAccess", "")
@@ -58,8 +59,18 @@
         FrmLaunchLeft.RefreshPage(False, True)
     End Sub
 
+#End Region
+
+#Region "皮肤/披风"
+
+    '展开
+    Private Sub BtnSkin_Click(sender As Object, e As RoutedEventArgs) Handles BtnSkin.Click
+        BtnSkin.ContextMenu.IsOpen = True
+    End Sub
+
+    '修改皮肤
     Private IsChanging As Boolean = False
-    Private Sub Skin_Click(sender As Object, e As MouseButtonEventArgs) Handles Skin.Click
+    Public Sub BtnSkinEdit_Click(sender As Object, e As RoutedEventArgs)
         '检查条件,获取新皮肤
         If IsChanging Then
             Hint("正在更改皮肤中,请稍候!")
@@ -103,7 +114,7 @@ Retry:
                                Dim ResultJson As JObject = GetJson(Result)
                                For Each Skin As JObject In ResultJson("skins")
                                    If Skin("state").ToString = "ACTIVE" Then
-                                       MySkin.ReloadCache(Skin("url"), True)
+                                       MySkin.ReloadCache(Skin("url"))
                                        Exit Sub
                                    End If
                                Next
@@ -120,4 +131,21 @@ Retry:
                        End Sub, "Ms Skin Upload")
     End Sub
 
+    '保存皮肤
+    Public Sub BtnSkinSave_Click(sender As Object, e As RoutedEventArgs)
+        Skin.BtnSkinSave_Click()
+    End Sub
+
+    '刷新头像
+    Public Sub BtnSkinRefresh_Click(sender As Object, e As RoutedEventArgs)
+        Skin.RefreshClick()
+    End Sub
+
+    '修改披风
+    Public Sub BtnSkinCape_Click(sender As Object, e As RoutedEventArgs)
+        Skin.BtnSkinCape_Click()
+    End Sub
+
+#End Region
+
 End Class

+ 4 - 4
Plain Craft Launcher 2/Pages/PageVersion/PageVersionLeft.xaml.vb

@@ -7,11 +7,11 @@
 
     Public Sub RefreshModDisabled() Handles Me.Loaded
         If Version IsNot Nothing AndAlso Version.Modable Then
-            ItemMod.Height = 36
-            ItemModDisabled.Height = 0
+            ItemMod.Visibility = Visibility.Visible
+            ItemModDisabled.Visibility = Visibility.Collapsed
         Else
-            ItemMod.Height = 0
-            ItemModDisabled.Height = 36
+            ItemMod.Visibility = Visibility.Collapsed
+            ItemModDisabled.Visibility = Visibility.Visible
         End If
     End Sub
 

+ 0 - 14
Plain Craft Launcher 2/Plain Craft Launcher 2.vbproj

@@ -313,12 +313,6 @@
     <Compile Include="Pages\PageLaunch\PageLoginLegacy.xaml.vb">
       <DependentUpon>PageLoginLegacy.xaml</DependentUpon>
     </Compile>
-    <Compile Include="Pages\PageLaunch\PageLoginMojang.xaml.vb">
-      <DependentUpon>PageLoginMojang.xaml</DependentUpon>
-    </Compile>
-    <Compile Include="Pages\PageLaunch\PageLoginMojangSkin.xaml.vb">
-      <DependentUpon>PageLoginMojangSkin.xaml</DependentUpon>
-    </Compile>
     <Compile Include="Pages\PageSelectRight.xaml.vb">
       <DependentUpon>PageSelectRight.xaml</DependentUpon>
     </Compile>
@@ -570,14 +564,6 @@
       <SubType>Designer</SubType>
       <Generator>MSBuild:Compile</Generator>
     </Page>
-    <Page Include="Pages\PageLaunch\PageLoginMojang.xaml">
-      <SubType>Designer</SubType>
-      <Generator>MSBuild:Compile</Generator>
-    </Page>
-    <Page Include="Pages\PageLaunch\PageLoginMojangSkin.xaml">
-      <SubType>Designer</SubType>
-      <Generator>MSBuild:Compile</Generator>
-    </Page>
     <Page Include="Pages\PageSelectRight.xaml">
       <Generator>MSBuild:Compile</Generator>
       <SubType>Designer</SubType>