2.13.1.1
This commit is contained in:
+1
-1
Submodule MeloongCore updated: 8bfb4f709f...811438aa3c
+1
-1
@@ -68,7 +68,7 @@ public static class Versions {
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 版本管理中 Mod 信息缓存的版本号。
|
/// 版本管理中 Mod 信息缓存的版本号。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const int LocalModCacheVersion = 18;
|
public const int LocalModCacheVersion = 19;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Minecraft 本地实例信息缓存的版本号。
|
/// Minecraft 本地实例信息缓存的版本号。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
+1
-1
@@ -204,7 +204,7 @@ public static class JavaUtils {
|
|||||||
static bool HasReparsePoint(FileSystemInfo info) {
|
static bool HasReparsePoint(FileSystemInfo info) {
|
||||||
if (PathUtils.IsParentOf(Paths.AppData + @".minecraft\runtime\", info.FullName)) return false; // 不筛查 PCL 的下载路径(#8928)
|
if (PathUtils.IsParentOf(Paths.AppData + @".minecraft\runtime\", info.FullName)) return false; // 不筛查 PCL 的下载路径(#8928)
|
||||||
do {
|
do {
|
||||||
if (info.Attributes.HasFlag(FileAttributes.ReparsePoint)) return true;
|
if (info.Attributes.HasFlagF(FileAttributes.ReparsePoint)) return true;
|
||||||
info = info is FileInfo fileInfo ? fileInfo.Directory : ((DirectoryInfo) info).Parent;
|
info = info is FileInfo fileInfo ? fileInfo.Directory : ((DirectoryInfo) info).Parent;
|
||||||
} while (info is not null);
|
} while (info is not null);
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -11,11 +11,11 @@ Public Class FormMain
|
|||||||
Dim FeatureList As New List(Of KeyValuePair(Of Integer, String))
|
Dim FeatureList As New List(Of KeyValuePair(Of Integer, String))
|
||||||
'统计更新日志条目
|
'统计更新日志条目
|
||||||
If BuildType = BuildTypes.Release Then
|
If BuildType = BuildTypes.Release Then
|
||||||
If LastVersion < 408 Then 'Release 2.13.1.0
|
If LastVersion < 408 Then 'Release 2.13.1.1
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "优化:版本设置中,添加打开截图文件夹的快捷方式"))
|
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "优化:版本设置中,添加打开截图文件夹的快捷方式"))
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "优化:导出整合包时,可以勾选导出光影设置文件"))
|
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "优化:导出整合包时,可以勾选导出光影设置文件"))
|
||||||
FeatureCount += 21
|
FeatureCount += 23
|
||||||
BugCount += 22
|
BugCount += 28
|
||||||
End If
|
End If
|
||||||
If LastVersion < 406 Then 'Release 2.13.0.1
|
If LastVersion < 406 Then 'Release 2.13.0.1
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "新增:重做 Java 管理与相关设置,允许调整 Java 优先级、指定 Java 版本范围等"))
|
FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "新增:重做 Java 管理与相关设置,允许调整 Java 优先级、指定 Java 版本范围等"))
|
||||||
@@ -93,6 +93,11 @@ Public Class FormMain
|
|||||||
'3:BUG+ IMP* FEAT-
|
'3:BUG+ IMP* FEAT-
|
||||||
'2:BUG* IMP-
|
'2:BUG* IMP-
|
||||||
'1:BUG-
|
'1:BUG-
|
||||||
|
If LastVersion < 410 Then 'Snapshot 2.13.1.1
|
||||||
|
If LastVersion = 409 Then FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复:更新 Mod 时可能更新成另一个 Mod 加载器的版本"))
|
||||||
|
FeatureCount += 2
|
||||||
|
BugCount += 6
|
||||||
|
End If
|
||||||
If LastVersion < 409 Then 'Snapshot 2.13.1.0
|
If LastVersion < 409 Then 'Snapshot 2.13.1.0
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "优化:版本设置中,添加打开截图文件夹的快捷方式"))
|
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "优化:版本设置中,添加打开截图文件夹的快捷方式"))
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "优化:导出整合包时,可以勾选导出光影设置文件"))
|
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "优化:导出整合包时,可以勾选导出光影设置文件"))
|
||||||
@@ -781,7 +786,7 @@ Public Class FormMain
|
|||||||
If PanMsg.Children.Any Then
|
If PanMsg.Children.Any Then
|
||||||
If e.Key = Key.Enter Then
|
If e.Key = Key.Enter Then
|
||||||
CType(PanMsg.Children(0), Object).Btn1_Click()
|
CType(PanMsg.Children(0), Object).Btn1_Click()
|
||||||
ElseIf e.Key = Key.Escape Then
|
ElseIf e.Key = Key.Escape OrElse (e.Key = Key.W AndAlso Keyboard.Modifiers.HasFlag(ModifierKeys.Control)) Then
|
||||||
Dim Msg As Object = PanMsg.Children(0)
|
Dim Msg As Object = PanMsg.Children(0)
|
||||||
If TypeOf Msg IsNot MyMsgInput AndAlso TypeOf Msg IsNot MyMsgSelect AndAlso Msg.Btn3.Visibility = Visibility.Visible Then
|
If TypeOf Msg IsNot MyMsgInput AndAlso TypeOf Msg IsNot MyMsgSelect AndAlso Msg.Btn3.Visibility = Visibility.Visible Then
|
||||||
Msg.Btn3_Click()
|
Msg.Btn3_Click()
|
||||||
@@ -823,6 +828,11 @@ Public Class FormMain
|
|||||||
If TypeOf PageRight Is IRefreshable Then CType(PageRight, IRefreshable).Refresh()
|
If TypeOf PageRight Is IRefreshable Then CType(PageRight, IRefreshable).Refresh()
|
||||||
Return
|
Return
|
||||||
End If
|
End If
|
||||||
|
'Ctrl + w 关闭程序
|
||||||
|
If e.Key = Key.W AndAlso Keyboard.Modifiers.HasFlag(ModifierKeys.Control) Then
|
||||||
|
EndProgram(True)
|
||||||
|
Return
|
||||||
|
End If
|
||||||
'调用启动游戏
|
'调用启动游戏
|
||||||
If e.Key = Key.Enter AndAlso PageCurrent = FormMain.PageType.Launch Then
|
If e.Key = Key.Enter AndAlso PageCurrent = FormMain.PageType.Launch Then
|
||||||
If IsAprilEnabled AndAlso Not IsAprilGiveup Then
|
If IsAprilEnabled AndAlso Not IsAprilGiveup Then
|
||||||
|
|||||||
@@ -6,12 +6,12 @@ Public Module ModBase
|
|||||||
#Region "声明"
|
#Region "声明"
|
||||||
|
|
||||||
'下列版本信息由更新器自动修改
|
'下列版本信息由更新器自动修改
|
||||||
Public Const VersionBaseName As String = "2.13.1.0" '显示用版本名
|
Public Const VersionBaseName As String = "2.13.1.1" '显示用版本名
|
||||||
Public Const CommitHash As String = "" 'Commit Hash,由 GitHub Workflow 自动替换
|
Public Const CommitHash As String = "" 'Commit Hash,由 GitHub Workflow 自动替换
|
||||||
#If RELEASE Then
|
#If RELEASE Then
|
||||||
Public Const VersionCode As Integer = 408 '正式版
|
Public Const VersionCode As Integer = 408 '正式版
|
||||||
#Else
|
#Else
|
||||||
Public Const VersionCode As Integer = 409 '快照版
|
Public Const VersionCode As Integer = 410 '快照版
|
||||||
#End If
|
#End If
|
||||||
|
|
||||||
'版本信息
|
'版本信息
|
||||||
|
|||||||
@@ -217,8 +217,7 @@ Retry:
|
|||||||
Optional Content As Object = Nothing, Optional Headers As Dictionary(Of String, String) = Nothing,
|
Optional Content As Object = Nothing, Optional Headers As Dictionary(Of String, String) = Nothing,
|
||||||
Optional SimulateBrowserHeaders As Boolean = False, Optional Timeout As Integer = 25000, Optional Encoding As Encoding = Nothing) As Byte()
|
Optional SimulateBrowserHeaders As Boolean = False, Optional Timeout As Integer = 25000, Optional Encoding As Encoding = Nothing) As Byte()
|
||||||
If RunInUi() AndAlso Not Url.Contains("//127.") Then Throw New Exception("在 UI 线程执行了网络请求")
|
If RunInUi() AndAlso Not Url.Contains("//127.") Then Throw New Exception("在 UI 线程执行了网络请求")
|
||||||
Dim Request As HttpRequestMessage = Nothing, CancelToken As CancellationTokenSource = Nothing,
|
Dim Request As HttpRequestMessage = Nothing, CancelToken As CancellationTokenSource = Nothing, Response As HttpResponseMessage = Nothing
|
||||||
Response As HttpResponseMessage = Nothing, HostIp As String = Nothing
|
|
||||||
Try
|
Try
|
||||||
'构建 RequestClient
|
'构建 RequestClient
|
||||||
Directory.CreateDirectory(PathTemp & "Cache\Http\")
|
Directory.CreateDirectory(PathTemp & "Cache\Http\")
|
||||||
@@ -255,8 +254,6 @@ Retry:
|
|||||||
Retrier.Attempt(delay:=Function() TimeSpan.FromMilliseconds(200), isRetryAllowed:=Function(ex) TypeOf ex Is FileNotFoundException OrElse TypeOf ex Is IOException, action:=
|
Retrier.Attempt(delay:=Function() TimeSpan.FromMilliseconds(200), isRetryAllowed:=Function(ex) TypeOf ex Is FileNotFoundException OrElse TypeOf ex Is IOException, action:=
|
||||||
Sub(Attempt)
|
Sub(Attempt)
|
||||||
CancelToken?.Dispose() : CancelToken = New CancellationTokenSource(Timeout)
|
CancelToken?.Dispose() : CancelToken = New CancellationTokenSource(Timeout)
|
||||||
HostIp = DNSLookup(Request, CancelToken.Token)
|
|
||||||
If HostIp IsNot Nothing Then IPReliability.GetOrAdd(HostIp, -0.01) '预先降低一点,这样快速的重复请求会使用不同的 IP 以提高成功率
|
|
||||||
Dim ClonedRequest As HttpRequestMessage = Request.Clone() 'HttpRequestMessage 只能发送一次,重试时需要克隆一个新的
|
Dim ClonedRequest As HttpRequestMessage = Request.Clone() 'HttpRequestMessage 只能发送一次,重试时需要克隆一个新的
|
||||||
Try
|
Try
|
||||||
Response = RequestClient.SendAsync(ClonedRequest, HttpCompletionOption.ResponseHeadersRead, CancelToken.Token).GetResultWithTimeout(CancelToken, Timeout)
|
Response = RequestClient.SendAsync(ClonedRequest, HttpCompletionOption.ResponseHeadersRead, CancelToken.Token).GetResultWithTimeout(CancelToken, Timeout)
|
||||||
@@ -274,26 +271,22 @@ Retry:
|
|||||||
End Using
|
End Using
|
||||||
End Using
|
End Using
|
||||||
If Not Response.IsSuccessStatusCode Then
|
If Not Response.IsSuccessStatusCode Then
|
||||||
RecordIPReliability(HostIp, -0.7)
|
|
||||||
Dim ResponseMessage = ResponseBytes.GetString(Encoding)
|
Dim ResponseMessage = ResponseBytes.GetString(Encoding)
|
||||||
Throw New HttpRequestCodeException(
|
Throw New HttpRequestCodeException(
|
||||||
$"错误码 {Response.StatusCode} ({CInt(Response.StatusCode)}),{Method},{Url},{HostIp}" &
|
$"错误码 {Response.StatusCode} ({CInt(Response.StatusCode)}),{Method},{Url}" &
|
||||||
If(String.IsNullOrEmpty(ResponseMessage), "", vbCrLf & ResponseMessage), Response.StatusCode, ResponseMessage)
|
If(String.IsNullOrEmpty(ResponseMessage), "", vbCrLf & ResponseMessage), Response.StatusCode, ResponseMessage)
|
||||||
End If
|
End If
|
||||||
'输出
|
|
||||||
RecordIPReliability(HostIp, 0.5)
|
|
||||||
Return ResponseBytes
|
Return ResponseBytes
|
||||||
Catch ex As HttpRequestException
|
Catch ex As HttpRequestException
|
||||||
Throw
|
Throw
|
||||||
Catch ex As TimeoutException
|
Catch ex As TimeoutException
|
||||||
Throw New WebException($"连接服务器超时,请稍后再试,或使用 VPN 改善网络环境({Method}, {Url},IP:{HostIp})", WebExceptionStatus.Timeout)
|
Throw New WebException($"连接服务器超时,请稍后再试,或使用 VPN 改善网络环境({Method}, {Url})", WebExceptionStatus.Timeout)
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
If TypeOf ex IsNot TaskCanceledException Then ex.ThrowIfCanceled() 'GetResultWithTimeout 会抛出 TaskCanceledException
|
If TypeOf ex IsNot TaskCanceledException Then ex.ThrowIfCanceled() 'GetResultWithTimeout 会抛出 TaskCanceledException
|
||||||
RecordIPReliability(HostIp, -1)
|
|
||||||
If ex.IsBadNetwork Then
|
If ex.IsBadNetwork Then
|
||||||
Throw New WebException($"网络请求失败,请稍后再试,或使用 VPN 改善网络环境({Method}, {Url},IP:{HostIp})", WebExceptionStatus.Timeout)
|
Throw New WebException($"网络请求失败,请稍后再试,或使用 VPN 改善网络环境({Method}, {Url})", WebExceptionStatus.Timeout)
|
||||||
Else
|
Else
|
||||||
Throw New Exception($"网络请求出现意外异常({Method}, {Url},{HostIp})", ex)
|
Throw New Exception($"网络请求出现意外异常({Method}, {Url})", ex)
|
||||||
End If
|
End If
|
||||||
Finally
|
Finally
|
||||||
Request?.Dispose()
|
Request?.Dispose()
|
||||||
@@ -304,72 +297,6 @@ Retry:
|
|||||||
Private RequestClient As HttpClient = Nothing
|
Private RequestClient As HttpClient = Nothing
|
||||||
Private RequestClientLock As New Object
|
Private RequestClientLock As New Object
|
||||||
|
|
||||||
''' <summary>
|
|
||||||
''' 进行 DNS 解析。它仅在选择的 IP 与系统默认的不一致时才对 URL 中的 Host 进行替换。
|
|
||||||
''' 返回请求时应使用的 IP。若解析失败,则返回 Nothing。
|
|
||||||
''' </summary>
|
|
||||||
Private Function DNSLookup(Request As HttpRequestMessage, CancelToken As CancellationToken) As String
|
|
||||||
Dim Host = Request.RequestUri.Host
|
|
||||||
'不对部分有严格 SNI 限制的域名进行 DNS 解析(#8295)
|
|
||||||
If {"mojang.com", "minecraft.net", "minecraftservices.com"}.Any(Function(h) Host.ContainsIgnoreCase(h)) Then Return Nothing
|
|
||||||
'若一分钟内已失败过,则不再重复尝试解析,以减少断网时的 Exception 数量
|
|
||||||
Dim LastFailureTime As Date
|
|
||||||
If DNSFailureRecord.TryGetValue(Host, LastFailureTime) Then
|
|
||||||
If Date.Now - LastFailureTime < New TimeSpan(0, 1, 0) Then
|
|
||||||
Return Nothing
|
|
||||||
Else
|
|
||||||
DNSFailureRecord.Remove(Host)
|
|
||||||
End If
|
|
||||||
End If
|
|
||||||
'初步 DNS 解析
|
|
||||||
Dim Candidates As IPAddress()
|
|
||||||
Try
|
|
||||||
Dim AsyncResult = Dns.BeginGetHostAddresses(Host, Nothing, Nothing)
|
|
||||||
If WaitHandle.WaitAny(New WaitHandle() {AsyncResult.AsyncWaitHandle, CancelToken.WaitHandle}) Then Throw New TimeoutException("DNS 解析超时")
|
|
||||||
Candidates = Dns.EndGetHostAddresses(AsyncResult).Distinct.ToArray
|
|
||||||
Catch ex As Exception
|
|
||||||
Logger.Warn(ex, $"DNS 解析失败({Host})")
|
|
||||||
DNSFailureRecord(Host) = Date.Now
|
|
||||||
Return Nothing
|
|
||||||
End Try
|
|
||||||
If Not Candidates.Any Then
|
|
||||||
Logger.Info($"DNS 解析无结果({Host})")
|
|
||||||
Return Nothing
|
|
||||||
End If
|
|
||||||
'若同时存在 IPv4 和 IPv6 地址,仅选择其中一类(因为 GFW 可能只屏蔽了 IPv4 或 IPv6)
|
|
||||||
Dim Reliabilities = Candidates.ToDictionary(Function(i) i, Function(i) IPReliability.GetOrDefault(i.ToString, 0))
|
|
||||||
Dim IPv4Targets = Candidates.Where(Function(i) i.AddressFamily = AddressFamily.InterNetwork).ToArray
|
|
||||||
Dim IPv6Targets = Candidates.Where(Function(i) i.AddressFamily = AddressFamily.InterNetworkV6).ToArray
|
|
||||||
If IPv4Targets.Any AndAlso IPv6Targets.Any Then
|
|
||||||
Dim IPv4Reliability = IPv4Targets.Max(Function(i) Reliabilities(i))
|
|
||||||
Dim IPv6Reliability = IPv6Targets.Max(Function(i) Reliabilities(i))
|
|
||||||
If Host = "api.modrinth.com" Then IPv6Reliability -= 0.1 '让 Modrinth 优先使用 IPv4 地址(#6887)
|
|
||||||
Logger.Trace(Function() $"DNS IPv4/IPv6 选择({Host}),IPv4 {IPv4Reliability:0.000},IPv6 {IPv6Reliability:0.000}")
|
|
||||||
Candidates = If(IPv4Reliability >= IPv6Reliability, IPv4Targets, IPv6Targets)
|
|
||||||
End If
|
|
||||||
'选择可靠度最高的 IP
|
|
||||||
Dim Target As IPAddress = Candidates.MaxBy(Function(i) Reliabilities(i))
|
|
||||||
Request.Headers.Host = Request.RequestUri.Authority
|
|
||||||
Request.RequestUri = (New UriBuilder(Request.RequestUri) With {.Host = If(Target.AddressFamily = AddressFamily.InterNetworkV6, $"[{Target}]", Target.ToString)}).Uri
|
|
||||||
Return Target.ToString
|
|
||||||
End Function
|
|
||||||
Private DNSFailureRecord As New ConcurrentDictionary(Of String, Date)
|
|
||||||
''' <summary>
|
|
||||||
''' 记录每个 IP 地址的请求可靠度。
|
|
||||||
''' 通常取值 -1 ~ +0.5,越高越好。未尝试过的 IP 应视为 0。
|
|
||||||
''' </summary>
|
|
||||||
Private IPReliability As New ConcurrentDictionary(Of String, Double)
|
|
||||||
''' <summary>
|
|
||||||
''' 根据请求结果,记录 IP 地址的可靠度。
|
|
||||||
''' </summary>
|
|
||||||
Private Sub RecordIPReliability(IP As String, Result As Double)
|
|
||||||
If IP Is Nothing Then Return
|
|
||||||
IPReliability.AddOrUpdate(IP,
|
|
||||||
Function() Result * 0.5,
|
|
||||||
Function(k, v) v * 0.5 + Result * 0.5
|
|
||||||
)
|
|
||||||
End Sub
|
|
||||||
|
|
||||||
#End Region
|
#End Region
|
||||||
|
|
||||||
#Region "多线程下载引擎"
|
#Region "多线程下载引擎"
|
||||||
@@ -976,7 +903,7 @@ StartThread:
|
|||||||
Logger.Log($"{LocalName}:开始,起始点 {Th.DownloadStart},{Th.Source.Url}", If(Th.DownloadStart = 0, LogLevel.Info, LogLevel.Trace))
|
Logger.Log($"{LocalName}:开始,起始点 {Th.DownloadStart},{Th.Source.Url}", If(Th.DownloadStart = 0, LogLevel.Info, LogLevel.Trace))
|
||||||
Dim ResultStream As Stream = Nothing, HttpRequest As HttpRequestMessage = Nothing,
|
Dim ResultStream As Stream = Nothing, HttpRequest As HttpRequestMessage = Nothing,
|
||||||
Response As HttpResponseMessage = Nothing, ResponseStream As Stream = Nothing,
|
Response As HttpResponseMessage = Nothing, ResponseStream As Stream = Nothing,
|
||||||
CancelToken As CancellationTokenSource = Nothing, HostIp As String = Nothing
|
CancelToken As CancellationTokenSource = Nothing
|
||||||
'部分下载源真的特别慢,并且只需要一个请求,例如 Ping 为 20s,如果增长太慢,就会造成类似 2.5s 5s 7.5s 10s 12.5s... 的极大延迟
|
'部分下载源真的特别慢,并且只需要一个请求,例如 Ping 为 20s,如果增长太慢,就会造成类似 2.5s 5s 7.5s 10s 12.5s... 的极大延迟
|
||||||
'延迟过长会导致某些特别慢的链接迟迟不被掐死
|
'延迟过长会导致某些特别慢的链接迟迟不被掐死
|
||||||
Dim Timeout As Integer = Math.Min(Math.Max(ConnectAverage, 15000) * (1 + Th.Source.FailCount), 30000)
|
Dim Timeout As Integer = Math.Min(Math.Max(ConnectAverage, 15000) * (1 + Th.Source.FailCount), 30000)
|
||||||
@@ -987,7 +914,6 @@ StartThread:
|
|||||||
HttpRequest = New HttpRequestMessage(HttpMethod.Get, Th.Source.Url)
|
HttpRequest = New HttpRequestMessage(HttpMethod.Get, Th.Source.Url)
|
||||||
SecretHeadersSign(Th.Source.Url, HttpRequest, SimulateBrowserHeaders)
|
SecretHeadersSign(Th.Source.Url, HttpRequest, SimulateBrowserHeaders)
|
||||||
CancelToken = New CancellationTokenSource(Timeout)
|
CancelToken = New CancellationTokenSource(Timeout)
|
||||||
HostIp = DNSLookup(HttpRequest, CancelToken.Token) 'DNS 预解析
|
|
||||||
If Not Th.IsFirstThread Then HttpRequest.Headers.Range = New Headers.RangeHeaderValue(Th.DownloadStart, Nothing)
|
If Not Th.IsFirstThread Then HttpRequest.Headers.Range = New Headers.RangeHeaderValue(Th.DownloadStart, Nothing)
|
||||||
Dim ContentLength As Long = 0
|
Dim ContentLength As Long = 0
|
||||||
Response = ThreadClient.SendAsync(HttpRequest, HttpCompletionOption.ResponseHeadersRead, CancelToken.Token).GetResultWithTimeout(CancelToken, Timeout)
|
Response = ThreadClient.SendAsync(HttpRequest, HttpCompletionOption.ResponseHeadersRead, CancelToken.Token).GetResultWithTimeout(CancelToken, Timeout)
|
||||||
@@ -1119,15 +1045,13 @@ SourceBreak:
|
|||||||
'本线程完成
|
'本线程完成
|
||||||
Th.State = NetState.Finished
|
Th.State = NetState.Finished
|
||||||
Logger.Trace(Function() $"{LocalName}:完成,已下载 {Th.DownloadDone}({Th.DownloadStart}~{Th.DownloadEnd})")
|
Logger.Trace(Function() $"{LocalName}:完成,已下载 {Th.DownloadDone}({Th.DownloadStart}~{Th.DownloadEnd})")
|
||||||
RecordIPReliability(HostIp, 0.5)
|
|
||||||
End If
|
End If
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
If ex.IsBadNetwork OrElse TypeOf ex Is TaskCanceledException Then
|
If ex.IsBadNetwork OrElse TypeOf ex Is TaskCanceledException Then
|
||||||
Logger.Info(New TimeoutException($"{LocalName}:超时({Timeout}ms),{ex.Message},IP:{If(String.IsNullOrEmpty(HostIp), "自动", "")}"))
|
Logger.Info(New TimeoutException($"{LocalName}:超时({Timeout}ms),{ex.Message}"))
|
||||||
Else
|
Else
|
||||||
Logger.Info(ex, $"{LocalName}:出错,IP:{HostIp}")
|
Logger.Info(ex, $"{LocalName}:出错")
|
||||||
End If
|
End If
|
||||||
RecordIPReliability(HostIp, -0.7)
|
|
||||||
SourceFail(Th, ex, False)
|
SourceFail(Th, ex, False)
|
||||||
Finally
|
Finally
|
||||||
'释放资源
|
'释放资源
|
||||||
|
|||||||
@@ -1379,11 +1379,16 @@ OnLoaded:
|
|||||||
If Instance.State <> McInstanceState.Error AndAlso
|
If Instance.State <> McInstanceState.Error AndAlso
|
||||||
ReadIni(Instance.PathVersion & "PCL\Setup.ini", "VersionVanillaName", "Unknown") <> "Unknown" Then
|
ReadIni(Instance.PathVersion & "PCL\Setup.ini", "VersionVanillaName", "Unknown") <> "Unknown" Then
|
||||||
'读取版本信息
|
'读取版本信息
|
||||||
|
Dim ReadCachedInfo =
|
||||||
|
Function(Key As String) As String
|
||||||
|
Dim Value = ReadIni(Instance.PathVersion & "PCL\Setup.ini", Key, Nothing)
|
||||||
|
Return If(Value = "", Nothing, Value) '对老版本 Setup.ini 的空值兼容
|
||||||
|
End Function
|
||||||
Dim VersionInfo As New McVersion With {
|
Dim VersionInfo As New McVersion With {
|
||||||
.Fabric = ReadIni(Instance.PathVersion & "PCL\Setup.ini", "VersionFabric", Nothing),
|
.Fabric = ReadCachedInfo("VersionFabric"),
|
||||||
.Forge = ReadIni(Instance.PathVersion & "PCL\Setup.ini", "VersionForge", Nothing),
|
.Forge = ReadCachedInfo("VersionForge"),
|
||||||
.NeoForge = ReadIni(Instance.PathVersion & "PCL\Setup.ini", "VersionNeoForge", Nothing),
|
.NeoForge = ReadCachedInfo("VersionNeoForge"),
|
||||||
.OptiFine = ReadIni(Instance.PathVersion & "PCL\Setup.ini", "VersionOptiFine", Nothing),
|
.OptiFine = ReadCachedInfo("VersionOptiFine"),
|
||||||
.HasLiteLoader = ReadIni(Instance.PathVersion & "PCL\Setup.ini", "VersionLiteLoader", False),
|
.HasLiteLoader = ReadIni(Instance.PathVersion & "PCL\Setup.ini", "VersionLiteLoader", False),
|
||||||
.VanillaName = ReadIni(Instance.PathVersion & "PCL\Setup.ini", "VersionVanillaName", "Unknown")
|
.VanillaName = ReadIni(Instance.PathVersion & "PCL\Setup.ini", "VersionVanillaName", "Unknown")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -436,8 +436,8 @@ Public Module ModModpack
|
|||||||
Urls = ResourceVersion.ParseModrinthTrackArguments(Urls,
|
Urls = ResourceVersion.ParseModrinthTrackArguments(Urls,
|
||||||
ResourceVersion.DownloadReason.ModPack, TargetVersion.VanillaName, TargetVersion.ModLoaders).ToList 'Modrinth 来源追踪信息
|
ResourceVersion.DownloadReason.ModPack, TargetVersion.VanillaName, TargetVersion.ModLoaders).ToList 'Modrinth 来源追踪信息
|
||||||
Urls = Urls.Distinct.ToList()
|
Urls = Urls.Distinct.ToList()
|
||||||
Dim TargetPath As String = $"{McFolderSelected}versions\{InstanceName}\{File("path")}"
|
Dim TargetPath As String = Path.Combine(McFolderSelected, "versions", InstanceName, File("path").ToString().TrimStart(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar))
|
||||||
If Not Path.GetFullPath(TargetPath).StartsWithF(Path.GetFullPath($"{McFolderSelected}versions\{InstanceName}\")) Then
|
If Not PathUtils.IsParentOf($"{McFolderSelected}versions\{InstanceName}\", TargetPath) Then
|
||||||
MyMsgBox($"整合包的文件路径超出了版本文件夹,请向整合包作者反馈此问题!{vbCrLf}目标:{Path.GetFullPath(TargetPath)}{vbCrLf}错误的文件:{TargetPath}", "文件路径校验失败", IsWarn:=True)
|
MyMsgBox($"整合包的文件路径超出了版本文件夹,请向整合包作者反馈此问题!{vbCrLf}目标:{Path.GetFullPath(TargetPath)}{vbCrLf}错误的文件:{TargetPath}", "文件路径校验失败", IsWarn:=True)
|
||||||
Throw New OperationCanceledException
|
Throw New OperationCanceledException
|
||||||
End If
|
End If
|
||||||
|
|||||||
@@ -120,12 +120,12 @@ Public Module LocalResourceLoaders
|
|||||||
Next
|
Next
|
||||||
Logger.Info($"有 {Mods.Where(Function(m) m.Project Is Nothing).Count} 个 Mod 需要联网获取信息,{Mods.Where(Function(m) m.Project IsNot Nothing).Count} 个 Mod 需要更新信息")
|
Logger.Info($"有 {Mods.Where(Function(m) m.Project Is Nothing).Count} 个 Mod 需要联网获取信息,{Mods.Where(Function(m) m.Project IsNot Nothing).Count} 个 Mod 需要更新信息")
|
||||||
If Not Mods.Any Then Return
|
If Not Mods.Any Then Return
|
||||||
'获取作为检查目标的加载器和版本
|
'获取作为检查目标的版本
|
||||||
'此处不应向下扩展检查的 MC 小版本,例如 Mod 在更新 1.16.5 后,对早期的 1.16.2 版本发布了修补补丁,这会导致 PCL 将 1.16.5 版本的 Mod 降级到 1.16.2
|
'此处不应向下扩展检查的 MC 小版本,例如 Mod 在更新 1.16.5 后,对早期的 1.16.2 版本发布了修补补丁,这会导致 PCL 将 1.16.5 版本的 Mod 降级到 1.16.2
|
||||||
Dim TargetMcVersion As McVersion = Loader.Input.Target
|
Dim TargetMcVersion As McVersion = Loader.Input.Target
|
||||||
Dim VanillaVersion = TargetMcVersion.VanillaName
|
Dim VanillaVersion = TargetMcVersion.VanillaName
|
||||||
'开始网络获取
|
'开始网络获取
|
||||||
Logger.Info($"目标加载器:{ModLoaders},版本:{VanillaVersion}")
|
Logger.Info($"正在检查 Mod 信息的版本:{VanillaVersion},加载器 {ModLoaders}")
|
||||||
Dim EndedThreadCount As Integer = 0, IsFailed As Boolean = False
|
Dim EndedThreadCount As Integer = 0, IsFailed As Boolean = False
|
||||||
Dim CurrentTaskThread As Thread = Thread.CurrentThread
|
Dim CurrentTaskThread As Thread = Thread.CurrentThread
|
||||||
'从 Modrinth 获取信息
|
'从 Modrinth 获取信息
|
||||||
@@ -140,6 +140,7 @@ Public Module LocalResourceLoaders
|
|||||||
'步骤 2:尝试读取工程信息缓存,构建其他 Mod 的对应关系
|
'步骤 2:尝试读取工程信息缓存,构建其他 Mod 的对应关系
|
||||||
If ModrinthVersion.Count = 0 Then Return
|
If ModrinthVersion.Count = 0 Then Return
|
||||||
Dim ModrinthMapping As New Dictionary(Of String, List(Of LocalResourceFile))
|
Dim ModrinthMapping As New Dictionary(Of String, List(Of LocalResourceFile))
|
||||||
|
Dim ModrinthLoaders As New Dictionary(Of LocalResourceFile, List(Of String))
|
||||||
For Each Entry In Mods
|
For Each Entry In Mods
|
||||||
If Not ModrinthVersion.ContainsKey(Entry.ModrinthHash) Then Continue For
|
If Not ModrinthVersion.ContainsKey(Entry.ModrinthHash) Then Continue For
|
||||||
If ModrinthVersion(Entry.ModrinthHash)("files")(0)("hashes")("sha1") <> Entry.ModrinthHash Then Continue For
|
If ModrinthVersion(Entry.ModrinthHash)("files")(0)("hashes")("sha1") <> Entry.ModrinthHash Then Continue For
|
||||||
@@ -149,6 +150,8 @@ Public Module LocalResourceLoaders
|
|||||||
ModrinthMapping(ProjectId).Add(Entry)
|
ModrinthMapping(ProjectId).Add(Entry)
|
||||||
'记录对应的 ProjectVersion
|
'记录对应的 ProjectVersion
|
||||||
Dim File = ResourceVersion.FromPlatformJson(ModrinthVersion(Entry.ModrinthHash), ResourceTypes.Mod)
|
Dim File = ResourceVersion.FromPlatformJson(ModrinthVersion(Entry.ModrinthHash), ResourceTypes.Mod)
|
||||||
|
ModrinthLoaders(Entry) = ModrinthVersion(Entry.ModrinthHash)("loaders").
|
||||||
|
Select(Function(l) l.ToString.Lower).Distinct.OrderBy(Function(l) l).ToList
|
||||||
If Entry.ProjectVersion Is Nothing OrElse Entry.ProjectVersion.ReleaseDate < File.ReleaseDate Then
|
If Entry.ProjectVersion Is Nothing OrElse Entry.ProjectVersion.ReleaseDate < File.ReleaseDate Then
|
||||||
Entry.ProjectVersion = File
|
Entry.ProjectVersion = File
|
||||||
Else
|
Else
|
||||||
@@ -169,17 +172,20 @@ Public Module LocalResourceLoaders
|
|||||||
Next
|
Next
|
||||||
Logger.Info($"已从 Modrinth 获取本地 Mod 信息,继续获取更新信息")
|
Logger.Info($"已从 Modrinth 获取本地 Mod 信息,继续获取更新信息")
|
||||||
'步骤 4:获取更新信息
|
'步骤 4:获取更新信息
|
||||||
If ModLoaders = ModLoaders.None Then
|
Dim ModsToUpdate = ModrinthMapping.SelectMany(Function(l) l.Value).ToList
|
||||||
Logger.Warn("该 Minecraft 版本没有可用的 Mod 加载器,不获取 Mod 更新信息")
|
If Not ModsToUpdate.Any Then Return
|
||||||
Return
|
Dim UpdateData As String = ModsToUpdate.
|
||||||
End If
|
Select(Function(m) $"{{""hash"": ""{m.ModrinthHash}"", ""loaders"": [""{ModrinthLoaders(m).Join(""",""")}""], ""game_versions"": [""{VanillaVersion}""]}}").
|
||||||
Dim ModrinthUpdate As JObject = DlModRequest("https://api.modrinth.com/v2/version_files/update", HttpMethod.Post,
|
Join(",")
|
||||||
$"{{""hashes"": [""{ModrinthMapping.SelectMany(Function(l) l.Value.Select(Function(m) m.ModrinthHash)).Join(""",""")}""], ""algorithm"": ""sha1"",
|
Dim ModrinthUpdate As JObject = DlModRequest("https://api.modrinth.com/v2/version_files/update_individual", HttpMethod.Post,
|
||||||
""loaders"": [""{ModLoaders.Flags.Join(""",""").Lower}""],""game_versions"": [""{VanillaVersion}""]}}", "application/json")
|
$"{{""algorithm"": ""sha1"", ""hashes"": [{UpdateData}]}}", "application/json")
|
||||||
For Each Entry In Mods
|
For Each Entry In Mods
|
||||||
If Not ModrinthUpdate.ContainsKey(Entry.ModrinthHash) OrElse Entry.ProjectVersion Is Nothing Then Continue For
|
If Not ModrinthUpdate.ContainsKey(Entry.ModrinthHash) OrElse Entry.ProjectVersion Is Nothing Then Continue For
|
||||||
Dim UpdateFile = ResourceVersion.FromPlatformJson(ModrinthUpdate(Entry.ModrinthHash), ResourceTypes.Mod)
|
Dim UpdateFile = ResourceVersion.FromPlatformJson(ModrinthUpdate(Entry.ModrinthHash), ResourceTypes.Mod)
|
||||||
If Not UpdateFile.DownloadAvailable Then Continue For
|
If Not UpdateFile.DownloadAvailable Then Continue For
|
||||||
|
Dim UpdateLoaders = ModrinthUpdate(Entry.ModrinthHash)("loaders").
|
||||||
|
Select(Function(l) l.ToString.Lower).Distinct.OrderBy(Function(l) l).ToList
|
||||||
|
If Not UpdateLoaders.SequenceEqual(ModrinthLoaders(Entry)) Then Continue For
|
||||||
Logger.Trace(Function() $"本地文件 {Entry.ProjectVersion.FileName} 在 Modrinth 上的最新版为 {UpdateFile.FileName}")
|
Logger.Trace(Function() $"本地文件 {Entry.ProjectVersion.FileName} 在 Modrinth 上的最新版为 {UpdateFile.FileName}")
|
||||||
If Entry.ProjectVersion.ReleaseDate >= UpdateFile.ReleaseDate OrElse Entry.ProjectVersion.Hash = UpdateFile.Hash Then Continue For
|
If Entry.ProjectVersion.ReleaseDate >= UpdateFile.ReleaseDate OrElse Entry.ProjectVersion.Hash = UpdateFile.Hash Then Continue For
|
||||||
'设置更新日志与更新文件
|
'设置更新日志与更新文件
|
||||||
@@ -217,6 +223,7 @@ Public Module LocalResourceLoaders
|
|||||||
|
|
||||||
'步骤 2:尝试读取工程信息缓存,构建其他 Mod 的对应关系
|
'步骤 2:尝试读取工程信息缓存,构建其他 Mod 的对应关系
|
||||||
Dim ProjectIdToLocalFiles As New Dictionary(Of Integer, List(Of LocalResourceFile))
|
Dim ProjectIdToLocalFiles As New Dictionary(Of Integer, List(Of LocalResourceFile))
|
||||||
|
Dim CurseForgeLoaders As New Dictionary(Of LocalResourceFile, ModLoaders)
|
||||||
For Each Project In CurseForgeRaw
|
For Each Project In CurseForgeRaw
|
||||||
Dim ProjectId = Project("id").ToString
|
Dim ProjectId = Project("id").ToString
|
||||||
Dim Hash As UInteger = Project("file")("fileFingerprint")
|
Dim Hash As UInteger = Project("file")("fileFingerprint")
|
||||||
@@ -226,6 +233,7 @@ Public Module LocalResourceLoaders
|
|||||||
ProjectIdToLocalFiles.AddIntoValueCollection(ProjectId, Entry)
|
ProjectIdToLocalFiles.AddIntoValueCollection(ProjectId, Entry)
|
||||||
'记录对应的 ProjectVersion
|
'记录对应的 ProjectVersion
|
||||||
Dim File = ResourceVersion.FromPlatformJson(Project("file"), ResourceTypes.Mod)
|
Dim File = ResourceVersion.FromPlatformJson(Project("file"), ResourceTypes.Mod)
|
||||||
|
CurseForgeLoaders(Entry) = File.ModLoaders
|
||||||
If Entry.ProjectVersion Is Nothing OrElse Entry.ProjectVersion.ReleaseDate < File.ReleaseDate Then Entry.ProjectVersion = File
|
If Entry.ProjectVersion Is Nothing OrElse Entry.ProjectVersion.ReleaseDate < File.ReleaseDate Then Entry.ProjectVersion = File
|
||||||
Next
|
Next
|
||||||
Next
|
Next
|
||||||
@@ -242,34 +250,34 @@ Public Module LocalResourceLoaders
|
|||||||
If ProjectJson("isAvailable") IsNot Nothing AndAlso Not ProjectJson("isAvailable").ToObject(Of Boolean) Then Continue For
|
If ProjectJson("isAvailable") IsNot Nothing AndAlso Not ProjectJson("isAvailable").ToObject(Of Boolean) Then Continue For
|
||||||
'设置 Entry 中的工程信息
|
'设置 Entry 中的工程信息
|
||||||
Dim Project As New ResourceProject(ProjectJson)
|
Dim Project As New ResourceProject(ProjectJson)
|
||||||
Dim TargetLoaders As ModLoaders = ModLoaders.None
|
|
||||||
For Each LocalFile In ProjectIdToLocalFiles(Project.Id) '倒查防止 CurseForge 返回的内容有漏
|
For Each LocalFile In ProjectIdToLocalFiles(Project.Id) '倒查防止 CurseForge 返回的内容有漏
|
||||||
If LocalFile.Project?.Platform = ResourcePlatforms.Modrinth Then
|
If LocalFile.Project?.Platform = ResourcePlatforms.Modrinth Then
|
||||||
LocalFile.Project = LocalFile.Project '再次触发修改事件
|
LocalFile.Project = LocalFile.Project '再次触发修改事件
|
||||||
Else
|
Else
|
||||||
LocalFile.Project = Project
|
LocalFile.Project = Project
|
||||||
TargetLoaders = TargetLoaders Or LocalFile.Project.ModLoaders
|
|
||||||
End If
|
End If
|
||||||
Next
|
'查找可能有版本更新的文件列表
|
||||||
TargetLoaders = TargetLoaders And ModLoaders '与目标 MC 版本的加载器取交集
|
Dim LatestFiles = ProjectJson("latestFilesIndexes").Where(
|
||||||
'查找或许版本更新的文件列表
|
Function(Entry)
|
||||||
If ModLoaders = ModLoaders.None Then Continue For '无法判断 MC 版本使用的加载器,跳过更新检查
|
'Mod Loader 匹配
|
||||||
Dim LatestFiles = ProjectJson("latestFilesIndexes").Where(
|
Dim EntryLoader As ModLoaders = If(Entry("modLoader") Is Nothing, ModLoaders.None,
|
||||||
Function(Entry)
|
Resource.FromCurseForgeModLoaderType(Entry("modLoader").ToObject(Of Integer)))
|
||||||
'Mod Loader 匹配
|
If CurseForgeLoaders(LocalFile) = ModLoaders.None Then
|
||||||
If Entry("modLoader") Is Nothing Then Return False
|
If EntryLoader <> ModLoaders.None Then Return False
|
||||||
Dim EntryLoader As ModLoaders = Resource.FromCurseForgeModLoaderType(Entry("modLoader").ToObject(Of Integer))
|
ElseIf Not CurseForgeLoaders(LocalFile).HasFlagF(EntryLoader) Then
|
||||||
If Not TargetLoaders.HasFlag(EntryLoader) Then Return False
|
Return False
|
||||||
'MC 版本匹配
|
End If
|
||||||
Dim EntryVersion As String = Entry("gameVersion")
|
'MC 版本匹配
|
||||||
Return EntryVersion IsNot Nothing AndAlso EntryVersion = VanillaVersion
|
Dim EntryVersion As String = Entry("gameVersion")
|
||||||
End Function).
|
Return EntryVersion IsNot Nothing AndAlso EntryVersion = VanillaVersion
|
||||||
MaxByAll(Function(Entry) Entry("gameVersion").ToString, New VersionComparer) '只保留最新的 MC 版本
|
End Function).
|
||||||
For Each Entry In LatestFiles
|
MaxByAll(Function(Entry) Entry("gameVersion").ToString, New VersionComparer) '只保留最新的 MC 版本
|
||||||
Dim FileId = Entry("fileId").ToObject(Of Integer)
|
For Each Entry In LatestFiles
|
||||||
If Not UpdateFileIds.ContainsKey(FileId) Then UpdateFileIds(FileId) = New List(Of LocalResourceFile)
|
Dim FileId = Entry("fileId").ToObject(Of Integer)
|
||||||
UpdateFileIds(FileId).AddRange(ProjectIdToLocalFiles(Project.Id))
|
If Not UpdateFileIds.ContainsKey(FileId) Then UpdateFileIds(FileId) = New List(Of LocalResourceFile)
|
||||||
FileIdToProjectSlug(FileId) = Project.Slug
|
UpdateFileIds(FileId).Add(LocalFile)
|
||||||
|
FileIdToProjectSlug(FileId) = Project.Slug
|
||||||
|
Next
|
||||||
Next
|
Next
|
||||||
Next
|
Next
|
||||||
Logger.Info($"已从 CurseForge 获取本地 Mod 信息,需要获取 {UpdateFileIds.Count} 个用于检查更新的文件信息")
|
Logger.Info($"已从 CurseForge 获取本地 Mod 信息,需要获取 {UpdateFileIds.Count} 个用于检查更新的文件信息")
|
||||||
@@ -283,6 +291,10 @@ Public Module LocalResourceLoaders
|
|||||||
Dim File = ResourceVersion.FromPlatformJson(FileJson, ResourceTypes.Mod)
|
Dim File = ResourceVersion.FromPlatformJson(FileJson, ResourceTypes.Mod)
|
||||||
If Not File.DownloadAvailable Then Continue For
|
If Not File.DownloadAvailable Then Continue For
|
||||||
For Each Entry As LocalResourceFile In UpdateFileIds(File.Id)
|
For Each Entry As LocalResourceFile In UpdateFileIds(File.Id)
|
||||||
|
If File.ModLoaders <> CurseForgeLoaders(Entry) Then
|
||||||
|
Logger.Warn($"从 CurseForge 获取到的更新文件 {File.FileName} 加载器为 {File.ModLoaders},与本地文件 {Entry.File.Name} 的加载器 {CurseForgeLoaders(Entry)} 不一致,已忽略", LogBehavior.None)
|
||||||
|
Continue For
|
||||||
|
End If
|
||||||
If UpdateFiles.ContainsKey(Entry) AndAlso UpdateFiles(Entry).ReleaseDate >= File.ReleaseDate Then Continue For
|
If UpdateFiles.ContainsKey(Entry) AndAlso UpdateFiles(Entry).ReleaseDate >= File.ReleaseDate Then Continue For
|
||||||
UpdateFiles(Entry) = File
|
UpdateFiles(Entry) = File
|
||||||
Next
|
Next
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ Public Class ResourceProject
|
|||||||
Get
|
Get
|
||||||
If Not LoadedDatabase Then
|
If Not LoadedDatabase Then
|
||||||
LoadedDatabase = True
|
LoadedDatabase = True
|
||||||
If Types.HasFlag(ResourceTypes.Mod) OrElse Types.HasFlag(ResourceTypes.DataPack) Then
|
If Types.HasFlagF(ResourceTypes.Mod) OrElse Types.HasFlagF(ResourceTypes.DataPack) Then
|
||||||
_WikiEntry = WikiEntry.All.Value.FirstOrDefault(Function(c) c.Slugs.GetOrDefault(Platform) = Slug)
|
_WikiEntry = WikiEntry.All.Value.FirstOrDefault(Function(c) c.Slugs.GetOrDefault(Platform) = Slug)
|
||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
@@ -415,7 +415,7 @@ Public Class ResourceProject
|
|||||||
If Not MissingProjectIds.Any() Then Return
|
If Not MissingProjectIds.Any() Then Return
|
||||||
'联网获取剩余的工程对象
|
'联网获取剩余的工程对象
|
||||||
Dim Projects As JArray
|
Dim Projects As JArray
|
||||||
If Platform.HasFlag(ResourcePlatforms.CurseForge) Then
|
If Platform.HasFlagF(ResourcePlatforms.CurseForge) Then
|
||||||
Projects = DlModRequest("https://api.curseforge.com/v1/mods",
|
Projects = DlModRequest("https://api.curseforge.com/v1/mods",
|
||||||
HttpMethod.Post, "{""modIds"": [" & MissingProjectIds.Join(","c) & "]}", "application/json")("data")
|
HttpMethod.Post, "{""modIds"": [" & MissingProjectIds.Join(","c) & "]}", "application/json")("data")
|
||||||
Else
|
Else
|
||||||
|
|||||||
@@ -21,8 +21,8 @@ Public Class ResourceSearcher
|
|||||||
''' </summary>
|
''' </summary>
|
||||||
Public ReadOnly Property CanContinue As Boolean
|
Public ReadOnly Property CanContinue As Boolean
|
||||||
Get
|
Get
|
||||||
If Tag.StartsWithF("/") OrElse Not Sources.HasFlag(ResourcePlatforms.CurseForge) Then Storage.CurseForgeTotal = 0
|
If Tag.StartsWithF("/") OrElse Not Sources.HasFlagF(ResourcePlatforms.CurseForge) Then Storage.CurseForgeTotal = 0
|
||||||
If Tag.EndsWithF("/") OrElse Not Sources.HasFlag(ResourcePlatforms.Modrinth) Then Storage.ModrinthTotal = 0
|
If Tag.EndsWithF("/") OrElse Not Sources.HasFlagF(ResourcePlatforms.Modrinth) Then Storage.ModrinthTotal = 0
|
||||||
If Storage.CurseForgeTotal = -1 OrElse Storage.ModrinthTotal = -1 Then Return True
|
If Storage.CurseForgeTotal = -1 OrElse Storage.ModrinthTotal = -1 Then Return True
|
||||||
Return Storage.CurseForgeOffset < Storage.CurseForgeTotal OrElse Storage.ModrinthOffset < Storage.ModrinthTotal
|
Return Storage.CurseForgeOffset < Storage.CurseForgeTotal OrElse Storage.ModrinthOffset < Storage.ModrinthTotal
|
||||||
End Get
|
End Get
|
||||||
@@ -241,7 +241,7 @@ Public Class ResourceSearcher
|
|||||||
Next
|
Next
|
||||||
End Function
|
End Function
|
||||||
'CurseForge
|
'CurseForge
|
||||||
If Request.Sources.HasFlag(ResourcePlatforms.CurseForge) Then
|
If Request.Sources.HasFlagF(ResourcePlatforms.CurseForge) Then
|
||||||
'数据库搜索
|
'数据库搜索
|
||||||
Static CurseForgeSearchEntries As List(Of SearchEntry(Of WikiEntry)) = GetSearchEntries(ResourcePlatforms.CurseForge).ToList()
|
Static CurseForgeSearchEntries As List(Of SearchEntry(Of WikiEntry)) = GetSearchEntries(ResourcePlatforms.CurseForge).ToList()
|
||||||
Dim CurseForgeSearchResults = Search(CurseForgeSearchEntries, RawSearchText, 100, 0.25)
|
Dim CurseForgeSearchResults = Search(CurseForgeSearchEntries, RawSearchText, 100, 0.25)
|
||||||
@@ -258,7 +258,7 @@ Public Class ResourceSearcher
|
|||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
'Modrinth
|
'Modrinth
|
||||||
If Request.Sources.HasFlag(ResourcePlatforms.Modrinth) Then
|
If Request.Sources.HasFlagF(ResourcePlatforms.Modrinth) Then
|
||||||
'数据库搜索
|
'数据库搜索
|
||||||
Static ModrinthSearchEntries As List(Of SearchEntry(Of WikiEntry)) = GetSearchEntries(ResourcePlatforms.Modrinth).ToList()
|
Static ModrinthSearchEntries As List(Of SearchEntry(Of WikiEntry)) = GetSearchEntries(ResourcePlatforms.Modrinth).ToList()
|
||||||
Dim ModrinthSearchResults = Search(ModrinthSearchEntries, RawSearchText, 100, 0.25)
|
Dim ModrinthSearchResults = Search(ModrinthSearchEntries, RawSearchText, 100, 0.25)
|
||||||
@@ -303,7 +303,7 @@ NextPage:
|
|||||||
Try
|
Try
|
||||||
|
|
||||||
'CurseForge 搜索
|
'CurseForge 搜索
|
||||||
If Request.Sources.HasFlag(ResourcePlatforms.CurseForge) AndAlso
|
If Request.Sources.HasFlagF(ResourcePlatforms.CurseForge) AndAlso
|
||||||
Not (Storage.CurseForgeTotal > -1 AndAlso Storage.CurseForgeTotal <= Storage.CurseForgeOffset) AndAlso '剩余的未显示的搜索结果不足
|
Not (Storage.CurseForgeTotal > -1 AndAlso Storage.CurseForgeTotal <= Storage.CurseForgeOffset) AndAlso '剩余的未显示的搜索结果不足
|
||||||
(Not IsChineseSearch OrElse (IsChineseSearch AndAlso Not String.IsNullOrEmpty(CurseForgeAltSearchText))) Then '如果是中文搜索,就只在有对应搜索关键词的时候才继续
|
(Not IsChineseSearch OrElse (IsChineseSearch AndAlso Not String.IsNullOrEmpty(CurseForgeAltSearchText))) Then '如果是中文搜索,就只在有对应搜索关键词的时候才继续
|
||||||
WorkThreads.Add(RunInNewThread(
|
WorkThreads.Add(RunInNewThread(
|
||||||
@@ -317,7 +317,7 @@ NextPage:
|
|||||||
For Each JsonEntry As JObject In RequestResult("data")
|
For Each JsonEntry As JObject In RequestResult("data")
|
||||||
Dim Project As New ResourceProject(JsonEntry)
|
Dim Project As New ResourceProject(JsonEntry)
|
||||||
If Request.Type = ResourceTypes.ResourcePack AndAlso Project.Tags.Contains("数据包") Then Continue For 'CurseForge 将一些数据包分类成了资源包
|
If Request.Type = ResourceTypes.ResourcePack AndAlso Project.Tags.Contains("数据包") Then Continue For 'CurseForge 将一些数据包分类成了资源包
|
||||||
If Request.Type <> ResourceTypes.Any AndAlso Not Project.Types.HasFlag(Request.Type) Then Continue For '过滤分区不匹配的搜索结果(#8265)
|
If Request.Type <> ResourceTypes.Any AndAlso Not Project.Types.HasFlagF(Request.Type) Then Continue For '过滤分区不匹配的搜索结果(#8265)
|
||||||
ProjectList.Add(Project)
|
ProjectList.Add(Project)
|
||||||
Next
|
Next
|
||||||
'更新结果
|
'更新结果
|
||||||
@@ -335,7 +335,7 @@ NextPage:
|
|||||||
End If
|
End If
|
||||||
|
|
||||||
'Modrinth 搜索
|
'Modrinth 搜索
|
||||||
If Request.Sources.HasFlag(ResourcePlatforms.Modrinth) AndAlso
|
If Request.Sources.HasFlagF(ResourcePlatforms.Modrinth) AndAlso
|
||||||
Not (Storage.ModrinthTotal > -1 AndAlso Storage.ModrinthTotal <= Storage.ModrinthOffset) AndAlso '剩余的未显示的搜索结果不足
|
Not (Storage.ModrinthTotal > -1 AndAlso Storage.ModrinthTotal <= Storage.ModrinthOffset) AndAlso '剩余的未显示的搜索结果不足
|
||||||
(Not IsChineseSearch OrElse (IsChineseSearch AndAlso Not String.IsNullOrEmpty(ModrinthAltSearchText))) Then '如果是中文搜索,就只在有对应搜索关键词的时候才继续
|
(Not IsChineseSearch OrElse (IsChineseSearch AndAlso Not String.IsNullOrEmpty(ModrinthAltSearchText))) Then '如果是中文搜索,就只在有对应搜索关键词的时候才继续
|
||||||
WorkThreads.Add(RunInNewThread(
|
WorkThreads.Add(RunInNewThread(
|
||||||
@@ -363,7 +363,7 @@ NextPage:
|
|||||||
End If
|
End If
|
||||||
|
|
||||||
'Modrinth 直接获取工程
|
'Modrinth 直接获取工程
|
||||||
If Request.Sources.HasFlag(ResourcePlatforms.Modrinth) AndAlso
|
If Request.Sources.HasFlagF(ResourcePlatforms.Modrinth) AndAlso
|
||||||
Not (Storage.ModrinthTotal > -1 AndAlso Storage.ModrinthTotal <= Storage.ModrinthOffset) AndAlso '剩余的未显示的搜索结果不足
|
Not (Storage.ModrinthTotal > -1 AndAlso Storage.ModrinthTotal <= Storage.ModrinthOffset) AndAlso '剩余的未显示的搜索结果不足
|
||||||
ModrinthSlugs.Any Then '有直接获取的 Slug
|
ModrinthSlugs.Any Then '有直接获取的 Slug
|
||||||
WorkThreads.Add(RunInNewThread(
|
WorkThreads.Add(RunInNewThread(
|
||||||
@@ -375,7 +375,7 @@ NextPage:
|
|||||||
For Each JsonEntry As JObject In DlModRequest(ModrinthUrl)
|
For Each JsonEntry As JObject In DlModRequest(ModrinthUrl)
|
||||||
Dim Project As New ResourceProject(JsonEntry)
|
Dim Project As New ResourceProject(JsonEntry)
|
||||||
'应用筛选
|
'应用筛选
|
||||||
If Request.Type <> ResourceTypes.Any AndAlso Not Project.Types.HasFlag(Request.Type) Then Continue For
|
If Request.Type <> ResourceTypes.Any AndAlso Not Project.Types.HasFlagF(Request.Type) Then Continue For
|
||||||
If Not String.IsNullOrEmpty(Request.Tag) AndAlso
|
If Not String.IsNullOrEmpty(Request.Tag) AndAlso
|
||||||
Not JsonEntry("categories").Any(Function(c) c.ToString = Request.Tag.AfterLast("/")) Then Continue For 'Project.Tags 已经转换成中文了,只能从 json 判
|
Not JsonEntry("categories").Any(Function(c) c.ToString = Request.Tag.AfterLast("/")) Then Continue For 'Project.Tags 已经转换成中文了,只能从 json 判
|
||||||
If Request.ModLoaders <> ModLoaders.None AndAlso Not IgnoreModLoaderFilter AndAlso
|
If Request.ModLoaders <> ModLoaders.None AndAlso Not IgnoreModLoaderFilter AndAlso
|
||||||
@@ -405,7 +405,7 @@ NextPage:
|
|||||||
|
|
||||||
'仅保留兼容 Forge 的 Mod,或老版本中没有标注任何 Mod Loader 的 Mod
|
'仅保留兼容 Forge 的 Mod,或老版本中没有标注任何 Mod Loader 的 Mod
|
||||||
If IgnoreModLoaderFilter Then
|
If IgnoreModLoaderFilter Then
|
||||||
RawResults.KeepIf(Function(p) p.ModLoaders = ModLoaders.None OrElse p.ModLoaders.HasFlag(ModLoaders.Forge))
|
RawResults.KeepIf(Function(p) p.ModLoaders = ModLoaders.None OrElse p.ModLoaders.HasFlagF(ModLoaders.Forge))
|
||||||
End If
|
End If
|
||||||
|
|
||||||
'确保存在结果
|
'确保存在结果
|
||||||
|
|||||||
@@ -185,7 +185,7 @@ Public Class ResourceVersion
|
|||||||
For Each Loader As ModLoaders In EnumUtils.GetAllFlags(Of ModLoaders)()
|
For Each Loader As ModLoaders In EnumUtils.GetAllFlags(Of ModLoaders)()
|
||||||
If RawLoaders.Contains(Loader.ToString.Lower) Then .ModLoaders = .ModLoaders Or Loader
|
If RawLoaders.Contains(Loader.ToString.Lower) Then .ModLoaders = .ModLoaders Or Loader
|
||||||
Next
|
Next
|
||||||
If .ResourceType.HasFlag(ResourceTypes.Mod) OrElse .ResourceType.HasFlag(ResourceTypes.DataPack) Then
|
If .ResourceType.HasFlagF(ResourceTypes.Mod) OrElse .ResourceType.HasFlagF(ResourceTypes.DataPack) Then
|
||||||
If RawLoaders.Intersect({"bukkit", "folia", "paper", "purpur", "spigot"}).Any() Then .ResourceType = ResourceTypes.Plugin 'Veinminer Enchantment 同时支持服务端与 Fabric
|
If RawLoaders.Intersect({"bukkit", "folia", "paper", "purpur", "spigot"}).Any() Then .ResourceType = ResourceTypes.Plugin 'Veinminer Enchantment 同时支持服务端与 Fabric
|
||||||
If RawLoaders.Contains("datapack") Then .ResourceType = ResourceTypes.DataPack
|
If RawLoaders.Contains("datapack") Then .ResourceType = ResourceTypes.DataPack
|
||||||
If .ModLoaders.Flags().Any() Then .ResourceType = ResourceTypes.Mod
|
If .ModLoaders.Flags().Any() Then .ResourceType = ResourceTypes.Mod
|
||||||
|
|||||||
@@ -51,6 +51,6 @@ Imports System.Runtime.InteropServices
|
|||||||
' 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
|
' 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
|
||||||
' 方法是按如下所示使用“*”
|
' 方法是按如下所示使用“*”
|
||||||
|
|
||||||
<Assembly: AssemblyVersion("2.13.1.0")>
|
<Assembly: AssemblyVersion("2.13.1.1")>
|
||||||
<Assembly: AssemblyFileVersion("2.13.1.0")>
|
<Assembly: AssemblyFileVersion("2.13.1.1")>
|
||||||
<Assembly: NeutralResourcesLanguage("")>
|
<Assembly: NeutralResourcesLanguage("")>
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ Public Module ModDownloadLib
|
|||||||
Dim VersionFolder As String = McFolderSelected & "versions\" & InstanceName & "\"
|
Dim VersionFolder As String = McFolderSelected & "versions\" & InstanceName & "\"
|
||||||
|
|
||||||
Dim Loaders As New List(Of LoaderBase)
|
Dim Loaders As New List(Of LoaderBase)
|
||||||
|
Dim NewInstance As McInstance = Nothing
|
||||||
|
|
||||||
'下载版本 Json 文件
|
'下载版本 Json 文件
|
||||||
If JsonUrl Is Nothing Then
|
If JsonUrl Is Nothing Then
|
||||||
@@ -23,14 +24,19 @@ Public Module ModDownloadLib
|
|||||||
Loaders.Add(New LoaderDownload(McDownloadClientJsonName, New List(Of NetFile) From {
|
Loaders.Add(New LoaderDownload(McDownloadClientJsonName, New List(Of NetFile) From {
|
||||||
New NetFile(DlSourceLauncherOrMetaGet(If(JsonUrl, "")), VersionFolder & InstanceName & ".json", New FileChecker With {.IsJson = True})
|
New NetFile(DlSourceLauncherOrMetaGet(If(JsonUrl, "")), VersionFolder & InstanceName & ".json", New FileChecker With {.IsJson = True})
|
||||||
}) With {.ProgressWeight = 3})
|
}) With {.ProgressWeight = 3})
|
||||||
|
'读取 Json 文件并创建实例
|
||||||
|
Loaders.Add(New LoaderTask(Of String, String)("读取 json 文件",
|
||||||
|
Sub(Task As LoaderTask(Of String, String))
|
||||||
|
NewInstance = New McInstance(VersionFolder)
|
||||||
|
NewInstance.Load()
|
||||||
|
End Sub) With {.ProgressWeight = 0, .Show = False})
|
||||||
|
|
||||||
'下载支持库文件
|
'下载支持库文件
|
||||||
Dim LoadersLib As New List(Of LoaderBase)
|
Dim LoadersLib As New List(Of LoaderBase)
|
||||||
LoadersLib.Add(New LoaderTask(Of String, List(Of NetFile))("分析原版支持库文件(副加载器)",
|
LoadersLib.Add(New LoaderTask(Of String, List(Of NetFile))("分析原版支持库文件(副加载器)",
|
||||||
Sub(Task As LoaderTask(Of String, List(Of NetFile)))
|
Sub(Task As LoaderTask(Of String, List(Of NetFile)))
|
||||||
Thread.Sleep(50) '等待 JSON 文件实际写入硬盘(#3710)
|
|
||||||
Logger.Info($"开始分析原版支持库文件:{VersionFolder}")
|
Logger.Info($"开始分析原版支持库文件:{VersionFolder}")
|
||||||
Task.Output = McLibNetFilesFromInstance(New McInstance(VersionFolder))
|
Task.Output = McLibNetFilesFromInstance(NewInstance)
|
||||||
End Sub) With {.ProgressWeight = 1, .Show = False})
|
End Sub) With {.ProgressWeight = 1, .Show = False})
|
||||||
LoadersLib.Add(New LoaderDownload("下载原版支持库文件(副加载器)", New List(Of NetFile)) With {.ProgressWeight = 13, .Show = False})
|
LoadersLib.Add(New LoaderDownload("下载原版支持库文件(副加载器)", New List(Of NetFile)) With {.ProgressWeight = 13, .Show = False})
|
||||||
Loaders.Add(New LoaderCombo(Of String)(McDownloadClientLibName, LoadersLib) With {.Block = False, .ProgressWeight = 14})
|
Loaders.Add(New LoaderCombo(Of String)(McDownloadClientLibName, LoadersLib) With {.Block = False, .ProgressWeight = 14})
|
||||||
@@ -40,7 +46,7 @@ Public Module ModDownloadLib
|
|||||||
LoadersAssets.Add(New LoaderTask(Of String, List(Of NetFile))("分析资源文件索引地址(副加载器)",
|
LoadersAssets.Add(New LoaderTask(Of String, List(Of NetFile))("分析资源文件索引地址(副加载器)",
|
||||||
Sub(Task As LoaderTask(Of String, List(Of NetFile)))
|
Sub(Task As LoaderTask(Of String, List(Of NetFile)))
|
||||||
Try
|
Try
|
||||||
Dim AssetIndex = DlClientAssetIndexGet(New McInstance(VersionFolder))
|
Dim AssetIndex = DlClientAssetIndexGet(NewInstance)
|
||||||
Task.Output = If(AssetIndex Is Nothing, New List(Of NetFile), New List(Of NetFile) From {AssetIndex})
|
Task.Output = If(AssetIndex Is Nothing, New List(Of NetFile), New List(Of NetFile) From {AssetIndex})
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
Throw New Exception("分析资源文件索引地址失败", ex)
|
Throw New Exception("分析资源文件索引地址失败", ex)
|
||||||
@@ -56,7 +62,7 @@ Public Module ModDownloadLib
|
|||||||
End Sub) With {.ProgressWeight = 1, .Show = False})
|
End Sub) With {.ProgressWeight = 1, .Show = False})
|
||||||
LoadersAssets.Add(New LoaderDownload("下载资源文件索引(副加载器)", New List(Of NetFile)) With {.ProgressWeight = 3, .Show = False})
|
LoadersAssets.Add(New LoaderDownload("下载资源文件索引(副加载器)", New List(Of NetFile)) With {.ProgressWeight = 3, .Show = False})
|
||||||
LoadersAssets.Add(New LoaderTask(Of String, List(Of NetFile))("分析所需资源文件(副加载器)",
|
LoadersAssets.Add(New LoaderTask(Of String, List(Of NetFile))("分析所需资源文件(副加载器)",
|
||||||
Sub(Task) Task.Output = McAssetsFixList(New McInstance(VersionFolder), True, Task)) With {.ProgressWeight = 0.01, .Show = False})
|
Sub(Task) Task.Output = McAssetsFixList(NewInstance, True, Task)) With {.ProgressWeight = 0.01, .Show = False})
|
||||||
LoadersAssets.Add(New LoaderDownload("下载资源文件(副加载器)", New List(Of NetFile)) With {.ProgressWeight = 14, .Show = False})
|
LoadersAssets.Add(New LoaderDownload("下载资源文件(副加载器)", New List(Of NetFile)) With {.ProgressWeight = 14, .Show = False})
|
||||||
Loaders.Add(New LoaderCombo(Of String)("下载原版资源文件", LoadersAssets) With {.Block = False, .ProgressWeight = 18})
|
Loaders.Add(New LoaderCombo(Of String)("下载原版资源文件", LoadersAssets) With {.Block = False, .ProgressWeight = 18})
|
||||||
|
|
||||||
|
|||||||
@@ -307,7 +307,7 @@ Public Class PageInstanceOverall
|
|||||||
Dim IsShiftPressed As Boolean = My.Computer.Keyboard.ShiftKeyDown
|
Dim IsShiftPressed As Boolean = My.Computer.Keyboard.ShiftKeyDown
|
||||||
Dim IsHintIndie As Boolean = PageInstanceLeft.Instance.State <> McInstanceState.Error AndAlso PageInstanceLeft.Instance.PathIndie <> McFolderSelected
|
Dim IsHintIndie As Boolean = PageInstanceLeft.Instance.State <> McInstanceState.Error AndAlso PageInstanceLeft.Instance.PathIndie <> McFolderSelected
|
||||||
Dim SavesFolder = DirectoryUtils.GetInfo(PageInstanceLeft.Instance.PathIndie & "saves\")
|
Dim SavesFolder = DirectoryUtils.GetInfo(PageInstanceLeft.Instance.PathIndie & "saves\")
|
||||||
Dim SaveEntries = If(SavesFolder.Exists, SavesFolder.EnumerateDirectories.OrderByDescending(Function(Save) Save.LastWriteTime).Select(Function(Save) $"{Save.Name}(上次修改:{StringUtils.FormatTimeSpan(Save.LastWriteTime - Date.Now, False)})").ToList, New List(Of String))
|
Dim SaveEntries = If(IsHintIndie AndAlso SavesFolder.Exists, SavesFolder.EnumerateDirectories.OrderByDescending(Function(Save) Save.LastWriteTime).Select(Function(Save) $"{Save.Name}(上次修改:{StringUtils.FormatTimeSpan(Save.LastWriteTime - Date.Now, False)})").ToList, New List(Of String))
|
||||||
Select Case MyMsgBox($"你确定要{If(IsShiftPressed, "永久", "")}删除版本 {PageInstanceLeft.Instance.Name} 吗?" &
|
Select Case MyMsgBox($"你确定要{If(IsShiftPressed, "永久", "")}删除版本 {PageInstanceLeft.Instance.Name} 吗?" &
|
||||||
If(IsHintIndie, vbCrLf & "该版本对应的存档、资源包、Mod 等文件也将被一并删除!" &
|
If(IsHintIndie, vbCrLf & "该版本对应的存档、资源包、Mod 等文件也将被一并删除!" &
|
||||||
If(SaveEntries.Any, vbCrLf & vbCrLf & "这会删除以下存档:" & vbCrLf & "· " & SaveEntries.Join(vbCrLf & "· "), ""), ""),
|
If(SaveEntries.Any, vbCrLf & vbCrLf & "这会删除以下存档:" & vbCrLf & "· " & SaveEntries.Join(vbCrLf & "· "), ""), ""),
|
||||||
|
|||||||
@@ -134,8 +134,10 @@
|
|||||||
<WrapPanel Margin="0,0,0,10">␍ <TextBlock Margin="0,1.5,6,0" Text="L" />
|
<WrapPanel Margin="0,0,0,10">␍ <TextBlock Margin="0,1.5,6,0" Text="L" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="Z" />
|
<TextBlock Margin="0,1.5,6,0" Text="Z" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="N" />
|
<TextBlock Margin="0,1.5,6,0" Text="N" />
|
||||||
|
<TextBlock Margin="0,1.5,6,0" Text="P." />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="...:" />
|
<TextBlock Margin="0,1.5,6,0" Text="...:" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="妖" />
|
<TextBlock Margin="0,1.5,6,0" Text="妖" />
|
||||||
|
<TextBlock Margin="0,1.5,6,0" Text="FL" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="萧" />
|
<TextBlock Margin="0,1.5,6,0" Text="萧" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="乔" />
|
<TextBlock Margin="0,1.5,6,0" Text="乔" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="cc" />
|
<TextBlock Margin="0,1.5,6,0" Text="cc" />
|
||||||
@@ -150,6 +152,7 @@
|
|||||||
<TextBlock Margin="0,1.5,6,0" Text="33" />
|
<TextBlock Margin="0,1.5,6,0" Text="33" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="kk" />
|
<TextBlock Margin="0,1.5,6,0" Text="kk" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="jjb" />
|
<TextBlock Margin="0,1.5,6,0" Text="jjb" />
|
||||||
|
<TextBlock Margin="0,1.5,6,0" Text="狮." />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="+1" />
|
<TextBlock Margin="0,1.5,6,0" Text="+1" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="Iirs" />
|
<TextBlock Margin="0,1.5,6,0" Text="Iirs" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="Lio" />
|
<TextBlock Margin="0,1.5,6,0" Text="Lio" />
|
||||||
@@ -158,16 +161,22 @@
|
|||||||
<TextBlock Margin="0,1.5,6,0" Text="Sht" />
|
<TextBlock Margin="0,1.5,6,0" Text="Sht" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="Nul" />
|
<TextBlock Margin="0,1.5,6,0" Text="Nul" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="250" />
|
<TextBlock Margin="0,1.5,6,0" Text="250" />
|
||||||
|
<TextBlock Margin="0,1.5,6,0" Text="Life" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="kile" />
|
<TextBlock Margin="0,1.5,6,0" Text="kile" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="pbc" />
|
<TextBlock Margin="0,1.5,6,0" Text="pbc" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="Aya" />
|
<TextBlock Margin="0,1.5,6,0" Text="Aya" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="mjp" />
|
<TextBlock Margin="0,1.5,6,0" Text="mjp" />
|
||||||
|
<TextBlock Margin="0,1.5,6,0" Text="azzt" />
|
||||||
|
<TextBlock Margin="0,1.5,6,0" Text="小小" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="冒子" />
|
<TextBlock Margin="0,1.5,6,0" Text="冒子" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="王道" />
|
<TextBlock Margin="0,1.5,6,0" Text="王道" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="鸡人" />
|
<TextBlock Margin="0,1.5,6,0" Text="鸡人" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="喵根" />
|
<TextBlock Margin="0,1.5,6,0" Text="喵根" />
|
||||||
|
<TextBlock Margin="0,1.5,6,0" Text="折花" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="归墟" />
|
<TextBlock Margin="0,1.5,6,0" Text="归墟" />
|
||||||
|
<TextBlock Margin="0,1.5,6,0" Text="墨渊" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="键来" />
|
<TextBlock Margin="0,1.5,6,0" Text="键来" />
|
||||||
|
<TextBlock Margin="0,1.5,6,0" Text="睚眦" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="而后" />
|
<TextBlock Margin="0,1.5,6,0" Text="而后" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="南安" />
|
<TextBlock Margin="0,1.5,6,0" Text="南安" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="曰久" />
|
<TextBlock Margin="0,1.5,6,0" Text="曰久" />
|
||||||
@@ -213,7 +222,21 @@
|
|||||||
<TextBlock Margin="0,1.5,6,0" Text="哈哈" />
|
<TextBlock Margin="0,1.5,6,0" Text="哈哈" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="小洛" />
|
<TextBlock Margin="0,1.5,6,0" Text="小洛" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="璃辰" />
|
<TextBlock Margin="0,1.5,6,0" Text="璃辰" />
|
||||||
|
<TextBlock Margin="0,1.5,6,0" Text="茉莉" />
|
||||||
|
<TextBlock Margin="0,1.5,6,0" Text="旅人" />
|
||||||
|
<TextBlock Margin="0,1.5,6,0" Text="航卡" />
|
||||||
|
<TextBlock Margin="0,1.5,6,0" Text="班总" />
|
||||||
|
<TextBlock Margin="0,1.5,6,0" Text="小圆" />
|
||||||
|
<TextBlock Margin="0,1.5,6,0" Text="梨子" />
|
||||||
|
<TextBlock Margin="0,1.5,6,0" Text="风?" />
|
||||||
|
<TextBlock Margin="0,1.5,6,0" Text="瓜瓜" />
|
||||||
|
<TextBlock Margin="0,1.5,6,0" Text="阳光" />
|
||||||
|
<TextBlock Margin="0,1.5,6,0" Text="菜菜" />
|
||||||
|
<TextBlock Margin="0,1.5,6,0" Text="副连" />
|
||||||
|
<TextBlock Margin="0,1.5,6,0" Text="如舟" />
|
||||||
|
<TextBlock Margin="0,1.5,6,0" Text="bow" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="Byet" />
|
<TextBlock Margin="0,1.5,6,0" Text="Byet" />
|
||||||
|
<TextBlock Margin="0,1.5,6,0" Text="Kian" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="ZDD" />
|
<TextBlock Margin="0,1.5,6,0" Text="ZDD" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="Um1" />
|
<TextBlock Margin="0,1.5,6,0" Text="Um1" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="2514" />
|
<TextBlock Margin="0,1.5,6,0" Text="2514" />
|
||||||
@@ -224,21 +247,26 @@
|
|||||||
<TextBlock Margin="0,1.5,6,0" Text="joker" />
|
<TextBlock Margin="0,1.5,6,0" Text="joker" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="RXZY" />
|
<TextBlock Margin="0,1.5,6,0" Text="RXZY" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="白成y" />
|
<TextBlock Margin="0,1.5,6,0" Text="白成y" />
|
||||||
|
<TextBlock Margin="0,1.5,6,0" Text="mww" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="Rofni" />
|
<TextBlock Margin="0,1.5,6,0" Text="Rofni" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="mzqc" />
|
<TextBlock Margin="0,1.5,6,0" Text="mzqc" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="jason" />
|
<TextBlock Margin="0,1.5,6,0" Text="jason" />
|
||||||
|
<TextBlock Margin="0,1.5,6,0" Text="youzi" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="xxlzta" />
|
<TextBlock Margin="0,1.5,6,0" Text="xxlzta" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="end_x" />
|
<TextBlock Margin="0,1.5,6,0" Text="end_x" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="QWYJ" />
|
<TextBlock Margin="0,1.5,6,0" Text="QWYJ" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="qwqw" />
|
<TextBlock Margin="0,1.5,6,0" Text="qwqw" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="Angel" />
|
<TextBlock Margin="0,1.5,6,0" Text="Angel" />
|
||||||
|
<TextBlock Margin="0,1.5,6,0" Text="15041" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="晓空er" />
|
<TextBlock Margin="0,1.5,6,0" Text="晓空er" />
|
||||||
|
<TextBlock Margin="0,1.5,6,0" Text="kaoyu" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="肥富帅" />
|
<TextBlock Margin="0,1.5,6,0" Text="肥富帅" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="小王子" />
|
<TextBlock Margin="0,1.5,6,0" Text="小王子" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="狐狸涩" />
|
<TextBlock Margin="0,1.5,6,0" Text="狐狸涩" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="大涡流" />
|
<TextBlock Margin="0,1.5,6,0" Text="大涡流" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="无名氏" />
|
<TextBlock Margin="0,1.5,6,0" Text="无名氏" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="紫风狐" />
|
<TextBlock Margin="0,1.5,6,0" Text="紫风狐" />
|
||||||
|
<TextBlock Margin="0,1.5,6,0" Text="杨巨焕" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="范桂圆" />
|
<TextBlock Margin="0,1.5,6,0" Text="范桂圆" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="芸芸云" />
|
<TextBlock Margin="0,1.5,6,0" Text="芸芸云" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="快夏波" />
|
<TextBlock Margin="0,1.5,6,0" Text="快夏波" />
|
||||||
@@ -255,6 +283,7 @@
|
|||||||
<TextBlock Margin="0,1.5,6,0" Text="乐永昶" />
|
<TextBlock Margin="0,1.5,6,0" Text="乐永昶" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="lingke" />
|
<TextBlock Margin="0,1.5,6,0" Text="lingke" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="东雪莲" />
|
<TextBlock Margin="0,1.5,6,0" Text="东雪莲" />
|
||||||
|
<TextBlock Margin="0,1.5,6,0" Text="殷疯子" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="伊文斯" />
|
<TextBlock Margin="0,1.5,6,0" Text="伊文斯" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="丁乙恒" />
|
<TextBlock Margin="0,1.5,6,0" Text="丁乙恒" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="朔望月" />
|
<TextBlock Margin="0,1.5,6,0" Text="朔望月" />
|
||||||
@@ -273,12 +302,22 @@
|
|||||||
<TextBlock Margin="0,1.5,6,0" Text="浮千傀" />
|
<TextBlock Margin="0,1.5,6,0" Text="浮千傀" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="恰啦啦" />
|
<TextBlock Margin="0,1.5,6,0" Text="恰啦啦" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="梦痕丿" />
|
<TextBlock Margin="0,1.5,6,0" Text="梦痕丿" />
|
||||||
|
<TextBlock Margin="0,1.5,6,0" Text="三叶铭" />
|
||||||
|
<TextBlock Margin="0,1.5,6,0" Text="卿姬昉" />
|
||||||
|
<TextBlock Margin="0,1.5,6,0" Text="疯一回" />
|
||||||
|
<TextBlock Margin="0,1.5,6,0" Text="李困困" />
|
||||||
|
<TextBlock Margin="0,1.5,6,0" Text="厄尔萨" />
|
||||||
|
<TextBlock Margin="0,1.5,6,0" Text="伏拉夫" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="α-蒎烯" />
|
<TextBlock Margin="0,1.5,6,0" Text="α-蒎烯" />
|
||||||
|
<TextBlock Margin="0,1.5,6,0" Text="你的JK" />
|
||||||
|
<TextBlock Margin="0,1.5,6,0" Text="jiujinh" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="慕qwq" />
|
<TextBlock Margin="0,1.5,6,0" Text="慕qwq" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="Twicat" />
|
<TextBlock Margin="0,1.5,6,0" Text="Twicat" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="stenac" />
|
<TextBlock Margin="0,1.5,6,0" Text="stenac" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="JOKER" />
|
<TextBlock Margin="0,1.5,6,0" Text="JOKER" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="半日谣." />
|
<TextBlock Margin="0,1.5,6,0" Text="半日谣." />
|
||||||
|
<TextBlock Margin="0,1.5,6,0" Text="EX星辞" />
|
||||||
|
<TextBlock Margin="0,1.5,6,0" Text="Tefrish" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="Triple9" />
|
<TextBlock Margin="0,1.5,6,0" Text="Triple9" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="gediao" />
|
<TextBlock Margin="0,1.5,6,0" Text="gediao" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="Zen1th" />
|
<TextBlock Margin="0,1.5,6,0" Text="Zen1th" />
|
||||||
@@ -292,12 +331,18 @@
|
|||||||
<TextBlock Margin="0,1.5,6,0" Text="Yi_xuan" />
|
<TextBlock Margin="0,1.5,6,0" Text="Yi_xuan" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="MC芬达" />
|
<TextBlock Margin="0,1.5,6,0" Text="MC芬达" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="shallow" />
|
<TextBlock Margin="0,1.5,6,0" Text="shallow" />
|
||||||
|
<TextBlock Margin="0,1.5,6,0" Text="ETL蓝夢" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="𝕳轩辕氏" />
|
<TextBlock Margin="0,1.5,6,0" Text="𝕳轩辕氏" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="谜茶360" />
|
<TextBlock Margin="0,1.5,6,0" Text="谜茶360" />
|
||||||
|
<TextBlock Margin="0,1.5,6,0" Text="颜沐Jun" />
|
||||||
|
<TextBlock Margin="0,1.5,6,0" Text="CS2七松" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="Eventful" />
|
<TextBlock Margin="0,1.5,6,0" Text="Eventful" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="Molioos" />
|
<TextBlock Margin="0,1.5,6,0" Text="Molioos" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="logicum" />
|
<TextBlock Margin="0,1.5,6,0" Text="logicum" />
|
||||||
|
<TextBlock Margin="0,1.5,6,0" Text="Mr_loba" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="一叶知秋" />
|
<TextBlock Margin="0,1.5,6,0" Text="一叶知秋" />
|
||||||
|
<TextBlock Margin="0,1.5,6,0" Text="我妻狗卷" />
|
||||||
|
<TextBlock Margin="0,1.5,6,0" Text="御神凌霜" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="狼烟居士" />
|
<TextBlock Margin="0,1.5,6,0" Text="狼烟居士" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="千风伶羽" />
|
<TextBlock Margin="0,1.5,6,0" Text="千风伶羽" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="mumiao" />
|
<TextBlock Margin="0,1.5,6,0" Text="mumiao" />
|
||||||
@@ -332,11 +377,16 @@
|
|||||||
<TextBlock Margin="0,1.5,6,0" Text="春山如笑" />
|
<TextBlock Margin="0,1.5,6,0" Text="春山如笑" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="幻天阿绝" />
|
<TextBlock Margin="0,1.5,6,0" Text="幻天阿绝" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="忘道蜂枫" />
|
<TextBlock Margin="0,1.5,6,0" Text="忘道蜂枫" />
|
||||||
|
<TextBlock Margin="0,1.5,6,0" Text="深海无渊" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="心软的神" />
|
<TextBlock Margin="0,1.5,6,0" Text="心软的神" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="砂锅豆腐" />
|
<TextBlock Margin="0,1.5,6,0" Text="砂锅豆腐" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="好人好逝" />
|
<TextBlock Margin="0,1.5,6,0" Text="好人好逝" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="登峰破晓" />
|
<TextBlock Margin="0,1.5,6,0" Text="登峰破晓" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="东隅未殁" />
|
<TextBlock Margin="0,1.5,6,0" Text="东隅未殁" />
|
||||||
|
<TextBlock Margin="0,1.5,6,0" Text="星花银影" />
|
||||||
|
<TextBlock Margin="0,1.5,6,0" Text="往事如昔" />
|
||||||
|
<TextBlock Margin="0,1.5,6,0" Text="林克之空" />
|
||||||
|
<TextBlock Margin="0,1.5,6,0" Text="0X00001" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="MuMAA" />
|
<TextBlock Margin="0,1.5,6,0" Text="MuMAA" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="溯枫qwq" />
|
<TextBlock Margin="0,1.5,6,0" Text="溯枫qwq" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="Tacenda" />
|
<TextBlock Margin="0,1.5,6,0" Text="Tacenda" />
|
||||||
@@ -344,6 +394,7 @@
|
|||||||
<TextBlock Margin="0,1.5,6,0" Text="👁👄👃" />
|
<TextBlock Margin="0,1.5,6,0" Text="👁👄👃" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="秋慕owo" />
|
<TextBlock Margin="0,1.5,6,0" Text="秋慕owo" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="船长Yuki" />
|
<TextBlock Margin="0,1.5,6,0" Text="船长Yuki" />
|
||||||
|
<TextBlock Margin="0,1.5,6,0" Text="HIMEKO" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="是小61呀" />
|
<TextBlock Margin="0,1.5,6,0" Text="是小61呀" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="47号虾球" />
|
<TextBlock Margin="0,1.5,6,0" Text="47号虾球" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="Alancnel" />
|
<TextBlock Margin="0,1.5,6,0" Text="Alancnel" />
|
||||||
@@ -360,6 +411,7 @@
|
|||||||
<TextBlock Margin="0,1.5,6,0" Text="MselQAQ" />
|
<TextBlock Margin="0,1.5,6,0" Text="MselQAQ" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="UZQueen" />
|
<TextBlock Margin="0,1.5,6,0" Text="UZQueen" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="hihospital" />
|
<TextBlock Margin="0,1.5,6,0" Text="hihospital" />
|
||||||
|
<TextBlock Margin="0,1.5,6,0" Text="cutegirl3k" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="Prifo_lone" />
|
<TextBlock Margin="0,1.5,6,0" Text="Prifo_lone" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="有....暗星!" />
|
<TextBlock Margin="0,1.5,6,0" Text="有....暗星!" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="Hitsser 1.0" />
|
<TextBlock Margin="0,1.5,6,0" Text="Hitsser 1.0" />
|
||||||
@@ -382,11 +434,13 @@
|
|||||||
<TextBlock Margin="0,1.5,6,0" Text="离人如飘萍" />
|
<TextBlock Margin="0,1.5,6,0" Text="离人如飘萍" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="秋葉逐殘夏" />
|
<TextBlock Margin="0,1.5,6,0" Text="秋葉逐殘夏" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="水星有海吗" />
|
<TextBlock Margin="0,1.5,6,0" Text="水星有海吗" />
|
||||||
|
<TextBlock Margin="0,1.5,6,0" Text="吃饱爱睡觉" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="ac纯萌新cy" />
|
<TextBlock Margin="0,1.5,6,0" Text="ac纯萌新cy" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="岁月suiyue" />
|
<TextBlock Margin="0,1.5,6,0" Text="岁月suiyue" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="陌然MajorC" />
|
<TextBlock Margin="0,1.5,6,0" Text="陌然MajorC" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="-Pareidolia." />
|
<TextBlock Margin="0,1.5,6,0" Text="-Pareidolia." />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="蛙蛙大王Kzr" />
|
<TextBlock Margin="0,1.5,6,0" Text="蛙蛙大王Kzr" />
|
||||||
|
<TextBlock Margin="0,1.5,6,0" Text="Aurorawalk" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="Yhcmdbfwz" />
|
<TextBlock Margin="0,1.5,6,0" Text="Yhcmdbfwz" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="Ayers赜蠹嬭" />
|
<TextBlock Margin="0,1.5,6,0" Text="Ayers赜蠹嬭" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="We1J1uSh1" />
|
<TextBlock Margin="0,1.5,6,0" Text="We1J1uSh1" />
|
||||||
@@ -405,6 +459,7 @@
|
|||||||
<TextBlock Margin="0,1.5,6,0" Text="小田love白子" />
|
<TextBlock Margin="0,1.5,6,0" Text="小田love白子" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="Sasha_Xiong" />
|
<TextBlock Margin="0,1.5,6,0" Text="Sasha_Xiong" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="赤狸_crisnow" />
|
<TextBlock Margin="0,1.5,6,0" Text="赤狸_crisnow" />
|
||||||
|
<TextBlock Margin="0,1.5,6,0" Text="dorod月gour" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="Name0emaN" />
|
<TextBlock Margin="0,1.5,6,0" Text="Name0emaN" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="happypickles" />
|
<TextBlock Margin="0,1.5,6,0" Text="happypickles" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="无中生有为dd" />
|
<TextBlock Margin="0,1.5,6,0" Text="无中生有为dd" />
|
||||||
@@ -439,13 +494,17 @@
|
|||||||
<TextBlock Margin="0,1.5,6,0" Text="没什么名字好取" />
|
<TextBlock Margin="0,1.5,6,0" Text="没什么名字好取" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="Wanderer5147" />
|
<TextBlock Margin="0,1.5,6,0" Text="Wanderer5147" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="取个名字耗阳寿" />
|
<TextBlock Margin="0,1.5,6,0" Text="取个名字耗阳寿" />
|
||||||
|
<TextBlock Margin="0,1.5,6,0" Text="北熊何时与狼行" />
|
||||||
|
<TextBlock Margin="0,1.5,6,0" Text="向着有风的地方" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="AAA神秘人批发" />
|
<TextBlock Margin="0,1.5,6,0" Text="AAA神秘人批发" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="Bangbang2025" />
|
<TextBlock Margin="0,1.5,6,0" Text="Bangbang2025" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="贝吉蒙Begimon" />
|
<TextBlock Margin="0,1.5,6,0" Text="贝吉蒙Begimon" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="取个名字真难0.0" />
|
<TextBlock Margin="0,1.5,6,0" Text="取个名字真难0.0" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="NoTuring_Steve" />
|
<TextBlock Margin="0,1.5,6,0" Text="NoTuring_Steve" />
|
||||||
|
<TextBlock Margin="0,1.5,6,0" Text="VividerCafe2379" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="冰冰watermelon" />
|
<TextBlock Margin="0,1.5,6,0" Text="冰冰watermelon" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="DOODOODOOD" />
|
<TextBlock Margin="0,1.5,6,0" Text="DOODOODOOD" />
|
||||||
|
<TextBlock Margin="0,1.5,6,0" Text="怕做苦力的苦力怕" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="小句号就是小句号" />
|
<TextBlock Margin="0,1.5,6,0" Text="小句号就是小句号" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="弹跳爆炸小鱼珠🐟" />
|
<TextBlock Margin="0,1.5,6,0" Text="弹跳爆炸小鱼珠🐟" />
|
||||||
<TextBlock Margin="0,1.5,6,0" Text="Xanadu Silk Fable" />
|
<TextBlock Margin="0,1.5,6,0" Text="Xanadu Silk Fable" />
|
||||||
|
|||||||
@@ -186,7 +186,7 @@ Public Class PageSelectRight
|
|||||||
Dim IsShiftPressed As Boolean = My.Computer.Keyboard.ShiftKeyDown
|
Dim IsShiftPressed As Boolean = My.Computer.Keyboard.ShiftKeyDown
|
||||||
Dim IsHintIndie As Boolean = Instance.State <> McInstanceState.Error AndAlso Instance.PathIndie <> McFolderSelected
|
Dim IsHintIndie As Boolean = Instance.State <> McInstanceState.Error AndAlso Instance.PathIndie <> McFolderSelected
|
||||||
Dim SavesFolder = DirectoryUtils.GetInfo(Instance.PathIndie & "saves\")
|
Dim SavesFolder = DirectoryUtils.GetInfo(Instance.PathIndie & "saves\")
|
||||||
Dim SaveEntries = If(SavesFolder.Exists, SavesFolder.EnumerateDirectories.OrderByDescending(Function(Save) Save.LastWriteTime).Select(Function(Save) $"{Save.Name}(上次修改:{StringUtils.FormatTimeSpan(Save.LastWriteTime - Date.Now, False)})").ToList, New List(Of String))
|
Dim SaveEntries = If(IsHintIndie AndAlso SavesFolder.Exists, SavesFolder.EnumerateDirectories.OrderByDescending(Function(Save) Save.LastWriteTime).Select(Function(Save) $"{Save.Name}(上次修改:{StringUtils.FormatTimeSpan(Save.LastWriteTime - Date.Now, False)})").ToList, New List(Of String))
|
||||||
Select Case MyMsgBox($"你确定要{If(IsShiftPressed, "永久", "")}删除版本 {Instance.Name} 吗?" &
|
Select Case MyMsgBox($"你确定要{If(IsShiftPressed, "永久", "")}删除版本 {Instance.Name} 吗?" &
|
||||||
If(IsHintIndie, vbCrLf & "该版本对应的存档、资源包、Mod 等文件也将被一并删除!", "") &
|
If(IsHintIndie, vbCrLf & "该版本对应的存档、资源包、Mod 等文件也将被一并删除!", "") &
|
||||||
If(SaveEntries.Any, vbCrLf & vbCrLf & "这会删除以下存档:" & vbCrLf & "· " & SaveEntries.Join(vbCrLf & "· "), ""),
|
If(SaveEntries.Any, vbCrLf & vbCrLf & "这会删除以下存档:" & vbCrLf & "· " & SaveEntries.Join(vbCrLf & "· "), ""),
|
||||||
|
|||||||
Reference in New Issue
Block a user