diff --git a/Plain Craft Launcher 2/Application.xaml.vb b/Plain Craft Launcher 2/Application.xaml.vb index b7a5504..43d1698 100644 --- a/Plain Craft Launcher 2/Application.xaml.vb +++ b/Plain Craft Launcher 2/Application.xaml.vb @@ -30,7 +30,7 @@ Public Class Application UpdateReplace(e.Args(1), e.Args(2).Trim(""""), e.Args(3).Trim(""""), e.Args(4)) Environment.[Exit](Result.Cancel) Exit Sub - ElseIf e.Args(0) = "--link" Then + ElseIf e.Args(0).StartsWith("--link") Then '稍作等待后切换到联机页面 Thread.Sleep(1000) FormMain.IsLinkRestart = True @@ -142,11 +142,9 @@ Public Class Application End Sub '动态 DLL 调用 - Private Shared AssemblyStun As Assembly Private Shared AssemblyNAudio As Assembly Private Shared AssemblyJson As Assembly Private Shared AssemblyDialog As Assembly - Private Shared ReadOnly AssemblyStunLock As New Object Private Shared ReadOnly AssemblyNAudioLock As New Object Private Shared ReadOnly AssemblyJsonLock As New Object Private Shared ReadOnly AssemblyDialogLock As New Object @@ -175,14 +173,6 @@ Public Class Application End If Return AssemblyDialog End SyncLock - ElseIf args.Name.StartsWith("STUN") Then - SyncLock AssemblyStunLock - If AssemblyStun Is Nothing Then - Log("[Start] 加载 DLL:STUN") - AssemblyStun = Assembly.Load(GetResources("STUN")) - End If - Return AssemblyStun - End SyncLock Else Return Nothing End If diff --git a/Plain Craft Launcher 2/Controls/MyCard.vb b/Plain Craft Launcher 2/Controls/MyCard.vb index 72c2523..72c0cd3 100644 --- a/Plain Craft Launcher 2/Controls/MyCard.vb +++ b/Plain Craft Launcher 2/Controls/MyCard.vb @@ -25,9 +25,9 @@ Public Sub New() MainChrome = New SystemDropShadowChrome With {.Margin = New Thickness(-9.5, -9, 0.5, -0.5), .Opacity = 0.1, .CornerRadius = New CornerRadius(6)} MainChrome.SetResourceReference(SystemDropShadowChrome.ColorProperty, "ColorObject1") - Children.Add(MainChrome) + Children.Insert(0, MainChrome) MainBorder = New Border With {.Background = New SolidColorBrush(Color.FromArgb(205, 255, 255, 255)), .CornerRadius = New CornerRadius(6), .IsHitTestVisible = False} - Children.Add(MainBorder) + Children.Insert(1, MainBorder) MainGrid = New Grid Children.Add(MainGrid) End Sub diff --git a/Plain Craft Launcher 2/Controls/MyIconButton.xaml.vb b/Plain Craft Launcher 2/Controls/MyIconButton.xaml.vb index aba7e65..db8e038 100644 --- a/Plain Craft Launcher 2/Controls/MyIconButton.xaml.vb +++ b/Plain Craft Launcher 2/Controls/MyIconButton.xaml.vb @@ -30,6 +30,7 @@ Color White Black + Red Custom End Enum Public Property Theme As Themes = Themes.Color @@ -101,6 +102,8 @@ AnimList.Add(AaColor(Path, Shape.FillProperty, "ColorBrush2", AnimationColorIn)) Case Themes.White AnimList.Add(AaColor(PanBack, BackgroundProperty, New MyColor(50, 255, 255, 255) - PanBack.Background, AnimationColorIn)) + Case Themes.Red + AnimList.Add(AaColor(Path, Shape.FillProperty, New MyColor(255, 76, 76) - Path.Fill, AnimationColorIn)) Case Themes.Black AnimList.Add(AaColor(Path, Shape.FillProperty, New MyColor(230, 0, 0, 0) - Path.Fill, AnimationColorIn)) Case Themes.Custom @@ -117,6 +120,9 @@ Case Themes.White AnimList.Add(AaColor(Path, Shape.FillProperty, "ColorBrush8", AnimationColorOut)) AnimList.Add(AaColor(PanBack, BackgroundProperty, New MyColor(0, 255, 255, 255) - PanBack.Background, AnimationColorOut)) + Case Themes.Red + AnimList.Add(AaColor(Path, Shape.FillProperty, New MyColor(160, 255, 76, 76) - Path.Fill, AnimationColorOut)) + PanBack.Background = New MyColor(0, 255, 255, 255) Case Themes.Black AnimList.Add(AaColor(Path, Shape.FillProperty, New MyColor(160, 0, 0, 0) - Path.Fill, AnimationColorOut)) PanBack.Background = New MyColor(0, 255, 255, 255) @@ -135,6 +141,8 @@ Path.SetResourceReference(Shape.FillProperty, "ColorBrush5") Case Themes.White Path.SetResourceReference(Shape.FillProperty, "ColorBrush8") + Case Themes.Red + Path.Fill = New MyColor(160, 255, 76, 76) Case Themes.Black Path.Fill = New MyColor(160, 0, 0, 0) Case Themes.Custom diff --git a/Plain Craft Launcher 2/Controls/MyPageRight.vb b/Plain Craft Launcher 2/Controls/MyPageRight.vb index 50c2a6a..ab6c666 100644 --- a/Plain Craft Launcher 2/Controls/MyPageRight.vb +++ b/Plain Craft Launcher 2/Controls/MyPageRight.vb @@ -12,7 +12,7 @@ LoaderExit '加载环退出动画 ContentEnter '内容进入动画 ContentStay '内容正常显示 - ReloadExit '刷新导致的全部退出动画 + ContentExit '刷新导致的全部退出动画,或页面内容退出(子页面更改)导致的全部退出动画 PageExit '切换页面导致的全部退出动画 End Enum Private _PageState As PageStates = PageStates.Empty @@ -48,7 +48,8 @@ ''' 在工作线程执行的加载器。 ''' 当加载器执行完成,在 UI 线程触发的 UI 初始化事件。 Public Sub PageLoaderInit(LoaderUi As MyLoading, PanLoader As FrameworkElement, PanContent As FrameworkElement, PanAlways As FrameworkElement, - RealLoader As LoaderBase, FinishedInvoke As Action(Of LoaderBase), Optional InputInvoke As Func(Of Object) = Nothing, + RealLoader As LoaderBase, + Optional FinishedInvoke As Action(Of LoaderBase) = Nothing, Optional InputInvoke As Func(Of Object) = Nothing, Optional AutoRun As Boolean = True) '初始化参数 Me.PanLoader = PanLoader @@ -59,14 +60,16 @@ Me.PageLoaderInputInvoke = InputInvoke Me.PageLoaderAutoRun = AutoRun '添加结束 Invoke - AddHandler RealLoader.PreviewFinish, - Sub() - Do While PageState = MyPageRight.PageStates.PageExit OrElse PageState = MyPageRight.PageStates.ReloadExit - Thread.Sleep(10) '不在退出动画时执行 UI 线程操作,避免退出动画被重置 + If FinishedInvoke IsNot Nothing Then + AddHandler RealLoader.PreviewFinish, + Sub() + Do While PageState = MyPageRight.PageStates.PageExit OrElse PageState = MyPageRight.PageStates.ContentExit + Thread.Sleep(10) '不在退出动画时执行 UI 线程操作,避免退出动画被重置 Loop - RunInUiWait(Sub() FinishedInvoke(RealLoader)) - Thread.Sleep(20) '由于大量初始化控件会导致掉帧,延迟触发 State 改变事件 + RunInUiWait(Sub() FinishedInvoke(RealLoader)) + Thread.Sleep(20) '由于大量初始化控件会导致掉帧,延迟触发 State 改变事件 End Sub + End If AddHandler RealLoader.OnStateChangedUi, Sub(Loader As LoaderBase, NewState As LoadState, OldState As LoadState) RunInUi(Sub() PageLoaderState(Loader, NewState, OldState)) '隐藏 UI PanLoader.Visibility = Visibility.Collapsed @@ -82,14 +85,13 @@ PageLoader.Start(Input) End If End If - If PageLoader.State = LoadState.Finished Then + If PageLoader.State = LoadState.Finished AndAlso FinishedInvoke IsNot Nothing Then RunInUiWait(Sub() FinishedInvoke(RealLoader)) '加载器已提前完成,直接触发事件 End If '设置加载环 PageLoaderUi.State = RealLoader AddHandler PageLoaderUi.Click, Sub() If RealLoader.State = LoadState.Failed Then PageLoaderRestart() '点击重试事件 End Sub - '重试 Public Sub PageLoaderRestart(Optional Input As Object = Nothing, Optional IsForceRestart As Boolean = True) '由外部调用的重试 If Not PageLoaderAutoRun Then Exit Sub @@ -112,32 +114,38 @@ ''' Public Sub PageOnEnter() If ModeDebug Then Log("[UI] 已触发 PageOnEnter") - RaiseEvent OnPageEnter() - + RaiseEvent PageEnter() Select Case PageState Case PageStates.Empty - If PageLoader Is Nothing OrElse PageLoader.State = LoadState.Finished OrElse PageLoader.State = LoadState.Aborted Then + If PageLoader Is Nothing OrElse PageLoader.State = LoadState.Finished OrElse PageLoader.State = LoadState.Waiting OrElse PageLoader.State = LoadState.Aborted Then + '如果加载器在进入页面时不启动(例如 HiPer 联机),那么在此时就会有 State = Waiting PageState = PageStates.ContentEnter TriggerEnterAnimation(PanAlways, If(PanContent, Child)) ElseIf PageLoader.State = LoadState.Loading Then PageState = PageStates.LoaderWait AniStart(AaCode(AddressOf PageOnLoaderWaitFinished, 200), "PageRight PageChange " & PageUuid) - ElseIf PageLoader.State = LoadState.Failed Then + Else 'PageLoader.State = LoadState.Failed PageState = PageStates.LoaderEnter TriggerEnterAnimation(PanAlways, PanLoader) - ElseIf PageLoader.State = LoadState.Waiting Then - '由于 “页面加载器 Minecraft Version List 不应在 PageOnEnter 事件出现 Waiting 状态” 的神秘反馈添加的临时修复 + End If + Case PageStates.ContentExit + '和上面的一样,但是不管 PanAlways + If PageLoader Is Nothing OrElse PageLoader.State = LoadState.Finished OrElse PageLoader.State = LoadState.Waiting OrElse PageLoader.State = LoadState.Aborted Then + PageState = PageStates.ContentEnter + TriggerEnterAnimation(If(PanContent, Child)) + ElseIf PageLoader.State = LoadState.Loading Then PageState = PageStates.LoaderWait AniStart(AaCode(AddressOf PageOnLoaderWaitFinished, 200), "PageRight PageChange " & PageUuid) - Log("[Anim] 警告:页面加载器 " & PageLoader.Name & " 不应在 PageOnEnter 事件出现 " & GetStringFromEnum(PageLoader.State) & " 状态", LogLevel.Debug) - Else - Throw New Exception("页面加载器 " & PageLoader.Name & " 不应在 PageOnEnter 事件出现 " & GetStringFromEnum(PageLoader.State) & " 状态。") + Else 'PageLoader.State = LoadState.Failed + PageState = PageStates.LoaderEnter + TriggerEnterAnimation(PanLoader) End If + Case PageStates.ContentEnter '重复调用 PageOnEnter,直接忽略 Case Else Throw New Exception("在状态为 " & GetStringFromEnum(PageState) & " 时触发了 PageOnEnter 事件。") End Select End Sub - Public Event OnPageEnter() + Public Event PageEnter() ''' ''' 需要切换到其他页面。 ''' 需要立即切换至 PageExit 或 Empty。 @@ -154,7 +162,7 @@ Case PageStates.LoaderWait PageState = PageStates.PageExit TriggerExitAnimation(PanAlways) - Case PageStates.LoaderExit, PageStates.ReloadExit + Case PageStates.LoaderExit, PageStates.ContentExit PageState = PageStates.PageExit If PanAlways IsNot Nothing Then TriggerExitAnimation(PanAlways, If(PanContent, Child)) Case PageStates.PageExit, PageStates.Empty @@ -178,6 +186,29 @@ If PanAlways IsNot Nothing Then PanAlways.Visibility = Visibility.Collapsed End If End Sub + ''' + ''' PanContent 中的子页面改变,需要让当前内容退出,再显示新的内容。 + ''' 需要在 PageEnter 事件确认要显示的子页面有哪些。 + ''' + Public Sub PageOnContentExit() + If ModeDebug Then Log("[UI] 已触发 PageOnContentExit") + If PageLoader IsNot Nothing AndAlso PageLoader.State = LoadState.Loading Then + Throw New Exception("在调用 PageOnContentExit 时,加载器不能为 Loading 状态") + 'Loading 的加载器可能触发进一步变化,难以预测会触发子页面的动画还是加载器完成的动画 + End If + Select Case PageState + Case PageStates.ContentEnter, PageStates.ContentStay + PageState = PageStates.ContentExit + TriggerExitAnimation(PanContent) + Case PageStates.LoaderExit + PageState = PageStates.ContentExit + Case PageStates.LoaderEnter, PageStates.LoaderStayForce, PageStates.LoaderStay + PageState = PageStates.ContentExit + TriggerExitAnimation(PanLoader) + Case PageStates.LoaderWait, PageStates.Empty + PageOnEnter() + End Select + End Sub '内部触发的事件 ''' @@ -205,8 +236,7 @@ Select Case PageState Case PageStates.PageExit PageState = PageStates.Empty - Case PageStates.ReloadExit - PageState = PageStates.Empty + Case PageStates.ContentExit PageOnEnter() Case PageStates.LoaderExit PageState = PageStates.ContentEnter @@ -258,20 +288,20 @@ Private Sub PageLoaderState(sender As Object, NewState As LoadState, OldState As LoadState) Select Case NewState Case LoadState.Failed, LoadState.Loading - If Not OldState = LoadState.Finished Then Exit Sub - If ModeDebug Then Log("[UI] 已触发 PageLoaderState (Refresh)") - '重新开始运行 + If OldState = LoadState.Failed OrElse OldState = LoadState.Loading Then Exit Sub + If ModeDebug Then Log("[UI] 已触发 PageLoaderState (Start/Refresh)") + '(重新)开始运行 '需要从部分状态切换到 ReloadExit Select Case PageState Case PageStates.ContentEnter, PageStates.ContentStay - PageState = PageStates.ReloadExit + PageState = PageStates.ContentExit TriggerExitAnimation(PanContent) - Case PageStates.LoaderExit, PageStates.ReloadExit - PageState = PageStates.ReloadExit + Case PageStates.LoaderExit + PageState = PageStates.ContentExit End Select - Case LoadState.Finished - If Not OldState = LoadState.Loading Then Exit Sub - If ModeDebug Then Log("[UI] 已触发 PageLoaderState (Stop)") + Case LoadState.Finished, LoadState.Aborted, LoadState.Waiting + If Not (OldState = LoadState.Failed OrElse OldState = LoadState.Loading) Then Exit Sub + If ModeDebug Then Log("[UI] 已触发 PageLoaderState (Stop/Abort)") '运行结束 '需要从 LoaderWait 切换到 ContentEnter,或从 LoaderStay 切换到 LoaderExit Select Case PageState @@ -360,13 +390,14 @@ End Function Private Sub GetAllAnimControls(Element As FrameworkElement, ByRef AllControls As List(Of FrameworkElement), IgnoreInvisibility As Boolean) If Not IgnoreInvisibility AndAlso Element.Visibility = Visibility.Collapsed Then Exit Sub - If TypeOf Element Is MyCard OrElse TypeOf Element Is MyHint Then + If TypeOf Element Is MyCard OrElse TypeOf Element Is MyHint OrElse TypeOf Element Is TextBlock OrElse TypeOf Element Is MyTextButton Then AllControls.Add(Element) ElseIf TypeOf Element Is ContentControl Then - GetAllAnimControls(CType(Element, ContentControl).Content, AllControls, IgnoreInvisibility) + Dim Content = CType(Element, ContentControl).Content + If Content IsNot Nothing AndAlso TypeOf Content Is FrameworkElement Then GetAllAnimControls(Content, AllControls, IgnoreInvisibility) ElseIf TypeOf Element Is Panel Then - For Each Element2 As FrameworkElement In CType(Element, Panel).Children - GetAllAnimControls(Element2, AllControls, IgnoreInvisibility) + For Each Element2 In CType(Element, Panel).Children + If TypeOf Element2 Is FrameworkElement Then GetAllAnimControls(Element2, AllControls, IgnoreInvisibility) Next End If End Sub diff --git a/Plain Craft Launcher 2/FormMain.xaml.vb b/Plain Craft Launcher 2/FormMain.xaml.vb index a8bba2d..8d59064 100644 --- a/Plain Craft Launcher 2/FormMain.xaml.vb +++ b/Plain Craft Launcher 2/FormMain.xaml.vb @@ -17,7 +17,7 @@ Public Class FormMain BugCount += 9 End If If LastVersion < 260 Then 'Release 2.3.2 - FeatureList.Add(New KeyValuePair(Of Integer, String)(5, "解决了联机人数 ≥3 人时出现的频繁掉线或突发高延迟的问题")) + FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "解决了联机人数 ≥3 人时出现的频繁掉线或突发高延迟的问题")) FeatureCount += 22 BugCount += 4 End If @@ -32,22 +32,21 @@ Public Class FormMain BugCount += 3 End If If LastVersion < 253 Then 'Release 2.2.13 - FeatureList.Add(New KeyValuePair(Of Integer, String)(7, "支持在安装菜单中直接安装 OptiFabric")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(5, "支持调整 Mod 文件名中中文译名的位置")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "崩溃分析优化,支持分析更多 Forge 相关的崩溃")) + FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "支持在安装菜单中直接安装 OptiFabric")) + FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "支持调整 Mod 文件名中中文译名的位置")) + FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "崩溃分析优化,支持分析更多 Forge 相关的崩溃")) FeatureCount += 13 BugCount += 27 End If If LastVersion < 250 Then 'Release 2.2.11 - FeatureList.Add(New KeyValuePair(Of Integer, String)(6, "支持将 Mod 文件拖入窗口进行安装")) + FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "支持将 Mod 文件拖入窗口进行安装")) If LastVersion = 246 Then FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "修复无法使用中文搜索 Mod 的 Bug")) FeatureCount += 8 BugCount += 33 End If If LastVersion < 246 Then 'Release 2.2.9 - FeatureList.Add(New KeyValuePair(Of Integer, String)(5, "Mod 下载支持筛选 Forge Mod 与 Fabric Mod")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "大幅修改联机页面布局(作为联机优化的第二个阶段)")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "Mod、整合包下载的综合优化")) + FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "Mod 下载支持筛选 Forge Mod 与 Fabric Mod")) + FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "Mod、整合包下载的综合优化")) FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "修复使用离线登录进入 Forge 的存档可能导致游戏崩溃")) FeatureCount += 13 BugCount += 11 @@ -62,92 +61,41 @@ Public Class FormMain BugCount += 2 End If If LastVersion < 236 Then 'Release 2.2.5 - FeatureList.Add(New KeyValuePair(Of Integer, String)(6, "网络状态检测支持检测 Windows 防火墙与网络延迟")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(6, "重制右侧页面的切换动画,卡片与提示条将逐个进入退出,并具有独特的位移动画")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(5, "添加 MC 1.18 中要求 Java 17 的检测与提醒")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "优化页面切换、下载的性能")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "允许拖拽按钮的设置第三方登录")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "修复网络状态检测的结果总为 A 级的 Bug")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "修复无法下载新版本的 Forge 的 Bug")) + FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "网络状态检测支持检测 Windows 防火墙与网络延迟")) + FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "重制右侧页面的切换动画,卡片与提示条将逐个进入退出,并具有独特的位移动画")) + FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "添加 MC 1.18 中要求 Java 17 的检测与提醒")) + FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "优化页面切换、下载的性能")) + FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "允许拖拽按钮设置第三方登录")) + FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "修复无法下载新版本的 Forge 的 Bug")) FeatureCount += 25 BugCount += 22 End If If LastVersion < 233 Then 'Release 2.2.3 - FeatureList.Add(New KeyValuePair(Of Integer, String)(7, "微软账号支持更换皮肤与披风")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(6, "支持拖拽整合包文件到 PCL2 进行快捷安装")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(6, "Mod 下载支持显示对应的 MC 版本与 Mod 加载器,且可以跳转到 MCBBS 介绍页")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(5, "支持安装 1.17 OptiFine + Forge")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(5, "使用 Mojang 账号登录将会显示迁移提醒")) + FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "微软账号支持更换皮肤与披风")) + FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "支持拖拽整合包文件到 PCL2 进行快捷安装")) + FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "Mod 下载支持显示对应的 MC 版本与 Mod 加载器,且可以跳转到 MCBBS 介绍页")) + FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "支持安装 1.17 OptiFine + Forge")) + FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "使用 Mojang 账号登录将会显示迁移提醒")) FeatureCount += 12 BugCount += 26 End If If LastVersion < 231 Then 'Release 2.2.1, Also 229 - FeatureList.Add(New KeyValuePair(Of Integer, String)(9, "联机功能的早期测试(尚未完成,延迟很高,之后会优化的)")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(5, "添加 1.18 实验性快照 5 的特供下载,且支持列表的联网更新")) + FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "添加 1.18 实验性快照 5 的特供下载,且支持列表的联网更新")) FeatureCount += 11 BugCount += 3 End If - If LastVersion < 226 Then 'Release 2.1.4 - FeatureList.Add(New KeyValuePair(Of Integer, String)(6, "支持 1.17.1 Forge、Fabric 的安装与启动")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "优化 Forge 下载与安装速度,提高安装稳定性")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "更新内置帮助库,添加数个指南页面与整合包、存档的安装教程")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "支持将游戏文件夹压缩包作为游戏整合包导入")) - FeatureCount += 12 - BugCount += 13 - End If - If LastVersion < 224 Then 'Release 2.1.3 - FeatureList.Add(New KeyValuePair(Of Integer, String)(6, "界面与动画综合优化,重新制作主题配色")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(5, "添加 1.18 实验性快照的特供下载")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "更新内置帮助库,添加光影、数据包、Mod 等资源的安装教程")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "游戏崩溃分析优化")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "若设置为自动更新,PCL2 会在关闭时才替换文件")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "追加大量千万████的可能性")) - 'FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "支持 1.17 Forge 的安装与启动")) - FeatureCount += 33 - BugCount += 20 - End If - If LastVersion < 217 Then 'Release 2.0.5 - FeatureList.Add(New KeyValuePair(Of Integer, String)(7, "可以根据游戏版本自动选择所需的 Java")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(6, "允许在 Java 版本检测不通过时强制指定使用 Java")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(6, "允许为不同版本独立设置 Java")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(5, "Java 选择与搜索的综合优化")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "修复无法使用 Mod、整合包搜索功能的 Bug")) - FeatureCount += 8 - BugCount += 20 - End If - If LastVersion < 214 Then 'Release 2.0.2 - FeatureList.Add(New KeyValuePair(Of Integer, String)(6, "添加一键关闭所有运行中的 Minecraft 的按钮")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(5, "增加对 MC 1.17 需要 Java 16 的检测与说明")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "Minecraft 崩溃分析优化")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "修复无法修改部分个性化设置的严重 Bug")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复 Windows 7 可能无法登录微软账号的严重 Bug")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复网络不稳定时安装整合包极易失败的严重 Bug")) - FeatureCount += 10 - BugCount += 13 - End If - If LastVersion < 212 Then 'Release 2.0.0 - FeatureList.Add(New KeyValuePair(Of Integer, String)(9, "添加帮助页面,且可以自行添加、删除其中的内容")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(6, "支持安装 MCBBS 格式的整合包")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(5, "自定义主页/帮助页面的 XAML 功能扩展")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(5, "同时安装 OptiFine 与 Forge 时,OptiFine 将作为 Mod 安装")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "优化 CurseForge 搜索")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "优化多个报错提示,更加人性化")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "适配适用于快照版 MC 的 OptiFine")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "修复进入 OptiFine 下载页面导致卡死的严重 Bug")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复无法启动部分 OptiFine+Forge 版本的 Bug")) - FeatureCount += 20 - BugCount += 42 - End If #Else - '9:大+ - '8:中大+ - '7:中+,大* - '6:中小型+,中大* - '5:小型+,中* - '4:中小* - '3:小* - '2:极度严重的 Bug - '1:严重的 Bug + '5: FEAT+ + '4: IMP+ FEAT* + '3:BUG+ IMP* FEAT- + '2:BUG* IMP- + '1:BUG- + If LastVersion < 266 Then 'Snapshot 2.4.0 + FeatureList.Add(New KeyValuePair(Of Integer, String)(5, "追加新的联机方式(HiPer 联机模块)")) + FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "游戏崩溃的弹窗添加了直接查看日志的选项")) + FeatureCount += 3 + BugCount += 8 + End If If LastVersion < 264 Then 'Snapshot 2.3.5 FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "修复无法启动部分 Forge 版本的 Bug")) FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复多个可能导致 OptiFine、Forge 安装失败的 Bug")) @@ -160,7 +108,7 @@ Public Class FormMain BugCount += 5 End If If LastVersion < 262 Then 'Snapshot 2.3.3 - FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "修复无法使用 Mod、整合包搜索功能的 Bug")) + FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "修复无法使用 Mod、整合包搜索功能的 Bug")) BugCount += 1 End If If LastVersion < 261 Then 'Snapshot 2.3.2 @@ -168,11 +116,10 @@ Public Class FormMain BugCount += 4 End If If LastVersion < 259 Then 'Snapshot 2.3.1 - FeatureList.Add(New KeyValuePair(Of Integer, String)(5, "解决了联机人数 ≥3 人时出现的频繁掉线或突发高延迟的问题")) + FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "解决了联机人数 ≥3 人时出现的频繁掉线或突发高延迟的问题")) FeatureCount += 14 End If If LastVersion < 258 Then 'Snapshot 2.3.0 - FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "修复下载部分 Mod、整合包的 Bug")) FeatureCount += 4 BugCount += 4 End If @@ -182,19 +129,19 @@ Public Class FormMain BugCount += 3 End If If LastVersion < 254 Then 'Snapshot 2.2.13 - FeatureList.Add(New KeyValuePair(Of Integer, String)(5, "支持调整 Mod 文件名中中文译名的位置")) + FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "支持调整 Mod 文件名中中文译名的位置")) FeatureCount += 3 BugCount += 17 End If If LastVersion < 252 Then 'Snapshot 2.2.12 - FeatureList.Add(New KeyValuePair(Of Integer, String)(7, "支持在安装菜单中直接安装 OptiFabric")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "崩溃分析优化,支持分析更多 Forge 相关的崩溃")) - If LastVersion = 251 Then FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复同时安装 Forge 和 OptiFine 时 OptiFine 无效的 Bug")) + FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "支持在安装菜单中直接安装 OptiFabric")) + FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "崩溃分析优化,支持分析更多 Forge 相关的崩溃")) + If LastVersion = 251 Then FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "修复同时安装 Forge 和 OptiFine 时 OptiFine 无效的 Bug")) FeatureCount += 10 BugCount += 10 End If If LastVersion < 251 Then 'Snapshot 2.2.11 - FeatureList.Add(New KeyValuePair(Of Integer, String)(6, "支持将 Mod 文件拖入窗口进行安装")) + FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "支持将 Mod 文件拖入窗口进行安装")) FeatureCount += 2 BugCount += 16 End If @@ -204,14 +151,13 @@ Public Class FormMain BugCount += 17 End If If LastVersion < 247 Then 'Snapshot 2.2.9 - FeatureList.Add(New KeyValuePair(Of Integer, String)(5, "Mod 下载支持筛选 Forge Mod 与 Fabric Mod")) + FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "Mod 下载支持筛选 Forge Mod 与 Fabric Mod")) FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "Mod、整合包下载的综合优化")) FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "修复使用离线登录进入 Forge 的存档可能导致游戏崩溃")) FeatureCount += 8 BugCount += 4 End If If LastVersion < 245 Then 'Snapshot 2.2.8 - FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "大幅修改联机页面布局(作为联机优化的第二个阶段)")) FeatureCount += 5 BugCount += 7 End If @@ -221,116 +167,48 @@ Public Class FormMain End If If LastVersion < 239 Then 'Snapshot 2.2.6 If LastVersion >= 235 Then FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "修复自动更新由于路径错误失败的 Bug")) - If LastVersion = 237 Then FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "修复无法使用联机模块的 Bug")) + If LastVersion = 237 Then FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "修复无法使用联机模块的 Bug")) FeatureCount += 1 BugCount += 1 End If If LastVersion < 237 Then 'Snapshot 2.2.5 - FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "允许拖拽按钮的设置第三方登录")) + FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "允许拖拽按钮设置第三方登录")) If LastVersion = 235 Then FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "修复在启动游戏时有可能卡死的 Bug")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "修复无法下载新版本的 Forge 的 Bug")) FeatureCount += 2 BugCount += 3 End If If LastVersion < 235 Then 'Snapshot 2.2.4 - FeatureList.Add(New KeyValuePair(Of Integer, String)(6, "网络状态检测支持检测 Windows 防火墙与网络延迟")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(6, "重制右侧页面的切换动画,卡片与提示条将逐个进入退出,并具有独特的位移动画")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(5, "添加 MC 1.18 中要求 Java 17 的检测与提醒")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "优化页面切换、下载的性能")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "修复网络状态检测的结果总为 A 级的 Bug")) + FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "网络状态检测支持检测 Windows 防火墙与网络延迟")) + FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "重制右侧页面的切换动画,卡片与提示条将逐个进入退出,并具有独特的位移动画")) + FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "添加 MC 1.18 中要求 Java 17 的检测与提醒")) + FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "优化页面切换、下载的性能")) FeatureCount += 23 BugCount += 19 End If If LastVersion < 234 Then 'Snapshot 2.2.3 - FeatureList.Add(New KeyValuePair(Of Integer, String)(6, "支持拖拽整合包文件到 PCL2 进行快捷安装")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(5, "支持安装 1.17 OptiFine + Forge")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(5, "Mod 详情页面支持跳转 MCBBS 介绍页")) + FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "支持拖拽整合包文件到 PCL2 进行快捷安装")) + FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "支持安装 1.17 OptiFine + Forge")) + FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "Mod 详情页面支持跳转 MCBBS 介绍页")) FeatureCount += 10 BugCount += 17 End If If LastVersion < 232 Then 'Snapshot 2.2.2 - FeatureList.Add(New KeyValuePair(Of Integer, String)(7, "微软账号支持更换皮肤与披风")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(6, "支持显示 Mod 与整合包对应的 MC 版本与 Mod 加载器名称")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(5, "使用 Mojang 账号登录将会显示迁移提醒")) + FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "微软账号支持更换皮肤与披风")) + FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "支持显示 Mod 与整合包对应的 MC 版本与 Mod 加载器名称")) + FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "使用 Mojang 账号登录将会显示迁移提醒")) FeatureCount += 2 BugCount += 9 End If If LastVersion < 230 Then 'Snapshot 2.2.1, Also 228 - If LastVersion = 227 Then FeatureList.Add(New KeyValuePair(Of Integer, String)(6, "联机功能的小优化")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(5, "添加 1.18 实验性快照 5 的特供下载,且支持列表的联网更新")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "修复 Win7 上使用联机功能导致日志文件极大,占用硬盘空间的 Bug")) + FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "添加 1.18 实验性快照 5 的特供下载,且支持列表的联网更新")) + FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复 Win7 上 IOI 联机导致日志文件极大,占用硬盘空间的 Bug")) FeatureCount += 12 BugCount += 4 End If If LastVersion < 227 Then 'Snapshot 2.2.0 - FeatureList.Add(New KeyValuePair(Of Integer, String)(9, "新增联机功能的早期测试版本")) FeatureCount += 2 BugCount += 2 End If - If LastVersion < 225 Then 'Snapshot 2.1.4 - FeatureList.Add(New KeyValuePair(Of Integer, String)(6, "支持 1.17.1 Forge、Fabric 的安装与启动")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "优化 Forge 下载与安装速度,提高安装稳定性")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "更新内置帮助库,添加数个指南页面与整合包、存档的安装教程")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "支持将游戏文件夹压缩包作为游戏整合包导入")) - FeatureCount += 12 - BugCount += 13 - End If - If LastVersion < 223 Then 'Snapshot 2.1.3 - BugCount += 4 - End If - If LastVersion < 222 Then 'Snapshot 2.1.2 - FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "更新内置帮助库,添加光影、数据包、Mod 的安装教程")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "游戏崩溃分析优化")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "修复登录微软账号启动游戏时报错的 Bug")) - FeatureCount += 8 - BugCount += 11 - End If - If LastVersion < 221 Then 'Snapshot 2.1.1 - FeatureList.Add(New KeyValuePair(Of Integer, String)(6, "界面与动画综合优化,重新制作主题配色")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "若识别码不变,更新密钥在输入一次后会一直有效")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "若设置为自动更新,PCL2 会在关闭时才替换文件")) - FeatureCount += 10 - BugCount += 5 - End If - If LastVersion < 220 Then 'Snapshot 2.1.0 - 'FeatureList.Add(New KeyValuePair(Of Integer, String)(5, "界面与动画综合优化")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "追加大量千万████的可能性")) - FeatureCount += 15 - End If - If LastVersion < 219 Then 'Snapshot 2.0.5 - FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "修复无法使用 Mod、整合包搜索功能的 Bug")) - BugCount += 2 - End If - If LastVersion < 218 Then 'Snapshot 2.0.4 - FeatureList.Add(New KeyValuePair(Of Integer, String)(6, "允许为不同版本独立设置 Java")) - BugCount += 12 - End If - If LastVersion < 216 Then 'Snapshot 2.0.3 - FeatureList.Add(New KeyValuePair(Of Integer, String)(7, "可以根据游戏版本自动选择所需的 Java")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(6, "允许在 Java 版本检测不通过时强制指定使用 Java")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(5, "Java 选择与搜索的综合优化")) - FeatureCount += 8 - BugCount += 7 - End If - If LastVersion < 215 Then 'Snapshot 2.0.2 - If LastVersion = 213 Then FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复账号切换、版本选择下拉框无法展开的严重 Bug")) - If LastVersion = 213 Then FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复误判部分客户端需要 Java 16,导致无法启动游戏的严重 Bug")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复 Windows 7 可能无法登录微软账号的严重 Bug")) - BugCount += 1 - End If - If LastVersion < 213 Then 'Snapshot 2.0.1 - FeatureList.Add(New KeyValuePair(Of Integer, String)(6, "添加一键关闭所有运行中的 Minecraft 的按钮")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(5, "增加对 MC 1.17 需要 Java 16 的检测与说明")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "Minecraft 崩溃分析优化")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复网络不稳定时安装整合包极易失败的严重 Bug")) - FeatureCount += 10 - BugCount += 12 - End If - If LastVersion < 211 Then 'Snapshot 2.0.0 - FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "适配适用于快照版 MC 的 OptiFine")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "修复进入 OptiFine 下载页面导致卡死的严重 Bug")) - BugCount += 3 - End If #End If '整理更新日志文本 Dim ContentList As New List(Of String) @@ -361,7 +239,10 @@ Public Class FormMain '窗口加载 Private IsWindowLoadFinished As Boolean = False - Public Shared IsLinkRestart As Boolean = False '是否为联机提权后自动重启 + ''' + ''' 是否为联机提权后自动重启。 + ''' + Public Shared IsLinkRestart As Boolean = False Public Sub New() ApplicationStartTick = GetTimeTick() '窗体参数初始化 @@ -392,7 +273,7 @@ Public Class FormMain PanMainLeft.Child = FrmLaunchLeft PanMainRight.Child = FrmLaunchRight FrmLaunchRight.PageState = MyPageRight.PageStates.ContentStay - If IsLinkRestart Then PageChange(PageType.Link) + If IsLinkRestart Then PageChange(PageType.Link, PageSubType.LinkIoi) '模式提醒 #If DEBUG Then Hint("[开发者模式] PCL 正以开发者模式运行,这可能会造成严重的性能下降,请务必立即向开发者反馈此问题!", HintType.Critical) @@ -469,7 +350,7 @@ Public Class FormMain RunInNewThread(Sub() If Not Setup.Get("SystemEula") Then Reopen: - Select Case MyMsgBox("在使用 PCL2 前,请同意 PCL2 的用户协议与免责声明。", "协议授权", "同意", "拒绝", "打开用户协议与免责声明页面") + Select Case MyMsgBox("在使用 PCL2 前,请同意 PCL2 的用户协议与免责声明。", "协议授权", "同意", "拒绝", "查看用户协议与免责声明") Case 1 Setup.Set("SystemEula", True) Case 2 @@ -481,7 +362,6 @@ Reopen: End If Try Thread.Sleep(200) - If Setup.Get("LinkAuto") Then PageLinkIoi.InitLoader.Start() DlClientListMojangLoader.Start(1) RunCountSub() ServerLoader.Start(1) @@ -558,9 +438,13 @@ Reopen: "多谢各位的理解啦!", "重新解锁提醒") End If '移动自定义皮肤 - If LastVersionCode <= 161 AndAlso File.Exists(Path & "PCL\CustomSkin.png") AndAlso Not File.Exists(PathTemp & "CustomSkin.png") Then - CopyFile(Path & "PCL\CustomSkin.png", PathTemp & "CustomSkin.png") - Log("[Start] 已移动离线自定义皮肤") + If LastVersionCode <= 161 AndAlso File.Exists(Path & "PCL\CustomSkin.png") AndAlso Not File.Exists(PathAppdata & "CustomSkin.png") Then + CopyFile(Path & "PCL\CustomSkin.png", PathAppdata & "CustomSkin.png") + Log("[Start] 已移动离线自定义皮肤 (162)") + End If + If LastVersionCode <= 263 AndAlso File.Exists(PathTemp & "CustomSkin.png") AndAlso Not File.Exists(PathAppdata & "CustomSkin.png") Then + CopyFile(PathTemp & "CustomSkin.png", PathAppdata & "CustomSkin.png") + Log("[Start] 已移动离线自定义皮肤 (264)") End If '解除帮助页面的隐藏 If LastVersionCode <= 205 Then @@ -632,13 +516,14 @@ Reopen: IsProgramEnded = True AniControlEnabled += 1 PageLinkIoi.IoiStop(False) + PageLinkHiper.HiperStop(False) If IsUpdateWaitingRestart Then UpdateRestart(False) If ReturnCode = Result.Exception Then If Not IsLogShown Then FeedbackInfo() Log("请在 https://jinshuju.net/f/rP4b6E?x_field_1=crash 提交错误报告,以便于作者解决此问题!") IsLogShown = True - ShellAndGetExitCode(Path & "PCL\Log1.txt") + ShellOnly(Path & "PCL\Log1.txt") End If Thread.Sleep(500) '防止 PCL 在记事本打开前就被掐掉 End If @@ -841,7 +726,7 @@ Reopen: '获取并检查目标版本 Dim TargetVersion As McVersion = McVersionCurrent If PageCurrent = PageType.VersionSetup Then TargetVersion = PageVersionLeft.Version - If PageCurrent = PageType.VersionSelect OrElse TargetVersion Is Nothing OrElse Not TargetVersion.Version.Modable Then + If PageCurrent = PageType.VersionSelect OrElse TargetVersion Is Nothing OrElse Not TargetVersion.Modable Then '正在选择版本,或当前版本不能安装 Mod Hint("若要安装 Mod,请先选择一个可以安装 Mod 的版本!") ElseIf Not (PageCurrent = PageType.VersionSetup AndAlso PageCurrentSub = PageSubType.VersionMod) Then @@ -1039,11 +924,11 @@ Install: SetupUI = 1 SetupSystem = 2 SetupLink = 3 - LinkCato = 2 - LinkIoi = 3 - LinkSetup = 5 - LinkHelp = 6 - LinkFeedback = 7 + LinkHiper = 1 + LinkIoi = 2 + LinkSetup = 4 + LinkHelp = 5 + LinkFeedback = 6 OtherHelp = 0 OtherAbout = 1 OtherTest = 2 @@ -1281,7 +1166,6 @@ Install: PageChangeAnim(FrmDownloadLeft, FrmDownloadLeft.PageGet(SubType)) Case PageType.Link '联机 If FrmLinkLeft Is Nothing Then FrmLinkLeft = New PageLinkLeft - If FrmLinkIoi Is Nothing Then FrmLinkIoi = New PageLinkIoi PageChangeAnim(FrmLinkLeft, FrmLinkLeft.PageGet(SubType)) Case PageType.Setup '设置 If FrmSetupLeft Is Nothing Then FrmSetupLeft = New PageSetupLeft @@ -1337,7 +1221,6 @@ Install: AniStart({ AaCode(Sub() AniControlEnabled += 1 - CType(PanMainRight.Child, MyPageRight).PageOnForceExit() '把新页面添加进容器 PanMainLeft.Child = PageLeft PageLeft.Opacity = 0 diff --git a/Plain Craft Launcher 2/Modules/Base/ModAnimation.vb b/Plain Craft Launcher 2/Modules/Base/ModAnimation.vb index b2b9f0e..eea7562 100644 --- a/Plain Craft Launcher 2/Modules/Base/ModAnimation.vb +++ b/Plain Craft Launcher 2/Modules/Base/ModAnimation.vb @@ -777,12 +777,12 @@ Public Module ModAnimation Log("[Animation] 动画线程开始") Do While True '两帧之间的间隔时间 - Dim DeltaTime As Long = MathRange(GetTimeTick() - AniLastTick, 0, 10000) + Dim DeltaTime As Long = MathRange(GetTimeTick() - AniLastTick, 0, 100000) If DeltaTime < 3 Then GoTo Sleeper AniLastTick = GetTimeTick() '记录 FPS If ModeDebug Then - If MathRange(AniLastTick - AniFPSTimer, 0, 10000) >= 500 Then + If MathRange(AniLastTick - AniFPSTimer, 0, 100000) >= 500 Then AniFPS = AniFPSCounter AniFPSCounter = 0 AniFPSTimer = AniLastTick diff --git a/Plain Craft Launcher 2/Modules/Base/ModBase.vb b/Plain Craft Launcher 2/Modules/Base/ModBase.vb index 9a41170..7d20b7a 100644 --- a/Plain Craft Launcher 2/Modules/Base/ModBase.vb +++ b/Plain Craft Launcher 2/Modules/Base/ModBase.vb @@ -10,12 +10,12 @@ Public Module ModBase #Region "声明" '下列版本信息由更新器自动修改 - Public Const VersionBaseName As String = "2.3.5" '不含分支前缀的显示用版本名 - Public Const VersionStandardCode As String = "2.3.5." & VersionBranchCode '标准格式的四段式版本号 + Public Const VersionBaseName As String = "2.4.0" '不含分支前缀的显示用版本名 + Public Const VersionStandardCode As String = "2.4.0." & VersionBranchCode '标准格式的四段式版本号 #If BETA Then Public Const VersionCode As Integer = 265 'Release #Else - Public Const VersionCode As Integer = 264 'Snapshot + Public Const VersionCode As Integer = 266 'Snapshot #End If '自动生成的版本信息 Public Const VersionDisplayName As String = VersionBranchName & " " & VersionBaseName @@ -82,6 +82,10 @@ Public Module ModBase ''' 程序的缓存文件夹路径,以“\”结尾。 ''' Public PathTemp As String = If(Setup.Get("SystemSystemCache") = "", IO.Path.GetTempPath() & "PCL\", Setup.Get("SystemSystemCache")).ToString.Replace("/", "\").TrimEnd("\") & "\" + ''' + ''' AppData 中的 PCL 文件夹路径,以“\”结尾。 + ''' + Public PathAppdata As String = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) & "\PCL\" #End Region @@ -447,6 +451,32 @@ Public Module ModBase #Region "数学" + ''' + ''' 2~65 进制的转换。 + ''' + Public Function RadixConvert(Input As String, FromRadix As Integer, ToRadix As Integer) As String + Const Digits As String = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/+=" + '零与负数的处理 + If String.IsNullOrEmpty(Input) Then Return "0" + Dim IsNegative As Boolean = Input.StartsWith("-") + If IsNegative Then Input = Input.TrimStart("-") + '转换为十进制 + Dim RealNum As Long = 0, Scale As Long = 1 + For Each Digit In Input.Reverse.Select(Function(l) Digits.IndexOf(l)) + RealNum += Digit * Scale + Scale *= FromRadix + Next + '转换为指定进制 + Dim Result = "" + While RealNum > 0 + Dim NewNum As Integer = RealNum Mod ToRadix + RealNum = (RealNum - NewNum) / ToRadix + Result = Digits(NewNum) & Result + End While + '负数的结束处理与返回 + Return If(IsNegative, "-", "") & Result + End Function + ''' ''' 计算二阶贝塞尔曲线。 ''' @@ -1039,14 +1069,14 @@ Re: Next Return Result.ToString Catch ex As Exception - If Not Retry Then + If Retry OrElse TypeOf ex Is FileNotFoundException Then + Log(ex, "获取文件 MD5 失败:" & FilePath) + Return "" + Else Retry = True Log(ex, "获取文件 MD5 可重试失败:" & FilePath, LogLevel.Normal) Thread.Sleep(RandomInteger(200, 500)) GoTo Re - Else - Log(ex, "获取文件 MD5 失败:" & FilePath) - Return "" End If End Try End Function @@ -1070,14 +1100,14 @@ Re: Next Return Result.ToString Catch ex As Exception - If Not Retry Then + If Retry OrElse TypeOf ex Is FileNotFoundException Then + Log(ex, "获取文件 SHA256 失败:" & FilePath) + Return "" + Else Retry = True Log(ex, "获取文件 SHA256 可重试失败:" & FilePath, LogLevel.Normal) Thread.Sleep(RandomInteger(200, 500)) GoTo Re - Else - Log(ex, "获取文件 SHA256 失败:" & FilePath) - Return "" End If End Try End Function @@ -1101,14 +1131,14 @@ Re: Next Return Result.ToString Catch ex As Exception - If Not Retry Then + If Retry OrElse TypeOf ex Is FileNotFoundException Then + Log(ex, "获取文件 SHA1 失败:" & FilePath) + Return "" + Else Retry = True Log(ex, "获取文件 SHA1 可重试失败:" & FilePath, LogLevel.Normal) Thread.Sleep(RandomInteger(200, 500)) GoTo Re - Else - Log(ex, "获取文件 SHA1 失败:" & FilePath) - Return "" End If End Try End Function @@ -1175,7 +1205,7 @@ Re: If Hash <> GetAuthMD5(LocalPath) Then Return "文件 MD5 应为 " & Hash & ",实际为 " & GetAuthMD5(LocalPath) ElseIf Hash.Length = 64 Then 'SHA256 If Hash <> GetAuthSHA256(LocalPath) Then Return "文件 SHA256 应为 " & Hash & ",实际为 " & GetAuthSHA256(LocalPath) - Else 'SHA1 + Else 'SHA1 (40) If Hash <> GetAuthSHA1(LocalPath) Then Return "文件 SHA1 应为 " & Hash & ",实际为 " & GetAuthSHA1(LocalPath) End If End If @@ -1803,28 +1833,36 @@ NextElement: End Sub End Class + ''' + ''' 前台运行文件。 + ''' + ''' 文件名。可以为“notepad”等缩写。 + ''' 运行参数。 + Public Sub ShellOnly(FileName As String, Optional Arguments As String = "") + Using Program As New Process + Program.StartInfo.Arguments = Arguments + Program.StartInfo.FileName = FileName + Log("[System] 执行外部命令:" & FileName & " " & Arguments) + Program.Start() + End Using + End Sub ''' ''' 前台运行文件并返回返回值。 ''' ''' 文件名。可以为“notepad”等缩写。 ''' 运行参数。 - ''' 是否等待该程序结束。默认为 False。 ''' 等待该程序结束的最长时间(毫秒)。超时会返回 Result.Timeout。 - Public Function ShellAndGetExitCode(FileName As String, Optional Arguments As String = "", Optional WaitForExit As Boolean = False, Optional Timeout As Integer = 1000000) As Result + Public Function ShellAndGetExitCode(FileName As String, Optional Arguments As String = "", Optional Timeout As Integer = 1000000) As Result Try Using Program As New Process Program.StartInfo.Arguments = Arguments Program.StartInfo.FileName = FileName Log("[System] 执行外部命令并等待返回码:" & FileName & " " & Arguments) Program.Start() - If WaitForExit Then - If Program.WaitForExit(Timeout) Then - Return Program.ExitCode - Else - Return Result.Timeout - End If + If Program.WaitForExit(Timeout) Then + Return Program.ExitCode Else - Return Result.Success + Return Result.Timeout End If End Using Catch ex As Exception @@ -1909,6 +1947,18 @@ NextElement: ''' 如果当前并非 UI 线程,则会阻断当前线程,直至 UI 线程执行完毕。 ''' 为防止线程互锁,请仅在开始加载动画、从 UI 获取输入时使用! ''' + Public Function RunInUiWait(Of Output)(Action As Func(Of Output)) As Output + If RunInUi() Then + Return Action() + Else + Return Application.Current.Dispatcher.Invoke(Action) + End If + End Function + ''' + ''' 确保在 UI 线程中执行代码。 + ''' 如果当前并非 UI 线程,则会阻断当前线程,直至 UI 线程执行完毕。 + ''' 为防止线程互锁,请仅在开始加载动画、从 UI 获取输入时使用! + ''' Public Sub RunInUiWait(Action As Action) If RunInUi() Then Action() @@ -2003,11 +2053,11 @@ NextElement: End Try End Sub ''' - ''' 打开 explorer。 + ''' 打开 explorer。注意参数中的路径要尽量加上双引号! ''' Public Sub OpenExplorer(Argument As String) Try - Process.Start("explorer.exe", Argument) + ShellOnly("explorer.exe", Argument) Catch ex As Exception Log(ex, "打开资源管理器失败,请尝试关闭安全软件(如 360 安全卫士)", LogLevel.Msgbox) End Try diff --git a/Plain Craft Launcher 2/Modules/Base/ModLoader.vb b/Plain Craft Launcher 2/Modules/Base/ModLoader.vb index f744460..e977f03 100644 --- a/Plain Craft Launcher 2/Modules/Base/ModLoader.vb +++ b/Plain Craft Launcher 2/Modules/Base/ModLoader.vb @@ -418,7 +418,7 @@ Loader.State = LoadState.Waiting Next End If - Update() + RunInThread(AddressOf Update) End Sub Public Overrides Sub Abort() '改变状态 @@ -484,7 +484,6 @@ Case LoadState.Finished '检查是否需要重启 If Loader.GetType.Name.StartsWith("LoaderTask") Then '类型名后面带有泛型,必须用 StartsWith - 'UNDONE: 这里的 IgnoreReloadTimeout 导致加载器不会重启,也就是微软登录不会自动重新登录 If CType(Loader, Object).ShouldStart(If(Input IsNot Nothing AndAlso Loader.GetType.GenericTypeArguments.First Is Input.GetType, Input, Nothing), IgnoreReloadTimeout:=True) Then If ModeDebug Then Log("[Loader] 由于输入条件变更,重启已完成的加载器 " & Loader.Name) GoTo Restart diff --git a/Plain Craft Launcher 2/Modules/Base/ModNet.vb b/Plain Craft Launcher 2/Modules/Base/ModNet.vb index a679ff8..586a6ed 100644 --- a/Plain Craft Launcher 2/Modules/Base/ModNet.vb +++ b/Plain Craft Launcher 2/Modules/Base/ModNet.vb @@ -1,9 +1,28 @@ Imports System.Net Public Module ModNet - Public Const NetDownloadEnd As String = ".PCLDownloading" + ''' + ''' 测试 Ping。失败则返回 -1。 + ''' + Public Function Ping(Ip As String, Optional Timeout As Integer = 10000, Optional MakeLog As Boolean = True) As Integer + Dim PingResult As NetworkInformation.PingReply + Try + PingResult = (New NetworkInformation.Ping).Send(Ip) + Catch ex As Exception + If MakeLog Then Log("[Net] Ping " & Ip & " 失败:" & ex.Message) + Return -1 + End Try + If PingResult.Status = NetworkInformation.IPStatus.Success Then + If MakeLog Then Log("[Net] Ping " & Ip & " 结束:" & PingResult.RoundtripTime & "ms") + Return PingResult.RoundtripTime + Else + If MakeLog Then Log("[Net] Ping " & Ip & " 失败") + Return -1 + End If + End Function + ''' ''' 以 WebClient 获取网页源代码。会进行至多 45 秒 3 次的尝试,允许最长 30s 的超时。 ''' @@ -940,7 +959,7 @@ Capture: Next '是否禁用多线程,以及规定碎片大小 Dim TargetUrl As String = GetSource().Url - If TargetUrl.Contains("pcl2-server") OrElse TargetUrl.Contains("gitcode.net") Then Return False + If TargetUrl.Contains("pcl2-server") OrElse TargetUrl.Contains("gitcode.net") OrElse TargetUrl.Contains("mcer.cn") Then Return False Dim RealFilePieceLimit = If(TargetUrl.Contains("download.mcbbs.net"), FilePieceLimit * 5, FilePieceLimit) '寻找最大碎片 Dim FilePieceMax As NetThread = Threads diff --git a/Plain Craft Launcher 2/Modules/Base/ModValidate.vb b/Plain Craft Launcher 2/Modules/Base/ModValidate.vb index 8d9b118..3e10a9f 100644 --- a/Plain Craft Launcher 2/Modules/Base/ModValidate.vb +++ b/Plain Craft Launcher 2/Modules/Base/ModValidate.vb @@ -49,10 +49,10 @@ End Class Public Class ValidateRegex Inherits Validate Public Property Regex As String - Public Property ErrorDescription As String = "" + Public Property ErrorDescription As String = "正则检查失败!" Public Sub New() End Sub '用于 XAML 初始化 - Public Sub New(Regex As String, Optional ErrorDescription As String = "") + Public Sub New(Regex As String, Optional ErrorDescription As String = "正则检查失败!") Me.Regex = Regex Me.ErrorDescription = ErrorDescription End Sub diff --git a/Plain Craft Launcher 2/Modules/Minecraft/ModCrash.vb b/Plain Craft Launcher 2/Modules/Minecraft/ModCrash.vb index f43985b..ec52624 100644 --- a/Plain Craft Launcher 2/Modules/Minecraft/ModCrash.vb +++ b/Plain Craft Launcher 2/Modules/Minecraft/ModCrash.vb @@ -9,7 +9,7 @@ SyncLock IsAnalyzeCacheClearedLock If Not IsAnalyzeCacheCleared Then Try - DeleteDirectory(PathTemp & "CrashAnalyzer") + DeleteDirectory(PathTemp & "CrashAnalyzer\") Catch ex As Exception Log(ex, "清理崩溃分析缓存失败") End Try @@ -153,6 +153,7 @@ ExtraLog CrashReport End Enum + Private DirectFile As KeyValuePair(Of String, String())? = Nothing '在弹窗中选择直接打开的文件 ''' ''' 从 AnalyzeRawFiles 中提取实际有用的文本片段存储到 AnalyzeFiles,并整理可用于生成报告的文件。 ''' 返回找到的用于分析的项目数。 @@ -161,18 +162,22 @@ Log("[Crash] 步骤 2:准备日志文本") '对日志文件进行分类 + DirectFile = Nothing Dim TotalFiles As New List(Of KeyValuePair(Of AnalyzeFileType, KeyValuePair(Of String, String()))) For Each LogFile In AnalyzeRawFiles Dim FileName As String = GetFileNameFromPath(LogFile.Key) Dim TargetType As AnalyzeFileType If FileName.StartsWith("hs_err") Then TargetType = AnalyzeFileType.HsErr + DirectFile = LogFile ElseIf FileName.StartsWith("crash-") Then TargetType = AnalyzeFileType.CrashReport + DirectFile = LogFile ElseIf FileName = "latest.log" OrElse FileName = "latest log.txt" OrElse FileName = "debug.log" OrElse FileName = "debug log.txt" OrElse FileName = "游戏崩溃前的输出.txt" OrElse FileName = "rawoutput.log" OrElse FileName = "启动器日志.txt" OrElse FileName = "PCL2 启动器日志.txt" OrElse FileName = "log1.txt" Then TargetType = AnalyzeFileType.MinecraftLog + If DirectFile Is Nothing Then DirectFile = LogFile ElseIf FileName.EndsWith(".log") OrElse FileName.EndsWith(".txt") Then TargetType = AnalyzeFileType.ExtraLog Else @@ -689,8 +694,19 @@ NextStack: Public Sub Output(IsHandAnalyze As Boolean, Optional ExtraFiles As List(Of String) = Nothing) '弹窗提示 FrmMain.ShowWindowToTop() - Select Case MyMsgBox(GetAnalyzeResult(IsHandAnalyze), If(IsHandAnalyze, "错误报告分析结果", "Minecraft 出现错误"), "确定", If(IsHandAnalyze, "", "导出错误报告")) +Redo: + Select Case MyMsgBox(GetAnalyzeResult(IsHandAnalyze), If(IsHandAnalyze, "错误报告分析结果", "Minecraft 出现错误"), + "确定", If(IsHandAnalyze OrElse DirectFile Is Nothing, "", "查看日志"), If(IsHandAnalyze, "", "导出错误报告")) Case 2 + If File.Exists(DirectFile.Value.Key) Then + ShellOnly(DirectFile.Value.Key) + Else + Dim FilePath As String = PathTemp & "Crash.txt" + WriteFile(FilePath, Join(DirectFile.Value.Value, vbCrLf)) + ShellOnly(FilePath) + End If + GoTo Redo + Case 3 Dim FileAddress As String = Nothing Try '获取文件路径 @@ -723,11 +739,7 @@ NextStack: Log(ex, "导出错误报告失败", LogLevel.Feedback) Exit Sub End Try - Try - Process.Start("explorer", "/select," & FileAddress) - Catch ex As Exception - Log(ex, "打开错误报告的存放文件夹失败") - End Try + OpenExplorer("/select,""" & FileAddress & """") End Select End Sub ''' diff --git a/Plain Craft Launcher 2/Modules/Minecraft/ModDownload.vb b/Plain Craft Launcher 2/Modules/Minecraft/ModDownload.vb index 78737e4..9c8d1a3 100644 --- a/Plain Craft Launcher 2/Modules/Minecraft/ModDownload.vb +++ b/Plain Craft Launcher 2/Modules/Minecraft/ModDownload.vb @@ -1217,7 +1217,7 @@ ''' CurseForge 工程列表获取事件。 ''' Public Sub DlCfProjectSub(Task As LoaderTask(Of DlCfProjectRequest, DlCfProjectResult)) - Dim RawFilter As String = If(Task.Input.SearchFilter, "") + Dim RawFilter As String = If(Task.Input.SearchFilter, "").Trim.ToLower Task.Input.SearchFilter = RawFilter Log("[Download] CurseForge 工程列表搜索原始文本:" & RawFilter) '中文请求关键字处理 @@ -1263,12 +1263,20 @@ Dim RightKeywords As New List(Of String) For Each Keyword In AllPossibleKeywords.Split(" ") If Keyword.Trim = "" Then Continue For + If Keyword = "forge" OrElse Keyword = "fabric" OrElse Keyword = "for" Then 'https://github.com/Hex-Dragon/PCL2/issues/208 + Log("[Download] 已跳过搜索关键词 " & Keyword, LogLevel.Developer) + Continue For + End If RightKeywords.Add(Keyword) Next - Task.Input.SearchFilter = Join(ArrayNoDouble(RightKeywords), " ").ToLower + If RawFilter.Length > 0 AndAlso RightKeywords.Count = 0 Then + Task.Input.SearchFilter = RawFilter '全都被过滤掉了 + Else + Task.Input.SearchFilter = Join(ArrayNoDouble(RightKeywords), " ").ToLower + End If '例外项:OptiForge、OptiFabric(拆词后因为包含 Forge/Fabric 导致无法搜到实际的 Mod) - If RawFilter.ToLower.Contains("optiforge") Then Task.Input.SearchFilter = "optiforge" - If RawFilter.ToLower.Contains("optifabric") Then Task.Input.SearchFilter = "optifabric" + If RawFilter.Replace(" ", "").ToLower.Contains("optiforge") Then Task.Input.SearchFilter = "optiforge" + If RawFilter.Replace(" ", "").ToLower.Contains("optifabric") Then Task.Input.SearchFilter = "optifabric" Log("[Download] CurseForge 工程列表搜索最终文本:" & Task.Input.SearchFilter, LogLevel.Developer) '正式获取 Dim Url = Task.Input.GetAddress() @@ -1505,7 +1513,6 @@ Json = NetGetCodeByRequestRetry("https://api.curseforge.com/v1/mods/" & ProjectId & "/files?pageSize=999", Accept:="application/json", IsJson:=True)("data") Else 'Mod 使用每个版本最新的文件 - 'TODO: 完整 Mod 文件列表支持 Json = GetJson(NetRequestRetry("https://api.curseforge.com/v1/mods/files", "POST", "{""fileIds"": [" & Join(TargetProject.FileIndexes, ",") & "]}", "application/json"))("data") End If Dim Files As New Dictionary(Of Integer, DlCfFile) @@ -1633,6 +1640,10 @@ ExitSub: If WaitCycle = 0 Then '启动第一个源 LoaderList(0).Key.Start(MainLoader.Input, IsForceRestart) + '将其他源标记为未启动,以确保可以切换下载源(#184) + For i = 1 To LoaderList.Count - 1 + LoaderList(i).Key.State = LoadState.Waiting + Next End If For i = 0 To LoaderList.Count - 1 If WaitCycle = LoaderList(i).Value * 100 Then diff --git a/Plain Craft Launcher 2/Modules/Minecraft/ModLaunch.vb b/Plain Craft Launcher 2/Modules/Minecraft/ModLaunch.vb index 69371a2..e417841 100644 --- a/Plain Craft Launcher 2/Modules/Minecraft/ModLaunch.vb +++ b/Plain Craft Launcher 2/Modules/Minecraft/ModLaunch.vb @@ -15,7 +15,7 @@ Public Module ModLaunch End Sub '启动状态切换 - Public McLaunchLoader As New LoaderTask(Of String, Object)("Loader Launch", AddressOf McLaunchStart) With {.OnStateChanged = AddressOf McLaunchState, .ReloadTimeout = 1} + Public McLaunchLoader As New LoaderTask(Of String, Object)("Loader Launch", AddressOf McLaunchStart) With {.OnStateChanged = AddressOf McLaunchState} Public McLaunchLoaderReal As LoaderCombo(Of Object) Public McLaunchProcess As Process Public McLaunchWatcher As Watcher @@ -206,12 +206,13 @@ NextInner: Public AccessToken As String = "" Public Uuid As String = "" Public UserName As String = "" + Public ProfileJson As String = "" Public Sub New() Type = McLoginType.Ms End Sub Public Overrides Function GetHashCode() As Integer - Return GetHash(OAuthRefreshToken & AccessToken & Uuid & UserName) Mod Integer.MaxValue + Return GetHash(OAuthRefreshToken & AccessToken & Uuid & UserName & ProfileJson) Mod Integer.MaxValue End Function End Class Public Class McLoginLegacy @@ -419,7 +420,8 @@ NextInner: Data.Progress = 0.05 '检查是否已经登录完成 If Input.AccessToken <> "" AndAlso Not Data.IsForceRestarting Then - Data.Output = New McLoginResult With {.AccessToken = Input.AccessToken, .Name = Input.UserName, .Uuid = Input.Uuid, .Type = "Microsoft", .ClientToken = Input.Uuid} + Data.Output = New McLoginResult With + {.AccessToken = Input.AccessToken, .Name = Input.UserName, .Uuid = Input.Uuid, .Type = "Microsoft", .ClientToken = Input.Uuid, .ProfileJson = Input.ProfileJson} GoTo SkipLogin End If '尝试登录 @@ -456,6 +458,7 @@ Relogin: Setup.Set("CacheMsAccess", AccessToken) Setup.Set("CacheMsUuid", Result(0)) Setup.Set("CacheMsName", Result(1)) + Setup.Set("CacheMsProfileJson", Result(2)) Data.Output = New McLoginResult With {.AccessToken = AccessToken, .Name = Result(1), .Uuid = Result(0), .Type = "Microsoft", .ClientToken = Result(0), .ProfileJson = Result(2)} '解锁主题 SkipLogin: @@ -1076,6 +1079,18 @@ SystemBrowser: Private McLaunchArgument As String + ''' + ''' 释放 Java Wrapper 并返回文件路径。 + ''' + Public Function ExtractJavaWrapper() As String + Dim WrapperPath As String = PathAppdata & "JavaWrapper.jar" + If Not File.Exists(WrapperPath) OrElse New FileInfo(WrapperPath).Length > 20 * 1024 Then + WriteFile(WrapperPath, GetResources("JavaWrapper")) + McLaunchLog("已自动释放 Java Wrapper") + End If + Return WrapperPath + End Function + '主方法,合并 Jvm、Game、Replace 三部分的参数数据 Private Sub McLaunchArgumentMain(Loader As LoaderTask(Of String, List(Of McLibToken))) McLaunchLog("开始获取 Minecraft 启动参数") @@ -1175,12 +1190,7 @@ SystemBrowser: '添加 Java Wrapper 作为主 Jar If McLaunchJavaSelected.VersionCode >= 9 Then DataList.Add("--add-exports cpw.mods.bootstraplauncher/cpw.mods.bootstraplauncher=ALL-UNNAMED") - Dim WrapperPath As String = PathAppdata & "JavaWrapper.jar" - If Not File.Exists(WrapperPath) Then - WriteFile(WrapperPath, GetResources("JavaWrapper")) - McLaunchLog("已自动释放 Java Wrapper") - End If - DataList.Add("-jar """ & WrapperPath & """") + DataList.Add("-jar """ & ExtractJavaWrapper() & """") '添加 MainClass If Version.JsonObject("mainClass") Is Nothing Then @@ -1244,12 +1254,7 @@ NextVersion: '添加 Java Wrapper 作为主 Jar If McLaunchJavaSelected.VersionCode >= 9 Then DataList.Add("--add-exports cpw.mods.bootstraplauncher/cpw.mods.bootstraplauncher=ALL-UNNAMED") - Dim WrapperPath As String = PathAppdata & "JavaWrapper.jar" - If Not File.Exists(WrapperPath) Then - WriteFile(WrapperPath, GetResources("JavaWrapper")) - McLaunchLog("已自动释放 Java Wrapper") - End If - DataList.Add("-jar """ & WrapperPath & """") + DataList.Add("-jar """ & ExtractJavaWrapper() & """") '将 "-XXX" 与后面 "XXX" 合并到一起 '如果不合并,会导致 Forge 1.17 启动无效,它有两个 --add-exports,进一步导致其中一个在后面被去重 @@ -1619,7 +1624,7 @@ NextVersion: Directory.CreateDirectory(McVersionCurrent.PathIndie & "resourcepacks\") Dim ZipFileAddress As String = McVersionCurrent.PathIndie & "resourcepacks\PCL2 Skin.zip" Dim NewTypeSetup As Boolean = McVersionCurrent.Version.McCodeMain >= 13 OrElse McVersionCurrent.Version.McCodeMain < 6 - If McLoginLoader.Input.Type = McLoginType.Legacy AndAlso Setup.Get("LaunchSkinType") = 4 AndAlso File.Exists(PathTemp & "CustomSkin.png") Then + If McLoginLoader.Input.Type = McLoginType.Legacy AndAlso Setup.Get("LaunchSkinType") = 4 AndAlso File.Exists(PathAppdata & "CustomSkin.png") Then Directory.CreateDirectory(PathTemp) Dim MetaFileAddress As String = PathTemp & "pack.mcmeta" Dim PackPicAddress As String = PathTemp & "pack.png" @@ -1659,7 +1664,7 @@ NextVersion: Dim Bit As New MyBitmap(PathImage & "Heads/Logo.png") Bit.Save(PackPicAddress) WriteFile(MetaFileAddress, "{""pack"":{""pack_format"":" & PackFormat & ",""description"":""PCL2 自定义离线皮肤资源包""}}") - Dim Skin As New MyBitmap(PathTemp & "CustomSkin.png") + Dim Skin As New MyBitmap(PathAppdata & "CustomSkin.png") If (McVersionCurrent.Version.McCodeMain = 6 OrElse McVersionCurrent.Version.McCodeMain = 7) AndAlso Skin.Pic.Height = 64 Then McLaunchLog("该 Minecraft 版本不支持双层皮肤,已进行裁剪") Skin = Skin.Clip(New System.Drawing.Rectangle(0, 0, 64, 32)) diff --git a/Plain Craft Launcher 2/Modules/Minecraft/ModMinecraft.vb b/Plain Craft Launcher 2/Modules/Minecraft/ModMinecraft.vb index b5cfcc3..72c3f81 100644 --- a/Plain Craft Launcher 2/Modules/Minecraft/ModMinecraft.vb +++ b/Plain Craft Launcher 2/Modules/Minecraft/ModMinecraft.vb @@ -404,7 +404,6 @@ Wait: Log(ex, "遍历查找 Java 时出错(" & OriginalPath.FullName & ")") End Try End Sub - Public PathAppdata As String = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) & "\PCL\" '获取 @@ -837,7 +836,7 @@ UserPass: ''' Public ReadOnly Property PathIndie As String Get - Return GetPathIndie(Version.Modable) + Return GetPathIndie(Modable) End Get End Property ''' @@ -917,6 +916,15 @@ UserPass: ''' Public DisplayType As McVersionCardType = McVersionCardType.Auto ''' + ''' 该版本是否可以安装 Mod。 + ''' + Public ReadOnly Property Modable As Boolean + Get + Return Version.HasFabric OrElse Version.HasForge OrElse Version.HasLiteLoader OrElse + DisplayType = McVersionCardType.API '#223 + End Get + End Property + ''' ''' 版本信息。 ''' Public Property Version As McVersionInfo @@ -1009,7 +1017,7 @@ UserPass: _Version.McName = Regex GoTo VersionSearchFinish End If - 'TODO: [Quilt 支持] 从 Quilt 版本中获取版本号 + 'FUTURE: [Quilt 支持] 从 Quilt 版本中获取版本号 '从 jar 项中获取版本号 If JsonObject("jar") IsNot Nothing Then _Version.McName = JsonObject("jar").ToString @@ -1324,7 +1332,7 @@ Recheck: Version.HasLiteLoader = True End If 'Fabric、Forge - 'TODO: [Quilt 支持] 确认这里的玩意儿对不对 + 'FUTURE: [Quilt 支持] 确认这里的玩意儿对不对 If RealJson.Contains("net.fabricmc:fabric-loader") OrElse RealJson.Contains("org.quiltmc:quilt-loader") Then State = McVersionState.Fabric Version.FabricVersion = If(RegexSeek(RealJson, "(?<=(net.fabricmc:fabric-loader:)|(org.quiltmc:quilt-loader:))[0-9\.]+(\+build.[0-9]+)?"), "未知版本").Replace("+build", "") @@ -1511,15 +1519,6 @@ ExitDataLoad: 'API - ''' - ''' 该版本是否可以安装 Mod。 - ''' - Public ReadOnly Property Modable As Boolean - Get - Return HasFabric OrElse HasForge OrElse HasLiteLoader - End Get - End Property - ''' ''' 生成对此版本信息的用户友好的描述性字符串。 ''' diff --git a/Plain Craft Launcher 2/My Project/AssemblyInfo.vb b/Plain Craft Launcher 2/My Project/AssemblyInfo.vb index f426611..3f55573 100644 --- a/Plain Craft Launcher 2/My Project/AssemblyInfo.vb +++ b/Plain Craft Launcher 2/My Project/AssemblyInfo.vb @@ -51,6 +51,6 @@ Imports System.Runtime.InteropServices ' 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号 ' 方法是按如下所示使用“*” - - + + diff --git a/Plain Craft Launcher 2/My Project/Resources.Designer.vb b/Plain Craft Launcher 2/My Project/Resources.Designer.vb index ab2984a..033f910 100644 --- a/Plain Craft Launcher 2/My Project/Resources.Designer.vb +++ b/Plain Craft Launcher 2/My Project/Resources.Designer.vb @@ -140,16 +140,6 @@ Namespace My.Resources End Get End Property - ''' - ''' 查找 System.Byte[] 类型的本地化资源。 - ''' - Friend ReadOnly Property STUN() As Byte() - Get - Dim obj As Object = ResourceManager.GetObject("STUN", resourceCulture) - Return CType(obj,Byte()) - End Get - End Property - ''' ''' 查找 System.Byte[] 类型的本地化资源。 ''' diff --git a/Plain Craft Launcher 2/My Project/Resources.resx b/Plain Craft Launcher 2/My Project/Resources.resx index 1f4dccf..fb11c58 100644 --- a/Plain Craft Launcher 2/My Project/Resources.resx +++ b/Plain Craft Launcher 2/My Project/Resources.resx @@ -142,9 +142,6 @@ ..\Resources\NAudio.dll;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - ..\Resources\STUN.dll;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - ..\Resources\transformer.jar;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 diff --git a/Plain Craft Launcher 2/Pages/PageDownload/ModDownloadLib.vb b/Plain Craft Launcher 2/Pages/PageDownload/ModDownloadLib.vb index 97b5104..2b710bd 100644 --- a/Plain Craft Launcher 2/Pages/PageDownload/ModDownloadLib.vb +++ b/Plain Craft Launcher 2/Pages/PageDownload/ModDownloadLib.vb @@ -378,12 +378,7 @@ Public Module ModDownloadLib Throw New Exception("未找到用于安装 OptiFine 的 Java") End If '添加 Java Wrapper 作为主 Jar - Dim WrapperPath As String = PathAppdata & "JavaWrapper.jar" - If Not File.Exists(WrapperPath) Then - WriteFile(WrapperPath, GetResources("JavaWrapper")) - McLaunchLog("已自动释放 Java Wrapper") - End If - Dim Arguments = "-Duser.home=""" & BaseMcFolderHome & """ -cp """ & Target & """ -jar """ & WrapperPath & """ optifine.Installer" + Dim Arguments = "-Duser.home=""" & BaseMcFolderHome & """ -cp """ & Target & """ -jar """ & ExtractJavaWrapper() & """ optifine.Installer" If Java.VersionCode >= 9 Then Arguments = "--add-exports cpw.mods.bootstraplauncher/cpw.mods.bootstraplauncher=ALL-UNNAMED " & Arguments '开始启动 SyncLock InstallSyncLock @@ -528,7 +523,10 @@ Public Module ModDownloadLib '等待原版文件下载完成 For Each Loader In ClientDownloadLoader.GetLoaderList If Loader.Name <> McDownloadClientLibName Then Continue For - Loader.WaitForExit() + If Loader.State = LoadState.Loading Then + Log("[Download] OptiFine 安装正在等待原版文件下载完成") + Loader.WaitForExit() + End If Exit For Next '拷贝原版文件 @@ -1094,12 +1092,7 @@ Public Module ModDownloadLib Throw New Exception("未找到用于安装 Forge 的 Java") End If '添加 Java Wrapper 作为主 Jar - Dim WrapperPath As String = PathAppdata & "JavaWrapper.jar" - If Not File.Exists(WrapperPath) Then - WriteFile(WrapperPath, GetResources("JavaWrapper")) - McLaunchLog("已自动释放 Java Wrapper") - End If - Dim Arguments = "-cp """ & PathTemp & "Cache\forge_installer.jar;" & Target & """ -jar """ & WrapperPath & """ com.bangbang93.ForgeInstaller """ & McFolder + Dim Arguments = "-cp """ & PathTemp & "Cache\forge_installer.jar;" & Target & """ -jar """ & ExtractJavaWrapper() & """ com.bangbang93.ForgeInstaller """ & McFolder If Java.VersionCode >= 9 Then Arguments = "--add-exports cpw.mods.bootstraplauncher/cpw.mods.bootstraplauncher=ALL-UNNAMED " & Arguments '开始启动 SyncLock InstallSyncLock @@ -1339,7 +1332,10 @@ Public Module ModDownloadLib '等待原版文件下载完成 For Each Loader In ClientDownloadLoader.GetLoaderList If Loader.Name <> McDownloadClientLibName Then Continue For - Loader.WaitForExit() + If Loader.State = LoadState.Loading Then + Log("[Download] Forge 安装正在等待原版文件下载完成") + Loader.WaitForExit() + End If Exit For Next '拷贝原版文件 diff --git a/Plain Craft Launcher 2/Pages/PageDownload/PageDownloadCfDetail.xaml.vb b/Plain Craft Launcher 2/Pages/PageDownload/PageDownloadCfDetail.xaml.vb index b18ea7b..bc08112 100644 --- a/Plain Craft Launcher 2/Pages/PageDownload/PageDownloadCfDetail.xaml.vb +++ b/Plain Craft Launcher 2/Pages/PageDownload/PageDownloadCfDetail.xaml.vb @@ -119,7 +119,7 @@ #End Region Private IsFirstInit As Boolean = True - Public Sub Init() Handles Me.OnPageEnter + Public Sub Init() Handles Me.PageEnter AniControlEnabled += 1 Project = FrmMain.PageCurrent.Additional PanBack.ScrollToHome() @@ -200,7 +200,7 @@ DefaultFolder = DownloadFolder If McVersionCurrent IsNot Nothing Then If Not McVersionCurrent.IsLoaded Then McVersionCurrent.Load() - If McVersionCurrent.Version.Modable Then + If McVersionCurrent.Modable Then DefaultFolder = McVersionCurrent.PathIndie & "mods\" Directory.CreateDirectory(DefaultFolder) End If diff --git a/Plain Craft Launcher 2/Pages/PageLaunch/PageLaunchLeft.xaml.vb b/Plain Craft Launcher 2/Pages/PageLaunch/PageLaunchLeft.xaml.vb index 7f9b597..f7e8459 100644 --- a/Plain Craft Launcher 2/Pages/PageLaunch/PageLaunchLeft.xaml.vb +++ b/Plain Craft Launcher 2/Pages/PageLaunch/PageLaunchLeft.xaml.vb @@ -479,12 +479,12 @@ UseDefault: End If End Try Case 4 '自定义 - If Not File.Exists(PathTemp & "CustomSkin.png") Then + If Not File.Exists(PathAppdata & "CustomSkin.png") Then Hint("未找到离线皮肤自定义文件,可能它已被删除。PCL2 将使用默认的 Steve 皮肤!") Setup.Set("LaunchSkinType", 1) GoTo UseDefault End If - Data.Output = PathTemp & "CustomSkin.png" + Data.Output = PathAppdata & "CustomSkin.png" End Select '刷新显示 If FrmLoginLegacy IsNot Nothing Then @@ -607,7 +607,7 @@ Finish: Public Sub LaunchButtonClick(Optional ServerIp As String = "") If BtnLaunch.IsEnabled AndAlso BtnLaunch.Visibility = Visibility.Visible AndAlso BtnLaunch.IsHitTestVisible Then If BtnLaunch.Text = "启动游戏" Then - McLaunchLoader.Start(ServerIp) + McLaunchLoader.Start(ServerIp, IsForceRestart:=True) ElseIf BtnLaunch.Text = "下载游戏" Then FrmMain.PageChange(FormMain.PageType.Download, FormMain.PageSubType.DownloadInstall) End If diff --git a/Plain Craft Launcher 2/Pages/PageLaunch/PageLoginMojangSkin.xaml.vb b/Plain Craft Launcher 2/Pages/PageLaunch/PageLoginMojangSkin.xaml.vb index 129a104..b614822 100644 --- a/Plain Craft Launcher 2/Pages/PageLaunch/PageLoginMojangSkin.xaml.vb +++ b/Plain Craft Launcher 2/Pages/PageLaunch/PageLoginMojangSkin.xaml.vb @@ -88,7 +88,7 @@ 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/msaprofile/mygames/editskin") + OpenWebsite("https://www.minecraft.net/zh-hans/profile/skin") End If ElseIf Result.Contains("request requires user authentication") Then Hint("正在重新登录,请稍后再次尝试更改皮肤!") diff --git a/Plain Craft Launcher 2/Pages/PageLaunch/PageLoginMsSkin.xaml.vb b/Plain Craft Launcher 2/Pages/PageLaunch/PageLoginMsSkin.xaml.vb index 6682b29..823c5a4 100644 --- a/Plain Craft Launcher 2/Pages/PageLaunch/PageLoginMsSkin.xaml.vb +++ b/Plain Craft Launcher 2/Pages/PageLaunch/PageLoginMsSkin.xaml.vb @@ -20,7 +20,7 @@ ''' Public Shared Function GetLoginData() As McLoginMs If McLoginMsLoader.State = LoadState.Finished Then - Return New McLoginMs With {.OAuthRefreshToken = Setup.Get("CacheMsOAuthRefresh"), .UserName = Setup.Get("CacheMsName"), .AccessToken = Setup.Get("CacheMsAccess"), .Uuid = Setup.Get("CacheMsUuid")} + Return New McLoginMs With {.OAuthRefreshToken = Setup.Get("CacheMsOAuthRefresh"), .UserName = Setup.Get("CacheMsName"), .AccessToken = Setup.Get("CacheMsAccess"), .Uuid = Setup.Get("CacheMsUuid"), .ProfileJson = Setup.Get("CacheMsProfileJson")} Else Return New McLoginMs With {.OAuthRefreshToken = Setup.Get("CacheMsOAuthRefresh"), .UserName = Setup.Get("CacheMsName")} End If @@ -51,6 +51,7 @@ Private Sub BtnExit_Click() Handles BtnExit.Click Setup.Set("CacheMsOAuthRefresh", "") Setup.Set("CacheMsAccess", "") + Setup.Set("CacheMsProfileJson", "") Setup.Set("CacheMsUuid", "") Setup.Set("CacheMsName", "") McLoginMsLoader.Abort() diff --git a/Plain Craft Launcher 2/Pages/PageLink/PageLinkFeedback.xaml b/Plain Craft Launcher 2/Pages/PageLink/PageLinkFeedback.xaml index 1d70083..fe74e5b 100644 --- a/Plain Craft Launcher 2/Pages/PageLink/PageLinkFeedback.xaml +++ b/Plain Craft Launcher 2/Pages/PageLink/PageLinkFeedback.xaml @@ -4,31 +4,35 @@ xmlns:local="clr-namespace:PCL" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" x:Class="PageLinkFeedback" d:DesignWidth="800" d:DesignHeight="800"> - - - - - + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - + + + + diff --git a/Plain Craft Launcher 2/Pages/PageLink/PageLinkFeedback.xaml.vb b/Plain Craft Launcher 2/Pages/PageLink/PageLinkFeedback.xaml.vb index 01d2504..304bb68 100644 --- a/Plain Craft Launcher 2/Pages/PageLink/PageLinkFeedback.xaml.vb +++ b/Plain Craft Launcher 2/Pages/PageLink/PageLinkFeedback.xaml.vb @@ -1,3 +1,2 @@ Public Class PageLinkFeedback - End Class diff --git a/Plain Craft Launcher 2/Pages/PageLink/PageLinkHiper.xaml b/Plain Craft Launcher 2/Pages/PageLink/PageLinkHiper.xaml new file mode 100644 index 0000000..deaca3f --- /dev/null +++ b/Plain Craft Launcher 2/Pages/PageLink/PageLinkHiper.xaml @@ -0,0 +1,226 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Plain Craft Launcher 2/Pages/PageLink/PageLinkIoi.xaml b/Plain Craft Launcher 2/Pages/PageLink/PageLinkIoi.xaml index 0ffc18d..fa912d0 100644 --- a/Plain Craft Launcher 2/Pages/PageLink/PageLinkIoi.xaml +++ b/Plain Craft Launcher 2/Pages/PageLink/PageLinkIoi.xaml @@ -8,7 +8,6 @@ - @@ -19,7 +18,7 @@ - + @@ -44,5 +43,8 @@ + + + diff --git a/Plain Craft Launcher 2/Pages/PageLink/PageLinkLeft.xaml b/Plain Craft Launcher 2/Pages/PageLink/PageLinkLeft.xaml index e20ed15..2ca0ad3 100644 --- a/Plain Craft Launcher 2/Pages/PageLink/PageLinkLeft.xaml +++ b/Plain Craft Launcher 2/Pages/PageLink/PageLinkLeft.xaml @@ -6,28 +6,18 @@ xmlns:local="clr-namespace:PCL" mc:Ignorable="d" AnimatedControl="{Binding ElementName=PanItem}" MinWidth="150"> - - - - - - - - - + - - @@ -37,8 +27,8 @@ - - + @@ -46,9 +36,9 @@ - - diff --git a/Plain Craft Launcher 2/Pages/PageLink/PageLinkLeft.xaml.vb b/Plain Craft Launcher 2/Pages/PageLink/PageLinkLeft.xaml.vb new file mode 100644 index 0000000..716e301 --- /dev/null +++ b/Plain Craft Launcher 2/Pages/PageLink/PageLinkLeft.xaml.vb @@ -0,0 +1,192 @@ +Imports NetFwTypeLib + +Public Class PageLinkLeft + + Private IsLoad As Boolean = False + Private IsPageSwitched As Boolean = False '如果在 Loaded 前切换到其他页面,会导致触发 Loaded 时再次切换一次 + Private Sub PageLinkLeft_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded + If IsLoad Then Exit Sub + IsLoad = True + '切换默认页面 + If IsPageSwitched Then Exit Sub + ItemHiper.SetChecked(True, False, False) + End Sub + Private Sub PageOtherLeft_Unloaded(sender As Object, e As RoutedEventArgs) Handles Me.Unloaded + IsPageSwitched = False + End Sub + +#Region "Windows 防火墙" + + '为联机模块添加防火墙通行权限的函数库 + '不加防火墙权限你要我怎么办,这联机根本连都连不上,球球你们别看到防火墙就说是后门了,真的很恼火…… + + ''' + ''' 获取某个文件是否被 Windows 防火墙阻止。 + ''' + Public Shared Function FirewallIsBlock(FilePath As String) As Boolean + '获取配置 + If FirewallPolicy Is Nothing Then + Try + FirewallPolicy = FirewallPolicyGet() + Catch ex As Exception + Log(ex, "Windows 防火墙:可能关闭得太死了,根本检测不到,笑死", LogLevel.Normal) + Return False + End Try + End If + '检查是否开启 + If Not FirewallPolicy.CurrentProfile.FirewallEnabled Then + Log("[Link] Windows 防火墙:防火墙关闭") + Return False + End If + '检查是否允许例外 + If FirewallPolicy.CurrentProfile.ExceptionsNotAllowed Then + Log("[Link] Windows 防火墙:防火墙开启,不允许例外") + Return True + End If + '检查白名单 + Dim Target As String = FilePath.Replace(PathTemp.Split("\").First, "").ToLower + For Each App As INetFwAuthorizedApplication In FirewallPolicy.CurrentProfile.AuthorizedApplications + If ModeDebug Then Log("[Link] 防火墙白名单(" & App.Enabled & "):" & App.ProcessImageFileName) + If Not App.Enabled Then Continue For + '信标的奇妙盘符 E:0/xxxxx/xxx 导致误判…… + Dim FileNameTrimmed As String = App.ProcessImageFileName.Replace(App.ProcessImageFileName.Split("\").First, "") + If App.ProcessImageFileName.ToLower.Contains(FilePath) Then + Log("[Link] Windows 防火墙:开启,已在白名单中(" & FilePath & ")") + Return False + End If + Next + Log("[Link] Windows 防火墙:开启,未在白名单中(" & FilePath & ")") + Return True + End Function + ''' + ''' 添加防火墙通行权限。需要管理员权限。 + ''' + Public Shared Sub FirewallAddAuthorized(DisplayName As String, FilePath As String) + Log("[Link] Windows 防火墙:添加通行权限(" & FilePath & ")") + '获取配置 + If FirewallPolicy Is Nothing Then FirewallPolicy = FirewallPolicyGet() + '添加项目 + FirewallPolicy.GetProfileByType(NET_FW_PROFILE_TYPE_.NET_FW_PROFILE_DOMAIN).AuthorizedApplications.Add(New FirewallApp(DisplayName, FilePath)) + FirewallPolicy.GetProfileByType(NET_FW_PROFILE_TYPE_.NET_FW_PROFILE_STANDARD).AuthorizedApplications.Add(New FirewallApp(DisplayName, FilePath)) + FirewallPolicy.CurrentProfile.AuthorizedApplications.Add(New FirewallApp(DisplayName, FilePath)) + End Sub + Private Class FirewallApp + Implements INetFwAuthorizedApplication + Public Property Name As String Implements INetFwAuthorizedApplication.Name + Public Property ProcessImageFileName As String Implements INetFwAuthorizedApplication.ProcessImageFileName + Public Property IpVersion As NET_FW_IP_VERSION_ = NET_FW_IP_VERSION_.NET_FW_IP_VERSION_ANY Implements INetFwAuthorizedApplication.IpVersion + Public Property Scope As NET_FW_SCOPE_ = NET_FW_SCOPE_.NET_FW_SCOPE_ALL Implements INetFwAuthorizedApplication.Scope + Public Property RemoteAddresses As String = "*" Implements INetFwAuthorizedApplication.RemoteAddresses + Public Property Enabled As Boolean = True Implements INetFwAuthorizedApplication.Enabled + Public Sub New(DisplayName As String, FilePath As String) + Name = DisplayName + ProcessImageFileName = FilePath + End Sub + End Class + '获取防火墙配置 + Public Shared FirewallPolicy As INetFwPolicy = Nothing + Public Shared Function FirewallPolicyGet() As INetFwPolicy + Const CLSID_FIREWALL_MANAGER As String = "{304CE942-6E39-40D8-943A-B913C40C9CD4}" + Dim objType As Type = Type.GetTypeFromCLSID(New Guid(CLSID_FIREWALL_MANAGER)) + Return TryCast(Activator.CreateInstance(objType), INetFwMgr).LocalPolicy + End Function + +#End Region + +#Region "页面切换" + + ''' + ''' 当前页面的编号。 + ''' + Public PageID As FormMain.PageSubType = FormMain.PageSubType.LinkHiper + + ''' + ''' 勾选事件改变页面。 + ''' + Private Sub PageCheck(sender As MyListItem, e As RouteEventArgs) Handles ItemHiper.Check, ItemIoi.Check, ItemSetup.Check, ItemHelp.Check, ItemFeedback.Check + '尚未初始化控件属性时,sender.Tag 为 Nothing,会导致切换到页面 0 + '若使用 IsLoaded,则会导致模拟点击不被执行(模拟点击切换页面时,控件的 IsLoaded 为 False) + If sender.Tag IsNot Nothing Then PageChange(Val(sender.Tag)) + End Sub + + Public Function PageGet(Optional ID As FormMain.PageSubType = -1) + If ID = -1 Then ID = PageID + Select Case ID + Case 0, FormMain.PageSubType.LinkHiper + If FrmLinkHiper Is Nothing Then FrmLinkHiper = New PageLinkHiper + Return FrmLinkHiper + Case FormMain.PageSubType.LinkIoi + If FrmLinkIoi Is Nothing Then FrmLinkIoi = New PageLinkIoi + Return FrmLinkIoi + Case FormMain.PageSubType.LinkSetup + If FrmSetupLink Is Nothing Then FrmSetupLink = New PageSetupLink + Return FrmSetupLink + Case FormMain.PageSubType.LinkHelp + If FrmLinkHelp Is Nothing Then FrmLinkHelp = PageOtherHelp.GetHelpPage(PathTemp & "Help\启动器\联机.json") + Return FrmLinkHelp + Case FormMain.PageSubType.LinkFeedback + If FrmLinkFeedback Is Nothing Then FrmLinkFeedback = New PageLinkFeedback + Return FrmLinkFeedback + Case Else + Throw New Exception("未知的更多子页面种类:" & ID) + End Select + End Function + + ''' + ''' 切换现有页面。 + ''' + Public Sub PageChange(ID As FormMain.PageSubType) + If PageID = ID Then Exit Sub + AniControlEnabled += 1 + IsPageSwitched = True + Try + PageChangeRun(PageGet(ID)) + PageID = ID + Catch ex As Exception + Log(ex, "切换设置分页面失败(ID " & ID & ")", LogLevel.Feedback) + Finally + AniControlEnabled -= 1 + End Try + End Sub + Private Shared Sub PageChangeRun(Target As MyPageRight) + AniStop("FrmMain PageChangeRight") '停止主页面的右页面切换动画,防止它与本动画一起触发多次 PageOnEnter + If Target.Parent IsNot Nothing Then Target.SetValue(ContentPresenter.ContentProperty, Nothing) + FrmMain.PageRight = Target + CType(FrmMain.PanMainRight.Child, MyPageRight).PageOnExit() + AniStart({ + AaCode(Sub() + CType(FrmMain.PanMainRight.Child, MyPageRight).PageOnForceExit() + FrmMain.PanMainRight.Child = FrmMain.PageRight + FrmMain.PageRight.Opacity = 0 + End Sub, 130), + AaCode(Sub() + '延迟触发页面通用动画,以使得在 Loaded 事件中加载的控件得以处理 + FrmMain.PageRight.Opacity = 1 + FrmMain.PageRight.PageOnEnter() + End Sub, 30, True) + }, "PageLeft PageChange") + End Sub + +#End Region + + Public Sub Reset(sender As Object, e As EventArgs) + If MyMsgBox("是否要初始化联机页的所有设置?该操作不可撤销。", "初始化确认",, "取消", IsWarn:=True) = 1 Then + If IsNothing(FrmSetupLink) Then FrmSetupLink = New PageSetupLink + FrmSetupLink.Reset() + End If + End Sub + + Private Sub BtnHiperStop_Loaded(sender As Object, e As RoutedEventArgs) + sender.Visibility = If(PageLinkHiper.HiperState = LoadState.Finished OrElse PageLinkHiper.HiperState = LoadState.Loading, Visibility.Visible, Visibility.Collapsed) + End Sub + Private Sub BtnHiperStop_Click(sender As Object, e As EventArgs) + PageLinkHiper.ModuleStopManually() + End Sub + Private Sub BtnIoiStop_Loaded(sender As Object, e As RoutedEventArgs) + sender.Visibility = If(PageLinkIoi.InitLoader.State = LoadState.Finished, Visibility.Visible, Visibility.Collapsed) + End Sub + Private Sub BtnIoiStop_Click(sender As Object, e As EventArgs) + PageLinkIoi.ModuleStopManually() + End Sub + +End Class diff --git a/Plain Craft Launcher 2/Pages/PageSelectLeft.xaml.vb b/Plain Craft Launcher 2/Pages/PageSelectLeft.xaml.vb index b231dda..d7483ae 100644 --- a/Plain Craft Launcher 2/Pages/PageSelectLeft.xaml.vb +++ b/Plain Craft Launcher 2/Pages/PageSelectLeft.xaml.vb @@ -238,7 +238,7 @@ For Each VersionPath In VersionFolder.EnumerateDirectories Dim Version As New McVersion(VersionPath.FullName) Version.Load() - If Not Version.Version.Modable Then Continue For + If Not Version.Modable Then Continue For '4. 该版本的隔离文件夹下不存在 mods Dim ModIndieFolder As New DirectoryInfo(Version.Path & "mods\") If ModIndieFolder.Exists AndAlso ModIndieFolder.EnumerateFiles.Count > 0 Then Exit Sub diff --git a/Plain Craft Launcher 2/Pages/PageSetup/PageSetupLaunch.xaml.vb b/Plain Craft Launcher 2/Pages/PageSetup/PageSetupLaunch.xaml.vb index 88835b0..e9fadeb 100644 --- a/Plain Craft Launcher 2/Pages/PageSetup/PageSetupLaunch.xaml.vb +++ b/Plain Craft Launcher 2/Pages/PageSetup/PageSetupLaunch.xaml.vb @@ -114,8 +114,8 @@ '设置文件 Try '拷贝文件 - File.Delete(PathTemp & "CustomSkin.png") - CopyFile(SkinInfo.LocalFile, PathTemp & "CustomSkin.png") + File.Delete(PathAppdata & "CustomSkin.png") + CopyFile(SkinInfo.LocalFile, PathAppdata & "CustomSkin.png") '更新设置 Setup.Set("LaunchSkinSlim", SkinInfo.IsSlim) Catch ex As Exception @@ -129,7 +129,7 @@ If Not (AniControlEnabled = 0 AndAlso e.RaiseByMouse) Then Exit Sub Try '已有图片则不再选择 - If File.Exists(PathTemp & "CustomSkin.png") Then Exit Sub + If File.Exists(PathAppdata & "CustomSkin.png") Then Exit Sub '没有图片则要求选择 Dim SkinInfo As McSkinInfo = McSkinSelect(True) If Not SkinInfo.IsVaild Then @@ -137,8 +137,8 @@ Exit Sub End If '拷贝文件 - File.Delete(PathTemp & "CustomSkin.png") - CopyFile(SkinInfo.LocalFile, PathTemp & "CustomSkin.png") + File.Delete(PathAppdata & "CustomSkin.png") + CopyFile(SkinInfo.LocalFile, PathAppdata & "CustomSkin.png") '更新设置 Setup.Set("LaunchSkinSlim", SkinInfo.IsSlim) Catch ex As Exception @@ -151,7 +151,7 @@ End Sub Private Sub BtnSkinDelete_Click(sender As Object, e As EventArgs) Handles BtnSkinDelete.Click Try - File.Delete(PathTemp & "CustomSkin.png") + File.Delete(PathAppdata & "CustomSkin.png") RadioSkinType0.SetChecked(True, True, True) Hint("离线皮肤已清空!", HintType.Finish) Catch ex As Exception @@ -335,7 +335,7 @@ Dim RamTarget2 As Double '估计没啥问题了的内存 Dim RamTarget3 As Double '放一百万个材质和 Mod 和光影需要的内存 If Version IsNot Nothing AndAlso Not Version.IsLoaded Then Version.Load() - If Version IsNot Nothing AndAlso Version.Version.Modable Then + If Version IsNot Nothing AndAlso Version.Modable Then '可安装 Mod 的版本 Dim ModDir As New DirectoryInfo(Version.PathIndie & "mods\") Dim ModCount As Integer = If(ModDir.Exists, ModDir.GetFiles.Length, 0) diff --git a/Plain Craft Launcher 2/Pages/PageSetup/PageSetupLink.xaml b/Plain Craft Launcher 2/Pages/PageSetup/PageSetupLink.xaml index ae13c9b..c6c4a99 100644 --- a/Plain Craft Launcher 2/Pages/PageSetup/PageSetupLink.xaml +++ b/Plain Craft Launcher 2/Pages/PageSetup/PageSetupLink.xaml @@ -6,8 +6,14 @@ d:DesignWidth="800" d:DesignHeight="800"> - - + + + + + + + + @@ -26,8 +32,6 @@ - diff --git a/Plain Craft Launcher 2/Pages/PageSetup/PageSetupLink.xaml.vb b/Plain Craft Launcher 2/Pages/PageSetup/PageSetupLink.xaml.vb index ad23b2f..55e5b6a 100644 --- a/Plain Craft Launcher 2/Pages/PageSetup/PageSetupLink.xaml.vb +++ b/Plain Craft Launcher 2/Pages/PageSetup/PageSetupLink.xaml.vb @@ -17,15 +17,15 @@ End Sub Public Sub Reload() - CheckLinkAuto.Checked = Setup.Get("LinkAuto") TextLinkName.Text = Setup.Get("LinkName") + CheckHiperCertWarn.Checked = Setup.Get("LinkHiperCertWarn") End Sub '初始化 Public Sub Reset() Try - Setup.Reset("LinkAuto") Setup.Reset("LinkName") + Setup.Reset("LinkHiperCertWarn") Log("[Setup] 已初始化联机页设置") Hint("已初始化联机页设置!", HintType.Finish, False) @@ -37,11 +37,19 @@ End Sub '将控件改变路由到设置改变 - Private Shared Sub CheckBoxChange(sender As MyCheckBox, e As Object) Handles CheckLinkAuto.Change - If AniControlEnabled = 0 Then Setup.Set(sender.Tag, sender.Checked) - End Sub Private Shared Sub TextBoxChange(sender As MyTextBox, e As Object) Handles TextLinkName.ValidatedTextChanged If AniControlEnabled = 0 Then Setup.Set(sender.Tag, sender.Text) End Sub + Private Shared Sub CheckBoxChange(sender As MyCheckBox, e As Object) Handles CheckHiperCertWarn.Change + If AniControlEnabled = 0 Then Setup.Set(sender.Tag, sender.Checked) + End Sub + + Private Sub BtnHiperLog_Click(sender As Object, e As EventArgs) Handles BtnHiperLog.Click + If File.Exists(PageLinkHiper.PathHiper & "logs\hiper.log") Then + OpenExplorer("/select,""" & PageLinkHiper.PathHiper & "logs\hiper.log""") + Else + Hint("没有找到 HiPer 联机模块的日志!") + End If + End Sub End Class diff --git a/Plain Craft Launcher 2/Pages/PageSetup/PageSetupSystem.xaml.vb b/Plain Craft Launcher 2/Pages/PageSetup/PageSetupSystem.xaml.vb index eb1f338..60207fa 100644 --- a/Plain Craft Launcher 2/Pages/PageSetup/PageSetupSystem.xaml.vb +++ b/Plain Craft Launcher 2/Pages/PageSetup/PageSetupSystem.xaml.vb @@ -183,7 +183,6 @@ Dim Temp As String() Temp = Directory.GetFiles(Path) For Each str As String In Temp - If str = PathTemp & "CustomSkin.png" OrElse str = PathTemp & "联机模块.exe" Then Continue For '不删除的文件 Try Dim Info As New FileInfo(str) Dim FileActualSize = Math.Ceiling(Info.Length / 4096) * 4096 diff --git a/Plain Craft Launcher 2/Pages/PageVersion/PageVersionLeft.xaml.vb b/Plain Craft Launcher 2/Pages/PageVersion/PageVersionLeft.xaml.vb index afcd0bc..c5d9f35 100644 --- a/Plain Craft Launcher 2/Pages/PageVersion/PageVersionLeft.xaml.vb +++ b/Plain Craft Launcher 2/Pages/PageVersion/PageVersionLeft.xaml.vb @@ -5,8 +5,8 @@ ''' Public Shared Version As McVersion - Private Sub PageVersionLeft_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded - If Version IsNot Nothing AndAlso Version.Version.Modable Then + Public Sub RefreshModDisabled() Handles Me.Loaded + If Version IsNot Nothing AndAlso Version.Modable Then ItemMod.Visibility = Visibility.Visible ItemModDisabled.Visibility = Visibility.Collapsed Else diff --git a/Plain Craft Launcher 2/Pages/PageVersion/PageVersionOverall.xaml.vb b/Plain Craft Launcher 2/Pages/PageVersion/PageVersionOverall.xaml.vb index b7d7cb6..f14c5cb 100644 --- a/Plain Craft Launcher 2/Pages/PageVersion/PageVersionOverall.xaml.vb +++ b/Plain Craft Launcher 2/Pages/PageVersion/PageVersionOverall.xaml.vb @@ -57,7 +57,11 @@ If ComboDisplayType.SelectedIndex <> 1 Then '改为不隐藏 Try + '若设置分类为可安装 Mod,则显示正常的 Mod 管理页面 WriteIni(PageVersionLeft.Version.Path & "PCL\Setup.ini", "DisplayType", ComboDisplayType.SelectedIndex) + PageVersionLeft.Version.DisplayType = ReadIni(PageVersionLeft.Version.Path & "PCL\Setup.ini", "DisplayType", McVersionCardType.Auto) + FrmVersionLeft.RefreshModDisabled() + WriteIni(PathMcFolder & "PCL.ini", "VersionCache", "") '要求刷新缓存 LoaderFolderRun(McVersionListLoader, PathMcFolder, LoaderFolderRunType.ForceRun, MaxDepth:=1, ExtraPath:="versions\") Catch ex As Exception diff --git a/Plain Craft Launcher 2/Pages/PageVersion/PageVersionSetup.xaml.vb b/Plain Craft Launcher 2/Pages/PageVersion/PageVersionSetup.xaml.vb index cd26a45..dba8492 100644 --- a/Plain Craft Launcher 2/Pages/PageVersion/PageVersionSetup.xaml.vb +++ b/Plain Craft Launcher 2/Pages/PageVersion/PageVersionSetup.xaml.vb @@ -275,7 +275,7 @@ Dim RamTarget2 As Double '估计没啥问题了的内存 Dim RamTarget3 As Double '安装过多附加组件需要的内存 If Version IsNot Nothing AndAlso Not Version.IsLoaded Then Version.Load() - If Version IsNot Nothing AndAlso Version.Version.Modable Then + If Version IsNot Nothing AndAlso Version.Modable Then '可安装 Mod 的版本 Dim ModDir As New DirectoryInfo(Version.PathIndie & "mods\") Dim ModCount As Integer = If(ModDir.Exists, ModDir.GetFiles.Length, 0) diff --git a/Plain Craft Launcher 2/Plain Craft Launcher 2.vbproj b/Plain Craft Launcher 2/Plain Craft Launcher 2.vbproj index 009c46e..53cb7b4 100644 --- a/Plain Craft Launcher 2/Plain Craft Launcher 2.vbproj +++ b/Plain Craft Launcher 2/Plain Craft Launcher 2.vbproj @@ -152,11 +152,6 @@ Resources\Ookii.Dialogs.Wpf.dll False - - False - Resources\STUN.dll - False - @@ -260,6 +255,9 @@ PageLinkFeedback.xaml + + PageLinkHiper.xaml + PageOtherHelpDetail.xaml @@ -517,6 +515,10 @@ MSBuild:Compile Designer + + MSBuild:Compile + Designer + Designer MSBuild:Compile @@ -786,22 +788,22 @@ False - Exclude - True + Exclude + True Assembly False - Exclude - True + Exclude + True Assembly @@ -869,9 +871,6 @@ - - - diff --git a/Plain Craft Launcher 2/Resources/Help.zip b/Plain Craft Launcher 2/Resources/Help.zip index 82b277d..a82592d 100644 Binary files a/Plain Craft Launcher 2/Resources/Help.zip and b/Plain Craft Launcher 2/Resources/Help.zip differ diff --git a/Plain Craft Launcher 2/Resources/STUN.dll b/Plain Craft Launcher 2/Resources/STUN.dll deleted file mode 100644 index 082d220..0000000 Binary files a/Plain Craft Launcher 2/Resources/STUN.dll and /dev/null differ diff --git a/Plain Craft Launcher 2/Resources/java-wrapper.jar b/Plain Craft Launcher 2/Resources/java-wrapper.jar index eb17c58..498ace7 100644 Binary files a/Plain Craft Launcher 2/Resources/java-wrapper.jar and b/Plain Craft Launcher 2/Resources/java-wrapper.jar differ