2.11.1
Some checks failed
Build / Build (Debug) (push) Has been cancelled
Build / Build (Release) (push) Has been cancelled
Some checks failed
Build / Build (Debug) (push) Has been cancelled
Build / Build (Release) (push) Has been cancelled
This commit is contained in:
@@ -113,6 +113,17 @@ Public Class FormMain
|
||||
'3:BUG+ IMP* FEAT-
|
||||
'2:BUG* IMP-
|
||||
'1:BUG-
|
||||
If LastVersion < 374 Then 'Snapshot 2.11.1
|
||||
If LastVersion >= 373 Then
|
||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "优化:使用离线登录也可以直接加入联机房间了"))
|
||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "优化:会从所有共享节点中自动选择负载最低的进行中继连接"))
|
||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "优化:若复制了邀请码,则可以直接快速加入房间"))
|
||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "优化:关闭 PCL 时总是会提示是否退出联机,防止在关闭 PCL 时无意地关闭或退出了房间"))
|
||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "新增:允许自定义要连接的节点"))
|
||||
End If
|
||||
FeatureCount += 9
|
||||
BugCount += 7
|
||||
End If
|
||||
If LastVersion < 373 Then 'Snapshot 2.11.0
|
||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(5, "新增:联机功能!"))
|
||||
FeatureCount += 7
|
||||
@@ -587,9 +598,7 @@ Public Class FormMain
|
||||
End Sub, "强行停止下载任务")
|
||||
End If
|
||||
'关闭联机?
|
||||
If FrmLinkMain IsNot Nothing Then
|
||||
If FrmLinkMain.TryExit(SendWarning) Then Return
|
||||
End If
|
||||
If FrmLinkMain?.TryExit(Not SendWarning, True) Then Return
|
||||
'关闭
|
||||
RunInUiWait(
|
||||
Sub()
|
||||
@@ -765,6 +774,21 @@ Public Class FormMain
|
||||
Catch ex As Exception
|
||||
Log(ex, "切回窗口时出错", LogLevel.Feedback)
|
||||
End Try
|
||||
'读取剪贴板,自动加入联机房间
|
||||
If PageLinkMain.LinkState <> PageLinkMain.LinkStates.Waiting Then Return '已启动联机
|
||||
Dim Code = ClipboardGetText() : If Code Is Nothing Then Return '剪贴板无文本
|
||||
If Setup.Get("LinkLastAutoJoinInviteCode") = Code Then Return
|
||||
If PageLinkMain.ValidateCodeFormat(Code) IsNot Nothing Then Return '不是邀请码
|
||||
Setup.Set("LinkLastAutoJoinInviteCode", Code)
|
||||
RunInThread(
|
||||
Sub()
|
||||
If MyMsgBox("嘿,是否使用复制的邀请码加入房间?", "加入联机房间", "加入", "取消") = 2 Then Return '防止弹窗阻碍主线程,所以必须放在工作线程
|
||||
RunInUi(
|
||||
Sub()
|
||||
PageLinkMain.Join(Code)
|
||||
ClipboardSet(Nothing, False)
|
||||
End Sub)
|
||||
End Sub)
|
||||
End Sub
|
||||
|
||||
'文件拖放
|
||||
|
||||
BIN
Plain Craft Launcher 2/Images/Heads/EasyTier.png
Normal file
BIN
Plain Craft Launcher 2/Images/Heads/EasyTier.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
@@ -5,6 +5,7 @@ Imports System.Runtime.CompilerServices
|
||||
Imports System.Security.Cryptography
|
||||
Imports System.Security.Principal
|
||||
Imports System.Text.RegularExpressions
|
||||
Imports System.Threading.Tasks
|
||||
Imports System.Xaml
|
||||
Imports Newtonsoft.Json
|
||||
|
||||
@@ -13,13 +14,13 @@ Public Module ModBase
|
||||
#Region "声明"
|
||||
|
||||
'下列版本信息由更新器自动修改
|
||||
Public Const VersionBaseName As String = "2.11.0" '不含分支前缀的显示用版本名
|
||||
Public Const VersionStandardCode As String = "2.11.0." & VersionBranchCode '标准格式的四段式版本号
|
||||
Public Const VersionBaseName As String = "2.11.1" '不含分支前缀的显示用版本名
|
||||
Public Const VersionStandardCode As String = "2.11.1." & VersionBranchCode '标准格式的四段式版本号
|
||||
Public Const CommitHash As String = "" 'Commit Hash,由 GitHub Workflow 自动替换
|
||||
#If BETA Then
|
||||
Public Const VersionCode As Integer = 372 'Release
|
||||
#Else
|
||||
Public Const VersionCode As Integer = 373 'Snapshot
|
||||
Public Const VersionCode As Integer = 374 'Snapshot
|
||||
#End If
|
||||
'自动生成的版本信息
|
||||
Public Const VersionDisplayName As String = VersionBranchName & " " & VersionBaseName
|
||||
@@ -1727,6 +1728,7 @@ RetryDir:
|
||||
''' </summary>
|
||||
<Extension> <MethodImpl(MethodImplOptions.AggressiveInlining)>
|
||||
Public Function StartsWithF(Str As String, Prefix As String, Optional IgnoreCase As Boolean = False) As Boolean
|
||||
If Str Is Nothing Then Return False
|
||||
Return Str.StartsWith(Prefix, If(IgnoreCase, StringComparison.OrdinalIgnoreCase, StringComparison.Ordinal))
|
||||
End Function
|
||||
''' <summary>
|
||||
@@ -1734,6 +1736,7 @@ RetryDir:
|
||||
''' </summary>
|
||||
<Extension> <MethodImpl(MethodImplOptions.AggressiveInlining)>
|
||||
Public Function EndsWithF(Str As String, Suffix As String, Optional IgnoreCase As Boolean = False) As Boolean
|
||||
If Str Is Nothing Then Return False
|
||||
Return Str.EndsWith(Suffix, If(IgnoreCase, StringComparison.OrdinalIgnoreCase, StringComparison.Ordinal))
|
||||
End Function
|
||||
''' <summary>
|
||||
@@ -1741,6 +1744,7 @@ RetryDir:
|
||||
''' </summary>
|
||||
<Extension> <MethodImpl(MethodImplOptions.AggressiveInlining)>
|
||||
Public Function ContainsF(Str As String, SubStr As String, Optional IgnoreCase As Boolean = False) As Boolean
|
||||
If Str Is Nothing Then Return False
|
||||
Return Str.IndexOf(SubStr, If(IgnoreCase, StringComparison.OrdinalIgnoreCase, StringComparison.Ordinal)) >= 0
|
||||
End Function
|
||||
''' <summary>
|
||||
@@ -1777,6 +1781,7 @@ RetryDir:
|
||||
''' 如果输入有误,返回 0。
|
||||
''' </summary>
|
||||
Public Function Val(Str As Object) As Double
|
||||
If Str Is Nothing Then Return 0
|
||||
Try
|
||||
Return If(TypeOf Str Is String AndAlso Str = "&", 0, Conversion.Val(Str))
|
||||
Catch
|
||||
@@ -2147,6 +2152,29 @@ RetryDir:
|
||||
Return result
|
||||
End Function
|
||||
|
||||
''' <summary>
|
||||
''' 为 Task 设置超时,在超时时抛出 TimeoutException。
|
||||
''' </summary>
|
||||
<Extension> Public Function GetResultWithTimeout(Of T)(TargetTask As Task(Of T), TokenSource As CancellationTokenSource, TimeoutMs As Integer) As T
|
||||
Dim DelayTask = Task.Delay(TimeoutMs)
|
||||
If Task.WhenAny(TargetTask, DelayTask).GetAwaiter().GetResult() Is DelayTask Then
|
||||
TokenSource.Cancel()
|
||||
Throw New TimeoutException($"任务超时({TimeoutMs} ms)")
|
||||
End If
|
||||
Return TargetTask.GetAwaiter().GetResult()
|
||||
End Function
|
||||
''' <summary>
|
||||
''' 为 Task 设置超时,在超时时抛出 TimeoutException。
|
||||
''' </summary>
|
||||
<Extension> Public Sub GetResultWithTimeout(TargetTask As Task, TokenSource As CancellationTokenSource, TimeoutMs As Integer)
|
||||
Dim DelayTask = Task.Delay(TimeoutMs)
|
||||
If Task.WhenAny(TargetTask, DelayTask).GetAwaiter().GetResult() Is DelayTask Then
|
||||
TokenSource.Cancel()
|
||||
Throw New TimeoutException($"任务超时({TimeoutMs} ms)")
|
||||
End If
|
||||
TargetTask.GetAwaiter().GetResult()
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
''' 可用于临时存放文件的,不含任何特殊字符的文件夹路径,以“\”结尾。
|
||||
''' </summary>
|
||||
@@ -2586,7 +2614,7 @@ Retry:
|
||||
RunInUi(
|
||||
Sub()
|
||||
My.Computer.Clipboard.Clear()
|
||||
My.Computer.Clipboard.SetText(Text)
|
||||
If Not String.IsNullOrEmpty(Text) Then My.Computer.Clipboard.SetText(Text)
|
||||
End Sub)
|
||||
Catch ex As Exception
|
||||
RetryCount += 1
|
||||
@@ -2600,6 +2628,21 @@ Retry:
|
||||
If ShowSuccessHint Then Hint("已成功复制!", HintType.Green)
|
||||
End Sub)
|
||||
End Sub
|
||||
''' <summary>
|
||||
''' 获取剪贴板文本。将在 UI 线程运行,且不会抛出异常。
|
||||
''' </summary>
|
||||
Public Function ClipboardGetText() As String
|
||||
Dim Result As String = Nothing
|
||||
RunInUiWait(
|
||||
Sub()
|
||||
Try
|
||||
If My.Computer.Clipboard.ContainsText() Then Result = My.Computer.Clipboard.GetText()
|
||||
Catch ex As Exception
|
||||
Log(ex, "获取剪贴板文本失败")
|
||||
End Try
|
||||
End Sub)
|
||||
Return Result
|
||||
End Function
|
||||
|
||||
''' <summary>
|
||||
''' 以 Byte() 形式获取程序中的资源。
|
||||
@@ -3079,6 +3122,7 @@ Retry:
|
||||
Public Sub Telemetry([Event] As String, ParamArray Datas As String())
|
||||
If Not Setup.Get("SystemSystemTelemetry") Then Return '用户关闭了遥测
|
||||
If Not ClsBaseUrl.StartsWithF("http") Then Return '开源版没有设置遥测地址
|
||||
If VersionBranchName = "Debug" Then Return '开发版本不上传遥测
|
||||
RunInNewThread(
|
||||
Sub()
|
||||
Try
|
||||
|
||||
@@ -344,12 +344,12 @@
|
||||
LastRunningThread.Start() '不能使用 RunInNewThread,否则在函数返回前线程就会运行完,导致误判 IsAborted
|
||||
End Sub
|
||||
Public Overrides Sub Failed(ex As Exception)
|
||||
[Error] = ex
|
||||
SyncLock LockState
|
||||
If IsAborted OrElse State >= LoadState.Finished Then Return
|
||||
State = LoadState.Failed
|
||||
End SyncLock
|
||||
Log(ex, $"加载线程 {Name} ({Thread.CurrentThread.ManagedThreadId}) 出错,已完成 {Math.Round(Progress * 100)}%", LogLevel.Developer)
|
||||
[Error] = ex
|
||||
TriggerThreadAbort()
|
||||
End Sub
|
||||
Public Overrides Sub Abort()
|
||||
@@ -464,11 +464,11 @@
|
||||
End Sub)
|
||||
End Sub
|
||||
Public Overrides Sub Failed(Ex As Exception)
|
||||
[Error] = Ex '先设置错误再调整状态,防止父加载器获取不到异常
|
||||
SyncLock LockState
|
||||
If State >= LoadState.Finished Then Return
|
||||
State = LoadState.Failed
|
||||
End SyncLock
|
||||
[Error] = Ex
|
||||
For Each Loader In Loaders
|
||||
Loader.Abort()
|
||||
Next
|
||||
|
||||
@@ -262,11 +262,11 @@ RequestFinished:
|
||||
})
|
||||
End If
|
||||
End SyncLock
|
||||
Response = RequestClient.SendAsync(Request, HttpCompletionOption.ResponseHeadersRead, CancelToken.Token).GetAwaiter().GetResult()
|
||||
Response = RequestClient.SendAsync(Request, HttpCompletionOption.ResponseHeadersRead, CancelToken.Token).GetResultWithTimeout(CancelToken, Timeout)
|
||||
Dim ResponseStream = Response.Content.ReadAsStreamAsync().GetAwaiter().GetResult()
|
||||
Dim ResponseBytes As Byte()
|
||||
Using Stream As New MemoryStream
|
||||
ResponseStream.CopyToAsync(Stream, 81920, CancelToken.Token).GetAwaiter().GetResult()
|
||||
ResponseStream.CopyToAsync(Stream, 81920, CancelToken.Token).GetResultWithTimeout(CancelToken, Timeout)
|
||||
ResponseBytes = Stream.ToArray()
|
||||
End Using
|
||||
'输出
|
||||
@@ -286,7 +286,7 @@ RequestFinished:
|
||||
Throw
|
||||
Catch ex As Exception
|
||||
RecordIPReliability(HostIp, -1)
|
||||
If TypeOf ex Is OperationCanceledException Then 'CancellationToken 超时
|
||||
If TypeOf ex Is OperationCanceledException OrElse TypeOf ex Is TimeoutException Then 'CancellationToken 超时
|
||||
Throw New WebException($"连接服务器超时,请稍后再试,或使用 VPN 改善网络环境({Method}, {Url},IP:{HostIp})", WebExceptionStatus.Timeout)
|
||||
ElseIf ex.IsNetworkRelated Then
|
||||
Throw New WebException($"网络请求失败,请稍后再试,或使用 VPN 改善网络环境({Method}, {Url},IP:{HostIp})", WebExceptionStatus.Timeout)
|
||||
@@ -992,7 +992,7 @@ StartThread:
|
||||
HostIp = DNSLookup(HttpRequest, CancelToken) 'DNS 预解析
|
||||
If Not Th.IsFirstThread Then HttpRequest.Headers.Range = New RangeHeaderValue(Th.DownloadStart, Nothing)
|
||||
Dim ContentLength As Long = 0
|
||||
Response = ThreadClient.SendAsync(HttpRequest, HttpCompletionOption.ResponseHeadersRead, CancelToken.Token).GetAwaiter().GetResult()
|
||||
Response = ThreadClient.SendAsync(HttpRequest, HttpCompletionOption.ResponseHeadersRead, CancelToken.Token).GetResultWithTimeout(CancelToken, Timeout)
|
||||
If Not Response.IsSuccessStatusCode Then Throw New Exception($"错误码 {Response.StatusCode} ({CInt(Response.StatusCode)}),{Th.Source.Url}") '状态码检查
|
||||
If State = NetState.Error Then GoTo SourceBreak '快速中断
|
||||
If ModeDebug AndAlso Response.RequestMessage.RequestUri.ToString <> Th.Source.Url Then Log($"[Download] {LocalName}:重定向至 {Response.RequestMessage.RequestUri}")
|
||||
@@ -1063,7 +1063,7 @@ NotSupportRange:
|
||||
ResponseStream = Response.Content.ReadAsStreamAsync().GetAwaiter().GetResult()
|
||||
If Setup.Get("SystemDebugDelay") Then Threading.Thread.Sleep(RandomInteger(50, 3000))
|
||||
Dim ResponseBytes As Byte() = New Byte(16384) {}
|
||||
HttpDataCount = ReadWithTimeout(ResponseStream, ResponseBytes, 0, 16384, Timeout)
|
||||
HttpDataCount = ResponseStream.ReadAsync(ResponseBytes, 0, 16384, CancelToken.Token).GetResultWithTimeout(CancelToken, Timeout)
|
||||
While (IsUnknownSize OrElse Th.DownloadUndone > 0) AndAlso '判断是否下载完成
|
||||
HttpDataCount > 0 AndAlso Not IsProgramEnded AndAlso State < NetState.Merge AndAlso (Not Th.Source.IsFailed OrElse Th.Source.SingleThread = Th)
|
||||
'限速
|
||||
@@ -1113,7 +1113,7 @@ NotSupportRange:
|
||||
'无数据,且已超时
|
||||
Throw New TimeoutException("操作超时,无数据。")
|
||||
End If
|
||||
HttpDataCount = ReadWithTimeout(ResponseStream, ResponseBytes, 0, 16384, Timeout)
|
||||
HttpDataCount = ResponseStream.ReadAsync(ResponseBytes, 0, 16384, CancelToken.Token).GetResultWithTimeout(CancelToken, Timeout)
|
||||
End While
|
||||
SourceBreak:
|
||||
If State = NetState.Error OrElse (Th.Source.IsFailed AndAlso Th.Source.SingleThread <> Th) OrElse (Th.DownloadUndone > 0 AndAlso Not IsUnknownSize) Then
|
||||
@@ -1130,7 +1130,8 @@ SourceBreak:
|
||||
RecordIPReliability(HostIp, 0.5)
|
||||
End If
|
||||
Catch ex As Exception
|
||||
Log($"[Download] {LocalName}:出错,{If(TypeOf ex Is OperationCanceledException, $"已超时({Timeout}ms)", ex.GetDetail())},IP:{HostIp}")
|
||||
Log($"[Download] {LocalName}:出错,{If(TypeOf ex Is OperationCanceledException OrElse TypeOf ex Is TimeoutException,
|
||||
$"已超时({Timeout}ms)", ex.GetDetail())},IP:{HostIp}")
|
||||
RecordIPReliability(HostIp, -0.7)
|
||||
SourceFail(Th, ex, False)
|
||||
Finally
|
||||
@@ -1650,15 +1651,15 @@ Retry:
|
||||
If State >= LoadState.Finished Then Return
|
||||
If ExList Is Nothing OrElse Not ExList.Any() Then ExList = New List(Of Exception) From {New Exception("未知错误!")}
|
||||
'寻找有效的错误信息
|
||||
Dim UsefulExs = ExList.Where(Function(e) TypeOf e IsNot OperationCanceledException AndAlso TypeOf e IsNot ThreadInterruptedException).ToList
|
||||
Dim UsefulExs = ExList.Where(Function(e) TypeOf e IsNot OperationCanceledException AndAlso TypeOf e IsNot TimeoutException AndAlso TypeOf e IsNot ThreadInterruptedException).ToList
|
||||
[Error] = If(UsefulExs.FirstOrDefault, ExList.FirstOrDefault)
|
||||
'获取实际失败的文件
|
||||
For Each File In Files
|
||||
If File.State <> NetState.Error Then Continue For
|
||||
If File.Sources.All(Function(s) TypeOf s.Ex Is OperationCanceledException OrElse TypeOf s.Ex Is TimeoutException OrElse TypeOf s.Ex Is ThreadInterruptedException) Then Continue For
|
||||
Dim Detail As String = Join(File.Sources.Select(Function(s) $"{If(s.Ex Is Nothing, "无错误信息。", s.Ex.GetBrief())}({s.Url})"), vbCrLf)
|
||||
[Error] = New Exception("文件下载失败:" & File.LocalPath & vbCrLf &
|
||||
"各下载源的错误如下:" & vbCrLf & Detail,
|
||||
[Error])
|
||||
"各下载源的错误如下:" & vbCrLf & Detail, [Error])
|
||||
'上报
|
||||
Telemetry("文件下载失败",
|
||||
"FileName", File.LocalName,
|
||||
@@ -1951,6 +1952,45 @@ Retry:
|
||||
Return False
|
||||
End Function
|
||||
|
||||
#End Region
|
||||
|
||||
#Region "端口"
|
||||
|
||||
''' <summary>
|
||||
''' 随机获取单个可用的端口。
|
||||
''' </summary>
|
||||
Public Function FindFreePort() As Integer
|
||||
Dim Listener As New TcpListener(IPAddress.Loopback, 0)
|
||||
Listener.Start()
|
||||
Dim port As Integer = CType(Listener.LocalEndpoint, IPEndPoint).Port
|
||||
Listener.Stop()
|
||||
Return port
|
||||
End Function
|
||||
|
||||
''' <summary>
|
||||
''' 获取当前已被占用的端口列表。
|
||||
''' </summary>
|
||||
Public Function GetUsedPorts() As List(Of Integer)
|
||||
Dim IPProperties = NetworkInformation.IPGlobalProperties.GetIPGlobalProperties()
|
||||
Dim UsedPorts As New List(Of Integer)
|
||||
UsedPorts.AddRange(IPProperties.GetActiveTcpListeners().Select(Function(ep) ep.Port))
|
||||
UsedPorts.AddRange(IPProperties.GetActiveUdpListeners().Select(Function(ep) ep.Port))
|
||||
UsedPorts.AddRange(IPProperties.GetActiveTcpConnections().Select(Function(conn) conn.LocalEndPoint.Port))
|
||||
Return UsedPorts.Distinct().ToList()
|
||||
End Function
|
||||
|
||||
''' <summary>
|
||||
''' 寻找数个连续编号的可用端口。
|
||||
''' </summary>
|
||||
Public Function FindFreePorts(ConsecutiveCount As Integer, ParamArray ExtraBlackLists As Integer()) As List(Of Integer)
|
||||
Dim UsedPorts = GetUsedPorts().Concat(ExtraBlackLists)
|
||||
For port = 12000 To 65000 - ConsecutiveCount
|
||||
Dim Range = Enumerable.Range(port, ConsecutiveCount)
|
||||
If Not Range.Any(Function(p) UsedPorts.Contains(p)) Then Return Range.ToList
|
||||
Next
|
||||
Throw New Exception("未能找到可用的端口!")
|
||||
End Function
|
||||
|
||||
#End Region
|
||||
|
||||
''' <summary>
|
||||
@@ -1985,27 +2025,4 @@ Retry:
|
||||
}.Any(Function(k) Detail.ContainsF(k, True))
|
||||
End Function
|
||||
|
||||
''' <summary>
|
||||
''' 随机获取一个可用的端口。
|
||||
''' </summary>
|
||||
Public Function GetAvailablePort() As Integer
|
||||
Dim Listener As New TcpListener(IPAddress.Loopback, 0)
|
||||
Listener.Start()
|
||||
Dim port As Integer = CType(Listener.LocalEndpoint, IPEndPoint).Port
|
||||
Listener.Stop()
|
||||
Return port
|
||||
End Function
|
||||
|
||||
''' <summary>
|
||||
''' 带有 Timeout 的读取 Stream 方法。
|
||||
''' </summary>
|
||||
Private Function ReadWithTimeout(TargetStream As Stream, Buffer() As Byte, Offset As Integer, Count As Integer, ReadTimeoutMs As Integer) As Integer
|
||||
Dim ReadTask = TargetStream.ReadAsync(Buffer, Offset, Count)
|
||||
Dim DelayTask = Task.Delay(ReadTimeoutMs)
|
||||
If Task.WhenAny(ReadTask, DelayTask).GetAwaiter().GetResult() Is DelayTask Then
|
||||
Throw New TimeoutException($"读取数据超时({ReadTimeoutMs} ms)")
|
||||
End If
|
||||
Return ReadTask.GetAwaiter().GetResult()
|
||||
End Function
|
||||
|
||||
End Module
|
||||
|
||||
@@ -114,12 +114,7 @@ Public Class ValidateInteger
|
||||
End Sub
|
||||
Public Overrides Function Validate(Str As String) As String
|
||||
Dim Valed As Integer
|
||||
If Not Integer.TryParse(Str, Valed) Then
|
||||
Return "请输入一个整数!"
|
||||
End If
|
||||
If Not RegexCheck(Str, "^(-?0|-?[1-9]\d*)$") Then
|
||||
Return "请输入一个不带有前导零的整数!"
|
||||
End If
|
||||
If Not Integer.TryParse(Str, Valed) Then Return "请输入一个整数!"
|
||||
If Str.Length > 9 Then Return "请输入一个大小合理的数字!"
|
||||
If Valed > Max Then Return "不可超过 " & Max & "!"
|
||||
If Valed < Min Then Return "不可低于 " & Min & "!"
|
||||
|
||||
@@ -73,8 +73,10 @@
|
||||
Sub(Task As LoaderTask(Of String, List(Of NetFile)))
|
||||
Try
|
||||
Dim IndexFile = DlClientAssetIndexGet(Version)
|
||||
Dim IndexFileInfo As New FileInfo(IndexFile.LocalPath)
|
||||
If AssetsIndexBehaviour <> AssetsIndexExistsBehaviour.AlwaysDownload AndAlso IndexFile.Check.Check(IndexFile.LocalPath) Is Nothing Then
|
||||
If IndexFile Is Nothing Then
|
||||
Task.Output = New List(Of NetFile)
|
||||
Log("[Download] 未找到版本 " & Version.Name & " 的合适的资源索引下载地址,游戏 assets 可能缺失", LogLevel.Debug)
|
||||
ElseIf AssetsIndexBehaviour <> AssetsIndexExistsBehaviour.AlwaysDownload AndAlso IndexFile.Check.Check(IndexFile.LocalPath) Is Nothing Then
|
||||
Task.Output = New List(Of NetFile)
|
||||
Else
|
||||
Task.Output = New List(Of NetFile) From {IndexFile}
|
||||
@@ -93,6 +95,11 @@
|
||||
LoadersAssetsUpdate.Add(New LoaderTask(Of String, List(Of NetFile))("后台分析资源文件索引地址",
|
||||
Sub(Task As LoaderTask(Of String, List(Of NetFile)))
|
||||
Dim BackAssetsFile As NetFile = DlClientAssetIndexGet(Version)
|
||||
If BackAssetsFile Is Nothing Then
|
||||
Log("[Download] 未找到版本 " & Version.Name & " 的合适的资源索引下载地址,游戏 assets 可能缺失", LogLevel.Debug)
|
||||
Task.Abort()
|
||||
Throw New ThreadInterruptedException
|
||||
End If
|
||||
RealAddress = BackAssetsFile.LocalPath
|
||||
TempAddress = PathTemp & "Cache\" & BackAssetsFile.LocalName
|
||||
BackAssetsFile.LocalPath = TempAddress
|
||||
|
||||
@@ -141,6 +141,7 @@ Public Class CustomEvent
|
||||
写入设置
|
||||
修改变量
|
||||
写入变量
|
||||
加入房间
|
||||
End Enum
|
||||
|
||||
''' <summary>
|
||||
@@ -283,6 +284,17 @@ Public Class CustomEvent
|
||||
WriteReg("CustomEvent" & Args(0), Args(1))
|
||||
If Args.Length = 2 Then Hint($"已写入变量:{Args(0)} → {Args(1)}", HintType.Green)
|
||||
|
||||
Case EventType.加入房间
|
||||
RunInUi(
|
||||
Sub()
|
||||
If String.IsNullOrWhiteSpace(Arg) Then
|
||||
PageLinkMain.Join()
|
||||
Else
|
||||
If Not EventSafetyConfirm("即将加入第三方联机房间。") Then Return
|
||||
PageLinkMain.Join(Arg)
|
||||
End If
|
||||
End Sub)
|
||||
|
||||
Case Else
|
||||
MyMsgBox("未知的事件类型:" & Type & vbCrLf & "请检查事件类型填写是否正确,或者 PCL 是否为最新版本。", "事件执行失败")
|
||||
End Select
|
||||
|
||||
@@ -51,6 +51,6 @@ Imports System.Runtime.InteropServices
|
||||
' 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
|
||||
' 方法是按如下所示使用“*”
|
||||
|
||||
<Assembly: AssemblyVersion("2.11.0.0")>
|
||||
<Assembly: AssemblyFileVersion("2.11.0.0")>
|
||||
<Assembly: AssemblyVersion("2.11.1.0")>
|
||||
<Assembly: AssemblyFileVersion("2.11.1.0")>
|
||||
<Assembly: NeutralResourcesLanguage("")>
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
<TextBlock VerticalAlignment="Center" Grid.Row="2" HorizontalAlignment="Left" Text="版本" Margin="0,0,18,0" />
|
||||
<local:MyComboBox x:Name="TextSearchVersion" Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="2" IsEditable="True" MaxDropDownHeight="320">
|
||||
<local:MyComboBoxItem Content="全部 (也可自行输入)" IsSelected="True" />
|
||||
<local:MyComboBoxItem Content="1.21.8" />
|
||||
<local:MyComboBoxItem Content="1.21.10" />
|
||||
<local:MyComboBoxItem Content="1.21.1" />
|
||||
<local:MyComboBoxItem Content="1.20.6" />
|
||||
<local:MyComboBoxItem Content="1.20.1" />
|
||||
|
||||
@@ -99,7 +99,8 @@ Public Module ModDownloadLib
|
||||
Sub(Task As LoaderTask(Of String, List(Of NetFile)))
|
||||
Try
|
||||
Dim Version As New McVersion(VersionFolder)
|
||||
Task.Output = New List(Of NetFile) From {DlClientAssetIndexGet(Version)}
|
||||
Dim AssetIndex = DlClientAssetIndexGet(Version)
|
||||
Task.Output = If(AssetIndex Is Nothing, New List(Of NetFile), New List(Of NetFile) From {AssetIndex})
|
||||
Catch ex As Exception
|
||||
Throw New Exception("分析资源文件索引地址失败", ex)
|
||||
End Try
|
||||
|
||||
@@ -104,6 +104,9 @@ Public Class PageLaunchRight
|
||||
Case 12
|
||||
Log("[Page] 主页预设:PCL GitHub 仪表盘")
|
||||
Url = "https://ddf.pcl-community.org/Custom.xaml"
|
||||
Case 13
|
||||
Log("[Page] 主页预设:PCL 更新摘要")
|
||||
Url = "https://raw.gitcode.com/ENC_Euphony/PCL-AI-Summary-HomePage/raw/master/Custom.xaml"
|
||||
End Select
|
||||
End Select
|
||||
'联网下载
|
||||
|
||||
@@ -121,7 +121,7 @@ Retry:
|
||||
Next
|
||||
Throw New Exception("未知错误(" & Result & ")")
|
||||
Catch ex As Exception
|
||||
If TypeOf ex Is OperationCanceledException Then
|
||||
If TypeOf ex Is OperationCanceledException OrElse TypeOf ex Is TimeoutException Then
|
||||
Hint("更改皮肤失败:连接皮肤服务器超时,请稍后再试,或使用 VPN 改善网络环境", HintType.Red)
|
||||
Else
|
||||
Log(ex, "更改皮肤失败", LogLevel.Hint)
|
||||
|
||||
@@ -152,7 +152,7 @@
|
||||
<TextBlock x:Name="LabFinishDesc" Grid.Column="3" Grid.ColumnSpan="3" Grid.Row="2" Margin="1,9,10,10"
|
||||
Text="描述文本。"
|
||||
FontSize="14" LineHeight="19" MaxWidth="400" TextWrapping="Wrap" Foreground="{StaticResource ColorBrushGray2}" />
|
||||
<local:MyButton x:Name="BtnFinishCopy" Grid.Column="4" Grid.Row="3" Margin="0,0,15,0" Text="复制" Padding="13,8" ColorType="Highlight" />
|
||||
<local:MyButton x:Name="BtnFinishCopy" Grid.Column="4" Grid.Row="3" Margin="0,0,15,0" Text="复制邀请码" Padding="13,8" ColorType="Highlight" />
|
||||
<local:MyButton x:Name="BtnFinishExit" Grid.Column="5" Grid.Row="3" Text="退出" Padding="13,8" />
|
||||
</Grid>
|
||||
</local:MyCard>
|
||||
@@ -186,12 +186,12 @@
|
||||
Data="m365,295.3c-15.1-3.6-36.5-1.8-39.6,17.5-1.2,12.4,0,107-.5,119.7.8,16.8-5.2,42.4,16.8,47.1,14.3,3.3,34.5,1.9,38.7-15.4,2.6-1.4.1-142.4,1-148.3-.7-10.9-6.2-17.8-16.4-20.6ZM234.1,311.6c-3.2-16.7-20-18.6-34.4-17.2-9.8.4-17.2,6.2-20,15.4-4.4,47.8-.2,97.3-1.6,144.8,0,16,9.8,26.6,24.6,26.1,14.4,1.4,29.1-2.9,31.7-19,2.2-8.8.8-63.9,1.1-74.1-1-25.3,2.1-50.6-1.5-75.9ZM521.4,300.6c-5.4-6.2-15.9-7.1-24.6-6.4-11.9-1-23,6.6-24.7,18.7-2.2,24.1-2,124-.2,148.1,2.6,19.7,24.1,22.4,40.1,18.4,11.9-2.4,16.6-15.2,16.3-27.1,0-33.6.1-69.3,0-103.1-1.2-15.1,4.2-37-6.9-48.5ZM708.8,194.2c.7-34.5-26.8-63.7-61.5-63.4-22.1-.1-52.4,0-75.6,0-13.4,1.1-8.7-12.1-9.6-20.9-1.6-30.6,7.5-67.2-17.5-90.9-11.7-11.9-27.4-18.4-44.3-18.4-64.8,0-129.7,0-194.5,0-37.7,1.4-76.5-3.1-113.8,2.2-48.1,14.7-46.7,55.3-45.4,97.3,0,8,.1,16.1,0,24.1.2,7-7.3,6.8-12.2,6.6-16,0-32,0-48,0-24.4-.7-51.3-1-68.6,18.4C5.8,161.2,0,176.1,0,194.7c0,0,0,350.9,0,350.9,0,22.9,5.5,41.7,16.8,57.5,19.2,27,45.9,40.7,79.5,40.7,37.4,0,77.4.1,129.9.1,42.5,0,85,0,127.5,0,11.2-1.3,273.6,2.4,278-1.8,46.1-9.1,77.1-46.8,77.1-93.8,0-117.8,0-237.9,0-354.1Zm-71-5.3c7.6.2,9.2,1.9,9.3,9.7,0,0,0,347.3,0,347.3,0,3.2.2,6.5-.3,9.9-2.8,19.3-18.9,32.3-38.5,31.9-4.5.4-508.9-.4-513.5,0-3.2,0-6.5.1-9.9-.4-19-2.9-31.8-17.8-31.8-37.1,0-117.9,0-233.9,0-350.9,0-9,2.3-10.3,10.9-10.3,0,0,131.2,0,131.2,0,1.6,0,3,0,4.5,0,0-1.5,0-2.7,0-4.3,0,0,0-115.7,0-115.7.1-8.3,1.9-10.1,10.3-10.1h280.3c8.3,0,10.1,1.8,10.1,10.3v114.1c0,1.9,0,3.7,0,5.6" />
|
||||
<TextBlock x:Name="LabFinishPort" IsHitTestVisible="False" Text="12345" VerticalAlignment="Center" Foreground="{StaticResource ColorBrushGray1}" Margin="0,0.5,13,0" />
|
||||
</StackPanel>
|
||||
<!--<StackPanel x:Name="BtnFinishIp" Orientation="Horizontal" Background="{StaticResource ColorBrushSemiTransparent}"
|
||||
ToolTip="服务器 IP ( 点击复制 )" ToolTipService.Placement="Center" ToolTipService.InitialShowDelay="50" ToolTipService.VerticalOffset="40" ToolTipService.HorizontalOffset="4">
|
||||
<StackPanel x:Name="BtnFinishIp" Orientation="Horizontal" Background="{StaticResource ColorBrushSemiTransparent}"
|
||||
ToolTip="服务器 IP(点击复制)" ToolTipService.Placement="Center" ToolTipService.InitialShowDelay="50" ToolTipService.VerticalOffset="40" ToolTipService.HorizontalOffset="4">
|
||||
<Path IsHitTestVisible="False" Height="17" Width="17" Stretch="Uniform" Fill="{StaticResource ColorBrushGray4}" Margin="11,0,7,0"
|
||||
Data="m346.4,692.8c-92.5,0-179.5-36-244.9-101.5C36,525.9,0,438.9,0,346.4S36,166.9,101.5,101.5C166.9,36,253.9,0,346.4,0s179.5,36,244.9,101.5c65.4,65.4,101.5,152.4,101.5,244.9s-36,179.5-101.5,244.9c-65.4,65.4-152.4,101.5-244.9,101.5Zm0-645.1c-164.7,0-298.7,134-298.7,298.7s134,298.7,298.7,298.7,298.7-134,298.7-298.7S511.1,47.7,346.4,47.7Zm13.8,473.4c-14.5,0-28.2-9.8-28.2-24.2V207.9c0-14.5,11.8-26.2,26.2-26.2h78.9c57.9,0,105.1,47.1,105.1,105.1s-47.1,105.1-105.1,105.1h-52.6v105.1c0,14.5-9.8,24.2-24.2,24.2Zm24.2-181.7h52.6c29,0,52.6-23.6,52.6-52.6s-20-49.2-46.5-52.3h-.4s-5.3-.4-5.3-.4h-53v105.2Zm-158.8,181.7c-14.5,0-28.2-9.8-28.2-24.2V207.9c0-14.5,11.8-26.2,26.2-26.2s26.2,11.8,26.2,26.2v289c0,14.5-9.8,24.2-24.2,24.2Z" />
|
||||
<TextBlock x:Name="LabFinishIp" IsHitTestVisible="False" Text="6.0.0.1:12345" VerticalAlignment="Center" Foreground="{StaticResource ColorBrushGray1}" Margin="0,0.5,13,0" />
|
||||
</StackPanel>-->
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</local:MyCard>
|
||||
</Grid>
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
Public Class PageLinkMain
|
||||
Imports System.Net.Sockets
|
||||
|
||||
Public Class PageLinkMain
|
||||
|
||||
'===============================
|
||||
' 状态机与前端页面
|
||||
@@ -6,33 +8,33 @@
|
||||
|
||||
#Region "状态管理"
|
||||
|
||||
Private Enum States
|
||||
Public Enum LinkStates
|
||||
Waiting
|
||||
Loading
|
||||
Failed
|
||||
Finished
|
||||
End Enum
|
||||
Private State As States = States.Waiting
|
||||
Public Shared LinkState As LinkStates = LinkStates.Waiting
|
||||
|
||||
''' <summary>
|
||||
''' 切换到指定的状态。
|
||||
''' </summary>
|
||||
Private Sub ChangeState(NewState As States)
|
||||
If State = NewState Then Return
|
||||
Dim OldState = State
|
||||
State = NewState
|
||||
Private Sub ChangeState(NewState As LinkStates)
|
||||
If LinkState = NewState Then Return
|
||||
Dim OldState = LinkState
|
||||
LinkState = NewState
|
||||
Log($"[Link] 主状态由 {GetStringFromEnum(OldState)} 变更为 {GetStringFromEnum(NewState)}")
|
||||
'触发状态切换
|
||||
RunInUi(
|
||||
Sub()
|
||||
Select Case NewState
|
||||
Case States.Waiting
|
||||
Case LinkStates.Waiting
|
||||
SwitchToWaiting(OldState)
|
||||
Case States.Loading
|
||||
Case LinkStates.Loading
|
||||
SwitchToLoading(OldState)
|
||||
Case States.Failed
|
||||
Case LinkStates.Failed
|
||||
SwitchToFailed(OldState)
|
||||
Case States.Finished
|
||||
Case LinkStates.Finished
|
||||
SwitchToFinished(OldState)
|
||||
End Select
|
||||
End Sub)
|
||||
@@ -45,18 +47,18 @@
|
||||
Sub(Loader As LoaderBase, NewState As LoadState, OldState As LoadState)
|
||||
Select Case NewState
|
||||
Case LoadState.Finished
|
||||
ChangeState(States.Finished)
|
||||
ChangeState(LinkStates.Finished)
|
||||
Case LoadState.Failed
|
||||
Telemetry("联机失败", "Exception", FilterUserName(Loader.Error.GetDetail, "*"))
|
||||
ChangeState(States.Failed)
|
||||
ChangeState(LinkStates.Failed)
|
||||
End Select
|
||||
End Sub
|
||||
End Sub
|
||||
|
||||
'页面动画兼容
|
||||
Private Sub UpdatePanelVisibility() Handles Me.PageEnter
|
||||
FrmLinkMain.PanSelect.Visibility = If(State = States.Waiting, Visibility.Visible, Visibility.Collapsed)
|
||||
FrmLinkMain.PanFinish.Visibility = If(State = States.Finished, Visibility.Visible, Visibility.Collapsed)
|
||||
FrmLinkMain.PanSelect.Visibility = If(LinkState = LinkStates.Waiting, Visibility.Visible, Visibility.Collapsed)
|
||||
FrmLinkMain.PanFinish.Visibility = If(LinkState = LinkStates.Finished, Visibility.Visible, Visibility.Collapsed)
|
||||
End Sub
|
||||
|
||||
#End Region
|
||||
@@ -64,7 +66,7 @@
|
||||
#Region "初始页面 (Waiting)"
|
||||
|
||||
'由任意状态切换到 Waiting
|
||||
Private Sub SwitchToWaiting(OldState As States)
|
||||
Private Sub SwitchToWaiting(OldState As LinkStates)
|
||||
'加载器与进程状态
|
||||
LinkLoader.Abort()
|
||||
SyncLock LinkLoader.LockState
|
||||
@@ -72,7 +74,7 @@
|
||||
End SyncLock
|
||||
ProcessStop()
|
||||
'页面切换
|
||||
If OldState <> States.Finished Then
|
||||
If OldState <> LinkStates.Finished Then
|
||||
'从完成页面退出时,PageOnContentExit 结束会触发 PageEnter 事件,这会调用 UpdatePanelVisibility
|
||||
'如果在现在提前调用了,会丢失完成页面的退出动画
|
||||
UpdatePanelVisibility()
|
||||
@@ -87,7 +89,7 @@
|
||||
'创建
|
||||
Private Sub Create_MouseLeftButtonUp() Handles PanSelectCreate.MouseLeftButtonUp
|
||||
'输入端口号
|
||||
Dim Port As String = MyMsgBoxInput("输入端口", $"在单人游戏的暂停菜单选择 {vbLQ}对局域网开放{vbRQ},然后输入端口数字。{vbCrLf}其实也可以输入其他游戏的端口……",
|
||||
Dim Port As String = MyMsgBoxInput("输入端口", $"在单人游戏的暂停菜单选择 {vbLQ}对局域网开放{vbRQ},然后输入端口数字。{vbCrLf}甚至可以输入其他游戏的端口……嗯……",
|
||||
ValidateRules:=New ObjectModel.Collection(Of Validate) From {New ValidateInteger(1024, 65535)},
|
||||
HintText:="端口号")
|
||||
If Port Is Nothing Then Return
|
||||
@@ -106,50 +108,31 @@
|
||||
NetworkSecret = GenerateRandomCode()
|
||||
Log($"[Link] 尝试创建房间,网络名 {NetworkName},网络密码 {NetworkSecret},端口 {ServerPort}")
|
||||
'启动
|
||||
ChangeState(States.Loading)
|
||||
ChangeState(LinkStates.Loading)
|
||||
End Sub
|
||||
|
||||
'加入
|
||||
Private LastCode As String = Nothing
|
||||
Private Sub Join_MouseLeftButtonUp() Handles PanSelectJoin.MouseLeftButtonUp
|
||||
'输入邀请码
|
||||
Private Shared LastCode As String = Nothing
|
||||
''' <summary>
|
||||
''' 输入邀请码,切换到联机页并立即加入房间。
|
||||
''' </summary>
|
||||
Public Shared Sub Join() Handles PanSelectJoin.MouseLeftButtonUp
|
||||
Dim Code As String = MyMsgBoxInput("输入邀请码", "输入房主发给你的邀请码。",
|
||||
HintText:=If(String.IsNullOrEmpty(LastCode), "", "使用上一次的邀请码:" & LastCode))
|
||||
HintText:=If(String.IsNullOrEmpty(LastCode), "", "使用上一次的邀请码:" & LastCode))
|
||||
If Not String.IsNullOrEmpty(LastCode) AndAlso Code IsNot Nothing AndAlso Code = "" Then Code = LastCode
|
||||
If Code Is Nothing Then Return
|
||||
Join(Code)
|
||||
End Sub
|
||||
Public Sub JoinInternal(Code As String)
|
||||
If Code Is Nothing Then Return
|
||||
'基础格式校验
|
||||
Code = Code.Between("【", "】").Between("[", "]") '从完整消息中提取
|
||||
Code = Code.ToUpper.Replace("O", "0").Replace("I", "1") '输入修正
|
||||
If Not (Code.Length >= 14 AndAlso Code(0) = "P"c AndAlso Code(5) = "-"c AndAlso Code(11) = "-"c) Then
|
||||
If Code.StartsWithF("U/") Then 'HMCL
|
||||
Hint("请让房主使用 PCL 创建房间!", HintType.Red)
|
||||
ElseIf Code.Length = 10 Then 'PCL CE
|
||||
Hint("请让房主使用非社区版的 PCL 创建房间!", HintType.Red)
|
||||
ElseIf Code.StartsWithF("P") Then '远古版 PCL
|
||||
Hint("你的 PCL 版本与房主的 PCL 版本不一致,或输入的邀请码有误!", HintType.Red)
|
||||
Else
|
||||
Hint("邀请码有误,请让房主使用 PCL 创建房间!", HintType.Red)
|
||||
End If
|
||||
Dim ValidateResult = ValidateCodeFormat(Code)
|
||||
If ValidateResult IsNot Nothing Then
|
||||
Hint(ValidateResult, HintType.Red)
|
||||
Return
|
||||
End If
|
||||
'离线登录警告
|
||||
If McLoginLoader.State = LoadState.Finished AndAlso McLoginLoader.Output.Type = "Legacy" AndAlso Not Setup.Get("LinkOfflineHint") Then
|
||||
Dim Solution As String
|
||||
If McVersionCurrent IsNot Nothing AndAlso McVersionCurrent.Version.McVersion >= New Version(1, 21, 5) Then
|
||||
Solution = $"请换用正版登录,或是让房主安装 {vbLQ}更高级联机设置{vbRQ} Mod 并禁用正版验证。"
|
||||
ElseIf McVersionCurrent IsNot Nothing AndAlso McVersionCurrent.Version.McVersion >= New Version(1, 12, 0) Then
|
||||
Solution = $"请换用正版登录,或是让房主安装 {vbLQ}自定义局域网联机{vbRQ} Mod 并关闭在线模式。"
|
||||
Else
|
||||
Solution = $"请换用正版登录,或是让房主用服务端开服,关闭 online-mode,然后在创建房间时输入服务端的端口号。"
|
||||
End If
|
||||
Select Case MyMsgBox($"如果不用正版登录可能会进不了服,显示 {vbLQ}无效会话{vbRQ}。" & vbCrLf & Solution,
|
||||
"离线登录警告", "继续", "继续且不再提示", "取消", IsWarn:=True)
|
||||
Case 2
|
||||
Setup.Set("LinkOfflineHint", True)
|
||||
Case 3
|
||||
Return
|
||||
End Select
|
||||
End If
|
||||
'基础信息
|
||||
IsServerSide = False
|
||||
ServerPort = RadixConvert(Code.Substring(1, 4), 16, 10)
|
||||
@@ -158,7 +141,45 @@
|
||||
Log($"[Link] 尝试加入房间,网络名 {NetworkName},网络密码 {NetworkSecret},端口 {ServerPort}")
|
||||
'启动
|
||||
LastCode = Code
|
||||
ChangeState(States.Loading)
|
||||
ChangeState(LinkStates.Loading)
|
||||
End Sub
|
||||
Public Shared Function ValidateCodeFormat(Code As String) As String
|
||||
If Code Is Nothing Then Return "邀请码为空!"
|
||||
Code = Code.Between("【", "】").Between("[", "]") '从完整消息中提取
|
||||
Code = Code.ToUpper.Replace("O", "0").Replace("I", "1") '输入修正
|
||||
If Not (Code.Length >= 14 AndAlso Code(0) = "P"c AndAlso Code(5) = "-"c AndAlso Code(11) = "-"c) Then
|
||||
If Code.StartsWithF("U/") Then 'HMCL
|
||||
Return "请让房主使用 PCL 创建房间!"
|
||||
ElseIf Code.Length = 10 Then 'PCL CE
|
||||
Return "请让房主使用非社区版的 PCL 创建房间!"
|
||||
Else
|
||||
Return "邀请码有误,请让房主使用 PCL 创建房间!"
|
||||
End If
|
||||
End If
|
||||
Return Nothing
|
||||
End Function
|
||||
|
||||
'自动加入
|
||||
|
||||
''' <summary>
|
||||
''' 切换到联机页并立即加入指定房间。
|
||||
''' </summary>
|
||||
Public Shared Sub Join(Code As String)
|
||||
If LinkState <> LinkStates.Waiting Then
|
||||
Hint("你已经在联机房间中了!", HintType.Red)
|
||||
ElseIf FrmMain.PageCurrent = FormMain.PageType.Link Then
|
||||
FrmLinkMain.JoinInternal(Code)
|
||||
Else
|
||||
AutoJoinCode = Code
|
||||
FrmMain.PageChange(FormMain.PageType.Link, FormMain.PageSubType.LinkMain)
|
||||
End If
|
||||
End Sub
|
||||
'在进入页面时自动尝试加入房间
|
||||
Private Shared AutoJoinCode As String = Nothing
|
||||
Private Sub PanSelectJoin_Loaded() Handles PanSelectJoin.Loaded
|
||||
If AutoJoinCode Is Nothing Then Return
|
||||
If LinkState = LinkStates.Waiting Then JoinInternal(AutoJoinCode)
|
||||
AutoJoinCode = Nothing
|
||||
End Sub
|
||||
|
||||
#End Region
|
||||
@@ -166,7 +187,7 @@
|
||||
#Region "加载页面 (Loading | Failed)"
|
||||
|
||||
'由 Waiting 或 Failed 状态切换到 Loading
|
||||
Private Sub SwitchToLoading(OldState As States)
|
||||
Private Sub SwitchToLoading(OldState As LinkStates)
|
||||
'清理变量
|
||||
Peers = Nothing
|
||||
FailCount = 0
|
||||
@@ -180,7 +201,7 @@
|
||||
End Sub
|
||||
|
||||
'由 Loading 状态切换到 Failed
|
||||
Private Sub SwitchToFailed(OldState As States)
|
||||
Private Sub SwitchToFailed(OldState As LinkStates)
|
||||
'加载器与进程状态
|
||||
LinkLoader.Abort()
|
||||
ProcessStop()
|
||||
@@ -217,12 +238,12 @@
|
||||
|
||||
'取消加载
|
||||
Private Sub BtnLoadCancel_Click() Handles BtnLoadCancel.Click
|
||||
ChangeState(States.Waiting)
|
||||
ChangeState(LinkStates.Waiting)
|
||||
End Sub
|
||||
|
||||
'点击重试
|
||||
Private Sub CardLoad_MouseLeftButtonUp() Handles CardLoad.MouseLeftButtonUp
|
||||
ChangeState(States.Loading)
|
||||
ChangeState(LinkStates.Loading)
|
||||
End Sub
|
||||
|
||||
'进度条
|
||||
@@ -252,7 +273,7 @@
|
||||
#Region "完成页面 (Finished)"
|
||||
|
||||
'由 Loading 状态切换到 Finished
|
||||
Private Sub SwitchToFinished(OldState As States)
|
||||
Private Sub SwitchToFinished(OldState As LinkStates)
|
||||
'由于只可能从加载器的完成事件触发,不需要管加载器
|
||||
UpdatePanelVisibility() '页面的实际切换会由 Loader 调用 MyPageRight 来触发
|
||||
|
||||
@@ -260,26 +281,27 @@
|
||||
If IsServerSide Then
|
||||
LabFinishTitle.Text = "已创建房间"
|
||||
LabFinishDesc.Text = $"把邀请码发给朋友,让大家加入房间吧!{vbCrLf}邀请码:{NetworkName}-{NetworkSecret}"
|
||||
BtnFinishCopy.Text = "复制邀请码"
|
||||
BtnFinishExit.Text = "关闭"
|
||||
BtnFinishCopy.Visibility = Visibility.Visible
|
||||
Copy() '立即复制邀请码
|
||||
'下边栏
|
||||
BtnFinishPing.ToolTip = "网络延迟"
|
||||
LineFinishPort.Visibility = Visibility.Visible
|
||||
BtnFinishPort.Visibility = Visibility.Visible
|
||||
LabFinishPort.Visibility = Visibility.Visible
|
||||
BtnFinishIp.Visibility = Visibility.Collapsed
|
||||
LabFinishIp.Visibility = Visibility.Collapsed
|
||||
LabFinishPort.Text = ServerPort
|
||||
Else
|
||||
LabFinishTitle.Text = "已加入房间"
|
||||
LabFinishDesc.Text = $"在多人游戏中选择直接连接,粘贴地址即可加入游戏!{vbCrLf}服务器地址:{ClientAddress}" '"如果提示无效会话,不要退出联机房间,重新启动游戏即可!"
|
||||
BtnFinishCopy.Text = "复制地址"
|
||||
LabFinishDesc.Text = $"在多人游戏页面的最下方就能找到联机房间!{vbCrLf}注意:使用离线登录时不要手动输入 IP!"
|
||||
BtnFinishExit.Text = "离开"
|
||||
BtnFinishCopy.Visibility = Visibility.Collapsed
|
||||
'下边栏
|
||||
BtnFinishPing.ToolTip = "与房主的延迟"
|
||||
LineFinishPort.Visibility = Visibility.Collapsed
|
||||
BtnFinishPort.Visibility = Visibility.Collapsed
|
||||
LabFinishPort.Visibility = Visibility.Collapsed
|
||||
LabFinishIp.Text = ClientAddress
|
||||
BtnFinishIp.Visibility = Visibility.Visible
|
||||
LabFinishIp.Visibility = Visibility.Visible
|
||||
End If
|
||||
Copy() '复制信息
|
||||
Update() '立即刷新
|
||||
End Sub
|
||||
|
||||
@@ -289,30 +311,37 @@
|
||||
|
||||
'退出
|
||||
Private Sub BtnFinishExit_Click() Handles BtnFinishExit.Click
|
||||
TryExit(True)
|
||||
TryExit(False, False)
|
||||
End Sub
|
||||
''' <summary>
|
||||
''' 退出联机。
|
||||
''' 返回是否弹出了警告窗口并且玩家选择了取消。
|
||||
''' </summary>
|
||||
Public Function TryExit(SendWarning As Boolean) As Boolean
|
||||
If State = States.Waiting OrElse State = States.Failed Then Return False
|
||||
If IsServerSide AndAlso PeopleCount > 1 Then
|
||||
If MyMsgBox("你确定要关闭联机房间吗?" & vbCrLf & "所有玩家都需要重新输入邀请码才可加入游戏!", "关闭房间", "确定", "取消", IsWarn:=True) = 2 Then Return True
|
||||
Public Function TryExit(Slient As Boolean, Closing As Boolean) As Boolean
|
||||
If LinkState = LinkStates.Waiting OrElse LinkState = LinkStates.Failed Then Return False
|
||||
If Not Slient Then
|
||||
If IsServerSide AndAlso PeopleCount > 1 Then
|
||||
If MyMsgBox("你确定要关闭联机房间吗?" & vbCrLf & "所有玩家都需要重新输入邀请码才可加入游戏!", "退出联机", "确定", "取消", IsWarn:=True) = 2 Then Return True
|
||||
ElseIf Closing Then
|
||||
If MyMsgBox(If(IsServerSide, "你确定要关闭联机房间吗?", "你确定要离开联机房间吗?"), "退出联机", "确定", "取消") = 2 Then Return True
|
||||
End If
|
||||
End If
|
||||
ChangeState(States.Waiting)
|
||||
ChangeState(LinkStates.Waiting)
|
||||
Return False
|
||||
End Function
|
||||
|
||||
'复制
|
||||
'复制邀请码
|
||||
Private Sub Copy() Handles BtnFinishCopy.Click
|
||||
If IsServerSide Then
|
||||
ClipboardSet($"在 PCL 启动器中输入邀请码【{NetworkName}-{NetworkSecret}】,即可加入联机房间!", False)
|
||||
Hint("已复制邀请码!", HintType.Green)
|
||||
Else
|
||||
ClipboardSet(ClientAddress, False)
|
||||
Hint("已复制服务器地址!", HintType.Green)
|
||||
End If
|
||||
Dim CodeText As String = $"在 PCL 启动器中输入邀请码【{NetworkName}-{NetworkSecret}】,即可加入联机房间!"
|
||||
ClipboardSet(CodeText, False)
|
||||
Setup.Set("LinkLastAutoJoinInviteCode", CodeText)
|
||||
Hint("已复制邀请码!", HintType.Green)
|
||||
End Sub
|
||||
|
||||
'复制 IP
|
||||
Private Sub BtnFinishIp_MouseLeftButtonUp(sender As Object, e As MouseButtonEventArgs) Handles BtnFinishIp.MouseLeftButtonUp
|
||||
ClipboardSet(ClientAddress, False)
|
||||
Hint("已复制服务器地址!", HintType.Green)
|
||||
End Sub
|
||||
|
||||
#End Region
|
||||
@@ -334,6 +363,14 @@
|
||||
''' </summary>
|
||||
Private ServerPort As Integer
|
||||
''' <summary>
|
||||
''' 客户端映射后的端口号。
|
||||
''' </summary>
|
||||
Private ClientPort As Integer
|
||||
''' <summary>
|
||||
''' RPC 端口号。
|
||||
''' </summary>
|
||||
Private RPCPort As Integer
|
||||
''' <summary>
|
||||
''' 在客户端映射后的地址。
|
||||
''' 除非已作为客户端启动 EasyTier,否则一直为 Nothing。
|
||||
''' </summary>
|
||||
@@ -414,7 +451,7 @@
|
||||
'解压
|
||||
Dim ExtractPath As String = RequestTaskTempFolder()
|
||||
ExtractFile(PathEasyTier & "EasyTier.zip", ExtractPath,
|
||||
ProgressIncrementHandler:=Sub(Progress) Task.Progress += Progress * 0.06)
|
||||
ProgressIncrementHandler:=Sub(Progress) Task.Progress += Progress * 0.05)
|
||||
Dim ExtractedPath As String = New DirectoryInfo(ExtractPath).EnumerateDirectories.FirstOrDefault?.FullName
|
||||
Log("[Link] 联机模块解压时的临时路径:" & ExtractedPath)
|
||||
CopyDirectory(ExtractedPath, PathEasyTier)
|
||||
@@ -427,28 +464,42 @@
|
||||
File.Delete(PathEasyTier & "EasyTier.zip")
|
||||
Setup.Set("LinkEasyTierVersion", ServerVersion)
|
||||
End If
|
||||
Task.Progress = 0.1
|
||||
'获取启动参数
|
||||
Task.Progress = 0.07
|
||||
'获取节点列表
|
||||
Dim Peers As List(Of String)
|
||||
Dim CustomPeers As String = Setup.Get("LinkCustomPeer")
|
||||
If String.IsNullOrWhiteSpace(CustomPeers) Then
|
||||
Peers = GetOnlinePeers()
|
||||
Else
|
||||
Peers = CustomPeers.Split(",,".ToCharArray).Select(Function(p) p.Trim).Where(Function(p) Not String.IsNullOrEmpty(p)).ToList()
|
||||
Log("[Link] 使用自定义节点")
|
||||
End If
|
||||
Task.Progress = 0.13
|
||||
'获取空闲端口
|
||||
UpdateLoadingPage("正在启动联机模块……", "启动联机模块")
|
||||
Dim FreePorts = FindFreePorts(5, ServerPort)
|
||||
ClientPort = FreePorts(0)
|
||||
RPCPort = FreePorts(1)
|
||||
Dim ListenersPort As Integer = FreePorts(2) '它会占用【当前、当前 +1、当前 +2】共三个端口
|
||||
'获取启动参数
|
||||
Dim Arguments As String = ServerConfig("Link")("Argument")
|
||||
Arguments += $" --network-name={NetworkName} --network-secret={NetworkSecret}"
|
||||
Arguments += $" --network-name={NetworkName} --network-secret={NetworkSecret} --listeners {ListenersPort} --rpc-portal {RPCPort}"
|
||||
HostName = If(IsServerSide, "Server-", "Client-") & RadixConvert(Math.Abs(Identify.GetHashCode), 10, 36)
|
||||
If IsServerSide Then
|
||||
Arguments += $" -i 10.114.114.114 --hostname={HostName} --tcp-whitelist={ServerPort} --udp-whitelist={ServerPort}"
|
||||
Else
|
||||
Arguments += $" -d --hostname={HostName} --tcp-whitelist=0 --udp-whitelist=0"
|
||||
'端口转发
|
||||
Dim Port As Integer = GetAvailablePort()
|
||||
ClientAddress = $"localhost:{Port}"
|
||||
Arguments += $" --port-forward tcp://[{IPAddress.IPv6Loopback}]:{Port}/10.114.114.114:{ServerPort}"
|
||||
Arguments += $" --port-forward udp://[{IPAddress.IPv6Loopback}]:{Port}/10.114.114.114:{ServerPort}"
|
||||
Arguments += $" --port-forward tcp://{IPAddress.Loopback}:{Port}/10.114.114.114:{ServerPort}"
|
||||
Arguments += $" --port-forward udp://{IPAddress.Loopback}:{Port}/10.114.114.114:{ServerPort}"
|
||||
ClientAddress = $"localhost:{ClientPort}"
|
||||
Arguments += $" --port-forward tcp://[{IPAddress.IPv6Loopback}]:{ClientPort}/10.114.114.114:{ServerPort}"
|
||||
Arguments += $" --port-forward udp://[{IPAddress.IPv6Loopback}]:{ClientPort}/10.114.114.114:{ServerPort}"
|
||||
Arguments += $" --port-forward tcp://{IPAddress.Loopback}:{ClientPort}/10.114.114.114:{ServerPort}"
|
||||
Arguments += $" --port-forward udp://{IPAddress.Loopback}:{ClientPort}/10.114.114.114:{ServerPort}"
|
||||
End If
|
||||
For Each Peer As String In ServerConfig("Link")("Peers")
|
||||
For Each Peer As String In Peers
|
||||
Arguments += $" -p=""{Peer}"""
|
||||
Next
|
||||
If Not Setup.Get("LinkShareMode") Then Arguments += " --private-mode true"
|
||||
Arguments += " --private-mode true" '老好人模式现在莫得用:If Not Setup.Get("LinkShareMode") Then
|
||||
'启动进程
|
||||
ProcessStart(Arguments)
|
||||
Task.Progress = 0.15
|
||||
@@ -482,9 +533,9 @@
|
||||
'超时判定
|
||||
If LastProgress <> Task.Progress Then
|
||||
TimeoutCounter = 0
|
||||
ElseIf TimeoutCounter < 20 Then
|
||||
ElseIf TimeoutCounter < 30 * 2 Then
|
||||
TimeoutCounter += 1
|
||||
Else '进度停滞超过 10s
|
||||
Else '进度停滞超过 30s
|
||||
Select Case PeerCount
|
||||
Case -1 'CLI 无返回
|
||||
Panic("无法启动联机模块", "近期日志:" & vbCrLf & LogHistory.Join(vbCrLf))
|
||||
@@ -497,6 +548,49 @@
|
||||
Loop Until Task.IsAborted
|
||||
If Task.IsAborted Then Throw New ThreadInterruptedException
|
||||
End Sub
|
||||
''' <summary>
|
||||
''' 从在线配置和 API 获取节点列表。
|
||||
''' </summary>
|
||||
Private Function GetOnlinePeers() As List(Of String)
|
||||
Dim Peers As List(Of String) = ServerConfig("Link")("Peers").Select(Function(p) p.ToString).ToList()
|
||||
Try
|
||||
'从 API 获取节点列表
|
||||
Dim BlackList As List(Of String) = ServerConfig("Link")("PeersBlackList").Select(Function(p) p.ToString).ToList() '黑名单
|
||||
Dim CentralNodes As New List(Of String)
|
||||
Dim RandomNodes As New List(Of Tuple(Of String, Double))
|
||||
For Each Node As JObject In CType(GetJson(NetRequestByClientRetry("https://uptime.easytier.cn/api/nodes?page=1&per_page=200")), JObject)("data")("items")
|
||||
'状态检查
|
||||
If Node("protocol").ToString <> "tcp" Then Continue For
|
||||
If Node("current_health_status").ToString <> "healthy" Then Continue For
|
||||
If Not Node("is_active").ToObject(Of Boolean) Then Continue For
|
||||
If Not Node("is_approved").ToObject(Of Boolean) Then Continue For
|
||||
Dim Tags = Node("tags").Select(Function(t) t.ToString).ToList
|
||||
If Not Tags.Contains("国内") Then Continue For
|
||||
If Tags.Contains("即将下线") Then Continue For
|
||||
Dim Address As String = Node("address").ToString
|
||||
If BlackList.Contains(Address) Then Continue For
|
||||
'添加节点
|
||||
If Tags.Contains("MC") Then
|
||||
CentralNodes.Add(Address)
|
||||
Else
|
||||
If Not Node("allow_relay").ToObject(Of Boolean) Then Continue For
|
||||
If Node("usage_percentage").ToObject(Of Double) = 0 Then Continue For '或许节点有问题才导致是 0 负载
|
||||
RandomNodes.Add(New Tuple(Of String, Double)(
|
||||
Address,
|
||||
Node("usage_percentage").ToObject(Of Double) * (103 - Node("health_percentage_24h").ToObject(Of Double)))) '负载,越低越好
|
||||
End If
|
||||
Next
|
||||
RandomNodes = RandomNodes.OrderBy(Function(n) n.Item2).ToList()
|
||||
Log($"[Link] 获取到 {CentralNodes.Count} 个中心节点,{RandomNodes.Count} 个随机节点")
|
||||
'选择节点
|
||||
Dim RandomCount As Integer = ServerConfig("Link")("RandomPeer").ToObject(Of Integer)
|
||||
If RandomNodes.Count < RandomCount Then Throw New Exception($"可用的随机节点数量不足,需要 {RandomCount} 个,实际 {RandomNodes.Count} 个")
|
||||
Peers = CentralNodes.Concat(RandomNodes.Take(RandomCount).Select(Function(n) n.Item1)).ToList()
|
||||
Catch ex As Exception
|
||||
Log(ex, "获取节点列表失败,联机质量可能受到影响", LogLevel.Hint)
|
||||
End Try
|
||||
Return Peers
|
||||
End Function
|
||||
|
||||
#End Region
|
||||
|
||||
@@ -544,26 +638,14 @@
|
||||
''' 出现意外错误,给出错误信息并结束联机。
|
||||
''' </summary>
|
||||
Private Sub Panic(Brief As String, Detail As String)
|
||||
If State = States.Loading Then
|
||||
If LinkState = LinkStates.Loading Then
|
||||
FailReason = Brief
|
||||
LinkLoader.Failed(New Exception(Detail))
|
||||
Else
|
||||
MyMsgBox(Detail, "联机出错:" & Brief, IsWarn:=True)
|
||||
ChangeState(States.Waiting)
|
||||
ChangeState(LinkStates.Waiting)
|
||||
Telemetry("联机失败", "Exception", FilterUserName(Brief & ":" & Detail, "*"))
|
||||
End If
|
||||
'收集到的 CLI 错误:
|
||||
|
||||
'Error: Timeout : deadline has elapsed
|
||||
'Caused by
|
||||
' deadline has elapsed
|
||||
|
||||
'Error: failed to get peer manager client
|
||||
'Caused by
|
||||
' 0: rust tun error failed to connect to server: Url {scheme: "tcp", cannot_be_a_base: false, username: "", password: None, host: Some(Domain("127.0.0.1")), port: Some(15888), path: "", query: None, fragment: None }
|
||||
' 1: failed to connect to server: Url {scheme: "tcp", cannot_be_a_base: false, username: "", password: None, host: Some(Domain("127.0.0.1")), port: Some(15888), path: "", query: None, fragment: None }
|
||||
' 2: IO error
|
||||
' 3: 由于目标计算机积极拒绝, 无法连接。 (os error 10061)
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
@@ -656,32 +738,33 @@
|
||||
''' 名称。
|
||||
''' </summary>
|
||||
Public ReadOnly Name As String
|
||||
''' <summary>
|
||||
''' 连接方式。
|
||||
''' </summary>
|
||||
Public ReadOnly Cost As String
|
||||
|
||||
''' <summary>
|
||||
''' 从 CLI 给出的信息行分析对应的数据。
|
||||
''' 从 CLI 给出的信息分析对应的数据。
|
||||
''' </summary>
|
||||
Public Sub New(Info As String)
|
||||
'具体每个部分的索引见 GetPeerData()
|
||||
Dim Parts = Info.Split("|").Select(Function(s) If(s.All(Function(c) c = " "c), s, s.Trim)).Where(Function(s) s <> "").ToList
|
||||
If Parts.Count <> 10 Then Throw New Exception($"信息列数有误")
|
||||
'延迟
|
||||
Ping = If(Parts(3) = "-", 0, Parts(3))
|
||||
Public Sub New(Info As JObject)
|
||||
'类别
|
||||
Dim PeerName = Parts(1)
|
||||
Dim PeerName = Info("hostname").ToString
|
||||
If PeerName = HostName Then
|
||||
Type = Types.Self
|
||||
ElseIf PeerName.StartsWithF("Client") Then
|
||||
Type = Types.Client
|
||||
ElseIf Parts(0).StartsWithF("10.114.114.114") Then '只允许这个 IP 作为房主,避免网络被多个房主搞炸的情况
|
||||
ElseIf Info("ipv4") = "10.114.114.114" Then '只允许这个 IP 作为房主,避免网络被多个房主搞炸的情况
|
||||
Type = Types.Server
|
||||
Else
|
||||
Type = Types.Misc
|
||||
End If
|
||||
'主机名
|
||||
'基础信息
|
||||
Ping = If(Info("lat_ms").ToString = "-", 0, Info("lat_ms").ToString)
|
||||
Name = PeerName
|
||||
Cost = Info("cost")
|
||||
End Sub
|
||||
Public Overrides Function ToString() As String
|
||||
Return $"{Type} - {Name} - Ping {Ping:0.0}ms"
|
||||
Return $"{Type} - {Name} - Ping {Ping:0.0}ms [{Cost}]"
|
||||
End Function
|
||||
End Class
|
||||
|
||||
@@ -705,12 +788,12 @@
|
||||
'| 10.114.114.114/24 | Server-J6P6IW | p2p | 5.63 | 0.0% | 1.65 kB | 1.64 kB | udp | PortRestricted | 2.4.5-4c4d172e |
|
||||
'| 10.114.114.114/24 | Server-J6PHIW (连接中) | relay(2) | 1000.00 | 0.0% | 0 B | 0 B | | PortRestricted | 2.4.5-4c4d172e |
|
||||
Try
|
||||
Dim CliResult = StartProcessAndGetOutput(PathEasyTier & "联机模块 CLI.exe", "peer", 2000, Encoding:=Encoding.UTF8, PrintLog:=False)
|
||||
Dim CliResult = StartProcessAndGetOutput(PathEasyTier & "联机模块 CLI.exe", $"-o json -p 127.0.0.1:{RPCPort} peer", 2000, Encoding:=Encoding.UTF8, PrintLog:=False)
|
||||
'解析
|
||||
If Not CliResult.Contains("lat(ms)") Then Throw New Exception("CLI 调用失败:" & vbCrLf & CliResult)
|
||||
If GetUuid() Mod If(ModeDebug, 4, 30) = 0 Then Log("[EasyTier] CLI 输出抽样:" & vbCrLf & CliResult)
|
||||
If Not CliResult.Contains("lat_ms") Then Throw New Exception("CLI 调用失败:" & vbCrLf & CliResult)
|
||||
If GetUuid() Mod If(ModeDebug, 23, 103) = 0 Then Log("[EasyTier] CLI 输出抽样:" & vbCrLf & CliResult)
|
||||
Dim NewPeers As New List(Of Peer)
|
||||
For Each Line In CliResult.Split(vbCrLf.ToCharArray, StringSplitOptions.RemoveEmptyEntries).Skip(2)
|
||||
For Each Line As JObject In CType(GetJson(CliResult), JArray).Skip(1)
|
||||
Try
|
||||
Dim Peer = New Peer(Line)
|
||||
If Peer.Type = Peer.Types.Self Then Continue For '自己
|
||||
@@ -724,7 +807,7 @@
|
||||
FailCount = 0
|
||||
Catch ex As Exception
|
||||
Log(ex, "获取节点信息失败")
|
||||
If State = States.Finished Then
|
||||
If LinkState = LinkStates.Finished Then
|
||||
FailCount += 1
|
||||
If FailCount >= 4 Then Panic("获取节点信息失败", ex.Message)
|
||||
End If
|
||||
@@ -741,18 +824,26 @@
|
||||
''' 0 代表尚不可用。
|
||||
''' </summary>
|
||||
Private Function GetPeerPing() As Double
|
||||
If Peers Is Nothing Then Return 0
|
||||
Dim PingTargets As IEnumerable(Of Peer)
|
||||
Dim Peer = GetTargetPeer()
|
||||
If Peer Is Nothing Then Return 0
|
||||
Return Peer.Ping
|
||||
End Function
|
||||
''' <summary>
|
||||
''' 服务端会返回所有节点中 Ping 的那一个,客户端会返回服务端。
|
||||
''' 若没有则为 Nothing。
|
||||
''' </summary>
|
||||
Private Function GetTargetPeer() As Peer
|
||||
If Peers Is Nothing Then Return Nothing
|
||||
Dim Targets As IEnumerable(Of Peer)
|
||||
If IsServerSide Then
|
||||
PingTargets = Peers
|
||||
Targets = Peers.Where(Function(p) p.Ping > 0)
|
||||
Else
|
||||
PingTargets = Peers.Where(Function(p) p.Type = Peer.Types.Server)
|
||||
End If
|
||||
If Not PingTargets.Any Then
|
||||
Return 0
|
||||
Else
|
||||
Return Math.Max(1, PingTargets.Select(Function(p) p.Ping).Min())
|
||||
Targets = Peers.Where(Function(p) p.Type = Peer.Types.Server AndAlso p.Ping > 0)
|
||||
End If
|
||||
If Not Targets.Any Then Return Nothing
|
||||
'返回 Ping 大于 0 且最低的那个
|
||||
Dim MinPing = Targets.Min(Function(p) p.Ping)
|
||||
Return Targets.First(Function(p) p.Ping = MinPing)
|
||||
End Function
|
||||
|
||||
''' <summary>
|
||||
@@ -768,7 +859,7 @@
|
||||
|
||||
#End Region
|
||||
|
||||
#Region "定时状态更新"
|
||||
#Region "定时任务"
|
||||
|
||||
'启动
|
||||
Private IsTimerStarted As Boolean = False
|
||||
@@ -781,13 +872,13 @@
|
||||
Try
|
||||
Thread.Sleep(200)
|
||||
Counter += 200
|
||||
'每 4 秒执行一次
|
||||
If Counter >= 4000 Then
|
||||
'每秒执行一次
|
||||
If Counter >= 1000 Then
|
||||
Counter = 0
|
||||
Update()
|
||||
End If
|
||||
'每 200ms 更新进度条
|
||||
If State = States.Loading Then RunInUi(AddressOf UpdateProgressBar)
|
||||
If LinkState = LinkStates.Loading Then RunInUi(AddressOf UpdateProgressBar)
|
||||
Catch ex As Exception
|
||||
Log(ex, "联机模块主时钟出错", LogLevel.Feedback)
|
||||
Thread.Sleep(10000)
|
||||
@@ -796,9 +887,10 @@
|
||||
End Sub, "Link Timer")
|
||||
End Sub
|
||||
|
||||
'每 4 秒或进入页面时更新一次信息
|
||||
'每秒或进入页面时触发
|
||||
Private BroadcastSocket As New Socket(SocketType.Dgram, ProtocolType.Udp)
|
||||
Private Sub Update() Handles Me.Loaded
|
||||
If State <> States.Finished Then Return
|
||||
If LinkState <> LinkStates.Finished Then Return
|
||||
'重新获取信息
|
||||
SyncLock RefreshPeerLoader.LockState
|
||||
If RefreshPeerLoader.State <> LoadState.Loading Then RefreshPeerLoader.Start(IsForceRestart:=True)
|
||||
@@ -808,13 +900,25 @@
|
||||
RunInUi(
|
||||
Sub()
|
||||
Dim Ping As Double = GetPeerPing()
|
||||
Dim RelayLayer As Integer = If(GetTargetPeer().Cost.RegexSeek("(?<=relay\()\d+") Is Nothing,
|
||||
0, Val(GetTargetPeer().Cost.RegexSeek("(?<=relay\()\d+")) - 1)
|
||||
'更新 Ping 显示
|
||||
If Ping Mod 500 = 0 OrElse $"{Ping:0.0}" = "1.0" OrElse FailCount > 0 Then
|
||||
LabFinishPing.Text = "连接中"
|
||||
AniStop("Link Logo Rotation")
|
||||
Else
|
||||
LabFinishPing.Text = If(Ping >= 10, $"{Ping:0} ms", $"{Ping:0.0} ms")
|
||||
LabFinishPing.Text =
|
||||
If(RelayLayer > 0, If(RelayLayer > 1, $"中继 {RelayLayer} · ", "中继 · "), "") & '使用中继连接时显示 “中继” 前缀
|
||||
If(Ping >= 10, $"{Ping:0} ms", $"{Ping:0.0} ms")
|
||||
AniStart(AaRotateTransform(ImgFinishLogo, 500, 5000), "Link Logo Rotation") 'Logo 旋转动画
|
||||
End If
|
||||
'更新 Ping 的 Tooltip 显示
|
||||
Dim Tooltip As String = If(IsServerSide, "网络延迟", "与房主的延迟")
|
||||
If RelayLayer Then Tooltip &= If(IsServerSide,
|
||||
$"(你的网络环境较差,正经过 {RelayLayer} 层中继,可能会有点卡)",
|
||||
$"(你或者房主的网络环境较差,正经过 {RelayLayer} 层中继,可能会有点卡)")
|
||||
BtnFinishPing.ToolTip = Tooltip
|
||||
'更新人数显示
|
||||
LabFinishPlayer.Text = PeopleCount & " 人"
|
||||
End Sub)
|
||||
End If
|
||||
@@ -827,9 +931,20 @@
|
||||
End If
|
||||
If Not IsServerSide AndAlso Not Peers.Any(Function(p) p.Type = Peer.Types.Server) Then
|
||||
MyMsgBox("房主已离开房间!", "联机结束")
|
||||
ChangeState(States.Waiting)
|
||||
ChangeState(LinkStates.Waiting)
|
||||
Return
|
||||
End If
|
||||
'广播联机房间端口
|
||||
If Not IsServerSide Then
|
||||
Try
|
||||
BroadcastSocket.SendTo(
|
||||
Encoding.UTF8.GetBytes($"[MOTD]PCL 联机房间[/MOTD][AD]{ClientPort}[/AD]"),
|
||||
SocketFlags.None,
|
||||
New IPEndPoint(IPAddress.Loopback, 4445))
|
||||
Catch ex As Exception
|
||||
Log(ex, "广播联机房间端口失败")
|
||||
End Try
|
||||
End If
|
||||
End Sub
|
||||
''' <summary>
|
||||
''' 检查联机模块是否崩溃。
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
<RowDefinition Height="45" />
|
||||
<RowDefinition Height="45" />
|
||||
<RowDefinition Height="45" />
|
||||
<RowDefinition Height="45" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="40" />
|
||||
@@ -58,11 +59,13 @@
|
||||
<local:MyButton Text="打开百科" Grid.Row="1" Grid.Column="2" Height="35" local:CustomEventService.EventType="打开网页" local:CustomEventService.EventData="https://www.mcmod.cn" />
|
||||
<local:MyListItem Title="z0z0r4" Margin="-5,0,0,0" IsHitTestVisible="False" Grid.ColumnSpan="2" Info="提供了 MCIM 社区资源镜像源和帮助库图床!" Grid.Row="2" Grid.Column="1" />
|
||||
<local:MyButton Text="MCIM 主页" Grid.Row="2" Grid.Column="2" Height="35" local:CustomEventService.EventType="打开网页" local:CustomEventService.EventData="https://github.com/mcmod-info-mirror" />
|
||||
<local:MyListItem Title="00ll00" Margin="-5,0,0,0" IsHitTestVisible="False" Grid.ColumnSpan="2" Info="提供了 Java Launch Wrapper 和一些重要服务支持!" Grid.Row="3" Grid.Column="1" />
|
||||
<local:MyListItem Title="Patrick" Margin="-5,0,0,0" IsHitTestVisible="False" Grid.ColumnSpan="2" Info="设计并制作了 PCL 图标,让我从做图标的水深火热中得到了解脱……" Grid.Row="4" Grid.Column="1" />
|
||||
<local:MyListItem Title="Hao_Tian" Margin="-5,0,0,0" IsHitTestVisible="False" Grid.ColumnSpan="2" Info="在内测中找出了一大堆没人想得到的诡异 Bug,有非同寻常的 Bug 体质" Grid.Row="5" Grid.Column="1" />
|
||||
<local:MyListItem Title="Minecraft 中文论坛" Margin="-5,0,15,0" IsHitTestVisible="False" Info="虽然已经关站了,但感谢此前提供了 MCBBS 镜像源……" Grid.Row="6" Grid.Column="1" />
|
||||
<local:MyListItem Title="PCL 内群的各位" Margin="-5,0,0,0" IsHitTestVisible="False" Grid.ColumnSpan="2" Info="感谢内群的沙雕网友们这么久以来对我和 PCL 的支持与鼓励!" Grid.Row="7" Grid.Column="1" />
|
||||
<local:MyListItem Title="EasyTier" Margin="-5,0,0,0" IsHitTestVisible="False" Grid.ColumnSpan="2" Info="提供了联机模块!" Grid.Row="3" Grid.Column="1" />
|
||||
<local:MyButton Text="GitHub 页面" Grid.Row="3" Grid.Column="2" Height="35" local:CustomEventService.EventType="打开网页" local:CustomEventService.EventData="https://github.com/EasyTier/EasyTier" />
|
||||
<local:MyListItem Title="00ll00" Margin="-5,0,0,0" IsHitTestVisible="False" Grid.ColumnSpan="2" Info="提供了 Java Launch Wrapper 和一些重要服务支持!" Grid.Row="4" Grid.Column="1" />
|
||||
<local:MyListItem Title="Patrick" Margin="-5,0,0,0" IsHitTestVisible="False" Grid.ColumnSpan="2" Info="设计并制作了 PCL 图标,让我从做图标的水深火热中得到了解脱……" Grid.Row="5" Grid.Column="1" />
|
||||
<local:MyListItem Title="Hao_Tian" Margin="-5,0,0,0" IsHitTestVisible="False" Grid.ColumnSpan="2" Info="在内测中找出了一大堆没人想得到的诡异 Bug,有非同寻常的 Bug 体质" Grid.Row="6" Grid.Column="1" />
|
||||
<local:MyListItem Title="Minecraft 中文论坛" Margin="-5,0,15,0" IsHitTestVisible="False" Info="虽然已经关站了,但感谢此前提供了 MCBBS 镜像源……" Grid.Row="7" Grid.Column="1" />
|
||||
<local:MyListItem Title="PCL 内群的各位" Margin="-5,0,0,0" IsHitTestVisible="False" Grid.ColumnSpan="2" Info="感谢内群的沙雕网友们这么久以来对我和 PCL 的支持与鼓励!" Grid.Row="8" Grid.Column="1" />
|
||||
<Image Source="/Plain Craft Launcher 2;component/Images/Heads/bangbang93.png" Grid.Row="0" Margin="3">
|
||||
<Image.Clip>
|
||||
<EllipseGeometry Center="17 17" RadiusX="17" RadiusY="17" />
|
||||
@@ -78,27 +81,32 @@
|
||||
<EllipseGeometry Center="17 17" RadiusX="17" RadiusY="17" />
|
||||
</Image.Clip>
|
||||
</Image>
|
||||
<Image Source="/Plain Craft Launcher 2;component/Images/Heads/00ll00.png" Grid.Row="3" Margin="3">
|
||||
<Image Source="/Plain Craft Launcher 2;component/Images/Heads/EasyTier.png" Grid.Row="3" Margin="3">
|
||||
<Image.Clip>
|
||||
<EllipseGeometry Center="17 17" RadiusX="17" RadiusY="17" />
|
||||
</Image.Clip>
|
||||
</Image>
|
||||
<Image Source="/Plain Craft Launcher 2;component/Images/Heads/Patrick.png" Grid.Row="4" Margin="3">
|
||||
<Image Source="/Plain Craft Launcher 2;component/Images/Heads/00ll00.png" Grid.Row="4" Margin="3">
|
||||
<Image.Clip>
|
||||
<EllipseGeometry Center="17 17" RadiusX="17" RadiusY="17" />
|
||||
</Image.Clip>
|
||||
</Image>
|
||||
<Image Source="/Plain Craft Launcher 2;component/Images/Heads/Hao_Tian.jpg" Grid.Row="5" Margin="3">
|
||||
<Image Source="/Plain Craft Launcher 2;component/Images/Heads/Patrick.png" Grid.Row="5" Margin="3">
|
||||
<Image.Clip>
|
||||
<EllipseGeometry Center="17 17" RadiusX="17" RadiusY="17" />
|
||||
</Image.Clip>
|
||||
</Image>
|
||||
<Image Source="/Plain Craft Launcher 2;component/Images/Heads/MCBBS.png" Grid.Row="6" Margin="3">
|
||||
<Image Source="/Plain Craft Launcher 2;component/Images/Heads/Hao_Tian.jpg" Grid.Row="6" Margin="3">
|
||||
<Image.Clip>
|
||||
<EllipseGeometry Center="17 17" RadiusX="17" RadiusY="17" />
|
||||
</Image.Clip>
|
||||
</Image>
|
||||
<Image Source="/Plain Craft Launcher 2;component/Images/Heads/PCL2.png" Grid.Row="7" Margin="3">
|
||||
<Image Source="/Plain Craft Launcher 2;component/Images/Heads/MCBBS.png" Grid.Row="7" Margin="3">
|
||||
<Image.Clip>
|
||||
<EllipseGeometry Center="17 17" RadiusX="17" RadiusY="17" />
|
||||
</Image.Clip>
|
||||
</Image>
|
||||
<Image Source="/Plain Craft Launcher 2;component/Images/Heads/PCL2.png" Grid.Row="8" Margin="3">
|
||||
<Image.Clip>
|
||||
<EllipseGeometry Center="17 17" RadiusX="17" RadiusY="17" />
|
||||
</Image.Clip>
|
||||
@@ -107,217 +115,566 @@
|
||||
</local:MyCard>
|
||||
<local:MyCard Margin="0,0,0,15" Title="赞助者">
|
||||
<StackPanel Margin="25,40,10,20">
|
||||
<TextBlock HorizontalAlignment="Left" Text="以下是 2025 年 9 月的高级赞助者们!感谢各位对 PCL 和伟大的咕咕咕事业的支持!" Margin="0,0,25,5.5" TextTrimming="None" TextWrapping="WrapWithOverflow" />
|
||||
<WrapPanel Margin="0,0,0,10">
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="lecoe" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="QIUQI" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Aquadtr" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="stb" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="mco" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="楠" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="砂糖蜂蜜锡红茶" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="小宸老弟" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Le Play" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="烨神" />
|
||||
<TextBlock Width="240" Margin="0,1.5" Text="Kamazi_Yuka5201" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="滚动的拉布拉多" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="王牟" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Lazarus" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="幻觉" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="凌天" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="lIIIllIIllIIl" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Zsol" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="榴莲" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Night Voyager" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="JOHNJIANG" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="柒月" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="不温柔先森" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Freewind" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="纯萧子" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="扇" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Amturester" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="maigm" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="JO23" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="JCNB" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="星尘" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="姜桐桐233" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="AkaneRyoba" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="南山必胜客" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="57" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="咸菜萝卜煲" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="shawnlong" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="DDNGSZX1" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="KaguraZaka" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="谶纛" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="666" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="betwangzai" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="卑微小林" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="fjvg" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="TH-x" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Q" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="清鸢" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="P·咕·D·咕咕·F" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="顾木" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="LAZY" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="沙发上的沙发" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="有熊子来" />
|
||||
<TextBlock Width="240" Margin="0,1.5" Text="月下誓约,予爱以心" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="超级白给马" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="fwlqpalzmd" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="安执妄dying" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="黄开心" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="于是" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="荆槐序" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="三千游魂" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="^ ^" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="zz" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="爱炫鱼的猫" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="玄月" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="BRfake" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Lucien_Liu" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="煎bingo子" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="对方正在输入..." />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="hakureireimu" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="wwxa2019" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="TAIGA" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="墨玉" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Jane" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="雪下丨残影" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="未命名3742" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="烧冻鸡翅" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="嘟嘟可" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="利姆露" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="ATH9" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="教主" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="落雪有声" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="苏子霄" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="一握砂" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="马春明" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="远力高" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="玉米片" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="sun次方" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="憨憨橙子" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="染年" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="准江月" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="蓝叶" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="ELUCIDATE" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="兔饼干哈哈" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Styx誓约" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="V" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="月芸柔" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="灯火鬼魂" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="A" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="项刀关志" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="剑鱼776" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="叶明心" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Ashlxy" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="小时" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="fisher426" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="老罗" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="百忧解" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="杨三海" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="锂化氩" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="饺子川" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="流年遥想" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="基围虾" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="山有木兮325" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="37号村民" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="白承宣" />
|
||||
<TextBlock Width="240" Margin="0,1.5" Text="某蓝毛借钱不还的贝斯手" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="白狼" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="工蜂" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="封不觉" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="南樵鱼子" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="寂-御神幻狐" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="好" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="NeonSoda" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="UNICORN" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="红石beaker" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="EliasLSK" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="思考人生" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="L" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="起床了" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="服群" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="云符爱睡觉" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="幽幽秋" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="FAMS" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="会变身的栖仔" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="baka王" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="深海带鱼" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="四戒梨子" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="无限" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Xc_AcE" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="@6#" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="molFish" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="雪见" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="AAALLLAAANNN" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="华氏451" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="纸不好" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="博衍" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="志摩凛" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="八云蓝LIN" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="LittleBlue" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="老梦" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="动漫男主" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Red_橙子" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Junmucheng" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="无印" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="窗前露" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="1111111" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="什雨" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="七日 SEVENDAYS" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Gǔdù" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="白吃白喝" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="路明非" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="子不语" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="王璟" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="阿星" />
|
||||
<TextBlock Width="240" Margin="0,1.5" Text="小狗很担心你有没有好好喝水" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="hjhmeibao" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="网络白字话事人" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="想要点好运" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Timmy1950" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="栩" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="玛卡巴卡" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="楞可" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="顶级牛板筋收藏家" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="HansOffice" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="466某某某" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="zztzzy" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="辉光离子管" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="联开开" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="XIAOSHUAI" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="KMYLS" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="聽音" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="oPzPo" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="dream" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="123" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Zik yeung" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="wihz" />
|
||||
<TextBlock HorizontalAlignment="Left" Text="以下是 2025 年 10 月的高级赞助者们!感谢各位对 PCL 和伟大的咕咕咕事业的支持!" Margin="0,0,25,5.5" TextTrimming="None" TextWrapping="WrapWithOverflow" />
|
||||
<WrapPanel Margin="0,0,0,10">
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="阿瓦达" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="不若" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Albus" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="牛马" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="溯" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="他" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="寂静之空" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="断约" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="跑不快的啊走" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="三十三" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="魂夜" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="apoooooo" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="落户" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="落虞" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="漓九云" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Ding" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="yi9999" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="muo" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="科骏达" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="嫉妒" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="阿辉" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="L." />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="??????????)?" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="温雅" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="MingChuYa" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="S????? . ?" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="吴傻傻" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="会忘记九月嘛" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="咸鱼猫猫" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="MCMIAO" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="熠惊" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="emm" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="十月." />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Mark_ShaoYang" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="左" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Crocoldilopolis" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="!" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="风息" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="by烟火" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="优纪" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="人世间狡诈邪恶" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="廾匸" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="称之为翀" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="山海." />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="巫元dry" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="墨羽" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="暮秋知岁寒" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="司南" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="樱井弥生" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="墨枫逸尘" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="SmileRm" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="光" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="SquareBlock" />
|
||||
<TextBlock Width="240" Margin="0,1.5" Text="失去梦想的GGbond" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Kuni" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Herr" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="周清风" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="kirito" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Tt" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="柳絮随风行" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="trav" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Danielisdoge" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="王隔壁" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="怕是卧龙先生" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="懒人碎觉" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="神里绫华的狗" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="翁" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="是是是不是" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="水波不兴" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="zero" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="许愿流星雨" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="YiHuwuyue" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="CenturionSC" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="闲鱼下饭" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="残叶" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="浪浪天" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="西行寺叶叶子" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="覃丘丘" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Caryee" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="蓝涯" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="柒拾叁" />
|
||||
<TextBlock Width="240" Margin="0,1.5" Text="宇宙超级无敌霹雳小小鹤" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="尝尝彩虹" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="鰞鮾簋麳癜譅駼" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="薄荷巧克力蛋糕" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="CT" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="酋长想去欧洲" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="MOYO_" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="四季的猫." />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Jcey" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Nefelibata." />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="领域星" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="cnp" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="扔完炸药掏蜂鸟" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="新桑" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="北凉影" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="wax" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="白葉白不白" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="沐晨" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="。" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="哎呀呀" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="龙仔" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="六百六十六" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="剑瘗千秋" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="亻三人亍" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="人" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Freezinker" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="鱼丸" />
|
||||
<TextBlock Width="240" Margin="0,1.5" Text="NORMAL_MAN36" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="阿希佩尔" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="kikimmo" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="镜像折叠" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="留不住的刹那" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="." />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="朱小楠" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="鹤暝柘" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="莫离" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="江上tipsy" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="句号" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Master" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="边打铜锣边鬼叫" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="随便就好" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="赢于" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="夏目心" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="NOBODY112" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="黑糖" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="李" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="皮皮狗我们走" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="卜部美琴" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="商枝" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="嫑喊我" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="流星与朝阳" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="呀呼" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="EasyOrange" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="MATH算珠" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="暮光Ts" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="洛秋" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="瑾" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Tenno" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="酒奇" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="笑叹" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="今晚不熬夜" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="四月是你的谎言" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="方方" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Rei" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="lxh123123123" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="瓷" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="yyc我稀饭你" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="似水请客" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="冬季の信物" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Y先生" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="万兔森罗" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="携酒迎春风" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="消逝" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="昭苏" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="卡卡卡卡啊" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="鱿倪克" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="彺钰" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="尘飞雾散芳华慢" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="言欢" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="ZJD" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="别吵我在法考" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="WLan" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="457ssu" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="liu" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="PickStars" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="liu" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="贤" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="玄月" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="dailiweier" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="korfr" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="绕开这些天" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="田洛" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="天天向上" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="XINA-33" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Temmie" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="。" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="凌州" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="痴心夏天的风" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="予" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="笑死啦啦啦" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="旧曾谙" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="LightingPriest" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="sxdxm" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="GYWTT" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="煞神小郑" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="花" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="三金知日" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="sul" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="静心涵养" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="均就均吧" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Tuski_Velpro" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="望江寒" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="我该要E了" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="lxx" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="MX丶" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="乘风9527" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="修狗不是狗" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="奇怪的深渊增加了" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="森森1025" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="愚墨玄" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="饼子" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="王" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="清水优" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="熬夜的猫条?ω?" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="南瓜" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="不觉" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="晓町" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="王八吃绿豆" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="她面有愠色" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="shengli" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="哈基鸭" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="苏言`" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="cc的毅" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="亡利普贝当" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="小猪" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="莱莱" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="吾等一个人" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="一只呆呆." />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="李某顺" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="LBDLXLZT" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="二鸽咕咕咕" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="千了一水寒" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="大白" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="单林熙大王" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="qiji_SaMa" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="是我小白鸭~" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Yylinmu" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="zzz" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="遨菡" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="欧欧欧" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Freezing" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="潜汐" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="waaiu" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="小劫" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Lemon0904" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="呆头鹅" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="无所事事的达达" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="梦鱼" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="JiuJiu" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="阋yee" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="qsiwsi" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="你从未离去" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="独觞&自乐" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="定远" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="ZYX" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="玦" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="浬江河" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="ZERO" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="猫猫qwq" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="shark" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="宝箱怪" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="您的名字" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="零之执事" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="TTT" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="赵云撤" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="岩壑之崩" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Fox Hound" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Alon.E." />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="湺" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="陳拾憶" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="kwzddz" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="莲苂" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="少帅" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="," />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="传奇群野猫" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="挽枫" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Q7" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="阿卡找你玩" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="月月" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="POCKY" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="橙子饱宝" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="空城风雨" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Carlmu" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="日雨云曇" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Caerphilly" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Andy Wang" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Kepler" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="小大人" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="波风菇" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="孤丶渊" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="白沙" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="夜Ylz" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="不知道唉kk" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="墨染星云间" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="-Trespassin." />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="白天小生" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="霍柴玉铉" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="雨" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="慕可OvO" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="上杉绘梨衣" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="观天台(炀章)" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="两仪阴阳子" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="MOMOHAN" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="希瓦大陆_Hitable" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="比奇堡小佩奇" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="龙井茶叶" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="星辰" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="黑云画师" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="烤鱼" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="okufir" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="莫白" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="周星星" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="好无聊:-" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="轩辕朔" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Kakiko" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="摩卡茉莉" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="长忆安思" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Solomon" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="博麗靈夢" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="CMMing" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="择日再起床" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="逆黑C" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="星恒" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="销" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="XingLing2333" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Lesonmol" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="a" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="格拉索夫司机" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="LDG" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="爱玩游戏的路人" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="." />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="天灵地黄补肝丸子" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="阿撒托斯" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="離倌" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="飞向烛的蛾" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="JadePolarise" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="不爱吃饭的Hog" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="莉莉大饺子" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="yu" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="徐" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="欢乐颂" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="榴莲千层" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="LordyTheQDuck" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="衔纸人" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="粉色妖精小姐?" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="kongfan" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="白杨之下" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Eme.b" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="熊猫" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="颜5236" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="KK" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="青色小鲨鱼" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="阿惹" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="解析模式" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="秋夜纱" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Escape Star" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="LSEN志恒" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Azqs7109" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="艾雅法拉的狗" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="????????" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="LOWN" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="cuu7878" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="RemixQQ" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="CANYUEX" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="元路" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="承时之势" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="补丁" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="心枫浔尘" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="wujijuan" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="晨語古韵" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="流萤的星光" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="缄默" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="qq1967131327" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="sence4910" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="HilkK" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="ZThengao" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="玖镜Sama" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Glx?" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="派大星" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="河边鸺葵" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="SoftSui" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="徐家胤" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="至夏" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="溯洄SWZM" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="海睿洋" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="阿巴阿巴" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="灰合夏" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="XLMX" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="雲墨丶雪风" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="每天都是上上签" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Bright" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="UFO君" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="z001" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="琥色" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="MaxQi" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="姜淼淼" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Chenluoxcly" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="南宫墨白" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="白晓" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="ChengYhy" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="陆壹" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Agoni" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="可乐鸡翅" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="木诺于" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="无" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="imsunxinhao" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="在我嘴里种水稻" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="浮世三千" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="blue sky" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="wujiayi" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="XIAOXI" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="景天鸽" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="24598" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="世谈茶楼" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="jwl" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Saki" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="董铮" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="小羽" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="张浩轩" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="neltharion" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="小于" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="太乙" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="玉卿程" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="lalailoveyou" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="EternalSinDusk" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="风继续吹" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="一只落云呦" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="叶沚芃" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="花非花雾非雾" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="BIOKL" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="你先别急" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="MuMAA" />
|
||||
<TextBlock Width="240" Margin="0,1.5" Text="擻齺獼豳鏚嬼嬭鼬乸鑽麣覊" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="风眠" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="hgmzyyy" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Danc1n9" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="doodo" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="FrostNova" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="mc" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="柒" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="迷途" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="XU." />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="八云源" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="qbn5" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="许诺霓虹" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="X-ran" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="微风" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="阿米诺斯" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="玄纪2006" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="666" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="恋某人-柏然" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="The_Crispy" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="电脑and病毒哥" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="W" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="jys" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="lonelife" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="离断幽" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="对方正在输入..." />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="带我去跳海" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Jogycjh" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="F" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="鸽六" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="亦明" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="苏瑜年" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="单身使我快乐" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="井狗的慈父" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="YanTY" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="勿念fmj" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="道瑶" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="JerryGo" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="HAJ_IMI" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="林星是星" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="扶她大法好" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="心如霜雪" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Отомстить" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="云巴" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="?ιδη?、" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="候鸟" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="望格" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="锅巴" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="月野" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="烛龙" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Rock god-Morax" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="百忧解" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="林琴科" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="北雁蘿蔔" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="墨雪竹" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="雾里" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="鋆星" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="HPLY" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="淡然a" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="白玉京" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Ykir" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="三千" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="溪峡" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="avenqyx" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="xxz" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="tytd" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="yezhi" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="落子不悔" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="chenge886" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="秋雨淋枫落" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="斑斓根" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="空城微凉" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="晨099" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Ado" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="过硫酸钠" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="大禹" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="玖殇碎白" />
|
||||
<TextBlock Width="240" Margin="0,1.5" Text="Black_Banana_Cat" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="君染" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="XiaoMingPro" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="翎霜流火" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="李一年" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="白沢見知らぬ" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="洛阳蓝焰" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="123" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Zikyeung" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="zzz_10728701" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="啥都想玩的天云" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="棱镜凌空" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="瑾" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="zzzzzjy" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="南有乔树" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="wsaml" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="韬光养晦" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="李白" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="HurgerLiPy" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Crishen70400" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="孤独" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="夏末彡微凉" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="山本樱桃不是df" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="陶牧馆长" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="一二三四" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="17382073935" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="不知道" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="重庆你周哥" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="熳ai" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Rainbow Stars" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="无名岩" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="快乐小子" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="沙西凯" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="一只小孽QAQ" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="五度左右" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="咖喱鱼" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="千叶GG" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="李白" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="xsh" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="ChatCTL" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="杰" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="霜天天" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="辛兮辞" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="?" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="天绫绫地宁宁" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="无敌百搭的款式" />
|
||||
<TextBlock Width="240" Margin="0,1.5" Text="没事还有俾斯麦兜底" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Lewis" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="捞猴子的月亮呐" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="活着是为了摆烂" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="浔。" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="周南何" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="あんた" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="老乡老乡开开门" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="dedf" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Adminstrator" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="木子李" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="文刀木头鱼" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="泪刻我心" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="璃洺" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="wuzhi718" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="琳" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="fycn" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="风铃末末?" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="漫游池塘中" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="james" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="jiekun" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="gugugugugu" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Zomib" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="乱想的名字" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="fish" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Kfeadow" />
|
||||
<TextBlock Width="240" Margin="0,1.5" Text="MeltyAcoustAmber" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="Quan_Q" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="旋叶" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="YanXiaXia__" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="崩坏坏sama" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="中土来客" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="大星星" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="尋葉゛" />
|
||||
<TextBlock Width="120" Margin="0,1.5" Text="50MB" />
|
||||
</WrapPanel>
|
||||
<Grid Height="35">
|
||||
|
||||
@@ -111,8 +111,9 @@
|
||||
{"LaunchAdvanceGraphicCard", New SetupEntry(True, Source:=SetupSource.Registry)},
|
||||
{"LaunchRamType", New SetupEntry(0)},
|
||||
{"LaunchRamCustom", New SetupEntry(15)},
|
||||
{"LinkOfflineHint", New SetupEntry(False, Source:=SetupSource.Registry)},
|
||||
{"LinkLastAutoJoinInviteCode", New SetupEntry("", Source:=SetupSource.Registry)},
|
||||
{"LinkShareMode", New SetupEntry(True, Source:=SetupSource.Registry)},
|
||||
{"LinkCustomPeer", New SetupEntry("")},
|
||||
{"LinkEasyTierVersion", New SetupEntry(-1, Source:=SetupSource.Registry)},
|
||||
{"ToolHelpChinese", New SetupEntry(True, Source:=SetupSource.Registry)},
|
||||
{"ToolDownloadThread", New SetupEntry(63, Source:=SetupSource.Registry)},
|
||||
|
||||
@@ -86,14 +86,14 @@
|
||||
</local:MyComboBox>
|
||||
<local:MyTextBox Padding="0,0,5,0" Visibility="Collapsed" Grid.Column="1" Margin="50,0,0,0" x:Name="TextArgumentWindowWidth" Tag="LaunchArgumentWindowWidth" Width="60" HorizontalContentAlignment="Center" Text="854">
|
||||
<local:MyTextBox.ValidateRules>
|
||||
<local:ValidateInteger Min="1" Max="9999" />
|
||||
<local:ValidateInteger Min="1" Max="99999" />
|
||||
</local:MyTextBox.ValidateRules>
|
||||
</local:MyTextBox>
|
||||
<TextBlock x:Name="LabArgumentWindowMiddle" Visibility="Collapsed" Grid.Column="2" Text=" × " VerticalAlignment="Center" FontSize="18" />
|
||||
<local:MyTextBox Padding="0,0,5,0" Visibility="Collapsed" Grid.Column="3" Width="60" HorizontalContentAlignment="Center" x:Name="TextArgumentWindowHeight" Tag="LaunchArgumentWindowHeight" Text="480"
|
||||
ToolTip="Forge 1.12.2 等个别版本存在 Bug,会导致高度设定无效" ToolTipService.Placement="Right" ToolTipService.HorizontalOffset="5">
|
||||
<local:MyTextBox.ValidateRules>
|
||||
<local:ValidateInteger Min="1" Max="9999" />
|
||||
<local:ValidateInteger Min="1" Max="99999" />
|
||||
</local:MyTextBox.ValidateRules>
|
||||
</local:MyTextBox>
|
||||
</Grid>
|
||||
|
||||
@@ -6,11 +6,32 @@
|
||||
PanScroll="PanBack">
|
||||
<local:MyScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" x:Name="PanBack">
|
||||
<StackPanel x:Name="PanMain" Margin="25,10">
|
||||
<local:MyCard Margin="0,15" Title="联机">
|
||||
<StackPanel Margin="25,40,25,20" Orientation="Vertical">
|
||||
<local:MyCheckBox Text="老好人模式" x:Name="CheckShareMode" Tag="LinkShareMode" Height="22"
|
||||
<local:MyCard Margin="0,15" Title="高级设置" IsSwapped="True" CanSwap="True">
|
||||
<Grid Margin="25,40,25,22">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="1*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="28" />
|
||||
<RowDefinition Height="15" />
|
||||
<RowDefinition Height="35" />
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Left" Text="自定义节点" Margin="0,0,25,0" />
|
||||
<local:MyTextBox x:Name="TextCustomPeer" Tag="LinkCustomPeer" Grid.Column="1" MaxHeight="28"
|
||||
ToolTip="覆盖 PCL 所选择的节点,仅连接此处填写的节点。
如果你自己搭建了 EasyTier 节点,你可以用这个设置让 PCL 连接它。

使用逗号分隔多个节点,例如:
tcp://public.easytier.cn:11010,tcp://public2.easytier.cn:54321

房主和加入者必须连接到至少一个相同节点,才能互相连上。" />
|
||||
<local:MyCheckBox Text="老好人模式" x:Name="CheckShareMode" Grid.Row="1" Tag="LinkShareMode" Height="22" Visibility="Collapsed"
|
||||
ToolTip="启动联机后,用你的网络帮助其他玩家建立连接、降低延迟!
即使你不开启,开启了这个选项的其他玩家也会帮助你,不过,人人为我,我为人人嘛……" />
|
||||
</StackPanel>
|
||||
<StackPanel Orientation="Horizontal" Grid.Row="2" Grid.ColumnSpan="2" HorizontalAlignment="Left">
|
||||
<local:MyButton MinWidth="140" Padding="13,5" Margin="0,0,20,0" HorizontalAlignment="Left"
|
||||
Text=" 光荣地贡献节点!" ColorType="Highlight"
|
||||
ToolTip="联机功能全靠社区的各位无私贡献的节点才能存在!
如果你有空闲的服务器,欢迎搭建一个共享节点,人人为我,我为人人嘛……

你可以在 EasyTier 的【搭建共享节点】文档中查看搭建方式,搭建好后点击这里提交。
PCL 会自动选取节点进行连接。"
|
||||
local:CustomEventService.EventType="打开网页" local:CustomEventService.EventData="https://uptime.easytier.cn/submit" />
|
||||
<local:MyButton MinWidth="140" Padding="13,5" Margin="0,0,20,0" HorizontalAlignment="Left"
|
||||
Text="节点状态"
|
||||
local:CustomEventService.EventType="打开网页" local:CustomEventService.EventData="https://uptime.easytier.cn/" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</local:MyCard>
|
||||
</StackPanel>
|
||||
</local:MyScrollViewer>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Class PageSetupLink
|
||||
Public Class PageSetupLink
|
||||
|
||||
Private Shadows IsLoaded As Boolean = False
|
||||
|
||||
@@ -18,12 +18,14 @@
|
||||
End Sub
|
||||
Public Sub Reload()
|
||||
CheckShareMode.Checked = Setup.Get("LinkShareMode")
|
||||
TextCustomPeer.Text = Setup.Get("LinkCustomPeer")
|
||||
End Sub
|
||||
|
||||
'初始化
|
||||
Public Sub Reset()
|
||||
Try
|
||||
Setup.Reset("LinkShareMode")
|
||||
Setup.Reset("LinkCustomPeer")
|
||||
|
||||
Log("[Setup] 已初始化联机页设置")
|
||||
Hint("已初始化联机页设置!", HintType.Green, False)
|
||||
@@ -35,7 +37,7 @@
|
||||
End Sub
|
||||
|
||||
'将控件改变路由到设置改变
|
||||
Private Shared Sub TextBoxChange(sender As MyTextBox, e As Object) 'Handles TextLinkName.ValidatedTextChanged
|
||||
Private Shared Sub TextBoxChange(sender As MyTextBox, e As Object) Handles TextCustomPeer.ValidatedTextChanged
|
||||
If AniControlEnabled = 0 Then Setup.Set(sender.Tag, sender.Text)
|
||||
End Sub
|
||||
Private Shared Sub CheckBoxChange(sender As MyCheckBox, e As Object) Handles CheckShareMode.Change
|
||||
|
||||
@@ -253,6 +253,7 @@
|
||||
<local:MyComboBoxItem Content="OpenMCIM 仪表盘(作者:SALTWOOD)" Visibility="Collapsed" />
|
||||
<local:MyComboBoxItem Content="杂志主页(作者:CreeperIsASpy)" />
|
||||
<local:MyComboBoxItem Content="PCL GitHub 仪表盘(作者:Deep-Dark-Forest)" />
|
||||
<local:MyComboBoxItem Content="Minecraft 更新摘要(作者:pynickle,部分由 AI 生成)" />
|
||||
</local:MyComboBox>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
Imports System.Threading.Tasks
|
||||
|
||||
Public Class PageSpeedLeft
|
||||
Public Class PageSpeedLeft
|
||||
Private Const WatcherInterval As Integer = 300
|
||||
|
||||
'初始化
|
||||
|
||||
@@ -933,6 +933,8 @@
|
||||
<ItemGroup>
|
||||
<None Include="Resources\System.Net.Http.Formatting.dll" />
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<ItemGroup>
|
||||
<Resource Include="Images\Heads\EasyTier.png" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />
|
||||
</Project>
|
||||
Binary file not shown.
Reference in New Issue
Block a user