PageLaunchLeft.xaml.vb 46 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878
  1. Public Class PageLaunchLeft
  2. '加载当前版本
  3. Private IsLoad As Boolean = False
  4. Private IsLoadFinished As Boolean = False
  5. Public Sub PageLaunchLeft_Loaded() Handles Me.Loaded
  6. If IsLoad Then RefreshPage(True, False)
  7. AprilPosTrans.X = 0
  8. AprilPosTrans.Y = 0
  9. If IsLoad Then Exit Sub
  10. IsLoad = True
  11. AniControlEnabled += 1
  12. '开始按钮
  13. AddHandler McVersionListLoader.LoadingStateChanged, AddressOf RefreshButtonsUI
  14. AddHandler McFolderListLoader.LoadingStateChanged, AddressOf RefreshButtonsUI
  15. RefreshButtonsUI()
  16. '加载版本
  17. RunInNewThread(Sub()
  18. '确认 Minecraft 文件夹存在
  19. PathMcFolder = Setup.Get("LaunchFolderSelect").ToString.Replace("$", Path)
  20. If PathMcFolder = "" OrElse Not Directory.Exists(PathMcFolder) Then
  21. '无效的文件夹
  22. If PathMcFolder = "" Then
  23. Log("[Launch] 没有已储存的 Minecraft 文件夹")
  24. Else
  25. Log("[Launch] Minecraft 文件夹无效,该文件夹已不存在:" & PathMcFolder, LogLevel.Debug)
  26. End If
  27. McFolderListLoader.WaitForExit(IsForceRestart:=True)
  28. Setup.Set("LaunchFolderSelect", McFolderList(0).Path.Replace(Path, "$"))
  29. End If
  30. Log("[Launch] Minecraft 文件夹:" & PathMcFolder)
  31. If Setup.Get("SystemDebugDelay") Then Thread.Sleep(RandomInteger(500, 3000))
  32. '确认 Minecraft 版本存在
  33. Dim Selection As String = Setup.Get("LaunchVersionSelect")
  34. Dim Version As McVersion
  35. If Selection = "" Then
  36. Version = Nothing
  37. Else
  38. Version = New McVersion(Selection)
  39. End If
  40. If IsNothing(Version) OrElse Not (Version.Path.StartsWith(PathMcFolder) AndAlso Version.Check) Then
  41. '无效的版本
  42. Log("[Launch] Minecraft 版本无效" & If(IsNothing(Version), ",没有有效版本", ":" & Version.Path), If(IsNothing(Version), LogLevel.Normal, LogLevel.Debug))
  43. If Not McVersionListLoader.State = LoadState.Finished Then LoaderFolderRun(McVersionListLoader, PathMcFolder, LoaderFolderRunType.ForceRun, MaxDepth:=1, ExtraPath:="versions\", WaitForExit:=True)
  44. If McVersionList.Count = 0 OrElse McVersionList.First.Value(0).Logo.Contains("RedstoneBlock") Then
  45. Version = Nothing
  46. Setup.Set("LaunchVersionSelect", "")
  47. Log("[Launch] 无可用 Minecraft 版本")
  48. Else
  49. Version = McVersionList.First.Value(0)
  50. Setup.Set("LaunchVersionSelect", Version.Name)
  51. Log("[Launch] 自动选择 Minecraft 版本:" & Version.Path)
  52. End If
  53. End If
  54. RunInUi(Sub()
  55. McVersionCurrent = Version '绕这一圈是为了避免 McVersionCheck 触发第二次版本改变
  56. IsLoadFinished = True
  57. RefreshButtonsUI()
  58. RefreshPage(False, False) '有可能选择的版本变化了,需要重新刷新
  59. If McLoginAble() = "" Then McLoginLoader.Start() '自动登录
  60. End Sub)
  61. End Sub, "Version Check", ThreadPriority.AboveNormal)
  62. '改变页面
  63. Dim LoginType As McLoginType = Setup.Get("LoginType")
  64. If LoginType = McLoginType.Legacy OrElse LoginType = McLoginType.Mojang OrElse LoginType = McLoginType.Ms Then CType(FindName("RadioLoginType" & LoginType), MyRadioButton).Checked = True
  65. RefreshPage(False, False)
  66. AniControlEnabled -= 1
  67. End Sub
  68. #Region "切换大页面"
  69. ''' <summary>
  70. ''' 切换至启动中页面。
  71. ''' </summary>
  72. Public Sub PageChangeToLaunching()
  73. LaunchingPreload()
  74. PanInput.IsHitTestVisible = False
  75. PanLaunching.IsHitTestVisible = False
  76. LoadLaunching.State.LoadingState = MyLoading.MyLoadingState.Run
  77. PanLaunching.Visibility = Visibility.Visible
  78. AniStart({
  79. AaOpacity(PanInput, 0, 50), '略作延迟,这样如果预检测失败,不会出现奇怪的弹一下的动画
  80. AaOpacity(PanInput, -PanInput.Opacity, 110, , New AniEaseInFluent, True),
  81. AaScaleTransform(PanInput, 1.2 - CType(PanInput.RenderTransform, ScaleTransform).ScaleX, 160),
  82. AaOpacity(PanLaunching, 1 - PanLaunching.Opacity, 150, 100),
  83. AaScaleTransform(PanLaunching, 1 - CType(PanLaunching.RenderTransform, ScaleTransform).ScaleX, 500, 100, New AniEaseOutBack(AniEasePower.Weak)),
  84. AaCode(Sub() PanLaunching.IsHitTestVisible = True, 150)
  85. }, "Launch State Page")
  86. End Sub
  87. ''' <summary>
  88. ''' 切换至登录页面。
  89. ''' </summary>
  90. Public Sub PageChangeToLogin()
  91. PageGet(PageCurrent).Reload(KeepInput:=False)
  92. PanInput.IsHitTestVisible = False
  93. PanLaunching.IsHitTestVisible = False
  94. LoadLaunching.State.LoadingState = MyLoading.MyLoadingState.Stop
  95. PanInput.Visibility = Visibility.Visible
  96. AniStart({
  97. AaOpacity(PanLaunching, -PanLaunching.Opacity, 150),
  98. AaScaleTransform(PanLaunching, 0.8 - CType(PanLaunching.RenderTransform, ScaleTransform).ScaleX, 150,, New AniEaseOutFluent(AniEasePower.Weak)),
  99. AaOpacity(PanInput, 1 - PanInput.Opacity, 250, 50),
  100. AaScaleTransform(PanInput, 1 - CType(PanInput.RenderTransform, ScaleTransform).ScaleX, 300, 50, New AniEaseOutBack(AniEasePower.Weak)),
  101. AaCode(Sub() PanInput.IsHitTestVisible = True, 200)
  102. }, "Launch State Page", True)
  103. End Sub
  104. #End Region
  105. #Region "切换登录页面"
  106. Private Enum PageType
  107. None
  108. Mojang
  109. MojangSkin
  110. Legacy
  111. Nide
  112. NideSkin
  113. Auth
  114. AuthSkin
  115. Ms
  116. MsSkin
  117. End Enum
  118. ''' <summary>
  119. ''' 当前页面的种类。
  120. ''' </summary>
  121. Private PageCurrent As PageType = PageType.None
  122. Private Function PageGet(Type As PageType)
  123. Select Case Type
  124. Case PageType.Mojang
  125. If IsNothing(FrmLoginMojang) Then FrmLoginMojang = New PageLoginMojang
  126. Return FrmLoginMojang
  127. Case PageType.MojangSkin
  128. If IsNothing(FrmLoginMojangSkin) Then FrmLoginMojangSkin = New PageLoginMojangSkin
  129. Return FrmLoginMojangSkin
  130. Case PageType.Legacy
  131. If IsNothing(FrmLoginLegacy) Then FrmLoginLegacy = New PageLoginLegacy
  132. Return FrmLoginLegacy
  133. Case PageType.Nide
  134. If IsNothing(FrmLoginNide) Then FrmLoginNide = New PageLoginNide
  135. Return FrmLoginNide
  136. Case PageType.NideSkin
  137. If IsNothing(FrmLoginNideSkin) Then FrmLoginNideSkin = New PageLoginNideSkin
  138. Return FrmLoginNideSkin
  139. Case PageType.Auth
  140. If IsNothing(FrmLoginAuth) Then FrmLoginAuth = New PageLoginAuth
  141. Return FrmLoginAuth
  142. Case PageType.AuthSkin
  143. If IsNothing(FrmLoginAuthSkin) Then FrmLoginAuthSkin = New PageLoginAuthSkin
  144. Return FrmLoginAuthSkin
  145. Case PageType.Ms
  146. If IsNothing(FrmLoginMs) Then FrmLoginMs = New PageLoginMs
  147. Return FrmLoginMs
  148. Case PageType.MsSkin
  149. If IsNothing(FrmLoginMsSkin) Then FrmLoginMsSkin = New PageLoginMsSkin
  150. Return FrmLoginMsSkin
  151. Case Else
  152. Throw New ArgumentOutOfRangeException("Type", "即将切换的登录分页编号越界")
  153. End Select
  154. End Function
  155. ''' <summary>
  156. ''' 切换现有登录页面种类,返回新页面的实例。
  157. ''' </summary>
  158. ''' <param name="Type">新页面的种类。</param>
  159. ''' <param name="Anim">是否显示动画。</param>
  160. Private Function PageChange(Type As PageType, Anim As Boolean)
  161. Dim PageNew As Object = FrmLoginMojang '初始化一个东西,避免在执行时出现异常导致雪崩
  162. Try
  163. #Region "确定更改的页面实例并实例化"
  164. If PageCurrent = Type Then Return PageNew
  165. PageNew = PageGet(Type)
  166. #End Region
  167. #Region "切换页面"
  168. AniStop("FrmLogin PageChange")
  169. '清除页面关联性
  170. If Not IsNothing(PageNew) AndAlso Not IsNothing(PageNew.Parent) Then PageNew.SetValue(ContentPresenter.ContentProperty, Nothing)
  171. If Anim Then
  172. '动画
  173. Dispatcher.Invoke(Sub()
  174. '执行动画
  175. AniStart({
  176. AaOpacity(PanLogin, -PanLogin.Opacity, 100,, New AniEaseOutFluent),
  177. AaCode(Sub()
  178. AniControlEnabled += 1
  179. PanLogin.Children.Clear()
  180. PanLogin.Children.Add(PageNew)
  181. AniControlEnabled -= 1
  182. End Sub, 100),
  183. AaOpacity(PanLogin, 1, 100, 120, New AniEaseInFluent)
  184. }, "FrmLogin PageChange")
  185. End Sub, Threading.DispatcherPriority.Render)
  186. Else
  187. '无动画
  188. AniControlEnabled += 1
  189. PanLogin.Children.Clear()
  190. PanLogin.Children.Add(PageNew)
  191. AniControlEnabled -= 1
  192. End If
  193. #End Region
  194. PageCurrent = Type
  195. Return PageNew
  196. Catch ex As Exception
  197. Log(ex, "切换登录分页失败(" & GetStringFromEnum(CType(Type, [Enum])) & ")", LogLevel.Feedback)
  198. Return PageNew
  199. End Try
  200. End Function
  201. ''' <summary>
  202. ''' 确认当前显示的子页面正确,并刷新该页面。
  203. ''' </summary>
  204. Public Sub RefreshPage(KeepInput As Boolean, Anim As Boolean)
  205. '获取页面的可用种类并回写缓存
  206. Dim Type As PageType
  207. Dim LoginPageType As Integer
  208. If McVersionCurrent IsNot Nothing Then
  209. LoginPageType = Setup.Get("VersionServerLogin", Version:=McVersionCurrent)
  210. '缓存当前版本的页面种类,下一次打开 McVersionCurrent 为空时才能加载出正确的页面
  211. Setup.Set("LoginPageType", LoginPageType)
  212. Else
  213. LoginPageType = Setup.Get("LoginPageType")
  214. End If
  215. Select Case LoginPageType
  216. Case 0 '正版或离线
  217. UnknownType:
  218. If RadioLoginType1.Checked Then
  219. If Setup.Get("CacheMojangAccess") = "" Then
  220. Type = PageType.Mojang
  221. Else
  222. Type = PageType.MojangSkin
  223. End If
  224. Setup.Set("LoginType", McLoginType.Mojang)
  225. ElseIf RadioLoginType5.Checked Then
  226. If Setup.Get("CacheMsAccess") = "" Then
  227. Type = PageType.Ms
  228. Else
  229. Type = PageType.MsSkin
  230. End If
  231. Setup.Set("LoginType", McLoginType.Ms)
  232. Else
  233. Type = PageType.Legacy
  234. Setup.Set("LoginType", McLoginType.Legacy)
  235. End If
  236. PanType.Visibility = Visibility.Visible
  237. PanTypeOne.Visibility = Visibility.Collapsed
  238. RadioLoginType1.Visibility = Visibility.Visible
  239. RadioLoginType5.Visibility = Visibility.Visible
  240. RadioLoginType0.Visibility = Visibility.Visible
  241. Case 1 '仅正版
  242. If RadioLoginType1.Checked Then
  243. If Setup.Get("CacheMojangAccess") = "" Then
  244. Type = PageType.Mojang
  245. Else
  246. Type = PageType.MojangSkin
  247. End If
  248. Setup.Set("LoginType", McLoginType.Mojang)
  249. Else
  250. If Setup.Get("CacheMsAccess") = "" Then
  251. Type = PageType.Ms
  252. Else
  253. Type = PageType.MsSkin
  254. End If
  255. Setup.Set("LoginType", McLoginType.Ms)
  256. End If
  257. PanType.Visibility = Visibility.Visible
  258. PanTypeOne.Visibility = Visibility.Collapsed
  259. RadioLoginType1.Visibility = Visibility.Visible
  260. RadioLoginType5.Visibility = Visibility.Visible
  261. RadioLoginType0.Visibility = Visibility.Collapsed
  262. Case 2 '仅离线
  263. Type = PageType.Legacy
  264. Setup.Set("LoginType", McLoginType.Legacy)
  265. PanType.Visibility = Visibility.Collapsed
  266. PanTypeOne.Visibility = Visibility.Visible
  267. PathTypeOne.Data = (New GeometryConverter).ConvertFromString(Logo.IconButtonUser)
  268. LabTypeOne.Text = "离线登录"
  269. Case 3 '统一通行证
  270. If Setup.Get("CacheNideAccess") = "" Then
  271. Type = PageType.Nide
  272. Else
  273. Type = PageType.NideSkin
  274. End If
  275. Setup.Set("LoginType", McLoginType.Nide)
  276. PanType.Visibility = Visibility.Collapsed
  277. PanTypeOne.Visibility = Visibility.Visible
  278. PathTypeOne.Data = (New GeometryConverter).ConvertFromString(Logo.IconButtonCard)
  279. LabTypeOne.Text = "统一通行证登录"
  280. Case 4 'Authlib-Injector
  281. If Setup.Get("CacheAuthAccess") = "" Then
  282. Type = PageType.Auth
  283. Else
  284. Type = PageType.AuthSkin
  285. End If
  286. Setup.Set("LoginType", McLoginType.Auth)
  287. PanType.Visibility = Visibility.Collapsed
  288. PanTypeOne.Visibility = Visibility.Visible
  289. PathTypeOne.Data = (New GeometryConverter).ConvertFromString(Logo.IconButtonCard)
  290. LabTypeOne.Text = If(McVersionCurrent Is Nothing, Setup.Get("CacheAuthServerName"), Setup.Get("VersionServerAuthName", Version:=McVersionCurrent))
  291. If LabTypeOne.Text = "" Then LabTypeOne.Text = "第三方登录"
  292. Case Else
  293. Log("[Control] 未知的登录页面:" & LoginPageType, LogLevel.Hint)
  294. GoTo UnknownType
  295. End Select
  296. '刷新页面
  297. If PageCurrent = Type Then Exit Sub
  298. PageChange(Type, Anim).Reload(KeepInput)
  299. Dim Control As MyRadioButton = FindName("RadioLoginType" & Setup.Get("LoginType"))
  300. If Control IsNot Nothing Then Control.Checked = True
  301. End Sub
  302. Private Sub RadioLoginType_Change(sender As Object, raiseByMouse As Boolean) Handles RadioLoginType0.Check, RadioLoginType1.Check, RadioLoginType5.Check
  303. If raiseByMouse Then RefreshPage(True, True)
  304. End Sub
  305. #End Region
  306. #Region "皮肤"
  307. 'Mojang 正版皮肤
  308. Public Shared SkinMojang As New LoaderTask(Of EqualableList(Of String), String)("Loader Skin Mojang", AddressOf SkinMojangLoad, AddressOf SkinMojangInput, ThreadPriority.AboveNormal)
  309. Private Shared Function SkinMojangInput() As EqualableList(Of String)
  310. '获取名称
  311. Return New EqualableList(Of String) From {Setup.Get("CacheMojangName"), Setup.Get("CacheMojangUuid")}
  312. End Function
  313. Private Shared Sub SkinMojangLoad(Data As LoaderTask(Of EqualableList(Of String), String))
  314. '清空已有皮肤
  315. '如果在输入时清空皮肤,若输入内容一样则不会执行 Load 方法,导致皮肤不被加载
  316. RunInUi(Sub() If FrmLoginMojangSkin IsNot Nothing AndAlso FrmLoginMojangSkin.Skin IsNot Nothing Then FrmLoginMojangSkin.Skin.Clear())
  317. '获取 Url
  318. Dim UserName As String = Data.Input(0)
  319. Dim Uuid As String = Data.Input(1)
  320. If UserName = "" Then
  321. Data.Output = PathImage & "Skins/" & McSkinSex(McLoginLegacyUuid(UserName)) & ".png"
  322. Log("[Minecraft] 获取正版皮肤失败,ID 为空")
  323. GoTo Finish
  324. End If
  325. Try
  326. Dim Result As String = McSkinGetAddress(Uuid, "Mojang")
  327. If Data.IsAborted Then Throw New ThreadInterruptedException("当前任务已取消:" & UserName)
  328. Result = McSkinDownload(Result)
  329. If Data.IsAborted Then Throw New ThreadInterruptedException("当前任务已取消:" & UserName)
  330. Data.Output = Result
  331. Catch ex As Exception
  332. If ex.GetType.Name = "ThreadInterruptedException" Then
  333. Data.Output = ""
  334. Exit Sub
  335. ElseIf GetExceptionSummary(ex).Contains("429") Then
  336. Data.Output = PathImage & "Skins/" & McSkinSex(McLoginLegacyUuid(UserName)) & ".png"
  337. Log("[Minecraft] 获取正版皮肤失败(" & UserName & "):获取皮肤太过频繁,请 5 分钟后再试!", LogLevel.Hint)
  338. ElseIf GetExceptionSummary(ex).Contains("未设置自定义皮肤") Then
  339. Data.Output = PathImage & "Skins/" & McSkinSex(McLoginLegacyUuid(UserName)) & ".png"
  340. Log("[Minecraft] 用户未设置自定义皮肤,跳过皮肤加载")
  341. Else
  342. Data.Output = PathImage & "Skins/" & McSkinSex(McLoginLegacyUuid(UserName)) & ".png"
  343. Log(ex, "获取正版皮肤失败(" & UserName & ")", LogLevel.Hint)
  344. End If
  345. End Try
  346. Finish:
  347. '刷新显示
  348. If FrmLoginMojangSkin IsNot Nothing Then
  349. RunInUi(AddressOf FrmLoginMojangSkin.Skin.Load)
  350. ElseIf Not Data.IsAborted Then '如果已经中断,Input 也被清空,就不会再次刷新
  351. Data.Input = Nothing '清空输入,因为皮肤实际上没有被渲染,如果不清空切换到页面的 Start 会由于输入相同而不渲染
  352. End If
  353. End Sub
  354. '微软正版皮肤
  355. Public Shared SkinMs As New LoaderTask(Of EqualableList(Of String), String)("Loader Skin Ms", AddressOf SkinMsLoad, AddressOf SkinMsInput, ThreadPriority.AboveNormal)
  356. Private Shared Function SkinMsInput() As EqualableList(Of String)
  357. '获取名称
  358. Return New EqualableList(Of String) From {Setup.Get("CacheMsName"), Setup.Get("CacheMsUuid")}
  359. End Function
  360. Private Shared Sub SkinMsLoad(Data As LoaderTask(Of EqualableList(Of String), String))
  361. '清空已有皮肤
  362. '如果在输入时清空皮肤,若输入内容一样则不会执行 Load 方法,导致皮肤不被加载
  363. RunInUi(Sub() If FrmLoginMsSkin IsNot Nothing AndAlso FrmLoginMsSkin.Skin IsNot Nothing Then FrmLoginMsSkin.Skin.Clear())
  364. '获取 Url
  365. Dim UserName As String = Data.Input(0)
  366. Dim Uuid As String = Data.Input(1)
  367. If UserName = "" Then
  368. Data.Output = PathImage & "Skins/" & McSkinSex(McLoginLegacyUuid(UserName)) & ".png"
  369. Log("[Minecraft] 获取微软正版皮肤失败,ID 为空")
  370. GoTo Finish
  371. End If
  372. Try
  373. Dim Result As String = McSkinGetAddress(Uuid, "Ms")
  374. If Data.IsAborted Then Throw New ThreadInterruptedException("当前任务已取消:" & UserName)
  375. Result = McSkinDownload(Result)
  376. If Data.IsAborted Then Throw New ThreadInterruptedException("当前任务已取消:" & UserName)
  377. Data.Output = Result
  378. Catch ex As Exception
  379. If ex.GetType.Name = "ThreadInterruptedException" Then
  380. Data.Output = ""
  381. Exit Sub
  382. ElseIf GetExceptionSummary(ex).Contains("429") Then
  383. Data.Output = PathImage & "Skins/" & McSkinSex(McLoginLegacyUuid(UserName)) & ".png"
  384. Log("[Minecraft] 获取正版皮肤失败(" & UserName & "):获取皮肤太过频繁,请 5 分钟后再试!", LogLevel.Hint)
  385. ElseIf GetExceptionSummary(ex).Contains("未设置自定义皮肤") Then
  386. Data.Output = PathImage & "Skins/" & McSkinSex(McLoginLegacyUuid(UserName)) & ".png"
  387. Log("[Minecraft] 用户未设置自定义皮肤,跳过皮肤加载")
  388. Else
  389. Data.Output = PathImage & "Skins/" & McSkinSex(McLoginLegacyUuid(UserName)) & ".png"
  390. Log(ex, "获取微软正版皮肤失败(" & UserName & ")", LogLevel.Hint)
  391. End If
  392. End Try
  393. Finish:
  394. '刷新显示
  395. If FrmLoginMsSkin IsNot Nothing Then
  396. RunInUi(AddressOf FrmLoginMsSkin.Skin.Load)
  397. ElseIf Not Data.IsAborted Then '如果已经中断,Input 也被清空,就不会再次刷新
  398. Data.Input = Nothing '清空输入,因为皮肤实际上没有被渲染,如果不清空切换到页面的 Start 会由于输入相同而不渲染
  399. End If
  400. End Sub
  401. '离线皮肤
  402. Public Shared SkinLegacy As New LoaderTask(Of EqualableList(Of String), String)("Loader Skin Legacy", AddressOf SkinLegacyLoad, AddressOf SkinLegacyInput, ThreadPriority.AboveNormal)
  403. Private Shared Function SkinLegacyInput() As EqualableList(Of String)
  404. '根据类型判断输入
  405. Dim Type As Integer = Setup.Get("LaunchSkinType")
  406. Select Case Type
  407. Case 0
  408. If FrmLoginLegacy IsNot Nothing AndAlso FrmLoginLegacy.IsReloaded Then
  409. Return New EqualableList(Of String) From {0, If(FrmLoginLegacy.ComboName.Text, "")}
  410. ElseIf Setup.Get("LoginLegacyName") = "" Then
  411. Return New EqualableList(Of String) From {0, ""}
  412. Else
  413. Return New EqualableList(Of String) From {0, If(Setup.Get("LoginLegacyName").ToString.Split("¨")(0), "")}
  414. End If
  415. Case 3
  416. Return New EqualableList(Of String) From {3, Setup.Get("LaunchSkinID")}
  417. Case Else
  418. Return New EqualableList(Of String) From {Type}
  419. End Select
  420. End Function
  421. Private Shared Sub SkinLegacyLoad(Data As LoaderTask(Of EqualableList(Of String), String))
  422. '清空已有皮肤
  423. RunInUi(Sub() If FrmLoginLegacy IsNot Nothing AndAlso FrmLoginLegacy.Skin IsNot Nothing Then FrmLoginLegacy.Skin.Clear())
  424. '获取 Url
  425. Select Case Data.Input(0)
  426. Case 0 '默认
  427. Data.Output = PathImage & "Skins/" & McSkinSex(McLoginLegacyUuid(Data.Input(1))) & ".png"
  428. Case 1 'Steve
  429. UseDefault:
  430. Data.Output = PathImage & "Skins/Steve.png"
  431. Case 2 'Alex
  432. Data.Output = PathImage & "Skins/Alex.png"
  433. Case 3 '正版
  434. Dim ID As String = Data.Input(1)
  435. Try
  436. If ID.Count < 2 Then
  437. Data.Output = PathImage & "Skins/Steve.png"
  438. Else
  439. Dim Result As String = McLoginMojangUuid(ID, True)
  440. If Data.IsAborted Then Throw New ThreadInterruptedException("当前任务已取消:" & ID)
  441. Result = McSkinGetAddress(Result, "Mojang")
  442. If Data.IsAborted Then Throw New ThreadInterruptedException("当前任务已取消:" & ID)
  443. Result = McSkinDownload(Result)
  444. If Data.IsAborted Then Throw New ThreadInterruptedException("当前任务已取消:" & ID)
  445. Data.Output = Result
  446. End If
  447. Catch ex As Exception
  448. If ex.GetType.Name = "ThreadInterruptedException" Then
  449. Data.Output = ""
  450. Exit Sub
  451. ElseIf GetExceptionSummary(ex).Contains("429") Then
  452. Data.Output = PathImage & "Skins/" & McSkinSex(McLoginLegacyUuid(ID)) & ".png"
  453. Log("获取离线登录使用的正版皮肤失败(" & ID & "):获取皮肤太过频繁,请 5 分钟后再试!")
  454. Else
  455. Data.Output = PathImage & "Skins/" & McSkinSex(McLoginLegacyUuid(ID)) & ".png"
  456. Log(ex, "获取离线登录使用的正版皮肤失败(" & ID & ")")
  457. End If
  458. End Try
  459. Case 4 '自定义
  460. If Not File.Exists(PathAppdata & "CustomSkin.png") Then
  461. Hint("未找到离线皮肤自定义文件,可能它已被删除。PCL2 将使用默认的 Steve 皮肤!")
  462. Setup.Set("LaunchSkinType", 1)
  463. GoTo UseDefault
  464. End If
  465. Data.Output = PathAppdata & "CustomSkin.png"
  466. End Select
  467. '刷新显示
  468. If FrmLoginLegacy IsNot Nothing Then
  469. RunInUi(AddressOf FrmLoginLegacy.Skin.Load)
  470. ElseIf Not Data.IsAborted Then '如果已经中断,Input 也被清空,就不会再次刷新
  471. Data.Input = Nothing '清空输入,因为皮肤实际上没有被渲染,如果不清空切换到页面的 Start 会由于输入相同而不渲染
  472. End If
  473. End Sub
  474. '统一通行证皮肤
  475. Public Shared SkinNide As New LoaderTask(Of EqualableList(Of String), String)("Loader Skin Nide", AddressOf SkinNideLoad, AddressOf SkinNideInput, ThreadPriority.AboveNormal)
  476. Private Shared Function SkinNideInput() As EqualableList(Of String)
  477. '获取名称
  478. Return New EqualableList(Of String) From {Setup.Get("CacheNideName"), Setup.Get("CacheNideUuid")}
  479. End Function
  480. Private Shared Sub SkinNideLoad(Data As LoaderTask(Of EqualableList(Of String), String))
  481. '清空已有皮肤
  482. '如果在输入时清空皮肤,若输入内容一样则不会执行 Load 方法,导致皮肤不被加载
  483. RunInUi(Sub() If FrmLoginNideSkin IsNot Nothing AndAlso FrmLoginNideSkin.Skin IsNot Nothing Then FrmLoginNideSkin.Skin.Clear())
  484. '获取 Url
  485. Dim UserName As String = Data.Input(0)
  486. Dim Uuid As String = Data.Input(1)
  487. If UserName = "" Then
  488. Data.Output = PathImage & "Skins/" & McSkinSex(McLoginLegacyUuid(UserName)) & ".png"
  489. Log("[Minecraft] 获取统一通行证皮肤失败,ID 为空")
  490. GoTo Finish
  491. End If
  492. Try
  493. Dim Result As String = McSkinGetAddress(Uuid, "Nide")
  494. If Data.IsAborted Then Throw New ThreadInterruptedException("当前任务已取消:" & UserName)
  495. Result = McSkinDownload(Result)
  496. If Data.IsAborted Then Throw New ThreadInterruptedException("当前任务已取消:" & UserName)
  497. Data.Output = Result
  498. Catch ex As Exception
  499. If ex.GetType.Name = "ThreadInterruptedException" Then
  500. Data.Output = ""
  501. Exit Sub
  502. ElseIf GetExceptionSummary(ex).Contains("429") Then
  503. Data.Output = PathImage & "Skins/Steve.png"
  504. Log("[Minecraft] 获取统一通行证皮肤失败(" & UserName & "):获取皮肤太过频繁,请 5 分钟后再试!", LogLevel.Hint)
  505. ElseIf GetExceptionSummary(ex).Contains("未设置自定义皮肤") Then
  506. Data.Output = PathImage & "Skins/Steve.png"
  507. Log("[Minecraft] 用户未设置自定义皮肤,跳过皮肤加载")
  508. Else
  509. Data.Output = PathImage & "Skins/Steve.png"
  510. Log(ex, "获取统一通行证皮肤失败(" & UserName & ")", LogLevel.Hint)
  511. End If
  512. End Try
  513. Finish:
  514. '刷新显示
  515. If FrmLoginNideSkin IsNot Nothing Then
  516. RunInUi(AddressOf FrmLoginNideSkin.Skin.Load)
  517. ElseIf Not Data.IsAborted Then '如果已经中断,Input 也被清空,就不会再次刷新
  518. Data.Input = Nothing '清空输入,因为皮肤实际上没有被渲染,如果不清空切换到页面的 Start 会由于输入相同而不渲染
  519. End If
  520. End Sub
  521. 'Authlib-Injector 皮肤
  522. Public Shared SkinAuth As New LoaderTask(Of EqualableList(Of String), String)("Loader Skin Auth", AddressOf SkinAuthLoad, AddressOf SkinAuthInput, ThreadPriority.AboveNormal)
  523. Private Shared Function SkinAuthInput() As EqualableList(Of String)
  524. '获取名称
  525. Return New EqualableList(Of String) From {Setup.Get("CacheAuthName"), Setup.Get("CacheAuthUuid")}
  526. End Function
  527. Private Shared Sub SkinAuthLoad(Data As LoaderTask(Of EqualableList(Of String), String))
  528. '清空已有皮肤
  529. '如果在输入时清空皮肤,若输入内容一样则不会执行 Load 方法,导致皮肤不被加载
  530. RunInUi(Sub() If FrmLoginAuthSkin IsNot Nothing AndAlso FrmLoginAuthSkin.Skin IsNot Nothing Then FrmLoginAuthSkin.Skin.Clear())
  531. '获取 Url
  532. Dim UserName As String = Data.Input(0)
  533. Dim Uuid As String = Data.Input(1)
  534. If UserName = "" Then
  535. Data.Output = PathImage & "Skins/Steve.png"
  536. Log("[Minecraft] 获取 Authlib-Injector 皮肤失败,ID 为空")
  537. GoTo Finish
  538. End If
  539. Try
  540. Dim Result As String = McSkinGetAddress(Uuid, "Auth")
  541. If Data.IsAborted Then Throw New ThreadInterruptedException("当前任务已取消:" & UserName)
  542. Result = McSkinDownload(Result)
  543. If Data.IsAborted Then Throw New ThreadInterruptedException("当前任务已取消:" & UserName)
  544. Data.Output = Result
  545. Catch ex As Exception
  546. If ex.GetType.Name = "ThreadInterruptedException" Then
  547. Data.Output = ""
  548. Exit Sub
  549. ElseIf GetExceptionSummary(ex).Contains("429") Then
  550. Data.Output = PathImage & "Skins/Steve.png"
  551. Log("[Minecraft] 获取 Authlib-Injector 皮肤失败(" & UserName & "):获取皮肤太过频繁,请 5 分钟后再试!", LogLevel.Hint)
  552. ElseIf GetExceptionSummary(ex).Contains("未设置自定义皮肤") Then
  553. Data.Output = PathImage & "Skins/Steve.png"
  554. Log("[Minecraft] 用户未设置自定义皮肤,跳过皮肤加载")
  555. Else
  556. Data.Output = PathImage & "Skins/Steve.png"
  557. Log(ex, "获取 Authlib-Injector 皮肤失败(" & UserName & ")", LogLevel.Hint)
  558. End If
  559. End Try
  560. Finish:
  561. '刷新显示
  562. If FrmLoginAuthSkin IsNot Nothing Then
  563. RunInUi(AddressOf FrmLoginAuthSkin.Skin.Load)
  564. ElseIf Not Data.IsAborted Then '如果已经中断,Input 也被清空,就不会再次刷新
  565. Data.Input = Nothing '清空输入,因为皮肤实际上没有被渲染,如果不清空切换到页面的 Start 会由于输入相同而不渲染
  566. End If
  567. End Sub
  568. '全部皮肤加载器
  569. '需要放在其中元素的后面,否则会因为它提前被加载而莫名其妙变成 Nothing
  570. Public Shared SkinLoaders As New List(Of LoaderTask(Of EqualableList(Of String), String)) From {SkinMojang, SkinMs, SkinLegacy, SkinNide, SkinAuth}
  571. #End Region
  572. '版本选择按钮
  573. Private Sub BtnVersion_Click(sender As Object, e As EventArgs) Handles BtnVersion.Click
  574. FrmMain.PageChange(FormMain.PageType.VersionSelect)
  575. End Sub
  576. '启动按钮
  577. Public Sub LaunchButtonClick() Handles BtnLaunch.Click
  578. If Not BtnLaunch.IsEnabled Then Exit Sub
  579. '愚人节处理
  580. If IsAprilEnabled AndAlso Not IsAprilGiveup Then
  581. ThemeUnlock(12, False, "隐藏主题 滑稽彩 已解锁!")
  582. IsAprilGiveup = True
  583. FrmLaunchLeft.AprilScaleTrans.ScaleX = 1
  584. FrmLaunchLeft.AprilScaleTrans.ScaleY = 1
  585. FrmLaunchLeft.AprilPosTrans.X = 0
  586. FrmLaunchLeft.AprilPosTrans.Y = 0
  587. FrmMain.BtnExtraApril.ShowRefresh()
  588. End If
  589. '实际的启动
  590. If BtnLaunch.Text = "启动游戏" Then
  591. McLaunchStart()
  592. ElseIf BtnLaunch.Text = "下载游戏" Then
  593. FrmMain.PageChange(FormMain.PageType.Download, FormMain.PageSubType.DownloadInstall)
  594. End If
  595. End Sub
  596. Private BtnLaunchState As Integer = 0
  597. Private BtnLaunchVersion As McVersion = Nothing
  598. Public Sub RefreshButtonsUI() Handles BtnLaunch.Loaded
  599. If Not BtnLaunch.IsLoaded Then Exit Sub
  600. '获取当前状态
  601. Dim CurrentState As Integer
  602. If (Not IsLoadFinished) OrElse McVersionListLoader.State = LoadState.Loading OrElse McFolderListLoader.State = LoadState.Loading Then
  603. CurrentState = 0
  604. Else
  605. If McVersionCurrent Is Nothing Then
  606. If Setup.Get("UiHiddenPageDownload") AndAlso Not PageSetupUI.HiddenForceShow Then
  607. CurrentState = 1
  608. Else
  609. CurrentState = 2
  610. End If
  611. Else
  612. CurrentState = 3
  613. End If
  614. End If
  615. '更新状态
  616. If CurrentState = BtnLaunchState AndAlso
  617. If(McVersionCurrent Is Nothing, "", McVersionCurrent.Path) = If(BtnLaunchVersion Is Nothing, "", BtnLaunchVersion.Path) Then GoTo ExitRefresh
  618. BtnLaunchVersion = McVersionCurrent
  619. BtnLaunchState = CurrentState
  620. Select Case CurrentState
  621. Case 0
  622. Log("[Minecraft] 启动按钮:正在加载 Minecraft 版本")
  623. FrmLaunchLeft.BtnLaunch.Text = "正在加载"
  624. FrmLaunchLeft.BtnLaunch.IsEnabled = False
  625. FrmLaunchLeft.LabVersion.Text = "正在加载版本列表,请稍候"
  626. FrmLaunchLeft.BtnVersion.IsEnabled = False
  627. FrmLaunchLeft.BtnMore.Visibility = Visibility.Collapsed
  628. Case 1
  629. Log("[Minecraft] 启动按钮:无 Minecraft 版本,下载已禁用")
  630. FrmLaunchLeft.BtnLaunch.Text = "启动游戏"
  631. FrmLaunchLeft.BtnLaunch.IsEnabled = False
  632. FrmLaunchLeft.LabVersion.Text = "未找到可用的游戏版本"
  633. FrmLaunchLeft.BtnVersion.IsEnabled = True
  634. FrmLaunchLeft.BtnMore.Visibility = Visibility.Collapsed
  635. Case 2
  636. Log("[Minecraft] 启动按钮:无 Minecraft 版本,要求下载")
  637. FrmLaunchLeft.BtnLaunch.Text = "下载游戏"
  638. FrmLaunchLeft.BtnLaunch.IsEnabled = True
  639. FrmLaunchLeft.LabVersion.Text = "未找到可用的游戏版本"
  640. FrmLaunchLeft.BtnVersion.IsEnabled = True
  641. FrmLaunchLeft.BtnMore.Visibility = Visibility.Collapsed
  642. Case 3
  643. Log("[Minecraft] 启动按钮:Minecraft 版本:" & McVersionCurrent.Path)
  644. FrmLaunchLeft.BtnLaunch.Text = "启动游戏"
  645. FrmLaunchLeft.BtnVersion.IsEnabled = True
  646. FrmLaunchLeft.BtnLaunch.IsEnabled = True
  647. FrmLaunchLeft.LabVersion.Text = McVersionCurrent.Name
  648. 'FrmLaunchLeft.BtnMore.Visibility = Visibility.Visible '由功能隐藏设置修改
  649. End Select
  650. ExitRefresh:
  651. '功能隐藏
  652. FrmLaunchLeft.BtnVersion.Visibility = If(Not PageSetupUI.HiddenForceShow AndAlso Setup.Get("UiHiddenFunctionSelect"), Visibility.Collapsed, Visibility.Visible)
  653. If CurrentState = 3 Then
  654. FrmLaunchLeft.BtnMore.Visibility = FrmLaunchLeft.BtnVersion.Visibility
  655. End If
  656. End Sub
  657. '取消按钮
  658. Private Sub BtnCancel_Click() Handles BtnCancel.Click
  659. If McLaunchLoaderReal IsNot Nothing Then
  660. McLaunchLoaderReal.Abort()
  661. McLaunchLog("已取消启动")
  662. Try
  663. If McLaunchWatcher IsNot Nothing Then
  664. McLaunchWatcher.Kill()
  665. ElseIf McLaunchProcess IsNot Nothing Then
  666. If Not McLaunchProcess.HasExited Then McLaunchProcess.Kill()
  667. End If
  668. Catch ex As Exception
  669. Log(ex, "取消启动结束进程失败", LogLevel.Hint)
  670. End Try
  671. End If
  672. End Sub
  673. '更多按钮
  674. Private Sub BtnMore_Click(sender As Object, e As EventArgs) Handles BtnMore.Click
  675. McVersionCurrent.Load()
  676. PageVersionLeft.Version = McVersionCurrent
  677. FrmMain.PageChange(FormMain.PageType.VersionSetup, 0)
  678. End Sub
  679. '刷新 UI
  680. Public Sub LaunchingPreload()
  681. '修改登陆方式
  682. Select Case Setup.Get("LoginType")
  683. Case McLoginType.Legacy
  684. If PageLinkHiper.HiperState = LoadState.Finished Then
  685. LabLaunchingMethod.Text = "联机离线登录"
  686. Else
  687. LabLaunchingMethod.Text = "离线登录"
  688. End If
  689. Case McLoginType.Mojang
  690. LabLaunchingMethod.Text = "Mojang 正版登录"
  691. Case McLoginType.Ms
  692. LabLaunchingMethod.Text = "微软正版登录"
  693. Case McLoginType.Nide
  694. LabLaunchingMethod.Text = "统一通行证"
  695. Case McLoginType.Auth
  696. LabLaunchingMethod.Text = "Authlib-Injector"
  697. End Select
  698. '初始化页面
  699. LabLaunchingName.Text = McVersionCurrent.Name
  700. LabLaunchingStage.Text = "初始化"
  701. LabLaunchingTitle.Text = If(McLaunchLoader.Input Is Nothing OrElse McLaunchLoader.Input.SaveBatch Is Nothing, "正在启动游戏", "正在导出启动脚本")
  702. LabLaunchingProgress.Text = "0.00 %"
  703. LabLaunchingProgress.Opacity = 1
  704. LabLaunchingDownload.Visibility = Visibility.Visible
  705. LabLaunchingProgressLeft.Opacity = 0.6
  706. LabLaunchingDownload.Visibility = Visibility.Visible
  707. LabLaunchingDownload.Text = "0 B/s"
  708. LabLaunchingDownload.Opacity = 0
  709. LabLaunchingDownload.Visibility = Visibility.Collapsed
  710. LabLaunchingDownloadLeft.Opacity = 0
  711. LabLaunchingDownloadLeft.Visibility = Visibility.Collapsed
  712. ProgressLaunchingFinished.Width = New GridLength(0, GridUnitType.Star)
  713. ProgressLaunchingUnfinished.Width = New GridLength(1, GridUnitType.Star)
  714. PanLaunchingHint.Opacity = 0
  715. PanLaunchingHint.Visibility = Visibility.Collapsed
  716. PanLaunchingInfo.Width = Double.NaN '重置宽度改变动画
  717. McLaunchProcess = Nothing
  718. McLaunchWatcher = Nothing
  719. '获取 “你知道吗” 提示
  720. Dim Hint As String = PageOtherTest.GetRandomHint()
  721. Try
  722. Dim RawHints = Array.FindAll(
  723. ReadFile(Path & "PCL\hints.txt").Replace(vbLf, "").Split(vbCr),
  724. Function(Input As String) As Boolean
  725. Return Not String.IsNullOrWhiteSpace(Input)
  726. End Function)
  727. If RawHints.Count > 0 Then Hint = RandomOne(RawHints)
  728. Catch ex As Exception
  729. Log(ex, "获取自定义 你知道吗 提示失败", LogLevel.Hint)
  730. End Try
  731. LabLaunchingHint.Text = Hint
  732. End Sub
  733. Private ShowProgress As Double = 0
  734. ''' <summary>
  735. ''' 每 0.2s 执行一次,刷新启动的数据 UI 显示。
  736. ''' </summary>
  737. Public Sub LaunchingRefresh()
  738. Try
  739. If McLaunchLoaderReal.State = LoadState.Aborted Then Exit Sub
  740. '阶段状态获取
  741. Dim IsLaunched As Boolean = False '是否已经启动游戏,只是在等待窗口
  742. Try
  743. For Each Loader In McLaunchLoaderReal.GetLoaderList(False)
  744. If Loader.State = LoadState.Loading OrElse Loader.State = LoadState.Waiting Then
  745. LabLaunchingStage.Text = Loader.Name
  746. IsLaunched = Loader.Name = "等待游戏窗口出现" OrElse Loader.Name = "结束处理"
  747. Exit Try
  748. End If
  749. Next
  750. LabLaunchingStage.Text = "已完成"
  751. Catch ex As Exception
  752. Log(ex, "获取是否启动完成失败,可能是由于启动状态改变导致集合已修改")
  753. Exit Sub
  754. End Try
  755. If AniIsRun("Launch State Page") Then IsLaunched = False '等待页面切换动画完成
  756. '计算应显示的进度
  757. Dim ActualProgress = McLaunchLoaderReal.Progress
  758. If ActualProgress >= ShowProgress Then ShowProgress += (ActualProgress - ShowProgress) * 0.2 + 0.005 '向实际进度靠一点
  759. If ActualProgress <= ShowProgress Then ShowProgress = ActualProgress '原来或处理后变得比实际进度高,直接回退
  760. If IsLaunched Then ShowProgress = 1 '如果已经完成了,就不卖关子了
  761. '文本
  762. LabLaunchingTitle.Text = If(IsLaunched, "已启动游戏", If(McLaunchLoader.Input.SaveBatch Is Nothing, "正在启动游戏", "正在导出启动脚本"))
  763. LabLaunchingProgress.Text = StrFillNum(ShowProgress * 100, 2) & " %"
  764. Dim HasLaunchDownloader As Boolean = False
  765. Try
  766. For Each Loader In NetManager.Tasks
  767. If Loader.RealParent IsNot Nothing AndAlso Loader.RealParent.Name = "Minecraft 启动" AndAlso Loader.State = LoadState.Loading Then HasLaunchDownloader = True
  768. Next
  769. Catch ex As Exception
  770. Log(ex, "获取 Minecraft 启动下载器失败,可能是因为启动被取消")
  771. HasLaunchDownloader = False
  772. End Try
  773. LabLaunchingDownload.Text = GetString(NetManager.Speed) & "/s"
  774. '进度改变动画
  775. Dim AnimList As New List(Of AniData) From {
  776. AaGridLengthWidth(ProgressLaunchingFinished, ShowProgress - ProgressLaunchingFinished.Width.Value, 260,, New AniEaseOutFluent),
  777. AaGridLengthWidth(ProgressLaunchingUnfinished, 1 - ShowProgress - ProgressLaunchingUnfinished.Width.Value, 260,, New AniEaseOutFluent)
  778. }
  779. Dim IsDownloadStateChanged As Boolean = HasLaunchDownloader = (LabLaunchingDownload.Visibility = Visibility.Collapsed)
  780. If IsDownloadStateChanged Then
  781. LabLaunchingDownload.Visibility = Visibility.Visible
  782. LabLaunchingDownloadLeft.Visibility = Visibility.Visible
  783. AnimList.AddRange({
  784. AaOpacity(LabLaunchingDownload, If(HasLaunchDownloader, 1, 0) - LabLaunchingDownload.Opacity, 100),
  785. AaOpacity(LabLaunchingDownloadLeft, If(HasLaunchDownloader, 0.5, 0) - LabLaunchingDownloadLeft.Opacity, 100),
  786. AaCode(Sub()
  787. If Not HasLaunchDownloader Then
  788. LabLaunchingDownload.Visibility = Visibility.Collapsed
  789. LabLaunchingDownloadLeft.Visibility = Visibility.Collapsed
  790. End If
  791. End Sub, 110)
  792. })
  793. End If
  794. Dim IsProgressStateChanged As Boolean = (Not IsLaunched) = (LabLaunchingProgress.Visibility = Visibility.Collapsed)
  795. If IsProgressStateChanged Then
  796. LabLaunchingProgress.Visibility = Visibility.Visible
  797. LabLaunchingProgressLeft.Visibility = Visibility.Visible
  798. If IsLaunched Then
  799. 'IsWidthAnimating = True
  800. PanLaunchingHint.Visibility = Visibility.Visible
  801. 'AniStop("Launching Info Width")
  802. 'PanLaunchingInfo.Width = 260
  803. 'ActualUsedWidth = 260
  804. 'IsWidthAnimating = False
  805. End If
  806. AnimList.AddRange({
  807. AaOpacity(LabLaunchingProgress, If(Not IsLaunched, 1, 0) - LabLaunchingProgress.Opacity, 100),
  808. AaOpacity(LabLaunchingProgressLeft, If(Not IsLaunched, 0.5, 0) - LabLaunchingProgressLeft.Opacity, 100),
  809. AaOpacity(PanLaunchingHint, If(IsLaunched, 1, 0) - PanLaunchingHint.Opacity, 100)
  810. })
  811. End If
  812. AniStart(AnimList, "Launching Progress")
  813. Catch ex As Exception
  814. Log(ex, "刷新启动信息失败", LogLevel.Feedback)
  815. End Try
  816. End Sub
  817. '尺寸改变动画
  818. Private IsWidthAnimating As Boolean = False
  819. Private ActualUsedWidth As Double
  820. Private Sub PanLaunchingInfo_SizeChangedW(sender As Object, e As SizeChangedEventArgs) Handles PanLaunchingInfo.SizeChanged
  821. Dim DeltaWidth As Double = e.NewSize.Width - e.PreviousSize.Width
  822. If e.PreviousSize.Width = 0 OrElse IsWidthAnimating OrElse Math.Abs(DeltaWidth) < 1 OrElse PanLaunchingInfo.ActualWidth = 0 Then Exit Sub
  823. AniStart({
  824. AaWidth(PanLaunchingInfo, DeltaWidth, 180,, New AniEaseOutFluent),
  825. AaCode(Sub()
  826. IsWidthAnimating = False
  827. PanLaunchingInfo.Width = ActualUsedWidth
  828. End Sub,, True)
  829. }, "Launching Info Width")
  830. IsWidthAnimating = True
  831. ActualUsedWidth = PanLaunchingInfo.Width
  832. PanLaunchingInfo.Width = e.PreviousSize.Width
  833. End Sub
  834. Private IsHeightAnimating As Boolean = False
  835. Private ActualUsedHeight As Double
  836. Private Sub PanLaunchingInfo_SizeChangedH(sender As Object, e As SizeChangedEventArgs) Handles PanLaunchingInfo.SizeChanged
  837. Dim DeltaHeight As Double = e.NewSize.Height - e.PreviousSize.Height
  838. If e.PreviousSize.Height = 0 OrElse IsHeightAnimating OrElse Math.Abs(DeltaHeight) < 1 OrElse PanLaunchingInfo.ActualHeight = 0 Then Exit Sub
  839. AniStart({
  840. AaHeight(PanLaunchingInfo, DeltaHeight, 180,, New AniEaseOutFluent),
  841. AaCode(Sub()
  842. IsHeightAnimating = False
  843. PanLaunchingInfo.Height = ActualUsedHeight
  844. End Sub,, True)
  845. }, "Launching Info Height")
  846. IsHeightAnimating = True
  847. ActualUsedHeight = PanLaunchingInfo.Height
  848. PanLaunchingInfo.Height = e.PreviousSize.Height
  849. End Sub
  850. End Class