2.6.14
This commit is contained in:
@@ -11,12 +11,12 @@ Public Module ModBase
|
||||
#Region "声明"
|
||||
|
||||
'下列版本信息由更新器自动修改
|
||||
Public Const VersionBaseName As String = "2.6.13" '不含分支前缀的显示用版本名
|
||||
Public Const VersionStandardCode As String = "2.6.13." & VersionBranchCode '标准格式的四段式版本号
|
||||
Public Const VersionBaseName As String = "2.6.14" '不含分支前缀的显示用版本名
|
||||
Public Const VersionStandardCode As String = "2.6.14." & VersionBranchCode '标准格式的四段式版本号
|
||||
#If BETA Then
|
||||
Public Const VersionCode As Integer = 313 'Release
|
||||
#Else
|
||||
Public Const VersionCode As Integer = 312 'Snapshot
|
||||
Public Const VersionCode As Integer = 314 'Snapshot
|
||||
#End If
|
||||
'自动生成的版本信息
|
||||
Public Const VersionDisplayName As String = VersionBranchName & " " & VersionBaseName
|
||||
@@ -158,9 +158,13 @@ Public Module ModBase
|
||||
''' </summary>
|
||||
Public Const IconButtonUser As String = "M660.338 528.065c63.61-46.825 105.131-121.964 105.131-206.83 0-141.7-115.29-256.987-256.997-256.987-141.706 0-256.998 115.288-256.998 256.987 0 85.901 42.52 161.887 107.456 208.562-152.1 59.92-260.185 207.961-260.185 381.077 0 21.276 17.253 38.53 38.53 38.53 21.278 0 38.53-17.254 38.53-38.53 0-183.426 149.232-332.671 332.667-332.671 1.589 0 3.113-0.207 4.694-0.244 0.8 0.056 1.553 0.244 2.362 0.244 183.434 0 332.664 149.245 332.664 332.671 0 21.276 17.255 38.53 38.533 38.53 21.277 0 38.53-17.254 38.53-38.53 0-174.885-110.354-324.13-264.917-382.809z m-331.803-206.83c0-99.22 80.72-179.927 179.935-179.927s179.937 80.708 179.937 179.927c0 99.203-80.721 179.91-179.937 179.91s-179.935-80.708-179.935-179.91z"
|
||||
''' <summary>
|
||||
''' 图标按钮,微软,0.9x
|
||||
''' 图标按钮,盾牌,1x
|
||||
''' </summary>
|
||||
Public Const IconButtonMs As String = "M0,0h5v5h-5ZM6,0h5v5h-5v-5ZM0,6h5v5h-5v-5ZM6,6h5v5h-5v-5Z"
|
||||
Public Const IconButtonShield As String = "M511.488256 95.184408c35.310345 22.516742 95.184408 55.78011 167.34033 84.437781 75.738131 29.681159 148.405797 40.93953 191.392304 45.033483v353.615193c0 73.691154-50.662669 164.781609-136.123938 244.101949C649.65917 901.181409 558.568716 942.12094 512 942.12094c-46.568716 0-137.65917-40.93953-222.096952-119.748126C204.441779 742.54073 153.77911 651.450275 153.77911 577.247376v-353.103448c42.474763-4.093953 116.165917-15.352324 191.904048-45.545227 75.226387-30.192904 133.565217-63.456272 165.805098-83.414293M512 0c-4.093953 0-8.187906 1.535232-11.258371 3.582209l-14.84058 10.234882c-1.023488 0.511744-67.550225 47.592204-170.410794 88.531735-100.813593 39.916042-198.556722 41.963018-199.58021 41.963018l-25.075462 0.511744c-10.746627 0.511744-18.934533 8.187906-18.934533 18.422789v414.000999c0 216.97951 286.064968 446.24088 440.09995 446.24088s440.09995-229.261369 440.09995-445.729136V163.758121c0-10.234883-8.69965-18.422789-18.934533-18.422789l-24.563718-0.511744c-1.023488 0-98.766617-2.046977-199.58021-41.963018-103.372314-40.93953-170.410795-88.01999-170.922538-88.531734L523.258371 3.582209c-3.070465-2.558721-7.164418-3.582209-11.258371-3.582209z M743.308346 410.930535l-260.477761 260.477761c-15.864068 15.864068-41.963018 15.864068-57.827087 0l-144.823588-144.823588c-15.864068-15.864068-15.864068-41.963018 0-57.827087 8.187906-8.187906 18.422789-11.770115 29.169415-11.770115 10.234883 0 20.981509 4.093953 29.169416 11.770115l115.654173 115.654173L685.993003 352.591704c15.864068-15.864068 41.963018-15.864068 57.827087 0 15.352324 16.375812 15.352324 42.474763-0.511744 58.338831z"
|
||||
''' <summary>
|
||||
''' 图标按钮,离线,0.85x
|
||||
''' </summary>
|
||||
Public Const IconButtonOffline As String = "M533.293176 788.841412a60.235294 60.235294 0 1 1 85.202824 85.202823l-42.616471 42.586353c-129.355294 129.385412-339.124706 129.385412-468.510117 0-129.385412-129.385412-129.385412-339.124706 0-468.510117l42.586353-42.616471a60.235294 60.235294 0 1 1 85.202823 85.202824l-42.61647 42.586352a210.823529 210.823529 0 1 0 298.164706 298.164706l42.586352-42.61647z m255.548236-255.548236l42.61647-42.586352a210.823529 210.823529 0 1 0-298.164706-298.164706l-42.586352 42.61647a60.235294 60.235294 0 1 1-85.202824-85.202823l42.616471-42.586353c129.355294-129.385412 339.124706-129.385412 468.510117 0 129.385412 129.385412 129.385412 339.124706 0 468.510117l-42.586353 42.616471a60.235294 60.235294 0 1 1-85.202823-85.202824zM192.542118 192.542118a60.235294 60.235294 0 0 1 85.202823 0l553.712941 553.712941a60.235294 60.235294 0 0 1-85.202823 85.202823L192.542118 277.744941a60.235294 60.235294 0 0 1 0-85.202823z"
|
||||
''' <summary>
|
||||
''' 图标,音符,1x
|
||||
''' </summary>
|
||||
@@ -1980,9 +1984,10 @@ NextElement:
|
||||
Log("[System] 执行外部命令并等待返回结果:" & FileName & " " & Arguments)
|
||||
Using Program As New Process() With {.StartInfo = Info}
|
||||
Program.Start()
|
||||
Dim Result As String = Program.StandardOutput.ReadToEnd & Program.StandardError.ReadToEnd
|
||||
Program.WaitForExit(Timeout)
|
||||
If Not Program.HasExited Then Program.Kill()
|
||||
Return Program.StandardOutput.ReadToEnd & Program.StandardError.ReadToEnd
|
||||
Return Result
|
||||
End Using
|
||||
End Function
|
||||
|
||||
@@ -2111,6 +2116,7 @@ NextElement:
|
||||
''' </summary>
|
||||
Public Sub OpenWebsite(Url As String)
|
||||
Try
|
||||
If Not Url.ToLower.StartsWith("http") Then Throw New Exception(Url & " 不是一个有效的网址,它必须以 http 开头!")
|
||||
Log("[System] 正在打开网页:" & Url)
|
||||
Process.Start(Url)
|
||||
Catch ex As Exception
|
||||
|
||||
@@ -192,7 +192,6 @@ RequestFinished:
|
||||
If Url.StartsWith("https", StringComparison.OrdinalIgnoreCase) Then Request.ProtocolVersion = HttpVersion.Version11
|
||||
Request.Timeout = Timeout
|
||||
Request.Accept = Accept
|
||||
Request.KeepAlive = False
|
||||
SecretHeadersSign(Url, Request)
|
||||
Using res As HttpWebResponse = Request.GetResponse()
|
||||
Using HttpStream As Stream = res.GetResponseStream()
|
||||
@@ -393,7 +392,6 @@ RequestFinished:
|
||||
End If
|
||||
Req.ContentType = ContentType
|
||||
Req.Timeout = Timeout
|
||||
Req.KeepAlive = False
|
||||
SecretHeadersSign(Url, Req)
|
||||
If Url.StartsWith("https", StringComparison.OrdinalIgnoreCase) Then Req.ProtocolVersion = HttpVersion.Version11
|
||||
If Method = "POST" OrElse Method = "PUT" Then
|
||||
@@ -965,13 +963,12 @@ Capture:
|
||||
'是否禁用多线程,以及规定碎片大小
|
||||
Dim TargetUrl As String = GetSource().Url
|
||||
If TargetUrl.Contains("pcl2-server") OrElse TargetUrl.Contains("gitcode.net") OrElse TargetUrl.Contains("github.com") Then Return False
|
||||
Dim RealFilePieceLimit = If(TargetUrl.Contains("download.mcbbs.net"), FilePieceLimit * 5, FilePieceLimit)
|
||||
'寻找最大碎片
|
||||
Dim FilePieceMax As NetThread = Threads
|
||||
For Each Thread As NetThread In Threads
|
||||
If Thread.DownloadUndone > FilePieceMax.DownloadUndone Then FilePieceMax = Thread
|
||||
Next
|
||||
If FilePieceMax Is Nothing OrElse FilePieceMax.DownloadUndone < RealFilePieceLimit Then Return False
|
||||
If FilePieceMax Is Nothing OrElse FilePieceMax.DownloadUndone < FilePieceLimit Then Return False
|
||||
StartPosition = FilePieceMax.DownloadEnd - FilePieceMax.DownloadUndone * 0.4
|
||||
StartSource = GetSource()
|
||||
|
||||
@@ -1021,7 +1018,7 @@ StartThread:
|
||||
Dim HttpRequest As HttpWebRequest
|
||||
Dim ResultStream As Stream = Nothing
|
||||
'部分下载源真的特别慢,并且只需要一个请求,例如 Ping 为 20s,如果增长太慢,就会造成类似 2.5s 5s 7.5s 10s 12.5s... 的极大延迟
|
||||
'延迟过长会导致某些特别慢的链接迟迟不被掐死,即使 MCBBS 源在 10s 下也会出现类似情况
|
||||
'延迟过长会导致某些特别慢的链接迟迟不被掐死
|
||||
Dim Timeout As Integer = Math.Min(Math.Max(ConnectAverage, 6000) * (1 + Info.Source.FailCount), 30000)
|
||||
Info.State = NetState.Connect
|
||||
Try
|
||||
@@ -1206,7 +1203,9 @@ SourceBreak:
|
||||
'End SyncLock
|
||||
Info.Source.Ex = ex
|
||||
'根据情况判断,是否在多线程下禁用下载源(连续错误过多,或不支持断点续传)
|
||||
If ex.Message.Contains("该下载源不支持") OrElse ex.Message.Contains("未能解析") OrElse ex.Message.Contains("(404)") OrElse ex.Message.Contains("(403)") OrElse ex.Message.Contains("(502)") OrElse ex.Message.Contains("无返回数据") OrElse ex.Message.Contains("空间不足") OrElse
|
||||
'BMCLAPI 的部分源在高频率请求下会返回 403,所以不应因此禁用下载源
|
||||
If ex.Message.Contains("该下载源不支持") OrElse ex.Message.Contains("未能解析") OrElse ex.Message.Contains("(404)") OrElse
|
||||
ex.Message.Contains("(502)") OrElse ex.Message.Contains("无返回数据") OrElse ex.Message.Contains("空间不足") OrElse ex.Message.Contains("获取到的片大小不一致") OrElse
|
||||
(Info.Source.FailCount >= MathClamp(NetTaskThreadLimit, 5, 40) AndAlso DownloadDone < 1) OrElse
|
||||
Info.Source.FailCount > NetTaskThreadLimit Then
|
||||
Dim IsThisFail As Boolean = False
|
||||
@@ -1225,7 +1224,7 @@ Wrong:
|
||||
'本线程引发下载源被禁用
|
||||
If IsThisFail Then
|
||||
Log("[Download] " & LocalName & " " & Uuid & "#:下载源被禁用(" & Info.Source.Id & "):" & Info.Source.Url)
|
||||
Log(ex, "下载源 " & Info.Source.Id & " 已被禁用", If(ex.Message.Contains("不支持断点续传") OrElse ex.Message.Contains("404") OrElse ex.Message.Contains("416"), LogLevel.Developer, LogLevel.Debug))
|
||||
Log(ex, "下载源 " & Info.Source.Id & " 已被禁用", If(ex.Message.Contains("不支持断点续传") OrElse ex.Message.Contains("(404)") OrElse ex.Message.Contains("(416)"), LogLevel.Developer, LogLevel.Debug))
|
||||
If IsSourceFailed() Then
|
||||
'没有可用源
|
||||
Log("[Download] 文件 " & LocalName & " 已无可用下载源")
|
||||
@@ -1475,7 +1474,7 @@ Retry:
|
||||
End Get
|
||||
Set(value As Integer)
|
||||
_FailCount = value
|
||||
If State = LoadState.Loading AndAlso value >= Math.Min(2000, Math.Max(FileRemain * 5.5, NetTaskThreadLimit * 5.5 + 3)) Then
|
||||
If State = LoadState.Loading AndAlso value >= Math.Min(10000, Math.Max(FileRemain * 5.5, NetTaskThreadLimit * 5.5 + 3)) Then
|
||||
Log("[Download] 由于同加载器中失败次数过多引发强制失败:连续失败了 " & value & " 次", LogLevel.Debug)
|
||||
On Error Resume Next
|
||||
Dim ExList As New List(Of Exception)
|
||||
@@ -1846,69 +1845,70 @@ Retry:
|
||||
Private Sub StartManager()
|
||||
If IsManagerStarted Then Exit Sub
|
||||
IsManagerStarted = True
|
||||
RunInNewThread(Sub()
|
||||
Try
|
||||
Dim LastLoopTime As Long
|
||||
While True
|
||||
LastLoopTime = GetTimeTick()
|
||||
'若已完成,则清空
|
||||
If FileRemain = 0 AndAlso Files.Count > 0 Then
|
||||
SyncLock LockFiles
|
||||
Files.Clear()
|
||||
End SyncLock
|
||||
End If
|
||||
'开启新线程
|
||||
If Speed < NetTaskSpeedLimitLow OrElse FileRemain > NetTaskThreadLimit Then
|
||||
'速度小于下限或剩余文件还贼多,尝试开启线程
|
||||
Dim IsSuccess As Boolean = False
|
||||
Dim NewThreadCount As Integer
|
||||
'确定最大线程追加数
|
||||
NewThreadCount = Math.Max(FileRemain, MathClamp(NetTaskThreadCount / 2, 1, 4))
|
||||
NewThreadCount = Math.Floor(NewThreadCount / 2) '双线程启用减半
|
||||
NewThreadCount = MathClamp(NewThreadCount, 1, NetTaskThreadLimit)
|
||||
'循环追加
|
||||
Do
|
||||
IsSuccess = False
|
||||
'启动 Wait 的文件后立即会变成 Connect,导致第二次循环再次调用,所以需要先暂时存储进去……
|
||||
'此外为了减少 LockFiles 的占用时间,所以先遍历列表再开始
|
||||
Dim FilesWaiting As New List(Of NetFile)
|
||||
Dim FilesLoading As New List(Of NetFile)
|
||||
SyncLock LockFiles
|
||||
For Each File As NetFile In Files.Values
|
||||
If File.RandomCode Mod 2 = 0 Then Continue For
|
||||
If File.State = NetState.WaitForDownload Then
|
||||
FilesWaiting.Add(File)
|
||||
ElseIf File.State < NetState.Merge Then
|
||||
FilesLoading.Add(File)
|
||||
End If
|
||||
Next
|
||||
End SyncLock
|
||||
'为文件列表中的文件开始线程
|
||||
For Each File As NetFile In FilesWaiting
|
||||
If NewThreadCount = 0 Then Exit For
|
||||
If File.TryBeginThread() Then
|
||||
IsSuccess = True
|
||||
NewThreadCount -= 1
|
||||
End If
|
||||
Next
|
||||
For Each File As NetFile In FilesLoading
|
||||
If NewThreadCount = 0 Then Exit For
|
||||
If File.TryBeginThread() Then
|
||||
IsSuccess = True
|
||||
NewThreadCount -= 1
|
||||
End If
|
||||
Next
|
||||
Loop While NewThreadCount > 0 AndAlso IsSuccess
|
||||
End If
|
||||
'等待直至 120 ms
|
||||
Do While GetTimeTick() - LastLoopTime < 120
|
||||
Thread.Sleep(10)
|
||||
Loop
|
||||
End While
|
||||
Catch ex As Exception
|
||||
Log(ex, "下载管理启动线程 1 出错", LogLevel.Assert)
|
||||
End Try
|
||||
End Sub, "NetManager ThreadStarter Single")
|
||||
RunInNewThread(
|
||||
Sub()
|
||||
Try
|
||||
Dim LastLoopTime As Long
|
||||
While True
|
||||
LastLoopTime = GetTimeTick()
|
||||
'若已完成,则清空
|
||||
If FileRemain = 0 AndAlso Files.Count > 0 Then
|
||||
SyncLock LockFiles
|
||||
Files.Clear()
|
||||
End SyncLock
|
||||
End If
|
||||
'开启新线程
|
||||
If Speed < NetTaskSpeedLimitLow OrElse FileRemain > NetTaskThreadLimit Then
|
||||
'速度小于下限或剩余文件还贼多,尝试开启线程
|
||||
Dim IsSuccess As Boolean = False
|
||||
Dim NewThreadCount As Integer
|
||||
'确定最大线程追加数
|
||||
NewThreadCount = Math.Max(FileRemain, MathClamp(NetTaskThreadCount / 2, 1, 4))
|
||||
NewThreadCount = Math.Floor(NewThreadCount / 2) '双线程启用减半
|
||||
NewThreadCount = MathClamp(NewThreadCount, 1, NetTaskThreadLimit)
|
||||
'循环追加
|
||||
Do
|
||||
IsSuccess = False
|
||||
'启动 Wait 的文件后立即会变成 Connect,导致第二次循环再次调用,所以需要先暂时存储进去……
|
||||
'此外为了减少 LockFiles 的占用时间,所以先遍历列表再开始
|
||||
Dim FilesWaiting As New List(Of NetFile)
|
||||
Dim FilesLoading As New List(Of NetFile)
|
||||
SyncLock LockFiles
|
||||
For Each File As NetFile In Files.Values
|
||||
If File.RandomCode Mod 2 = 0 Then Continue For
|
||||
If File.State = NetState.WaitForDownload Then
|
||||
FilesWaiting.Add(File)
|
||||
ElseIf File.State < NetState.Merge Then
|
||||
FilesLoading.Add(File)
|
||||
End If
|
||||
Next
|
||||
End SyncLock
|
||||
'为文件列表中的文件开始线程
|
||||
For Each File As NetFile In FilesWaiting
|
||||
If NewThreadCount = 0 Then Exit For
|
||||
If File.TryBeginThread() Then
|
||||
IsSuccess = True
|
||||
NewThreadCount -= 1
|
||||
End If
|
||||
Next
|
||||
For Each File As NetFile In FilesLoading
|
||||
If NewThreadCount = 0 Then Exit For
|
||||
If File.TryBeginThread() Then
|
||||
IsSuccess = True
|
||||
NewThreadCount -= 1
|
||||
End If
|
||||
Next
|
||||
'等待 40 ms:BMCLAPI 部分时候有 20QPS 的限制
|
||||
Thread.Sleep(40)
|
||||
Loop While NewThreadCount > 0 AndAlso IsSuccess
|
||||
End If
|
||||
'等待 40 ms
|
||||
Thread.Sleep(40)
|
||||
End While
|
||||
Catch ex As Exception
|
||||
Log(ex, "下载管理启动线程 1 出错", LogLevel.Assert)
|
||||
End Try
|
||||
End Sub, "NetManager ThreadStarter Single")
|
||||
RunInNewThread(Sub()
|
||||
Try
|
||||
Dim LastLoopTime As Long
|
||||
|
||||
@@ -59,7 +59,6 @@
|
||||
Entry.WikiId = i
|
||||
If SplitedLine.Count >= 2 Then
|
||||
Entry.ChineseName = SplitedLine(1)
|
||||
Entry.MCBBS = If(SplitedLine.Count >= 3, SplitedLine(2), Nothing)
|
||||
If Entry.ChineseName.Contains("*") Then '处理 *
|
||||
Entry.ChineseName = Entry.ChineseName.Replace("*", " (" &
|
||||
String.Join(" ", If(Entry.CurseForgeSlug, Entry.ModrinthSlug).Split("-").Select(Function(w) w.Substring(0, 1).ToUpper & w.Substring(1, w.Length - 1))) & ")")
|
||||
@@ -82,10 +81,6 @@
|
||||
''' </summary>
|
||||
Public ChineseName As String = ""
|
||||
''' <summary>
|
||||
''' MCBBS 发布帖编号(例如 195107)。若为 Nothing 则没有发布帖。
|
||||
''' </summary>
|
||||
Public MCBBS As Integer?
|
||||
''' <summary>
|
||||
''' CurseForge Slug(例如 advanced-solar-panels)。
|
||||
''' </summary>
|
||||
Public CurseForgeSlug As String = Nothing
|
||||
@@ -95,7 +90,7 @@
|
||||
Public ModrinthSlug As String = Nothing
|
||||
|
||||
Public Overrides Function ToString() As String
|
||||
Return If(CurseForgeSlug, "") & "&" & If(ModrinthSlug, "") & "|" & WikiId & "|" & ChineseName & If(MCBBS Is Nothing, "", "|" & MCBBS)
|
||||
Return If(CurseForgeSlug, "") & "&" & If(ModrinthSlug, "") & "|" & WikiId & "|" & ChineseName
|
||||
End Function
|
||||
End Class
|
||||
|
||||
@@ -200,14 +195,6 @@
|
||||
End Get
|
||||
End Property
|
||||
''' <summary>
|
||||
''' MCBBS 的帖子 ID。若为 0 则没有。
|
||||
''' </summary>
|
||||
Public ReadOnly Property MCBBS As Integer
|
||||
Get
|
||||
Return If(DatabaseEntry Is Nothing, 0, If(DatabaseEntry.MCBBS, 0))
|
||||
End Get
|
||||
End Property
|
||||
''' <summary>
|
||||
''' 翻译后的中文名。若数据库没有则等同于 RawName。
|
||||
''' </summary>
|
||||
Public ReadOnly Property TranslatedName As String
|
||||
@@ -884,10 +871,10 @@ NoSubtitle:
|
||||
Dim SearchResult As String = ""
|
||||
For i = 0 To Math.Min(4, SearchResults.Count - 1) '就算全是准确的,也最多只要 5 个
|
||||
If Not SearchResults(i).AbsoluteRight AndAlso i >= Math.Min(2, SearchResults.Count - 1) Then Exit For '把 3 个结果拼合以提高准确度
|
||||
If SearchResults(i).Item.CurseForgeSlug IsNot Nothing Then SearchResult += SearchResults(i).Item.CurseForgeSlug.Replace("-", " ") & " "
|
||||
If SearchResults(i).Item.ModrinthSlug IsNot Nothing Then SearchResult += SearchResults(i).Item.ModrinthSlug.Replace("-", " ") & " "
|
||||
If SearchResults(i).Item.CurseForgeSlug IsNot Nothing Then SearchResult += SearchResults(i).Item.CurseForgeSlug.Replace("-", " ").Replace("/", " ") & " "
|
||||
If SearchResults(i).Item.ModrinthSlug IsNot Nothing Then SearchResult += SearchResults(i).Item.ModrinthSlug.Replace("-", " ").Replace("/", " ") & " "
|
||||
SearchResult += SearchResults(i).Item.ChineseName.Split(" (").Last.TrimEnd(") ").Split(" - ").First.
|
||||
Replace(":", "").Replace("(", "").Replace(")", "").ToLower & " "
|
||||
Replace(":", "").Replace("(", "").Replace(")", "").ToLower.Replace("/", " ") & " "
|
||||
Next
|
||||
Log("[Comp] 中文搜索原始关键词:" & SearchResult, LogLevel.Developer)
|
||||
'去除常见连接词
|
||||
@@ -911,9 +898,8 @@ NoSubtitle:
|
||||
For Each Keyword In AllPossibleKeywords.Split(" ")
|
||||
Keyword = Keyword.Trim("["c, "]"c)
|
||||
If Keyword = "" Then Continue For
|
||||
If {"forge", "fabric", "for", "mod",
|
||||
"forge/fabric", "fabric/forge", "fabric/quilt", "quilt/fabric"}.Contains(Keyword) Then '#208
|
||||
Log("[Comp] 已跳过搜索关键词:" & Keyword)
|
||||
If {"forge", "fabric", "for", "mod", "quilt"}.Contains(Keyword) Then '#208
|
||||
Log("[Comp] 已跳过搜索关键词:" & Keyword, LogLevel.Developer)
|
||||
Continue For
|
||||
End If
|
||||
RightKeywords.Add(Keyword)
|
||||
@@ -927,7 +913,7 @@ NoSubtitle:
|
||||
'例外项:OptiForge、OptiFabric(拆词后因为包含 Forge/Fabric 导致无法搜到实际的 Mod)
|
||||
If RawFilter.Replace(" ", "").ToLower.Contains("optiforge") Then Task.Input.SearchText = "optiforge"
|
||||
If RawFilter.Replace(" ", "").ToLower.Contains("optifabric") Then Task.Input.SearchText = "optifabric"
|
||||
Log("[Comp] 工程列表搜索最终文本:" & Task.Input.SearchText, LogLevel.Developer)
|
||||
Log("[Comp] 工程列表搜索最终文本:" & Task.Input.SearchText, LogLevel.Debug)
|
||||
Task.Progress = 0.1
|
||||
|
||||
#End Region
|
||||
|
||||
@@ -583,7 +583,8 @@ Done:
|
||||
If LogMc IsNot Nothing Then
|
||||
'常规信息
|
||||
If LogMc.Contains("An exception was thrown, the game will display an error screen and halt.") Then AppendReason(CrashReason.Forge报错, RegexSeek(LogMc, "(?<=the game will display an error screen and halt.[\n\r]+[^\n]+?Exception: )[\s\S]+?(?=\n\tat)")?.Trim(vbCrLf))
|
||||
If LogMc.Contains("A potential solution has been determined:") OrElse LogMc.Contains("确定了一种可能的解决方法,这样做可能会解决你的问题:") Then AppendReason(CrashReason.Fabric报错并给出解决方案, Join(RegexSearch(If(RegexSeek(LogMc, "(?<=A potential solution has been determined:\n)((\t)+ - [^\n]+\n)+"), If(RegexSeek(LogMc, "(?<=确定了一种可能的解决方法,这样做可能会解决你的问题:\n)((\t)+ - [^\n]+\n)+"), ""), "(?<=(\t)+)[^\n]+"), vbLf))
|
||||
If LogMc.Contains("A potential solution has been determined:") Then AppendReason(CrashReason.Fabric报错并给出解决方案, Join(RegexSearch(If(RegexSeek(LogMc, "(?<=A potential solution has been determined:\n)((\t)+ - [^\n]+\n)+"), ""), "(?<=(\t)+)[^\n]+"), vbLf))
|
||||
If LogMc.Contains("确定了一种可能的解决方法,这样做可能会解决你的问题:") Then AppendReason(CrashReason.Fabric报错并给出解决方案, Join(RegexSearch(If(RegexSeek(LogMc, "(?<=确定了一种可能的解决方法,这样做可能会解决你的问题:\n)((\t)+ - [^\n]+\n)+"), ""), "(?<=(\t)+)[^\n]+"), vbLf))
|
||||
End If
|
||||
|
||||
End Sub
|
||||
|
||||
@@ -221,9 +221,7 @@
|
||||
''' </summary>
|
||||
Public DlClientListBmclapiLoader As New LoaderTask(Of Integer, DlClientListResult)("DlClientList Bmclapi", AddressOf DlClientListBmclapiMain)
|
||||
Private Sub DlClientListBmclapiMain(Loader As LoaderTask(Of Integer, DlClientListResult))
|
||||
Dim Json As JObject = NetGetCodeByRequestRetry("https://bmclapi2.bangbang93.com/mc/game/version_manifest.json",
|
||||
BackupUrl:="https://download.mcbbs.net/mc/game/version_manifest.json",
|
||||
IsJson:=True)
|
||||
Dim Json As JObject = NetGetCodeByRequestRetry("https://bmclapi2.bangbang93.com/mc/game/version_manifest.json", IsJson:=True)
|
||||
Try
|
||||
Dim Versions As JArray = Json("versions")
|
||||
If Versions.Count < 200 Then Throw New Exception("获取到的版本列表长度不足(" & Json.ToString & ")")
|
||||
@@ -384,8 +382,7 @@
|
||||
''' </summary>
|
||||
Public DlOptiFineListBmclapiLoader As New LoaderTask(Of Integer, DlOptiFineListResult)("DlOptiFineList Bmclapi", AddressOf DlOptiFineListBmclapiMain)
|
||||
Private Sub DlOptiFineListBmclapiMain(Loader As LoaderTask(Of Integer, DlOptiFineListResult))
|
||||
Dim Json As JArray = NetGetCodeByRequestRetry("https://bmclapi2.bangbang93.com/optifine/versionList",
|
||||
BackupUrl:="https://download.mcbbs.net/optifine/versionList", IsJson:=True)
|
||||
Dim Json As JArray = NetGetCodeByRequestRetry("https://bmclapi2.bangbang93.com/optifine/versionList", IsJson:=True)
|
||||
Try
|
||||
Dim Versions As New List(Of DlOptiFineListEntry)
|
||||
For Each Token As JObject In Json
|
||||
@@ -469,8 +466,7 @@
|
||||
''' </summary>
|
||||
Public DlForgeListBmclapiLoader As New LoaderTask(Of Integer, DlForgeListResult)("DlForgeList Bmclapi", AddressOf DlForgeListBmclapiMain)
|
||||
Private Sub DlForgeListBmclapiMain(Loader As LoaderTask(Of Integer, DlForgeListResult))
|
||||
Dim Result As String = NetGetCodeByRequestRetry("https://bmclapi2.bangbang93.com/forge/minecraft", Encoding.Default,
|
||||
BackupUrl:="https://download.mcbbs.net/forge/minecraft")
|
||||
Dim Result As String = NetGetCodeByRequestRetry("https://bmclapi2.bangbang93.com/forge/minecraft", Encoding.Default)
|
||||
If Result.Length < 200 Then Throw New Exception("获取到的版本列表长度不足(" & Result & ")")
|
||||
'获取所有版本信息
|
||||
Dim Names As List(Of String) = RegexSearch(Result, "[0-9.]+(_pre[0-9]?)?")
|
||||
@@ -664,8 +660,7 @@
|
||||
''' Forge 版本列表,BMCLAPI。
|
||||
''' </summary>
|
||||
Public Sub DlForgeVersionBmclapiMain(Loader As LoaderTask(Of String, List(Of DlForgeVersionEntry)))
|
||||
Dim Json As JArray = NetGetCodeByRequestRetry("https://bmclapi2.bangbang93.com/forge/minecraft/" & Loader.Input,
|
||||
BackupUrl:="https://download.mcbbs.net/forge/minecraft/" & Loader.Input, IsJson:=True)
|
||||
Dim Json As JArray = NetGetCodeByRequestRetry("https://bmclapi2.bangbang93.com/forge/minecraft/" & Loader.Input, IsJson:=True)
|
||||
Dim Versions As New List(Of DlForgeVersionEntry)
|
||||
Try
|
||||
Dim Recommended As String = McDownloadForgeRecommendedGet(Loader.Input)
|
||||
@@ -827,8 +822,7 @@
|
||||
''' </summary>
|
||||
Public DlLiteLoaderListBmclapiLoader As New LoaderTask(Of Integer, DlLiteLoaderListResult)("DlLiteLoaderList Bmclapi", AddressOf DlLiteLoaderListBmclapiMain)
|
||||
Private Sub DlLiteLoaderListBmclapiMain(Loader As LoaderTask(Of Integer, DlLiteLoaderListResult))
|
||||
Dim Result As JObject = NetGetCodeByRequestRetry("https://bmclapi2.bangbang93.com/maven/com/mumfrey/liteloader/versions.json",
|
||||
BackupUrl:="https://download.mcbbs.net/maven/com/mumfrey/liteloader/versions.json", IsJson:=True)
|
||||
Dim Result As JObject = NetGetCodeByRequestRetry("https://bmclapi2.bangbang93.com/maven/com/mumfrey/liteloader/versions.json", IsJson:=True)
|
||||
Try
|
||||
Dim Json As JObject = Result("versions")
|
||||
Dim Versions As New List(Of DlLiteLoaderListEntry)
|
||||
@@ -914,8 +908,7 @@
|
||||
''' </summary>
|
||||
Public DlFabricListBmclapiLoader As New LoaderTask(Of Integer, DlFabricListResult)("DlFabricList Bmclapi", AddressOf DlFabricListBmclapiMain)
|
||||
Private Sub DlFabricListBmclapiMain(Loader As LoaderTask(Of Integer, DlFabricListResult))
|
||||
Dim Result As JObject = NetGetCodeByRequestRetry("https://bmclapi2.bangbang93.com/fabric-meta/v2/versions",
|
||||
BackupUrl:="https://download.mcbbs.net/fabric-meta/v2/versions", IsJson:=True)
|
||||
Dim Result As JObject = NetGetCodeByRequestRetry("https://bmclapi2.bangbang93.com/fabric-meta/v2/versions", IsJson:=True)
|
||||
Try
|
||||
Dim Output = New DlFabricListResult With {.IsOfficial = False, .SourceName = "BMCLAPI", .Value = Result}
|
||||
If Output.Value("game") Is Nothing OrElse Output.Value("loader") Is Nothing OrElse Output.Value("installer") Is Nothing Then Throw New Exception("获取到的列表缺乏必要项")
|
||||
@@ -943,26 +936,25 @@
|
||||
|
||||
Public Function DlSourceResourceGet(MojangBase As String) As String()
|
||||
MojangBase = MojangBase.Replace("http://resources.download.minecraft.net", "https://resources.download.minecraft.net")
|
||||
Return {MojangBase.Replace("https://piston-data.mojang.com", "https://download.mcbbs.net/assets").Replace("https://piston-meta.mojang.com", "https://download.mcbbs.net/assets").Replace("https://resources.download.minecraft.net", "https://download.mcbbs.net/assets"),
|
||||
MojangBase,
|
||||
MojangBase.Replace("https://piston-data.mojang.com", "https://bmclapi2.bangbang93.com/assets").Replace("https://piston-meta.mojang.com", "https://bmclapi2.bangbang93.com/assets").Replace("https://resources.download.minecraft.net", "https://bmclapi2.bangbang93.com/assets")
|
||||
Return {
|
||||
MojangBase.Replace("https://piston-data.mojang.com", "https://bmclapi2.bangbang93.com/assets").Replace("https://piston-meta.mojang.com", "https://bmclapi2.bangbang93.com/assets").Replace("https://resources.download.minecraft.net", "https://bmclapi2.bangbang93.com/assets"),
|
||||
MojangBase
|
||||
}
|
||||
End Function
|
||||
|
||||
Public Function DlSourceLibraryGet(MojangBase As String) As String()
|
||||
Return {MojangBase.Replace("https://piston-data.mojang.com", "https://download.mcbbs.net/maven").Replace("https://piston-meta.mojang.com", "https://download.mcbbs.net/maven").Replace("https://libraries.minecraft.net", "https://download.mcbbs.net/maven"),
|
||||
MojangBase.Replace("https://piston-data.mojang.com", "https://download.mcbbs.net/libraries").Replace("https://piston-meta.mojang.com", "https://download.mcbbs.net/libraries").Replace("https://libraries.minecraft.net", "https://download.mcbbs.net/libraries"),
|
||||
MojangBase,
|
||||
Return {
|
||||
MojangBase.Replace("https://piston-data.mojang.com", "https://bmclapi2.bangbang93.com/maven").Replace("https://piston-meta.mojang.com", "https://bmclapi2.bangbang93.com/maven").Replace("https://libraries.minecraft.net", "https://bmclapi2.bangbang93.com/maven"),
|
||||
MojangBase.Replace("https://piston-data.mojang.com", "https://bmclapi2.bangbang93.com/libraries").Replace("https://piston-meta.mojang.com", "https://bmclapi2.bangbang93.com/libraries").Replace("https://libraries.minecraft.net", "https://bmclapi2.bangbang93.com/libraries")
|
||||
MojangBase.Replace("https://piston-data.mojang.com", "https://bmclapi2.bangbang93.com/libraries").Replace("https://piston-meta.mojang.com", "https://bmclapi2.bangbang93.com/libraries").Replace("https://libraries.minecraft.net", "https://bmclapi2.bangbang93.com/libraries"),
|
||||
MojangBase
|
||||
}
|
||||
End Function
|
||||
|
||||
Public Function DlSourceLauncherOrMetaGet(MojangBase As String) As String()
|
||||
If MojangBase Is Nothing Then Throw New Exception("无对应的 json 下载地址")
|
||||
Return {MojangBase.Replace("https://piston-data.mojang.com", "https://download.mcbbs.net").Replace("https://piston-meta.mojang.com", "https://download.mcbbs.net").Replace("https://launcher.mojang.com", "https://download.mcbbs.net").Replace("https://launchermeta.mojang.com", "https://download.mcbbs.net"),
|
||||
MojangBase,
|
||||
MojangBase.Replace("https://piston-data.mojang.com", "https://bmclapi2.bangbang93.com").Replace("https://piston-meta.mojang.com", "https://bmclapi2.bangbang93.com").Replace("https://launcher.mojang.com", "https://bmclapi2.bangbang93.com").Replace("https://launchermeta.mojang.com", "https://bmclapi2.bangbang93.com")
|
||||
Return {
|
||||
MojangBase.Replace("https://piston-data.mojang.com", "https://bmclapi2.bangbang93.com").Replace("https://piston-meta.mojang.com", "https://bmclapi2.bangbang93.com").Replace("https://launcher.mojang.com", "https://bmclapi2.bangbang93.com").Replace("https://launchermeta.mojang.com", "https://bmclapi2.bangbang93.com"),
|
||||
MojangBase
|
||||
}
|
||||
End Function
|
||||
|
||||
|
||||
@@ -727,8 +727,7 @@ Wait:
|
||||
Private Sub JavaFileList(Loader As LoaderTask(Of Integer, List(Of NetFile)))
|
||||
Log("[Java] 开始获取 Java 下载信息")
|
||||
Dim IndexFileStr As String = NetGetCodeByDownload(
|
||||
{"https://download.mcbbs.net/v1/products/java-runtime/2ec0cc96c44e5a76b9c8b7c39df7210883d12871/all.json",
|
||||
"https://bmclapi2.bangbang93.com/v1/products/java-runtime/2ec0cc96c44e5a76b9c8b7c39df7210883d12871/all.json",
|
||||
{"https://bmclapi2.bangbang93.com/v1/products/java-runtime/2ec0cc96c44e5a76b9c8b7c39df7210883d12871/all.json",
|
||||
"https://piston-meta.mojang.com/v1/products/java-runtime/2ec0cc96c44e5a76b9c8b7c39df7210883d12871/all.json"},
|
||||
IsJson:=True)
|
||||
'获取下载地址
|
||||
@@ -740,8 +739,7 @@ Wait:
|
||||
Log($"[Java] 准备下载 Java {TargetEntry.Value("version")("name")}({TargetEntry.Key}):{Address}")
|
||||
'获取文件列表
|
||||
Dim ListFileStr As String = NetGetCodeByDownload(
|
||||
{Address.Replace("piston-meta.mojang.com", "download.mcbbs.net"),
|
||||
Address.Replace("piston-meta.mojang.com", "bmclapi2.bangbang93.com"),
|
||||
{Address.Replace("piston-meta.mojang.com", "bmclapi2.bangbang93.com"),
|
||||
Address},
|
||||
IsJson:=True)
|
||||
Dim BaseDir As String = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) & "\.minecraft\runtime\" & TargetEntry.Key & "\"
|
||||
@@ -753,8 +751,7 @@ Wait:
|
||||
If Checker.Check(BaseDir & File.Name) Is Nothing Then Continue For '跳过已存在的文件
|
||||
Dim Url As String = Info("url")
|
||||
Results.Add(New NetFile(
|
||||
{Url.Replace("piston-data.mojang.com", "download.mcbbs.net"),
|
||||
Url.Replace("piston-data.mojang.com", "bmclapi2.bangbang93.com"),
|
||||
{Url.Replace("piston-data.mojang.com", "bmclapi2.bangbang93.com"),
|
||||
Url},
|
||||
BaseDir & File.Name, Checker))
|
||||
Next
|
||||
|
||||
@@ -1911,9 +1911,9 @@ IgnoreCustomSkin:
|
||||
|
||||
'获取自定义命令
|
||||
Dim CustomCommandGlobal As String = Setup.Get("LaunchAdvanceRun")
|
||||
If CustomCommandGlobal <> "" Then CustomCommandGlobal = ArgumentReplace(CustomCommandGlobal)
|
||||
If CustomCommandGlobal <> "" Then CustomCommandGlobal = ArgumentReplace(CustomCommandGlobal, True)
|
||||
Dim CustomCommandVersion As String = Setup.Get("VersionAdvanceRun", Version:=McVersionCurrent)
|
||||
If CustomCommandVersion <> "" Then CustomCommandVersion = ArgumentReplace(CustomCommandVersion)
|
||||
If CustomCommandVersion <> "" Then CustomCommandVersion = ArgumentReplace(CustomCommandVersion, True)
|
||||
|
||||
'输出 bat
|
||||
Try
|
||||
@@ -2072,7 +2072,7 @@ IgnoreCustomSkin:
|
||||
'获取窗口标题
|
||||
Dim WindowTitle As String = Setup.Get("VersionArgumentTitle", Version:=McVersionCurrent)
|
||||
If WindowTitle = "" Then WindowTitle = Setup.Get("LaunchArgumentTitle")
|
||||
WindowTitle = ArgumentReplace(WindowTitle)
|
||||
WindowTitle = ArgumentReplace(WindowTitle, False)
|
||||
|
||||
'初始化等待
|
||||
Dim Watcher As New Watcher(Loader, McVersionCurrent, WindowTitle)
|
||||
@@ -2124,7 +2124,7 @@ IgnoreCustomSkin:
|
||||
''' <summary>
|
||||
''' 在启动结束时,对 PCL 约定的替换标记进行处理。
|
||||
''' </summary>
|
||||
Private Function ArgumentReplace(Raw As String) As String
|
||||
Private Function ArgumentReplace(Raw As String, ReplaceTimeAndDate As Boolean) As String
|
||||
If Raw Is Nothing Then Return Nothing
|
||||
'路径替换
|
||||
Raw = Raw.Replace("{minecraft}", PathMcFolder)
|
||||
@@ -2134,6 +2134,10 @@ IgnoreCustomSkin:
|
||||
'普通替换
|
||||
Raw = Raw.Replace("{user}", McLoginLoader.Output.Name)
|
||||
Raw = Raw.Replace("{uuid}", McLoginLoader.Output.Uuid)
|
||||
If ReplaceTimeAndDate Then '设置窗口标题时需要动态替换日期和时间
|
||||
Raw = Raw.Replace("{date}", Date.Now.ToString("yyyy/M/d"))
|
||||
Raw = Raw.Replace("{time}", Date.Now.ToString("HH:mm:ss"))
|
||||
End If
|
||||
Select Case McLoginLoader.Input.Type
|
||||
Case McLoginType.Legacy
|
||||
If PageLinkHiper.HiperState = LoadState.Finished Then
|
||||
|
||||
@@ -42,15 +42,19 @@
|
||||
#Region "读取默认(Original)文件夹,即当前、官启文件夹,可能没有结果"
|
||||
|
||||
'扫描当前文件夹
|
||||
If CheckPermission(Path) AndAlso Directory.Exists(Path & "versions\") Then CacheMcFolderList.Add(New McFolder With {.Name = "当前文件夹", .Path = Path, .Type = McFolderType.Original})
|
||||
For Each Folder As DirectoryInfo In New DirectoryInfo(Path).GetDirectories
|
||||
If CheckPermission(Folder.FullName) AndAlso Directory.Exists(Folder.FullName & "versions\") OrElse Folder.Name = ".minecraft" Then CacheMcFolderList.Add(New McFolder With {.Name = "当前文件夹", .Path = Folder.FullName & "\", .Type = McFolderType.Original})
|
||||
Next
|
||||
Try
|
||||
If Directory.Exists(Path & "versions\") Then CacheMcFolderList.Add(New McFolder With {.Name = "当前文件夹", .Path = Path, .Type = McFolderType.Original})
|
||||
For Each Folder As DirectoryInfo In New DirectoryInfo(Path).GetDirectories
|
||||
If Directory.Exists(Folder.FullName & "versions\") OrElse Folder.Name = ".minecraft" Then CacheMcFolderList.Add(New McFolder With {.Name = "当前文件夹", .Path = Folder.FullName & "\", .Type = McFolderType.Original})
|
||||
Next
|
||||
Catch ex As Exception
|
||||
Log(ex, "扫描 PCL 所在文件夹中是否有 MC 文件夹失败")
|
||||
End Try
|
||||
|
||||
'扫描官启文件夹
|
||||
Dim MojangPath As String = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) & "\.minecraft\"
|
||||
If (CacheMcFolderList.Count = 0 OrElse MojangPath <> CacheMcFolderList(0).Path) AndAlso '当前文件夹不是官启文件夹
|
||||
CheckPermission(MojangPath) AndAlso Directory.Exists(MojangPath & "versions\") Then '具有权限且存在 versions 文件夹
|
||||
If (Not CacheMcFolderList.Any OrElse MojangPath <> CacheMcFolderList(0).Path) AndAlso '当前文件夹不是官启文件夹
|
||||
Directory.Exists(MojangPath & "versions\") Then '具有权限且存在 versions 文件夹
|
||||
CacheMcFolderList.Add(New McFolder With {.Name = "官方启动器文件夹", .Path = MojangPath, .Type = McFolderType.Original})
|
||||
End If
|
||||
|
||||
@@ -406,7 +410,7 @@
|
||||
End If
|
||||
'无法获取
|
||||
_Version.McName = "Unknown"
|
||||
Info = "PCL 无法识别该版本,请向作者反馈此问题"
|
||||
Info = "PCL 无法识别该版本的 MC 版本号"
|
||||
Catch ex As Exception
|
||||
Log(ex, "识别 Minecraft 版本时出错")
|
||||
_Version.McName = "Unknown"
|
||||
@@ -1915,7 +1919,7 @@ NextVersion:
|
||||
'获取下载信息
|
||||
Try
|
||||
Log("[Minecraft] 开始获取 Authlib-Injector 下载信息")
|
||||
DownloadInfo = GetJson(NetGetCodeByDownload({"https://download.mcbbs.net/mirrors/authlib-injector/artifact/latest.json", "https://bmclapi2.bangbang93.com/mirrors/authlib-injector/artifact/latest.json"}, IsJson:=True))
|
||||
DownloadInfo = GetJson(NetGetCodeByDownload({"https://bmclapi2.bangbang93.com/mirrors/authlib-injector/artifact/latest.json"}, IsJson:=True))
|
||||
Catch ex As Exception
|
||||
Log(ex, "获取 Authlib-Injector 下载信息失败")
|
||||
End Try
|
||||
@@ -1926,9 +1930,7 @@ NextVersion:
|
||||
'开始下载
|
||||
Dim DownloadAddress As String = DownloadInfo("download_url")
|
||||
Log("[Minecraft] Authlib-Injector 需要更新:" & DownloadAddress, LogLevel.Developer)
|
||||
Result.Add(New NetFile({
|
||||
DownloadAddress.Replace("bmclapi2.bangbang93.com", "download.mcbbs.net"), DownloadAddress
|
||||
}, TargetFile, New FileChecker(Hash:=DownloadInfo("checksums")("sha256").ToString)))
|
||||
Result.Add(New NetFile({DownloadAddress}, TargetFile, New FileChecker(Hash:=DownloadInfo("checksums")("sha256").ToString)))
|
||||
End If
|
||||
End If
|
||||
End If
|
||||
@@ -1958,7 +1960,7 @@ NextVersion:
|
||||
'获取 Url 的真实地址
|
||||
Urls.Add(Token.Url)
|
||||
If Token.Url.Contains("launcher.mojang.com/v1/objects") Then Urls = DlSourceLauncherOrMetaGet(Token.Url).ToList() 'Mappings
|
||||
If Token.Url.Contains("maven") Then Urls.Insert(0, Token.Url.Replace(Mid(Token.Url, 1, Token.Url.IndexOf("maven")), "https://download.mcbbs.net/").Replace("maven.fabricmc.net", "maven").Replace("maven.minecraftforge.net", "maven"))
|
||||
If Token.Url.Contains("maven") Then Urls.Insert(0, Token.Url.Replace(Mid(Token.Url, 1, Token.Url.IndexOf("maven")), "https://bmclapi2.bangbang93.com/").Replace("maven.fabricmc.net", "maven").Replace("maven.minecraftforge.net", "maven"))
|
||||
End If
|
||||
If Token.LocalPath.Contains("transformer-discovery-service") Then
|
||||
'Transformer 文件释放
|
||||
@@ -1970,7 +1972,6 @@ NextVersion:
|
||||
Dim OptiFineBase As String = Token.LocalPath.Replace(If(Token.IsJumpLoader, JumpLoaderFolder, CustomMcFolder) & "libraries\optifine\OptiFine\", "").Split("_")(0) & "/" & GetFileNameFromPath(Token.LocalPath).Replace("-", "_")
|
||||
OptiFineBase = "/maven/com/optifine/" & OptiFineBase
|
||||
If OptiFineBase.Contains("_pre") Then OptiFineBase = OptiFineBase.Replace("com/optifine/", "com/optifine/preview_")
|
||||
Urls.Add("https://download.mcbbs.net" & OptiFineBase)
|
||||
Urls.Add("https://bmclapi2.bangbang93.com" & OptiFineBase)
|
||||
ElseIf Urls.Count <= 2 Then
|
||||
'普通文件
|
||||
|
||||
@@ -13,6 +13,14 @@ Public Module ModMod
|
||||
Public Sub New(Path As String)
|
||||
Me.Path = If(Path, "")
|
||||
End Sub
|
||||
''' <summary>
|
||||
''' Mod 的完整路径,去除最后的 .disabled 和 .old。
|
||||
''' </summary>
|
||||
Public ReadOnly Property RawPath As String
|
||||
Get
|
||||
Return GetPathFromFullPath(Path) & RawFileName
|
||||
End Get
|
||||
End Property
|
||||
|
||||
''' <summary>
|
||||
''' Mod 的完整文件名。
|
||||
@@ -768,6 +776,18 @@ VersionFindFail:
|
||||
End Property
|
||||
Private _ModrinthHash As String
|
||||
|
||||
#End Region
|
||||
|
||||
#Region "API"
|
||||
|
||||
Public Overrides Function ToString() As String
|
||||
Return $"{State} - {Path}"
|
||||
End Function
|
||||
Public Overrides Function Equals(obj As Object) As Boolean
|
||||
Dim target = TryCast(obj, McMod)
|
||||
Return target IsNot Nothing AndAlso Path = target.Path
|
||||
End Function
|
||||
|
||||
#End Region
|
||||
|
||||
''' <summary>
|
||||
@@ -844,6 +864,17 @@ VersionFindFail:
|
||||
'加载 McMod 对象
|
||||
Dim ModEntry As New McMod(ModFile.FullName)
|
||||
ModEntry.Load()
|
||||
Dim DumpMod As McMod = ModList.FirstOrDefault(Function(m) m.RawFileName = ModEntry.RawFileName)
|
||||
If DumpMod IsNot Nothing Then
|
||||
Dim DisabledMod As McMod = If(DumpMod.State = McMod.McModState.Disabled, DumpMod, ModEntry)
|
||||
Log($"[Mod] 重复的 Mod 文件:{DumpMod.FileName} 与 {ModEntry.FileName},已忽略 {DisabledMod.FileName}", LogLevel.Debug)
|
||||
If DisabledMod Is ModEntry Then
|
||||
Continue For
|
||||
Else
|
||||
ModList.Remove(DisabledMod)
|
||||
ModUpdateList.Remove(DisabledMod)
|
||||
End If
|
||||
End If
|
||||
ModList.Add(ModEntry)
|
||||
'读取 Comp 缓存
|
||||
If ModEntry.State = McMod.McModState.Unavaliable Then Continue For
|
||||
@@ -860,13 +891,14 @@ VersionFindFail:
|
||||
Log($"[Mod] 共有 {ModList.Count} 个 Mod,其中 {ModUpdateList.Where(Function(m) m.Comp Is Nothing).Count} 个需要联网获取信息,{ModUpdateList.Where(Function(m) m.Comp IsNot Nothing).Count} 个需要更新信息")
|
||||
|
||||
'排序
|
||||
ModList = Sort(ModList, Function(Left As McMod, Right As McMod) As Boolean
|
||||
If (Left.State = McMod.McModState.Unavaliable) <> (Right.State = McMod.McModState.Unavaliable) Then
|
||||
Return Left.State = McMod.McModState.Unavaliable
|
||||
Else
|
||||
Return Not Right.FileName.CompareTo(Left.FileName)
|
||||
End If
|
||||
End Function)
|
||||
ModList = Sort(ModList,
|
||||
Function(Left As McMod, Right As McMod) As Boolean
|
||||
If (Left.State = McMod.McModState.Unavaliable) <> (Right.State = McMod.McModState.Unavaliable) Then
|
||||
Return Left.State = McMod.McModState.Unavaliable
|
||||
Else
|
||||
Return Not Right.FileName.CompareTo(Left.FileName)
|
||||
End If
|
||||
End Function)
|
||||
|
||||
'回设
|
||||
If Loader.IsAborted Then Exit Sub
|
||||
|
||||
@@ -96,7 +96,7 @@
|
||||
'设置窗口标题
|
||||
For i = 1 To 3
|
||||
If IsWindowFinished AndAlso IsWindowAppeared AndAlso WindowTitle <> "" AndAlso State = MinecraftState.Running AndAlso Not GameProcess.HasExited Then
|
||||
Dim RealTitle As String = WindowTitle.Replace("{time}", Date.Now.ToShortTimeString)
|
||||
Dim RealTitle As String = WindowTitle.Replace("{date}", Date.Now.ToString("yyyy/M/d")).Replace("{time}", Date.Now.ToString("HH:mm:ss"))
|
||||
SetWindowText(WindowHandle, RealTitle.ToCharArray)
|
||||
End If
|
||||
Thread.Sleep(64)
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
For Each File In EnumerateFiles(Path & "PCL\Musics\")
|
||||
'文件夹可能会被加入 .ini 文件夹配置文件、一些乱七八糟的 .jpg 文件啥的
|
||||
Dim Ext As String = File.Extension.ToLower
|
||||
If {"ini", "jpg", "txt", "cfg", "lrc", "db", "png"}.Contains(Ext) Then Continue For
|
||||
If {".ini", ".jpg", ".txt", ".cfg", ".lrc", ".db", ".png"}.Contains(Ext) Then Continue For
|
||||
MusicAllList.Add(File.FullName)
|
||||
Next
|
||||
End If
|
||||
|
||||
Reference in New Issue
Block a user