龙腾猫跃 3 years ago
parent
commit
fd7049ceed
26 changed files with 249 additions and 539 deletions
  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 & "Email", Join(Dict.Keys.ToArray, "¨"))
             Setup.Set("Login" & Token & "Pass", Join(Dict.Values.ToArray, "¨"))
             Setup.Set("Login" & Token & "Pass", Join(Dict.Values.ToArray, "¨"))
             Select Case Token
             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"
                 Case "Nide"
                     FrmLoginNide.ComboName.ItemsSource = Dict.Keys
                     FrmLoginNide.ComboName.ItemsSource = Dict.Keys
                     FrmLoginNide.ComboName.Text = If(Dict.Keys.Count > 0, Dict.Keys(0), "")
                     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)
                     Dim AnimList As New List(Of AniData)
                     Select Case Theme
                     Select Case Theme
                         Case Themes.Color
                         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)
                             PanBack.Background = New MyColor(0, 255, 255, 255)
                         Case Themes.White
                         Case Themes.White
                             AnimList.Add(AaColor(Path, Shape.FillProperty, "ColorBrush8", AnimationColorOut))
                             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 RealOffset As Double
     Private Sub MyScrollViewer_PreviewMouseWheel(sender As Object, e As MouseWheelEventArgs) Handles Me.PreviewMouseWheel
     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
         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)
         PerformVerticalOffsetDelta(-e.Delta)
         e.Handled = True
         e.Handled = True
     End Sub
     End Sub

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

@@ -95,7 +95,13 @@ Public Class FormMain
         '3:BUG+ IMP* FEAT-
         '3:BUG+ IMP* FEAT-
         '2:BUG* IMP-
         '2:BUG* IMP-
         '1:BUG-
         '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)(4, "在缺少 Java 时会自动下载所需的 Java"))
             FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "添加 CurseForge / Modrinth 来源筛选"))
             FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "添加 CurseForge / Modrinth 来源筛选"))
             FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "为下载管理和音乐播放按钮添加进度条"))
             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 "声明"
 #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
 #If BETA Then
     Public Const VersionCode As Integer = 286 'Release
     Public Const VersionCode As Integer = 286 'Release
 #Else
 #Else
-    Public Const VersionCode As Integer = 288 'Snapshot
+    Public Const VersionCode As Integer = 289 'Snapshot
 #End If
 #End If
     '自动生成的版本信息
     '自动生成的版本信息
     Public Const VersionDisplayName As String = VersionBranchName & " " & VersionBaseName
     Public Const VersionDisplayName As String = VersionBranchName & " " & VersionBaseName
@@ -158,6 +158,10 @@ Public Module ModBase
         ''' </summary>
         ''' </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"
         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>
         ''' <summary>
+        ''' 图标按钮,微软,0.9x
+        ''' </summary>
+        Public Const IconButtonMs As String = "M0,0h5v5h-5ZM6,0h5v5h-5v-5ZM0,6h5v5h-5v-5ZM6,6h5v5h-5v-5Z"
+        ''' <summary>
         ''' 图标,音符,1x
         ''' 图标,音符,1x
         ''' </summary>
         ''' </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"
         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)
             File.Copy(FromPath, ToPath, True)
         Catch ex As Exception
         Catch ex As Exception
-            Throw New Exception("复制文件出错:" & FromPath & " -> " & ToPath, ex)
+            Throw New Exception("复制文件出错:" & FromPath & " → " & ToPath, ex)
         End Try
         End Try
     End Sub
     End Sub
     ''' <summary>
     ''' <summary>
@@ -1240,7 +1244,19 @@ Re:
             Directory.CreateDirectory(DestDirectory)
             Directory.CreateDirectory(DestDirectory)
             If CompressFilePath.EndsWith(".zip") OrElse CompressFilePath.EndsWith(".jar") OrElse CompressFilePath.EndsWith(".mrpack") Then
             If CompressFilePath.EndsWith(".zip") OrElse CompressFilePath.EndsWith(".jar") OrElse CompressFilePath.EndsWith(".mrpack") Then
                 '以 zip 方式解压
                 '以 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
                 Return True
             ElseIf CompressFilePath.EndsWith(".gz") Then
             ElseIf CompressFilePath.EndsWith(".gz") Then
                 '以 gz 方式解压
                 '以 gz 方式解压

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

@@ -1,5 +1,7 @@
 '一个万能的自动图片类型转换工具类
 '一个万能的自动图片类型转换工具类
 
 
+Imports System.Drawing.Imaging
+
 Public Class MyBitmap
 Public Class MyBitmap
 
 
     ''' <summary>
     ''' <summary>
@@ -29,7 +31,7 @@ Public Class MyBitmap
         Dim bitmapData = Bitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format32bppArgb)
         Dim bitmapData = Bitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format32bppArgb)
         Try
         Try
             Dim size = rect.Width * rect.Height * 4
             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
         Finally
             Bitmap.UnlockBits(bitmapData)
             Bitmap.UnlockBits(bitmapData)
         End Try
         End Try
@@ -109,8 +111,10 @@ Public Class MyBitmap
     Public Function Rotation(angle As Double) As System.Drawing.Bitmap
     Public Function Rotation(angle As Double) As System.Drawing.Bitmap
         Dim img As System.Drawing.Image = Me.Pic
         Dim img As System.Drawing.Image = Me.Pic
         Dim bitSize As Single = img.Width
         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)
         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.TranslateTransform(bitSize / 2, bitSize / 2)
             g.RotateTransform(angle)
             g.RotateTransform(angle)
             g.TranslateTransform(-bitSize / 2, -bitSize / 2)
             g.TranslateTransform(-bitSize / 2, -bitSize / 2)
@@ -124,9 +128,11 @@ Public Class MyBitmap
     ''' </summary>
     ''' </summary>
     Public Function Clip(rect As System.Drawing.Rectangle) As System.Drawing.Bitmap
     Public Function Clip(rect As System.Drawing.Rectangle) As System.Drawing.Bitmap
         Dim img As System.Drawing.Image = Pic
         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)
         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
         End Using
         Return bmp
         Return bmp
     End Function
     End Function

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

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

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

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

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

@@ -3,10 +3,14 @@
 Public Module ModDownloadLib
 Public Module ModDownloadLib
 
 
     ''' <summary>
     ''' <summary>
-    ''' 如果 OptiFine 与 Forge 同时开始安装,就会导致 Forge 安装失败,所以在这里添加一个锁。
+    ''' 如果 OptiFine 与 Forge 同时开始安装,就会导致 Forge 安装失败。
     ''' </summary>
     ''' </summary>
     Private InstallSyncLock As New Object
     Private InstallSyncLock As New Object
     ''' <summary>
     ''' <summary>
+    ''' 如果 OptiFine 与 Forge 同时复制原版 Jar,就会导致复制文件时冲突。
+    ''' </summary>
+    Private VanillaSyncLock As New Object
+    ''' <summary>
     ''' 最高的 Minecraft 大版本号,-1 代表尚未获取。
     ''' 最高的 Minecraft 大版本号,-1 代表尚未获取。
     ''' </summary>
     ''' </summary>
     Public McVersionHighest As Integer = -1
     Public McVersionHighest As Integer = -1
@@ -548,16 +552,18 @@ Public Module ModDownloadLib
                                                                              If Task.IsAborted Then Exit Sub
                                                                              If Task.IsAborted Then Exit Sub
                                                                              '拷贝原版文件
                                                                              '拷贝原版文件
                                                                              If Not IsCustomFolder 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")
                                                                                           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})
                                                                          End Sub) With {.ProgressWeight = 0.1, .Show = False})
 
 
         '安装(新旧方式均需要原版 Jar 和 Json)
         '安装(新旧方式均需要原版 Jar 和 Json)
@@ -1379,14 +1385,16 @@ Public Module ModDownloadLib
                                                                              If Task.IsAborted Then Exit Sub
                                                                              If Task.IsAborted Then Exit Sub
                                                                              '拷贝原版文件
                                                                              '拷贝原版文件
                                                                              If Not IsCustomFolder 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 Region
                                                                          End Sub) With {.ProgressWeight = 0.1, .Show = False})
                                                                          End Sub) With {.ProgressWeight = 0.1, .Show = False})
             Loaders.Add(New LoaderTask(Of Boolean, Boolean)("安装 Mod 加载器(方式 A)",
             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
     End Sub
 
 
     '保存皮肤
     '保存皮肤
-    Private Sub BtnSkinSave_Click(sender As Object, e As RoutedEventArgs) Handles BtnSkinSave.Click
+    Public Sub BtnSkinSave_Click() Handles BtnSkinSave.Click
         Save(Loader)
         Save(Loader)
     End Sub
     End Sub
     Public Shared Sub Save(Loader As LoaderTask(Of EqualableList(Of String), String))
     Public Shared Sub Save(Loader As LoaderTask(Of EqualableList(Of String), String))
@@ -121,7 +121,7 @@
     End Sub
     End Sub
 
 
     '刷新缓存
     '刷新缓存
-    Private Sub RefreshClick(sender As MyMenuItem, e As EventArgs) Handles BtnSkinRefresh.Click
+    Public Sub RefreshClick() Handles BtnSkinRefresh.Click
         RefreshCache(Loader)
         RefreshCache(Loader)
     End Sub
     End Sub
     ''' <summary>
     ''' <summary>
@@ -140,21 +140,20 @@
         Else
         Else
             RunInThread(Sub()
             RunInThread(Sub()
                             Try
                             Try
-                                Hint("正在刷新皮肤……")
+                                Hint("正在刷新头像……")
                                 '清空缓存
                                 '清空缓存
                                 Log("[Skin] 正在清空皮肤缓存")
                                 Log("[Skin] 正在清空皮肤缓存")
                                 If Directory.Exists(PathTemp & "Cache\Skin") Then DeleteDirectory(PathTemp & "Cache\Skin")
                                 If Directory.Exists(PathTemp & "Cache\Skin") Then DeleteDirectory(PathTemp & "Cache\Skin")
                                 If Directory.Exists(PathTemp & "Cache\Uuid") Then DeleteDirectory(PathTemp & "Cache\Uuid")
                                 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\IndexMs.ini")
                                 IniClearCache(PathTemp & "Cache\Skin\IndexNide.ini")
                                 IniClearCache(PathTemp & "Cache\Skin\IndexNide.ini")
                                 IniClearCache(PathTemp & "Cache\Skin\IndexAuth.ini")
                                 IniClearCache(PathTemp & "Cache\Skin\IndexAuth.ini")
                                 IniClearCache(PathTemp & "Cache\Uuid\Mojang.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)
                                     SkinLoader.WaitForExit(IsForceRestart:=True)
                                 Next
                                 Next
-                                Hint("已刷新皮肤!", HintType.Finish)
+                                Hint("已刷新头像!", HintType.Finish)
                             Catch ex As Exception
                             Catch ex As Exception
                                 Log(ex, "刷新皮肤缓存失败", LogLevel.Msgbox)
                                 Log(ex, "刷新皮肤缓存失败", LogLevel.Msgbox)
                             End Try
                             End Try
@@ -165,15 +164,14 @@
     ''' 在更换正版皮肤后,刷新正版皮肤。
     ''' 在更换正版皮肤后,刷新正版皮肤。
     ''' </summary>
     ''' </summary>
     ''' <param name="SkinAddress">新的正版皮肤完整地址。</param>
     ''' <param name="SkinAddress">新的正版皮肤完整地址。</param>
-    Public Shared Sub ReloadCache(SkinAddress As String, IsMsLogin As Boolean)
+    Public Shared Sub ReloadCache(SkinAddress As String)
         RunInThread(Sub()
         RunInThread(Sub()
                         Try
                         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)
                                 SkinLoader.WaitForExit(IsForceRestart:=True)
                             Next
                             Next
                             '完成提示
                             '完成提示
@@ -198,7 +196,7 @@
         End Set
         End Set
     End Property
     End Property
     Private IsChanging As Boolean = False
     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
         If IsChanging Then
             Hint("正在更改披风中,请稍候!")
             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"
                     <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="">
                           Data="">
                         <Path.RenderTransform>
                         <Path.RenderTransform>
-                            <ScaleTransform ScaleX="1.4" ScaleY="1.4" />
+                            <ScaleTransform ScaleX="1.2" ScaleY="1.2" />
                         </Path.RenderTransform>
                         </Path.RenderTransform>
                     </Path>
                     </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" />
                     <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="Auto" />
                 <ColumnDefinition Width="1*" />
                 <ColumnDefinition Width="1*" />
             </Grid.ColumnDefinitions>
             </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"
             <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"
             <!--<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" />-->
                              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>
         </Grid>

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

@@ -67,7 +67,7 @@
 
 
         '改变页面
         '改变页面
         Dim LoginType As McLoginType = Setup.Get("LoginType")
         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)
         RefreshPage(False, False)
 
 
         AniControlEnabled -= 1
         AniControlEnabled -= 1
@@ -117,8 +117,6 @@
 
 
     Private Enum PageType
     Private Enum PageType
         None
         None
-        Mojang
-        MojangSkin
         Legacy
         Legacy
         Nide
         Nide
         NideSkin
         NideSkin
@@ -134,12 +132,6 @@
 
 
     Private Function PageGet(Type As PageType)
     Private Function PageGet(Type As PageType)
         Select Case Type
         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
             Case PageType.Legacy
                 If IsNothing(FrmLoginLegacy) Then FrmLoginLegacy = New PageLoginLegacy
                 If IsNothing(FrmLoginLegacy) Then FrmLoginLegacy = New PageLoginLegacy
                 Return FrmLoginLegacy
                 Return FrmLoginLegacy
@@ -171,7 +163,7 @@
     ''' <param name="Type">新页面的种类。</param>
     ''' <param name="Type">新页面的种类。</param>
     ''' <param name="Anim">是否显示动画。</param>
     ''' <param name="Anim">是否显示动画。</param>
     Private Function PageChange(Type As PageType, Anim As Boolean)
     Private Function PageChange(Type As PageType, Anim As Boolean)
-        Dim PageNew As Object = FrmLoginMojang '初始化一个东西,避免在执行时出现异常导致雪崩
+        Dim PageNew As Object = FrmLoginMs '初始化一个东西,避免在执行时出现异常导致雪崩
         Try
         Try
 
 
 #Region "确定更改的页面实例并实例化"
 #Region "确定更改的页面实例并实例化"
@@ -232,14 +224,7 @@
         Select Case LoginPageType
         Select Case LoginPageType
             Case 0 '正版或离线
             Case 0 '正版或离线
 UnknownType:
 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
                     If Setup.Get("CacheMsAccess") = "" Then
                         Type = PageType.Ms
                         Type = PageType.Ms
                     Else
                     Else
@@ -252,28 +237,19 @@ UnknownType:
                 End If
                 End If
                 PanType.Visibility = Visibility.Visible
                 PanType.Visibility = Visibility.Visible
                 PanTypeOne.Visibility = Visibility.Collapsed
                 PanTypeOne.Visibility = Visibility.Collapsed
-                RadioLoginType1.Visibility = Visibility.Visible
                 RadioLoginType5.Visibility = Visibility.Visible
                 RadioLoginType5.Visibility = Visibility.Visible
                 RadioLoginType0.Visibility = Visibility.Visible
                 RadioLoginType0.Visibility = Visibility.Visible
             Case 1 '仅正版
             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
                 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
                 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
                 RadioLoginType5.Visibility = Visibility.Visible
                 RadioLoginType0.Visibility = Visibility.Collapsed
                 RadioLoginType0.Visibility = Visibility.Collapsed
             Case 2 '仅离线
             Case 2 '仅离线
@@ -316,7 +292,7 @@ UnknownType:
         Dim Control As MyRadioButton = FindName("RadioLoginType" & Setup.Get("LoginType"))
         Dim Control As MyRadioButton = FindName("RadioLoginType" & Setup.Get("LoginType"))
         If Control IsNot Nothing Then Control.Checked = True
         If Control IsNot Nothing Then Control.Checked = True
     End Sub
     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)
         If raiseByMouse Then RefreshPage(True, True)
     End Sub
     End Sub
 
 
@@ -324,54 +300,6 @@ UnknownType:
 
 
 #Region "皮肤"
 #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)
     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)
     Private Shared Function SkinMsInput() As EqualableList(Of String)
@@ -592,7 +520,7 @@ Finish:
 
 
     '全部皮肤加载器
     '全部皮肤加载器
     '需要放在其中元素的后面,否则会因为它提前被加载而莫名其妙变成 Nothing
     '需要放在其中元素的后面,否则会因为它提前被加载而莫名其妙变成 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
 #End Region
 
 
@@ -713,10 +641,8 @@ ExitRefresh:
                 Else
                 Else
                     LabLaunchingMethod.Text = "离线登录"
                     LabLaunchingMethod.Text = "离线登录"
                 End If
                 End If
-            Case McLoginType.Mojang
-                LabLaunchingMethod.Text = "Mojang 正版登录"
             Case McLoginType.Ms
             Case McLoginType.Ms
-                LabLaunchingMethod.Text = "微软正版登录"
+                LabLaunchingMethod.Text = "正版登录"
             Case McLoginType.Nide
             Case McLoginType.Nide
                 LabLaunchingMethod.Text = "统一通行证"
                 LabLaunchingMethod.Text = "统一通行证"
             Case McLoginType.Auth
             Case McLoginType.Auth

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

@@ -99,10 +99,4 @@
         Init()
         Init()
     End Sub
     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
 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"
       xmlns:local="clr-namespace:PCL"
       mc:Ignorable="d" d:DesignWidth="302.4" Margin="0,0,0,-2">
       mc:Ignorable="d" d:DesignWidth="302.4" Margin="0,0,0,-2">
     <StackPanel x:Name="PanEmpty">
     <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"/>
           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>
 </StackPanel>
 </StackPanel>

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

@@ -16,7 +16,7 @@
     ''' </summary>
     ''' </summary>
     Public Shared Function IsVaild(LoginData As McLoginMs) As String
     Public Shared Function IsVaild(LoginData As McLoginMs) As String
         If LoginData.OAuthRefreshToken = "" Then
         If LoginData.OAuthRefreshToken = "" Then
-            Return "请在登录账号后再继续!"
+            Return "请在登录账号后再启动游戏!"
         Else
         Else
             Return ""
             Return ""
         End If
         End If
@@ -61,5 +61,10 @@
                            End Try
                            End Try
                        End Sub, "Ms Login")
                        End Sub, "Ms Login")
     End Sub
     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
 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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
       xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
       xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
       xmlns:local="clr-namespace:PCL"
       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>
         <Grid.RowDefinitions>
-            <RowDefinition Height="19" />
+            <RowDefinition Height="75" />
             <RowDefinition Height="Auto" MinHeight="30" />
             <RowDefinition Height="Auto" MinHeight="30" />
             <RowDefinition Height="19" />
             <RowDefinition Height="19" />
+            <RowDefinition Height="24" />
+            <RowDefinition Height="19" />
         </Grid.RowDefinitions>
         </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>
     </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>
 </Grid>

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

@@ -26,28 +26,29 @@
         End If
         End If
     End Function
     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
     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
     End Sub
 
 
+    '修改账号信息
     Private Sub BtnEdit_Click(sender As Object, e As EventArgs) Handles BtnEdit.Click
     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
     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
     Private Sub BtnExit_Click() Handles BtnExit.Click
         Setup.Set("CacheMsOAuthRefresh", "")
         Setup.Set("CacheMsOAuthRefresh", "")
         Setup.Set("CacheMsAccess", "")
         Setup.Set("CacheMsAccess", "")
@@ -58,8 +59,18 @@
         FrmLaunchLeft.RefreshPage(False, True)
         FrmLaunchLeft.RefreshPage(False, True)
     End Sub
     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 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
         If IsChanging Then
             Hint("正在更改皮肤中,请稍候!")
             Hint("正在更改皮肤中,请稍候!")
@@ -103,7 +114,7 @@ Retry:
                                Dim ResultJson As JObject = GetJson(Result)
                                Dim ResultJson As JObject = GetJson(Result)
                                For Each Skin As JObject In ResultJson("skins")
                                For Each Skin As JObject In ResultJson("skins")
                                    If Skin("state").ToString = "ACTIVE" Then
                                    If Skin("state").ToString = "ACTIVE" Then
-                                       MySkin.ReloadCache(Skin("url"), True)
+                                       MySkin.ReloadCache(Skin("url"))
                                        Exit Sub
                                        Exit Sub
                                    End If
                                    End If
                                Next
                                Next
@@ -120,4 +131,21 @@ Retry:
                        End Sub, "Ms Skin Upload")
                        End Sub, "Ms Skin Upload")
     End Sub
     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
 End Class

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

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

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

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