2.4.0
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
''' 程序的缓存文件夹路径,以“\”结尾。
|
||||
''' </summary>
|
||||
Public PathTemp As String = If(Setup.Get("SystemSystemCache") = "", IO.Path.GetTempPath() & "PCL\", Setup.Get("SystemSystemCache")).ToString.Replace("/", "\").TrimEnd("\") & "\"
|
||||
''' <summary>
|
||||
''' AppData 中的 PCL 文件夹路径,以“\”结尾。
|
||||
''' </summary>
|
||||
Public PathAppdata As String = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) & "\PCL\"
|
||||
|
||||
#End Region
|
||||
|
||||
@@ -447,6 +451,32 @@ Public Module ModBase
|
||||
|
||||
#Region "数学"
|
||||
|
||||
''' <summary>
|
||||
''' 2~65 进制的转换。
|
||||
''' </summary>
|
||||
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
|
||||
|
||||
''' <summary>
|
||||
''' 计算二阶贝塞尔曲线。
|
||||
''' </summary>
|
||||
@@ -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
|
||||
|
||||
''' <summary>
|
||||
''' 前台运行文件。
|
||||
''' </summary>
|
||||
''' <param name="FileName">文件名。可以为“notepad”等缩写。</param>
|
||||
''' <param name="Arguments">运行参数。</param>
|
||||
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
|
||||
''' <summary>
|
||||
''' 前台运行文件并返回返回值。
|
||||
''' </summary>
|
||||
''' <param name="FileName">文件名。可以为“notepad”等缩写。</param>
|
||||
''' <param name="Arguments">运行参数。</param>
|
||||
''' <param name="WaitForExit">是否等待该程序结束。默认为 False。</param>
|
||||
''' <param name="Timeout">等待该程序结束的最长时间(毫秒)。超时会返回 Result.Timeout。</param>
|
||||
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 获取输入时使用!
|
||||
''' </summary>
|
||||
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
|
||||
''' <summary>
|
||||
''' 确保在 UI 线程中执行代码。
|
||||
''' 如果当前并非 UI 线程,则会阻断当前线程,直至 UI 线程执行完毕。
|
||||
''' 为防止线程互锁,请仅在开始加载动画、从 UI 获取输入时使用!
|
||||
''' </summary>
|
||||
Public Sub RunInUiWait(Action As Action)
|
||||
If RunInUi() Then
|
||||
Action()
|
||||
@@ -2003,11 +2053,11 @@ NextElement:
|
||||
End Try
|
||||
End Sub
|
||||
''' <summary>
|
||||
''' 打开 explorer。
|
||||
''' 打开 explorer。注意参数中的路径要尽量加上双引号!
|
||||
''' </summary>
|
||||
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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,9 +1,28 @@
|
||||
Imports System.Net
|
||||
|
||||
Public Module ModNet
|
||||
|
||||
Public Const NetDownloadEnd As String = ".PCLDownloading"
|
||||
|
||||
''' <summary>
|
||||
''' 测试 Ping。失败则返回 -1。
|
||||
''' </summary>
|
||||
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
|
||||
|
||||
''' <summary>
|
||||
''' 以 WebClient 获取网页源代码。会进行至多 45 秒 3 次的尝试,允许最长 30s 的超时。
|
||||
''' </summary>
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 '在弹窗中选择直接打开的文件
|
||||
''' <summary>
|
||||
''' 从 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
|
||||
''' <summary>
|
||||
|
||||
@@ -1217,7 +1217,7 @@
|
||||
''' CurseForge 工程列表获取事件。
|
||||
''' </summary>
|
||||
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
|
||||
|
||||
@@ -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
|
||||
|
||||
''' <summary>
|
||||
''' 释放 Java Wrapper 并返回文件路径。
|
||||
''' </summary>
|
||||
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))
|
||||
|
||||
@@ -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:
|
||||
''' </summary>
|
||||
Public ReadOnly Property PathIndie As String
|
||||
Get
|
||||
Return GetPathIndie(Version.Modable)
|
||||
Return GetPathIndie(Modable)
|
||||
End Get
|
||||
End Property
|
||||
''' <summary>
|
||||
@@ -917,6 +916,15 @@ UserPass:
|
||||
''' </summary>
|
||||
Public DisplayType As McVersionCardType = McVersionCardType.Auto
|
||||
''' <summary>
|
||||
''' 该版本是否可以安装 Mod。
|
||||
''' </summary>
|
||||
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
|
||||
''' <summary>
|
||||
''' 版本信息。
|
||||
''' </summary>
|
||||
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
|
||||
|
||||
''' <summary>
|
||||
''' 该版本是否可以安装 Mod。
|
||||
''' </summary>
|
||||
Public ReadOnly Property Modable As Boolean
|
||||
Get
|
||||
Return HasFabric OrElse HasForge OrElse HasLiteLoader
|
||||
End Get
|
||||
End Property
|
||||
|
||||
''' <summary>
|
||||
''' 生成对此版本信息的用户友好的描述性字符串。
|
||||
''' </summary>
|
||||
|
||||
Reference in New Issue
Block a user