diff --git a/.github/ISSUE_TEMPLATE/bug1.yml b/.github/ISSUE_TEMPLATE/bug1.yml index b8e113e..787d47f 100644 --- a/.github/ISSUE_TEMPLATE/bug1.yml +++ b/.github/ISSUE_TEMPLATE/bug1.yml @@ -8,9 +8,9 @@ body: label: "检查项" description: "请逐个检查下列项目,并勾选确认。" options: - - label: "**我所启动的游戏不是整合包,且未开启安装 Mod。** 安装 Mod 后的游戏崩溃不是 PCL2 的原因,请 **不要** 提交反馈。你可以在 QQ 群里或者论坛找人求助,但这里并不是你求助的地方。" + - label: "**我所启动的游戏不是整合包,且未安装任何 Mod。** 安装 Mod 后的游戏崩溃不是 PCL2 的原因,请 **不要** 提交反馈。你可以在 QQ 群里或者论坛找人求助,但这里并不是你求助的地方。" required: true - - label: "**我已尝试使用其他启动器,其他启动器没有出现问题。** 如果其他启动器也存在问题,证明是游戏本身存在问题,并非 PCL2 的问题,请 **不要** 提交反馈。[下载其他启动器](https://www.mcbbs.net/forum.php?mod=forumdisplay&fid=43&filter=typeid&typeid=908)" + - label: "**我已尝试使用其他启动器,其他启动器没有出现问题。** 如果其他启动器也存在问题,证明是游戏本身的问题,并非 PCL2 的问题,请 **不要** 提交反馈。[下载其他启动器](https://www.mcbbs.net/forum.php?mod=forumdisplay&fid=43&filter=typeid&typeid=908)" required: true - label: "我已点击 `设置 → 启动器 → 检查更新` 确认了启动器已为最新版,且最新版未修复这个 Bug。[怎样更新?](https://shimo.im/docs/qKPttVvXKqPD8YDC#anchor-oTgb)" required: true @@ -27,7 +27,7 @@ body: id: "yml-3" attributes: label: 错误报告、日志与附件 - description: "上传 PCL2 提供的错误报告。如果没有,也可以上传 PCL 文件夹中的 Log1~5.txt。" + description: "上传 PCL2 提供的错误报告(在崩溃时选择导出错误报告)。如果没有,也可以上传 PCL 文件夹中的 Log1~5.txt。" placeholder: "先点击这个文本框,然后再将文件直接拖拽到文本框中以上传。" validations: required: true \ No newline at end of file diff --git a/.gitignore b/.gitignore index 5f5ef7d..c346e33 100644 --- a/.gitignore +++ b/.gitignore @@ -350,7 +350,8 @@ PageOtherAbout.* PageOtherTest.* PageSetupUI.* # 公开联机代码可能导致安全风险 -PageLink/ +Plain Craft Launcher 2/Pages/PageLink/PageLinkIoi.xaml.vb +Plain Craft Launcher 2/Pages/PageLink/PageLinkHiPer.xaml.vb # 开发者工具 ModDevelop.vb # 不公开底层函数库,以免抄袭 diff --git a/Plain Craft Launcher 2/FormMain.xaml.vb b/Plain Craft Launcher 2/FormMain.xaml.vb index ff42f42..640c082 100644 --- a/Plain Craft Launcher 2/FormMain.xaml.vb +++ b/Plain Craft Launcher 2/FormMain.xaml.vb @@ -142,9 +142,14 @@ Public Class FormMain '3:小* '2:极度严重的 Bug '1:严重的 Bug + 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")) + FeatureCount += 2 + BugCount += 3 + End If If LastVersion < 263 Then 'Snapshot 2.3.4 FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "修复部分情况下无法启动路径带有中文的游戏的 Bug")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "修复多个可能导致 OptiFine、Forge 安装失败的 Bug")) FeatureCount += 11 BugCount += 5 End If diff --git a/Plain Craft Launcher 2/Modules/Base/ModBase.vb b/Plain Craft Launcher 2/Modules/Base/ModBase.vb index aae99a5..e3fb7bc 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.4" '不含分支前缀的显示用版本名 - Public Const VersionStandardCode As String = "2.3.4." & VersionBranchCode '标准格式的四段式版本号 + Public Const VersionBaseName As String = "2.3.5" '不含分支前缀的显示用版本名 + Public Const VersionStandardCode As String = "2.3.5." & VersionBranchCode '标准格式的四段式版本号 #If BETA Then Public Const VersionCode As Integer = 260 'Release #Else - Public Const VersionCode As Integer = 263 'Snapshot + Public Const VersionCode As Integer = 264 'Snapshot #End If '自动生成的版本信息 Public Const VersionDisplayName As String = VersionBranchName & " " & VersionBaseName @@ -2476,6 +2476,14 @@ Retry: If Not Exp Then Throw New Exception("断言命中") End Sub + '获取当前的堆栈信息 + Public Function GetStackTrace() As String + Dim Stack As New StackTrace() + Return Join(Stack.GetFrames().Skip(1).Select(Function(f) f.GetMethod). + Select(Function(f) f.Name & "(" & Join(f.GetParameters.Select(Function(p) p.ToString).ToList, ", ") & ") - " & f.Module.ToString).ToList, + vbCrLf).Replace(vbCrLf & vbCrLf, vbCrLf) + End Function + #End Region #Region "随机" diff --git a/Plain Craft Launcher 2/Modules/Minecraft/ModCrash.vb b/Plain Craft Launcher 2/Modules/Minecraft/ModCrash.vb index c8a1a61..f43985b 100644 --- a/Plain Craft Launcher 2/Modules/Minecraft/ModCrash.vb +++ b/Plain Craft Launcher 2/Modules/Minecraft/ModCrash.vb @@ -340,6 +340,7 @@ 没有可用的分析文件 使用32位Java导致JVM无法分配足够多的内存 Mod重复安装 + OptiFine与Forge不兼容 Fabric报错 Fabric报错并给出解决方案 Forge报错 @@ -449,6 +450,8 @@ Done: If LogMc.Contains("The driver does not appear to support OpenGL") Then AppendReason(CrashReason.显卡不支持OpenGL) If LogMc.Contains("java.lang.ClassCastException: java.base/jdk") Then AppendReason(CrashReason.使用JDK) If LogMc.Contains("java.lang.ClassCastException: class jdk.") Then AppendReason(CrashReason.使用JDK) + If LogMc.Contains("Cannot read field ""ofTelemetry"" because ""net.optifine.Config.gameSettings"" is null") Then AppendReason(CrashReason.OptiFine与Forge不兼容) + If LogMc.Contains("TRANSFORMER/net.optifine/net.optifine.reflect.Reflector.(Reflector.java") Then AppendReason(CrashReason.OptiFine与Forge不兼容) If LogMc.Contains("Open J9 is not supported") OrElse LogMc.Contains("OpenJ9 is incompatible") OrElse LogMc.Contains(".J9VMInternals.") Then AppendReason(CrashReason.使用OpenJ9) If LogMc.Contains("because module java.base does not export") Then AppendReason(CrashReason.Java版本过高) If LogMc.Contains("java.lang.ClassNotFoundException: java.lang.invoke.LambdaMetafactory") Then AppendReason(CrashReason.Java版本过高) @@ -554,7 +557,7 @@ Done: For Each Stack As String In StackSearchResults 'If Not Stack.Contains(".") Then Continue For For Each IgnoreStack In { - "java", "sun", "javax", "jdk", + "java", "sun", "javax", "jdk", "oolloo", "org.lwjgl", "com.sun", "net.minecraftforge", "com.mojang", "net.minecraft", "cpw.mods", "com.google", "org.apache", "org.spongepowered", "net.fabricmc", "com.mumfrey", "com.electronwill.nightconfig", "it.unimi.dsi", "MojangTricksIntelDriversForPerformance_javaw"} @@ -580,9 +583,9 @@ NextStack: If {"com", "org", "net", "asm", "fml", "mod", "jar", "sun", "lib", "map", "gui", "dev", "nio", "api", "dsi", "core", "init", "mods", "main", "file", "game", "load", "read", "done", "util", "tile", "item", "base", "forge", "setup", "block", "model", "mixin", "event", "unimi", - "common", "server", "config", "loader", "launch", "entity", "assist", "client", "modapi", "mojang", "shader", "events", "github", + "common", "server", "config", "loader", "launch", "entity", "assist", "client", "modapi", "mojang", "shader", "events", "github", "recipe", "preinit", "preload", "machine", "reflect", "channel", "general", "handler", "content", - "fastutil", "optifine", "minecraft", "transformers", "universal", "internal", "multipart", "minecraftforge", "override" + "fastutil", "optifine", "minecraft", "transformers", "universal", "internal", "multipart", "minecraftforge", "override", "blockentity" }.Contains(Word.ToLower) Then Continue For PossibleWords.Add(Word.Trim) Next @@ -819,6 +822,8 @@ NextStack: Else ResultString = "游戏似乎因为世界中的某些实体出现了问题。\n\n你可以创建一个新世界,并生成各种实体,观察游戏的运行情况:\n - 若正常运行,则是某些实体导致出错,你或许需要删除该世界。\n - 若仍然出错,问题就可能来自其他原因……\h" End If + Case CrashReason.OptiFine与Forge不兼容 + ResultString = "由于 OptiFine 与当前版本的 Forge 不兼容,导致了游戏崩溃。\n\n请前往 OptiFine 官网(https://optifine.net/downloads)查看 OptiFine 所兼容的 Forge 版本,并严格按照对应版本重新安装游戏。\n经测试,Forge 版本过高或过低都可能导致崩溃。" Case CrashReason.低版本Forge与高版本Java不兼容 ResultString = "由于低版本 Forge 与当前 Java 不兼容,导致了游戏崩溃。\n\n请尝试以下解决方案:\n - 更新 Forge 到 36.2.26 或更高版本\n - 换用版本低于 8.0.320 的 Java" Case CrashReason.版本Json中存在多个Forge diff --git a/Plain Craft Launcher 2/Modules/Minecraft/ModDownload.vb b/Plain Craft Launcher 2/Modules/Minecraft/ModDownload.vb index 5bbf007..78737e4 100644 --- a/Plain Craft Launcher 2/Modules/Minecraft/ModDownload.vb +++ b/Plain Craft Launcher 2/Modules/Minecraft/ModDownload.vb @@ -1266,6 +1266,9 @@ RightKeywords.Add(Keyword) Next Task.Input.SearchFilter = Join(ArrayNoDouble(RightKeywords), " ").ToLower + '例外项: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" Log("[Download] CurseForge 工程列表搜索最终文本:" & Task.Input.SearchFilter, LogLevel.Developer) '正式获取 Dim Url = Task.Input.GetAddress() diff --git a/Plain Craft Launcher 2/Modules/Minecraft/ModLaunch.vb b/Plain Craft Launcher 2/Modules/Minecraft/ModLaunch.vb index 11ddd3c..69371a2 100644 --- a/Plain Craft Launcher 2/Modules/Minecraft/ModLaunch.vb +++ b/Plain Craft Launcher 2/Modules/Minecraft/ModLaunch.vb @@ -1163,13 +1163,18 @@ SystemBrowser: 'Authlib-Injector If McLoginLoader.Output.Type = "Auth" Then Dim Server As String = Setup.Get("VersionServerAuthServer", Version:=McVersionCurrent) - Dim Response As String = NetGetCodeByRequestRetry(Server, Encoding.UTF8) - DataList.Insert(0, "-javaagent:authlib-injector.jar=" & Server & + Try + Dim Response As String = NetGetCodeByRequestRetry(Server, Encoding.UTF8) + DataList.Insert(0, "-javaagent:authlib-injector.jar=" & Server & " -Dauthlibinjector.side=client" & " -Dauthlibinjector.yggdrasil.prefetched=" & Convert.ToBase64String(Encoding.UTF8.GetBytes(Response))) + Catch ex As Exception + Throw New Exception("无法连接到第三方登录服务器(" & If(Server, Nothing) & ")", ex) + End Try End If '添加 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")) @@ -1233,10 +1238,19 @@ NextVersion: " -Dauthlibinjector.side=client" & " -Dauthlibinjector.yggdrasil.prefetched=" & Convert.ToBase64String(Encoding.UTF8.GetBytes(Response))) Catch ex As Exception - Throw New Exception("无法连接到第三方登录服务器(" & If(Server, Nothing) & ")") + Throw New Exception("无法连接到第三方登录服务器(" & If(Server, Nothing) & ")", ex) End Try End If + '添加 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 & """") + '将 "-XXX" 与后面 "XXX" 合并到一起 '如果不合并,会导致 Forge 1.17 启动无效,它有两个 --add-exports,进一步导致其中一个在后面被去重 Dim DeDuplicateDataList As New List(Of String) @@ -1258,14 +1272,6 @@ NextVersion: '去重 Dim Result As String = Join(ArrayNoDouble(DeDuplicateDataList), " ") - '添加 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 - Result += " -jar """ & WrapperPath & """" - '添加 MainClass If Version.JsonObject("mainClass") Is Nothing Then Throw New Exception("版本 Json 中没有 mainClass 项!") @@ -1285,9 +1291,6 @@ NextVersion: If Not BasicString.Contains("--height") Then BasicString += " --height ${resolution_height} --width ${resolution_width}" DataList.Add(BasicString) - '添加 Wrapper 导出参数 - DataList.Add("--add-exports cpw.mods.bootstraplauncher/cpw.mods.bootstraplauncher=ALL-UNNAMED") - Dim Result As String = Join(DataList, " ") '特别改变 OptiFineTweaker @@ -1341,9 +1344,6 @@ NextVersion: GoTo NextVersion End If - '添加 Wrapper 导出参数 - DataList.Add("--add-exports cpw.mods.bootstraplauncher/cpw.mods.bootstraplauncher=ALL-UNNAMED") - '将 "-XXX" 与后面 "XXX" 合并到一起 '如果不进行合并 Impact 会启动无效,它有两个 --tweakclass Dim DeDuplicateDataList As New List(Of String) diff --git a/Plain Craft Launcher 2/Modules/Minecraft/ModMinecraft.vb b/Plain Craft Launcher 2/Modules/Minecraft/ModMinecraft.vb index 5ceb23f..b5cfcc3 100644 --- a/Plain Craft Launcher 2/Modules/Minecraft/ModMinecraft.vb +++ b/Plain Craft Launcher 2/Modules/Minecraft/ModMinecraft.vb @@ -592,7 +592,7 @@ UserPass: '缺失 ''' - ''' 提示 Java 缺失并跳转下载。支持 Java 7、8、16。 + ''' 提示 Java 缺失并跳转下载。支持 Java 7、8、16、17。 ''' Public Sub JavaMissing(VersionCode As Integer) Select Case VersionCode @@ -613,8 +613,8 @@ UserPass: If Is32BitSystem Then MyMsgBox("该版本的 MC 已不支持 32 位操作系统。你必须增加内存并重装为 64 位系统才能继续。", "系统兼容性提示") Else - OpenWebsite("https://www.oracle.com/java/technologies/downloads/#jdk17-windows") - MyMsgBox("PCL2 未找到 Java " & VersionCode & "。" & vbCrLf & + OpenWebsite("https://www.oracle.com/java/technologies/downloads/#java17") + MyMsgBox("PCL2 未找到 Java 17。" & vbCrLf & "请在打开的网页中选择 x64 Installer,下载并安装。" & vbCrLf & "安装后在 PCL2 的 设置 → 启动设置 → 游戏 Java 中通过搜索或导入,确保安装的 Java 已列入 Java 列表。", "未找到 Java") diff --git a/Plain Craft Launcher 2/My Project/AssemblyInfo.vb b/Plain Craft Launcher 2/My Project/AssemblyInfo.vb index be4c942..f426611 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/Pages/PageDownload/ModDownloadLib.vb b/Plain Craft Launcher 2/Pages/PageDownload/ModDownloadLib.vb index d97e08d..97b5104 100644 --- a/Plain Craft Launcher 2/Pages/PageDownload/ModDownloadLib.vb +++ b/Plain Craft Launcher 2/Pages/PageDownload/ModDownloadLib.vb @@ -1,6 +1,8 @@ Imports System.IO.Compression Public Module ModDownloadLib + '如果 OptiFine 与 Forge 同时开始安装,就会导致 Forge 安装失败 + Private InstallSyncLock As New Object #Region "Minecraft 下载" @@ -372,90 +374,100 @@ Public Module ModDownloadLib '选择 Java Dim Java = JavaSelect(New Version(1, 8, 0, 0)) If Java Is Nothing Then - JavaMissing(8) + JavaMissing(17) Throw New Exception("未找到用于安装 OptiFine 的 Java") End If - '开始启动 - Dim Info = New ProcessStartInfo With { - .FileName = Java.PathJavaw, - .Arguments = "-Duser.home=""" & BaseMcFolderHome & """ -cp """ & Target & """ optifine.Installer", - .UseShellExecute = False, - .CreateNoWindow = True, - .RedirectStandardError = True, - .RedirectStandardOutput = True, - .WorkingDirectory = BaseMcFolderHome - } - If Info.EnvironmentVariables.ContainsKey("appdata") Then - Info.EnvironmentVariables("appdata") = BaseMcFolderHome - Else - Info.EnvironmentVariables.Add("appdata", BaseMcFolderHome) + '添加 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 - Log("[Download] 开始安装 OptiFine:" & Target) - Dim TotalLength As Integer = 0 - Dim process As New Process With {.StartInfo = Info} - Dim LastResult As String = "" - Using outputWaitHandle As New AutoResetEvent(False) - Using errorWaitHandle As New AutoResetEvent(False) - AddHandler process.OutputDataReceived, Function(sender, e) - Try - If e.Data Is Nothing Then - outputWaitHandle.[Set]() - Else - LastResult = e.Data - If ModeDebug Then Log("[Installer] " & LastResult) - TotalLength += 1 - Task.Progress += 0.9 / 7000 - End If - Catch ex As ObjectDisposedException - Catch ex As Exception - Log(ex, "读取 OptiFine 安装器信息失败") - End Try - Try - If Task.State = LoadState.Aborted AndAlso Not process.HasExited Then - Log("[Installer] 由于任务取消,已中止 OptiFine 安装") - process.Kill() - End If - Catch - End Try - Return Nothing - End Function - AddHandler process.ErrorDataReceived, Function(sender, e) - Try - If e.Data Is Nothing Then - errorWaitHandle.[Set]() - Else - LastResult = e.Data - If ModeDebug Then Log("[Installer] " & LastResult) - TotalLength += 1 - Task.Progress += 0.9 / 7000 - End If - Catch ex As ObjectDisposedException - Catch ex As Exception - Log(ex, "读取 OptiFine 安装器错误信息失败") - End Try - Try - If Task.State = LoadState.Aborted AndAlso Not process.HasExited Then - Log("[Installer] 由于任务取消,已中止 OptiFine 安装") - process.Kill() - End If - Catch - End Try - Return Nothing - End Function - process.Start() - process.BeginOutputReadLine() - process.BeginErrorReadLine() - '等待 - Do Until process.HasExited - Thread.Sleep(10) - Loop - '输出 - outputWaitHandle.WaitOne(10000) - errorWaitHandle.WaitOne(10000) - process.Dispose() - If TotalLength < 1000 Then Throw New Exception("安装器运行出错,末行为 " & LastResult) + Dim Arguments = "-Duser.home=""" & BaseMcFolderHome & """ -cp """ & Target & """ -jar """ & WrapperPath & """ optifine.Installer" + If Java.VersionCode >= 9 Then Arguments = "--add-exports cpw.mods.bootstraplauncher/cpw.mods.bootstraplauncher=ALL-UNNAMED " & Arguments + '开始启动 + SyncLock InstallSyncLock + Dim Info = New ProcessStartInfo With { + .FileName = Java.PathJavaw, + .Arguments = Arguments, + .UseShellExecute = False, + .CreateNoWindow = True, + .RedirectStandardError = True, + .RedirectStandardOutput = True, + .WorkingDirectory = BaseMcFolderHome + } + If Info.EnvironmentVariables.ContainsKey("appdata") Then + Info.EnvironmentVariables("appdata") = BaseMcFolderHome + Else + Info.EnvironmentVariables.Add("appdata", BaseMcFolderHome) + End If + Log("[Download] 开始安装 OptiFine:" & Target) + Dim TotalLength As Integer = 0 + Dim process As New Process With {.StartInfo = Info} + Dim LastResult As String = "" + Using outputWaitHandle As New AutoResetEvent(False) + Using errorWaitHandle As New AutoResetEvent(False) + AddHandler process.OutputDataReceived, Function(sender, e) + Try + If e.Data Is Nothing Then + outputWaitHandle.[Set]() + Else + LastResult = e.Data + If ModeDebug Then Log("[Installer] " & LastResult) + TotalLength += 1 + Task.Progress += 0.9 / 7000 + End If + Catch ex As ObjectDisposedException + Catch ex As Exception + Log(ex, "读取 OptiFine 安装器信息失败") + End Try + Try + If Task.State = LoadState.Aborted AndAlso Not process.HasExited Then + Log("[Installer] 由于任务取消,已中止 OptiFine 安装") + process.Kill() + End If + Catch + End Try + Return Nothing + End Function + AddHandler process.ErrorDataReceived, Function(sender, e) + Try + If e.Data Is Nothing Then + errorWaitHandle.[Set]() + Else + LastResult = e.Data + If ModeDebug Then Log("[Installer] " & LastResult) + TotalLength += 1 + Task.Progress += 0.9 / 7000 + End If + Catch ex As ObjectDisposedException + Catch ex As Exception + Log(ex, "读取 OptiFine 安装器错误信息失败") + End Try + Try + If Task.State = LoadState.Aborted AndAlso Not process.HasExited Then + Log("[Installer] 由于任务取消,已中止 OptiFine 安装") + process.Kill() + End If + Catch + End Try + Return Nothing + End Function + process.Start() + process.BeginOutputReadLine() + process.BeginErrorReadLine() + '等待 + Do Until process.HasExited + Thread.Sleep(10) + Loop + '输出 + outputWaitHandle.WaitOne(10000) + errorWaitHandle.WaitOne(10000) + process.Dispose() + If TotalLength < 1000 Then Throw New Exception("安装器运行出错,末行为 " & LastResult) + End Using End Using - End Using + End SyncLock End Sub ''' @@ -536,50 +548,50 @@ Public Module ModDownloadLib If IsNewVersion Then Log("[Download] 检测为新版 OptiFine:" & DownloadInfo.Inherit) Loaders.Add(New LoaderTask(Of List(Of NetFile), Boolean)("安装 OptiFine(方式 A)", - Sub(Task As LoaderTask(Of List(Of NetFile), Boolean)) - Dim BaseMcFolderHome As String = PathTemp & "InstallOptiFine" & RandomInteger(0, 100000) - Dim BaseMcFolder As String = BaseMcFolderHome & "\.minecraft\" - Try - '准备安装环境 - If Directory.Exists(BaseMcFolder & "versions\" & DownloadInfo.Inherit) Then - DeleteDirectory(BaseMcFolder & "versions\" & DownloadInfo.Inherit) - End If - My.Computer.FileSystem.CreateDirectory(BaseMcFolder & "versions\" & DownloadInfo.Inherit & "\") - McFolderLauncherProfilesJsonCreate(BaseMcFolder) - CopyFile(McFolder & "versions\" & DownloadInfo.Inherit & "\" & DownloadInfo.Inherit & ".json", - BaseMcFolder & "versions\" & DownloadInfo.Inherit & "\" & DownloadInfo.Inherit & ".json") - CopyFile(McFolder & "versions\" & DownloadInfo.Inherit & "\" & DownloadInfo.Inherit & ".jar", - BaseMcFolder & "versions\" & DownloadInfo.Inherit & "\" & DownloadInfo.Inherit & ".jar") - Task.Progress = 0.06 - '进行安装 - McDownloadOptiFineInstall(BaseMcFolderHome, Target, Task) - Task.Progress = 0.96 - '复制文件 - File.Delete(BaseMcFolder & "launcher_profiles.json") - My.Computer.FileSystem.CopyDirectory(BaseMcFolder, McFolder, True) - Task.Progress = 0.98 - '清理文件 - My.Computer.FileSystem.DeleteFile(Target) - DeleteDirectory(BaseMcFolderHome) - Catch ex As Exception - Throw New Exception("安装新版 OptiFine 版本失败", ex) - End Try - End Sub) With {.ProgressWeight = 8}) + Sub(Task As LoaderTask(Of List(Of NetFile), Boolean)) + Dim BaseMcFolderHome As String = PathTemp & "InstallOptiFine" & RandomInteger(0, 100000) + Dim BaseMcFolder As String = BaseMcFolderHome & "\.minecraft\" + Try + '准备安装环境 + If Directory.Exists(BaseMcFolder & "versions\" & DownloadInfo.Inherit) Then + DeleteDirectory(BaseMcFolder & "versions\" & DownloadInfo.Inherit) + End If + My.Computer.FileSystem.CreateDirectory(BaseMcFolder & "versions\" & DownloadInfo.Inherit & "\") + McFolderLauncherProfilesJsonCreate(BaseMcFolder) + CopyFile(McFolder & "versions\" & DownloadInfo.Inherit & "\" & DownloadInfo.Inherit & ".json", + BaseMcFolder & "versions\" & DownloadInfo.Inherit & "\" & DownloadInfo.Inherit & ".json") + CopyFile(McFolder & "versions\" & DownloadInfo.Inherit & "\" & DownloadInfo.Inherit & ".jar", + BaseMcFolder & "versions\" & DownloadInfo.Inherit & "\" & DownloadInfo.Inherit & ".jar") + Task.Progress = 0.06 + '进行安装 + McDownloadOptiFineInstall(BaseMcFolderHome, Target, Task) + Task.Progress = 0.96 + '复制文件 + File.Delete(BaseMcFolder & "launcher_profiles.json") + My.Computer.FileSystem.CopyDirectory(BaseMcFolder, McFolder, True) + Task.Progress = 0.98 + '清理文件 + My.Computer.FileSystem.DeleteFile(Target) + DeleteDirectory(BaseMcFolderHome) + Catch ex As Exception + Throw New Exception("安装新版 OptiFine 版本失败", ex) + End Try + End Sub) With {.ProgressWeight = 8}) Else Log("[Download] 检测为旧版 OptiFine:" & DownloadInfo.Inherit) Loaders.Add(New LoaderTask(Of List(Of NetFile), Boolean)("安装 OptiFine(方式 B)", - Sub(Task As LoaderTask(Of List(Of NetFile), Boolean)) - Try - '新建版本文件夹 - Directory.CreateDirectory(VersionFolder) - Task.Progress = 0.1 - '复制 Jar 文件 - If File.Exists(VersionFolder & Id & ".jar") Then File.Delete(VersionFolder & Id & ".jar") - CopyFile(McFolder & "versions\" & DownloadInfo.Inherit & "\" & DownloadInfo.Inherit & ".jar", VersionFolder & Id & ".jar") - Task.Progress = 0.7 - '建立 Json 文件 - Dim InheritVersion As New McVersion(McFolder & "versions\" & DownloadInfo.Inherit) - Dim Json As String = "{ + Sub(Task As LoaderTask(Of List(Of NetFile), Boolean)) + Try + '新建版本文件夹 + Directory.CreateDirectory(VersionFolder) + Task.Progress = 0.1 + '复制 Jar 文件 + If File.Exists(VersionFolder & Id & ".jar") Then File.Delete(VersionFolder & Id & ".jar") + CopyFile(McFolder & "versions\" & DownloadInfo.Inherit & "\" & DownloadInfo.Inherit & ".jar", VersionFolder & Id & ".jar") + Task.Progress = 0.7 + '建立 Json 文件 + Dim InheritVersion As New McVersion(McFolder & "versions\" & DownloadInfo.Inherit) + Dim Json As String = "{ ""id"": """ & Id & """, ""inheritsFrom"": """ & DownloadInfo.Inherit & """, ""time"": """ & If(DownloadInfo.ReleaseTime = "", InheritVersion.ReleaseTime.ToString("yyyy-MM-dd"), DownloadInfo.ReleaseTime.Replace("/", "-")) & "T23:33:33+08:00"", @@ -590,16 +602,16 @@ Public Module ModDownloadLib {""name"": ""net.minecraft:launchwrapper:1.12""} ], ""mainClass"": ""net.minecraft.launchwrapper.Launch""," - Task.Progress = 0.8 - If InheritVersion.IsOldJson Then - '输出旧版 Json 格式 - Json += " + Task.Progress = 0.8 + If InheritVersion.IsOldJson Then + '输出旧版 Json 格式 + Json += " ""minimumLauncherVersion"": 18, ""minecraftArguments"": """ & InheritVersion.JsonObject("minecraftArguments").ToString & " --tweakClass optifine.OptiFineTweaker"" }" - Else - '输出新版 Json 格式 - Json += " + Else + '输出新版 Json 格式 + Json += " ""minimumLauncherVersion"": ""21"", ""arguments"": { ""game"": [ @@ -608,12 +620,12 @@ Public Module ModDownloadLib ] } }" - End If - WriteFile(VersionFolder & Id & ".json", Json) - Catch ex As Exception - Throw New Exception("安装旧版 OptiFine 版本失败", ex) - End Try - End Sub) With {.ProgressWeight = 1}) + End If + WriteFile(VersionFolder & Id & ".json", Json) + Catch ex As Exception + Throw New Exception("安装旧版 OptiFine 版本失败", ex) + End Try + End Sub) With {.ProgressWeight = 1}) End If '下载支持库 @@ -1078,90 +1090,93 @@ Public Module ModDownloadLib '选择 Java Dim Java = JavaSelect(New Version(1, 8, 0, 60)) If Java Is Nothing Then - JavaMissing(8) + JavaMissing(17) 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 + If Java.VersionCode >= 9 Then Arguments = "--add-exports cpw.mods.bootstraplauncher/cpw.mods.bootstraplauncher=ALL-UNNAMED " & Arguments '开始启动 - Dim Argument As String = String.Format("-cp ""{0};{1}"" com.bangbang93.ForgeInstaller ""{2}", PathTemp & "Cache\forge_installer.jar", Target, McFolder) - Dim Info = New ProcessStartInfo With { - .FileName = Java.PathJavaw, - .Arguments = Argument, - .UseShellExecute = False, - .CreateNoWindow = True, - .RedirectStandardError = True, - .RedirectStandardOutput = True - } - Log("[Download] 开始安装 Forge:" & Argument) - Dim process As New Process With {.StartInfo = Info} - Dim LastResults As New Queue(Of String) - Using outputWaitHandle As New AutoResetEvent(False) - Using errorWaitHandle As New AutoResetEvent(False) - AddHandler process.OutputDataReceived, Function(sender, e) - Try - If e.Data Is Nothing Then - outputWaitHandle.[Set]() - Else - LastResults.Enqueue(e.Data) - If LastResults.Count > 100 Then LastResults.Dequeue() - ForgeInjectorLine(e.Data, Task) - End If - Catch ex As ObjectDisposedException - Catch ex As Exception - Log(ex, "读取 Forge 安装器信息失败") - End Try - Try - If Task.State = LoadState.Aborted AndAlso Not process.HasExited Then - Log("[Installer] 由于任务取消,已中止 Forge 安装") - process.Kill() - End If - Catch - End Try - Return Nothing - End Function - AddHandler process.ErrorDataReceived, Function(sender, e) - Try - If e.Data Is Nothing Then - errorWaitHandle.[Set]() - Else - LastResults.Enqueue(e.Data) - If LastResults.Count > 100 Then LastResults.Dequeue() - ForgeInjectorLine(e.Data, Task) - End If - Catch ex As ObjectDisposedException - Catch ex As Exception - Log(ex, "读取 Forge 安装器错误信息失败") - End Try - Try - If Task.State = LoadState.Aborted AndAlso Not process.HasExited Then - Log("[Installer] 由于任务取消,已中止 Forge 安装") - process.Kill() - End If - Catch - End Try - Return Nothing - End Function - process.Start() - process.BeginOutputReadLine() - process.BeginErrorReadLine() - '等待 - Do Until process.HasExited - Thread.Sleep(10) - Loop - '输出 - outputWaitHandle.WaitOne(10000) - errorWaitHandle.WaitOne(10000) - process.Dispose() - If LastResults.Last = "true" Then Exit Sub - Log(Join(LastResults, vbCrLf)) - Throw New Exception("Forge 安装器出错,末行为 " & LastResults.Last) + SyncLock InstallSyncLock + Dim Info = New ProcessStartInfo With { + .FileName = Java.PathJavaw, + .Arguments = Arguments, + .UseShellExecute = False, + .CreateNoWindow = True, + .RedirectStandardError = True, + .RedirectStandardOutput = True + } + Log("[Download] 开始安装 Forge:" & Arguments) + Dim process As New Process With {.StartInfo = Info} + Dim LastResults As New Queue(Of String) + Using outputWaitHandle As New AutoResetEvent(False) + Using errorWaitHandle As New AutoResetEvent(False) + AddHandler process.OutputDataReceived, Function(sender, e) + Try + If e.Data Is Nothing Then + outputWaitHandle.[Set]() + Else + LastResults.Enqueue(e.Data) + If LastResults.Count > 100 Then LastResults.Dequeue() + ForgeInjectorLine(e.Data, Task) + End If + Catch ex As ObjectDisposedException + Catch ex As Exception + Log(ex, "读取 Forge 安装器信息失败") + End Try + Try + If Task.State = LoadState.Aborted AndAlso Not process.HasExited Then + Log("[Installer] 由于任务取消,已中止 Forge 安装") + process.Kill() + End If + Catch + End Try + Return Nothing + End Function + AddHandler process.ErrorDataReceived, Function(sender, e) + Try + If e.Data Is Nothing Then + errorWaitHandle.[Set]() + Else + LastResults.Enqueue(e.Data) + If LastResults.Count > 100 Then LastResults.Dequeue() + ForgeInjectorLine(e.Data, Task) + End If + Catch ex As ObjectDisposedException + Catch ex As Exception + Log(ex, "读取 Forge 安装器错误信息失败") + End Try + Try + If Task.State = LoadState.Aborted AndAlso Not process.HasExited Then + Log("[Installer] 由于任务取消,已中止 Forge 安装") + process.Kill() + End If + Catch + End Try + Return Nothing + End Function + process.Start() + process.BeginOutputReadLine() + process.BeginErrorReadLine() + '等待 + Do Until process.HasExited + Thread.Sleep(10) + Loop + '输出 + outputWaitHandle.WaitOne(10000) + errorWaitHandle.WaitOne(10000) + process.Dispose() + If LastResults.Last = "true" Then Exit Sub + Log(Join(LastResults, vbCrLf)) + Throw New Exception("Forge 安装器出错,末行为 " & LastResults.Last) + End Using End Using - End Using - ''判断结果 - 'Dim ReturnData As String = - 'If ModeDebug Then Log("[Download] Forge 安装器 Log:" & vbCrLf & ReturnData & vbCrLf) - ' If Not ReturnData.TrimEnd(vbCrLf.ToCharArray()).EndsWith("true") Then - ' Throw New Exception("自动安装过程出错,日志尾部:" & vbCrLf & ReturnData.Substring(Math.Max(0, ReturnData.Length - 1000))) - 'End If + End SyncLock End Sub Private Sub ForgeInjectorLine(Content As String, Task As LoaderTask(Of Boolean, Boolean)) If Content.StartsWith(" Data") OrElse Content.StartsWith(" Slim") Then diff --git a/Plain Craft Launcher 2/Pages/PageLink/PageLinkFeedback.xaml b/Plain Craft Launcher 2/Pages/PageLink/PageLinkFeedback.xaml new file mode 100644 index 0000000..1d70083 --- /dev/null +++ b/Plain Craft Launcher 2/Pages/PageLink/PageLinkFeedback.xaml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Plain Craft Launcher 2/Pages/PageLink/PageLinkFeedback.xaml.vb b/Plain Craft Launcher 2/Pages/PageLink/PageLinkFeedback.xaml.vb new file mode 100644 index 0000000..01d2504 --- /dev/null +++ b/Plain Craft Launcher 2/Pages/PageLink/PageLinkFeedback.xaml.vb @@ -0,0 +1,3 @@ +Public Class PageLinkFeedback + +End Class diff --git a/Plain Craft Launcher 2/Pages/PageLink/PageLinkIoi.xaml b/Plain Craft Launcher 2/Pages/PageLink/PageLinkIoi.xaml new file mode 100644 index 0000000..0ffc18d --- /dev/null +++ b/Plain Craft Launcher 2/Pages/PageLink/PageLinkIoi.xaml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Plain Craft Launcher 2/Pages/PageLink/PageLinkLeft.xaml b/Plain Craft Launcher 2/Pages/PageLink/PageLinkLeft.xaml new file mode 100644 index 0000000..e20ed15 --- /dev/null +++ b/Plain Craft Launcher 2/Pages/PageLink/PageLinkLeft.xaml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +