This commit is contained in:
龙腾猫跃
2023-05-28 20:18:59 +08:00
parent c1a26a119f
commit ce164dd6fd
44 changed files with 1056 additions and 429 deletions
+26 -19
View File
@@ -11,12 +11,12 @@ Public Module ModBase
#Region "声明"
'下列版本信息由更新器自动修改
Public Const VersionBaseName As String = "2.6.1" '不含分支前缀的显示用版本名
Public Const VersionStandardCode As String = "2.6.1." & VersionBranchCode '标准格式的四段式版本号
Public Const VersionBaseName As String = "2.6.2" '不含分支前缀的显示用版本名
Public Const VersionStandardCode As String = "2.6.2." & VersionBranchCode '标准格式的四段式版本号
#If BETA Then
Public Const VersionCode As Integer = 293 'Release
#Else
Public Const VersionCode As Integer = 291 'Snapshot
Public Const VersionCode As Integer = 294 'Snapshot
#End If
'自动生成的版本信息
Public Const VersionDisplayName As String = VersionBranchName & " " & VersionBaseName
@@ -1210,11 +1210,11 @@ Re:
If MinSize >= 0 AndAlso MinSize > FileSize Then Return "文件大小应大于 " & MinSize & " B,实际为 " & FileSize & " B"
If Not String.IsNullOrEmpty(Hash) Then
If Hash.Length < 35 Then 'MD5
If Hash <> GetAuthMD5(LocalPath) Then Return "文件 MD5 应为 " & Hash & ",实际为 " & GetAuthMD5(LocalPath)
If Hash.ToLowerInvariant <> GetAuthMD5(LocalPath) Then Return "文件 MD5 应为 " & Hash & ",实际为 " & GetAuthMD5(LocalPath)
ElseIf Hash.Length = 64 Then 'SHA256
If Hash <> GetAuthSHA256(LocalPath) Then Return "文件 SHA256 应为 " & Hash & ",实际为 " & GetAuthSHA256(LocalPath)
If Hash.ToLowerInvariant <> GetAuthSHA256(LocalPath) Then Return "文件 SHA256 应为 " & Hash & ",实际为 " & GetAuthSHA256(LocalPath)
Else 'SHA1 (40)
If Hash <> GetAuthSHA1(LocalPath) Then Return "文件 SHA1 应为 " & Hash & ",实际为 " & GetAuthSHA1(LocalPath)
If Hash.ToLowerInvariant <> GetAuthSHA1(LocalPath) Then Return "文件 SHA1 应为 " & Hash & ",实际为 " & GetAuthSHA1(LocalPath)
End If
End If
If IsJson Then
@@ -1452,21 +1452,23 @@ Re:
''' </summary>
''' <param name="FileSize">以字节为单位的大小表示。</param>
Public Function GetString(FileSize As Long) As String
Dim IsNegative = FileSize < 0
If IsNegative Then FileSize *= -1
If FileSize < 1000 Then
'B 级
Return FileSize & " B"
Return If(IsNegative, "-", "") & FileSize & " B"
ElseIf FileSize < 1024 * 1000 Then
'K 级
Dim RoundResult As String = Math.Round(FileSize / 1024)
Return Math.Round(FileSize / 1024, CInt(MathRange(3 - RoundResult.Length, 0, 2))) & " K"
Return If(IsNegative, "-", "") & Math.Round(FileSize / 1024, CInt(MathRange(3 - RoundResult.Length, 0, 2))) & " K"
ElseIf FileSize < 1024 * 1024 * 1000 Then
'M 级
Dim RoundResult As String = Math.Round(FileSize / 1024 / 1024)
Return Math.Round(FileSize / 1024 / 1024, CInt(MathRange(3 - RoundResult.Length, 0, 2))) & " M"
Return If(IsNegative, "-", "") & Math.Round(FileSize / 1024 / 1024, CInt(MathRange(3 - RoundResult.Length, 0, 2))) & " M"
Else
'G 级
Dim RoundResult As String = Math.Round(FileSize / 1024 / 1024 / 1024)
Return Math.Round(FileSize / 1024 / 1024 / 1024, CInt(MathRange(3 - RoundResult.Length, 0, 2))) & " G"
Return If(IsNegative, "-", "") & Math.Round(FileSize / 1024 / 1024 / 1024, CInt(MathRange(3 - RoundResult.Length, 0, 2))) & " G"
End If
End Function
@@ -1481,6 +1483,14 @@ Re:
End Try
End Function
''' <summary>
''' 将第一个字符转换为大写,其余字符转换为小写。
''' </summary>
<Extension> Public Function Capitalize(word As String) As String
If String.IsNullOrEmpty(word) Then Return word
Return word.Substring(0, 1).ToUpperInvariant() & word.Substring(1).ToLowerInvariant()
End Function
''' <summary>
''' 将字符串统一至某个长度,过短则以 Code 将其右侧填充,过长则截取靠左的指定长度。
''' </summary>
@@ -1748,16 +1758,13 @@ Re:
Return principal.IsInRole(WindowsBuiltInRole.Administrator)
End Function
''' <summary>
''' 以管理员权限重新运行当前程序。返回是否成功。
''' 以管理员权限运行当前程序,并等待程序运行结束。
''' 返回程序的返回代码,如果运行失败将抛出异常。
''' </summary>
Public Function RerunAsAdmin(Argument As String) As Boolean
Try
Process.Start(New ProcessStartInfo(PathWithName) With {.Verb = "runas", .Arguments = Argument})
Return True
Catch ex As Exception
Log(ex, "以管理员权限运行程序失败")
Return False
End Try
Public Function RunAsAdmin(Argument As String) As Integer
Dim NewProcess = Process.Start(New ProcessStartInfo(PathWithName) With {.Verb = "runas", .Arguments = Argument})
NewProcess.WaitForExit()
Return NewProcess.ExitCode
End Function
Private Uuid As Integer = 1
@@ -1203,7 +1203,7 @@ SourceBreak:
'End SyncLock
Info.Source.Ex = ex
'根据情况判断,是否在多线程下禁用下载源(连续错误过多,或不支持断点续传)
If ex.Message.Contains("该下载源不支持") OrElse ex.Message.Contains("(404)") OrElse ex.Message.Contains("(403)") OrElse ex.Message.Contains("(502)") OrElse ex.Message.Contains("无返回数据") OrElse ex.Message.Contains("空间不足") OrElse
If ex.Message.Contains("该下载源不支持") OrElse ex.Message.Contains("未能解析") OrElse ex.Message.Contains("(404)") OrElse ex.Message.Contains("(403)") OrElse ex.Message.Contains("(502)") OrElse ex.Message.Contains("无返回数据") OrElse ex.Message.Contains("空间不足") OrElse
(Info.Source.FailCount >= MathRange(NetTaskThreadLimit, 5, 40) AndAlso DownloadDone < 1) OrElse
Info.Source.FailCount > NetTaskThreadLimit Then
Dim IsThisFail As Boolean = False
@@ -418,17 +418,46 @@
End If
'实例化 UI
Dim NewItem As New MyCompItem With {.Tag = Me}
'标题
Dim FinalName As String = TranslatedName.Split(" | ").First.Split(" - ").First.Split("(").First.Split("[").First
Dim ExNameList As List(Of String) = TranslatedName.Split({" | ", " - ", "(", ")", "[", "]", "{", "}"}, StringSplitOptions.RemoveEmptyEntries).
Select(Function(s) s.Trim(" /".ToCharArray)).Where(Function(w) Not String.IsNullOrEmpty(w)).ToList
ExNameList.RemoveAt(0)
If TranslatedName = RawName AndAlso '没有中文翻译
Not ExNameList.Any(Function(s) s.Contains("orge") OrElse s.Contains("abric") OrElse s.Contains("uilt")) AndAlso '不是标注 XX 版
Not (ExNameList.Count = 1 AndAlso ExNameList.First.ToUpper <> ExNameList.First) Then '不是缩写
FinalName = RawName '使用原名
ExNameList.Clear()
'整理 FinalName 与 ExNameList
'检查下列代码时可以参考 #1567 的测试例
Dim FinalName As String
Dim ExNameList As List(Of String)
If TranslatedName = RawName Then
'没有中文翻译
FinalName = TranslatedName.Split(" | ").First.Split(" - ").First.Split("(").First.Split("[").First
ExNameList = TranslatedName.Split({" | ", " - ", "(", ")", "[", "]", "{", "}"}, StringSplitOptions.RemoveEmptyEntries).
Select(Function(s) s.Trim(" /".ToCharArray)).Where(Function(w) Not String.IsNullOrEmpty(w)).ToList
ExNameList.RemoveAt(0)
If Not ExNameList.Any(Function(s) s.ToLower.Contains("forge") OrElse s.ToLower.Contains("fabric") OrElse s.ToLower.Contains("quilt")) AndAlso '不是标注 XX 版
Not (ExNameList.Count = 1 AndAlso ExNameList.First.ToUpper = ExNameList.First) Then '不是缩写
FinalName = RawName '使用原名
ExNameList.Clear()
End If
Else
'有中文翻译
'尝试将文本分为三段:FinalName (EnglishName) - Suffix
'检查时注意 Carpet:它没有中文译名,但有 Suffix
FinalName = TranslatedName.Split(" (").First.Split(" - ").First
Dim Suffix As String = ""
If TranslatedName.Split(")").Last.Contains(" - ") Then Suffix = TranslatedName.Split(")").Last.Split(" - ").Last
Dim EnglishName As String = TranslatedName
If Suffix <> "" Then EnglishName = EnglishName.Replace(" - " & Suffix, "")
EnglishName = EnglishName.Replace(FinalName, "").Trim("("c, ")"c, " "c)
'中段的额外信息截取
ExNameList = EnglishName.Split({" | ", " - ", "(", ")", "[", "]", "{", "}"}, StringSplitOptions.RemoveEmptyEntries).
Select(Function(s) s.Trim(" /".ToCharArray)).Where(Function(w) Not String.IsNullOrEmpty(w)).ToList
If ExNameList.Count > 1 AndAlso
Not ExNameList.Any(Function(s) s.ToLower.Contains("forge") OrElse s.ToLower.Contains("fabric") OrElse s.ToLower.Contains("quilt")) AndAlso '不是标注 XX 版
Not (ExNameList.Count = 2 AndAlso ExNameList.Last.ToUpper = ExNameList.Last) Then '不是缩写
ExNameList = New List(Of String) From {EnglishName} '使用原名
End If
'添加后缀
If Suffix <> "" Then
ExNameList.Add(Suffix)
ExNameList = ExNameList.Distinct().ToList()
End If
End If
'显示 FinalName 与 ExNameList
NewItem.LabTitle.Text = FinalName
If ExNameList.Count = 0 Then
NoExName:
@@ -440,7 +469,7 @@ NoExName:
If Ex.Length < 19 AndAlso Ex.ToLower.Contains("fabric") AndAlso Ex.ToLower.Contains("forge") Then Continue For
'将 “Forge” 等提示改为 “Forge 版”
If (Ex.ToLower.Contains("forge") OrElse Ex.ToLower.Contains("fabric") OrElse Ex.ToLower.Contains("quilt")) AndAlso
Not Ex.Contains("版") AndAlso Ex.Length < 19 Then Ex = Ex.Replace("Edition", "").Trim & " 版"
Not Ex.Contains("版") AndAlso Ex.Length < 19 Then Ex = Ex.Replace("Edition", "").Trim.Capitalize & " 版"
ExName &= " | " & Ex.Trim
Next
If ExName = "" Then GoTo NoExName
@@ -789,7 +818,7 @@ NoExName:
'去除常见连接词
Dim RealFilter As String = ""
For Each Word In SearchResult.Split(" ")
If {"the", "of", "a", "mod"}.Contains(Word.ToLower) OrElse Val(Word) > 0 Then Continue For
If {"the", "of", "a", "mod", "and"}.Contains(Word.ToLower) OrElse Val(Word) > 0 Then Continue For
If SearchResult.Split(" ").Count > 3 AndAlso {"ftb"}.Contains(Word.ToLower) Then Continue For
RealFilter += Word.TrimStart("{[(").TrimEnd("}])") & " "
Next
@@ -805,7 +834,8 @@ NoExName:
'最终处理关键字:分割、去重
Dim RightKeywords As New List(Of String)
For Each Keyword In AllPossibleKeywords.Split(" ")
If Keyword.Trim = "" Then Continue For
Keyword = Keyword.Trim("["c, "]"c)
If Keyword = "" Then Continue For
If {"forge", "fabric", "for", "mod",
"forge/fabric", "fabric/forge", "fabric/quilt", "quilt/fabric"}.Contains(Keyword) Then '#208
Log("[Comp] 已跳过搜索关键词:" & Keyword)
@@ -505,7 +505,8 @@ Done:
If LogMc.Contains("Found a duplicate mod") Then AppendReason(CrashReason.Mod重复安装, RegexSearch(If(RegexSeek(LogMc, "Found a duplicate mod[^\n]+"), ""), "[^\\/]+.jar", RegularExpressions.RegexOptions.IgnoreCase))
If LogMc.Contains("ModResolutionException: Duplicate") Then AppendReason(CrashReason.Mod重复安装, RegexSearch(If(RegexSeek(LogMc, "ModResolutionException: Duplicate[^\n]+"), ""), "[^\\/]+.jar", RegularExpressions.RegexOptions.IgnoreCase))
'Mod 导致的崩溃
If LogMc.Contains("Mixin prepare failed ") OrElse LogMc.Contains("Mixin apply failed ") OrElse LogMc.Contains("mixin.injection.throwables.") OrElse LogMc.Contains(".mixins.json] FAILED during )") Then
If LogMc.Contains("Mixin prepare failed ") OrElse LogMc.Contains("Mixin apply failed ") OrElse
LogMc.Contains("mixin.injection.throwables.") OrElse LogMc.Contains(".mixins.json] FAILED during )") Then
Dim ModId As String = RegexSeek(LogMc, "(?<=in )[^./ ]+(?=.mixins.json.+failed injection check)")
If ModId Is Nothing Then ModId = RegexSeek(LogMc, "(?<=in mixins.)[^./ ]+(?=.json.+failed injection check)")
If ModId Is Nothing Then ModId = RegexSeek(LogMc, "(?<= failed .+ in )[^./ ]+(?=.mixins.json)")
@@ -514,6 +515,10 @@ Done:
If ModId Is Nothing Then ModId = RegexSeek(LogMc, "(?<= in config \[mixins.)[^./ ]+(?=.json\] FAILED during )")
If ModId Is Nothing Then ModId = RegexSeek(LogMc, "(?<= in callback )[^./ ]+(?=.mixins.json:)")
If ModId Is Nothing Then ModId = RegexSeek(LogMc, "(?<=from mod )[^\] ]+(?=\] from phase)")
If ModId Is Nothing Then ModId = RegexSeek(LogMc, "(?<=for mod )[^./ ]+(?= failed)")
'兜底名称判断
If ModId Is Nothing Then ModId = RegexSeek(LogMc, "[^./ \]]+(?=.mixins.json")
If ModId Is Nothing Then ModId = RegexSeek(LogMc, "(?<=mixins.)[^./ \]]+(?=.json")
AppendReason(CrashReason.ModMixin失败, TryAnalyzeModName(If(ModId, "").TrimEnd((vbCrLf & " ").ToCharArray)))
End If
If LogMc.Contains("Caught exception from ") Then AppendReason(CrashReason.确定Mod导致游戏崩溃, TryAnalyzeModName(RegexSeek(LogMc, "(?<=Caught exception from )[^\n]+?")?.TrimEnd((vbCrLf & " ").ToCharArray)))
@@ -363,6 +363,7 @@ UserPass:
Catch ex As ThreadInterruptedException
Throw
Catch ex As Exception
If ex.InnerException IsNot Nothing AndAlso TypeOf (ex.InnerException) Is ThreadInterruptedException Then Throw ex.InnerException
Log(ex, "找到的 Java 已无法使用,尝试进行搜索")
AllowedJavaList = New List(Of JavaEntry)
JavaSearchLoader.Start(IsForceRestart:=True)
@@ -1091,7 +1091,7 @@ SystemBrowser:
#Region "Java 处理"
Private McLaunchJavaSelected As JavaEntry = Nothing
Public McLaunchJavaSelected As JavaEntry = Nothing
Private Sub McLaunchJava(Task As LoaderTask(Of Integer, Integer))
Dim MinVer As New Version(0, 0, 0, 0), MaxVer As New Version(999, 999, 999, 999)
@@ -1322,7 +1322,7 @@ SystemBrowser:
If Not ArgumentJvm.Contains("-Dlog4j2.formatMsgNoLookups=true") Then ArgumentJvm += " -Dlog4j2.formatMsgNoLookups=true"
DataList.Insert(0, ArgumentJvm) '可变 JVM 参数
DataList.Add("-Xmn256m")
DataList.Add("-Xmx" & Math.Floor(PageVersionSetup.GetRam(McVersionCurrent) * 1024) & "m")
DataList.Add("-Xmx" & Math.Floor(PageVersionSetup.GetRam(McVersionCurrent, Not McLaunchJavaSelected.Is64Bit) * 1024) & "m")
DataList.Add("""-Djava.library.path=" & Version.Path & Version.Name & "-natives""")
DataList.Add("-cp ${classpath}") '把支持库添加进启动参数表
@@ -1742,19 +1742,28 @@ NextVersion:
Dim SetupFileAddress As String = McVersionCurrent.PathIndie & "options.txt"
Try
'语言
If Setup.Get("ToolHelpChinese") Then
If Not File.Exists(SetupFileAddress) OrElse Not Directory.Exists(McVersionCurrent.PathIndie & "saves") Then
McLaunchLog("已根据设置自动修改语言为中文")
WriteIni(SetupFileAddress, "lang", "-") '触发缓存更改,避免删除后重新下载残留缓存
If McVersionCurrent.Version.McCodeMain >= 12 Then
WriteIni(SetupFileAddress, "lang", "zh_cn")
Else
WriteIni(SetupFileAddress, "lang", "zh_CN")
End If
WriteIni(SetupFileAddress, "forceUnicodeFont", "true")
Else
McLaunchLog("并非首次启动,不修改语言")
End If
'1.0- :没有语言选项
'1.1 ~ 5 :zh_CN 时正常,zh_cn 时崩溃(最后两位字母必须大写,否则将会 NPE 崩溃)
'1.6 ~ 10 :zh_CN 时正常,zh_cn 时自动切换为英文
'1.11 ~ 12:zh_cn 时正常,zh_CN 时虽然显示了中文但语言设置会错误地显示选择英文
'1.13+ :zh_cn 时正常,zh_CN 时自动切换为英文
Dim CurrentLang As String = ReadIni(SetupFileAddress, "lang", "none")
Dim RequiredLang As String = If(CurrentLang = "none", If(Setup.Get("ToolHelpChinese"), "zh_cn", "en_us"), CurrentLang.ToLower)
If McVersionCurrent.Version.McCodeMain < 12 Then '注意老版本(包含 MC 1.1)的 McCodeMain 可能为 -1
'将最后两位改为大写,前面的部分保留
RequiredLang = RequiredLang.Substring(0, RequiredLang.Length - 2) & RequiredLang.Substring(RequiredLang.Length - 2).ToUpper
End If
If CurrentLang = RequiredLang Then
McLaunchLog($"当前语言为 {CurrentLang},无需修改")
Else
WriteIni(SetupFileAddress, "lang", "-") '触发缓存更改,避免删除后重新下载残留缓存
WriteIni(SetupFileAddress, "lang", RequiredLang)
McLaunchLog($"已将语言从 {CurrentLang} 修改为 {RequiredLang}")
End If
'如果是初次设置,一并修改 forceUnicodeFont
If Setup.Get("ToolHelpChinese") AndAlso (CurrentLang = "none" OrElse Not Directory.Exists(McVersionCurrent.PathIndie & "saves")) Then
WriteIni(SetupFileAddress, "forceUnicodeFont", "true")
McLaunchLog("已开启 forceUnicodeFont")
End If
'窗口
Select Case Setup.Get("LaunchArgumentWindowType")
@@ -2059,7 +2068,7 @@ IgnoreCustomSkin:
McLaunchLog("游戏版本:" & McVersionCurrent.Version.ToString & "(" & McVersionCurrent.Version.McCodeMain & "." & McVersionCurrent.Version.McCodeSub & ")")
McLaunchLog("资源版本:" & McAssetsGetIndexName(McVersionCurrent))
McLaunchLog("版本继承:" & If(McVersionCurrent.InheritVersion = "", "无", McVersionCurrent.InheritVersion))
McLaunchLog("分配的内存:" & PageVersionSetup.GetRam(McVersionCurrent) & " GB(" & Math.Round(PageVersionSetup.GetRam(McVersionCurrent) * 1024) & " MB)")
McLaunchLog("分配的内存:" & PageVersionSetup.GetRam(McVersionCurrent, Not McLaunchJavaSelected.Is64Bit) & " GB(" & Math.Round(PageVersionSetup.GetRam(McVersionCurrent, Not McLaunchJavaSelected.Is64Bit) * 1024) & " MB)")
McLaunchLog("MC 文件夹:" & PathMcFolder)
McLaunchLog("版本文件夹:" & McVersionCurrent.Path)
McLaunchLog("版本隔离:" & (McVersionCurrent.PathIndie = McVersionCurrent.Path))
@@ -680,7 +680,7 @@ Recheck:
Case Else '根据 API 进行筛选
Dim RealJson As String = If(JsonObject, JsonText).ToString
'愚人节与快照版本
If If(JsonObject("type"), "").ToString = "fool" OrElse GetMcFoolName(Name) <> "" Then
If If(JsonObject("type"), "").ToString = "fool" OrElse GetMcFoolName(Version.McName) <> "" Then
State = McVersionState.Fool
ElseIf Version.McName.ToLower.Contains("w") OrElse Name.ToLower.Contains("combat") OrElse Version.McName.ToLower.Contains("rc") OrElse Version.McName.ToLower.Contains("pre") OrElse Version.McName.Contains("experimental") OrElse If(JsonObject("type"), "").ToString = "snapshot" OrElse If(JsonObject("type"), "").ToString = "pending" Then
State = McVersionState.Snapshot
@@ -756,7 +756,7 @@ ExitDataLoad:
Case McVersionState.Original, McVersionState.Forge, McVersionState.Fabric, McVersionState.OptiFine, McVersionState.LiteLoader
Info = Version.ToString
Case McVersionState.Fool
Info = GetMcFoolName(Name)
Info = GetMcFoolName(Version.McName)
Case McVersionState.Error
'已有错误信息
Case Else
@@ -1112,6 +1112,10 @@ OnLoaded:
'循环读取版本
For Each Folder As String In ReadIni(Path & "PCL.ini", "CardValue" & (i + 1), ":").Split(":")
If Folder = "" Then Continue For
If File.Exists(Path & "versions\" & Folder & "\.pclignore") Then
Log("[Minecraft] 跳过要求忽略的项目:" & Path & "versions\" & Folder)
Continue For
End If
Try
'读取单个版本
@@ -1187,6 +1191,10 @@ OnLoaded:
Log("[Minecraft] 跳过可能不是版本文件夹的项目:" & Folder.FullName)
Continue For
End If
If File.Exists(Folder.FullName & "\.pclignore") Then
Log("[Minecraft] 跳过要求忽略的项目:" & Folder.FullName)
Continue For
End If
Dim Version As New McVersion(Folder.FullName & "\")
VersionList.Add(Version)
Version.Load()
@@ -638,6 +638,8 @@ Retry:
Request.MinecraftName = Component("version")
Case "net.minecraftforge"
Request.ForgeVersion = Component("version")
Case "net.fabricmc.fabric-loader"
Request.FabricVersion = Component("version")
End Select
Next
'构造加载器
@@ -320,8 +320,12 @@
'获取窗口关联的进程
Dim ProcessId As Integer
GetWindowThreadProcessId(hwnd, ProcessId)
Dim WindowProcess = Process.GetProcessById(ProcessId)
If WindowProcess.StartTime < GameProcess.StartTime Then Exit Sub '需要是此后启动的进程
Try
If Process.GetProcessById(ProcessId).StartTime < GameProcess.StartTime Then Exit Sub '需要是此后启动的进程
Catch ex As Exception
Log(ex, "枚举 Minecraft 窗口进程失败")
Exit Sub
End Try
'返回
TryGetMinecraftWindow = New KeyValuePair(Of IntPtr, String)(hwnd, WindowText)
End Sub, 0)
@@ -39,8 +39,9 @@
</StackPanel>
<TextBlock x:Name="LabInfo" Grid.Row="2" Grid.Column="4" VerticalAlignment="Bottom" Margin="1,0,3,0.5"
TextTrimming="CharacterEllipsis" FontSize="12" Foreground="{StaticResource ColorBrushGray3}"
IsHitTestVisible="True" SnapsToDevicePixels="False" UseLayoutRounding="False"
ToolTipService.InitialShowDelay="150" ToolTipService.Placement="Relative" ToolTipService.PlacementRectangle="-8,-6,500,10000">
IsHitTestVisible="True" SnapsToDevicePixels="False" UseLayoutRounding="False"
ToolTipService.InitialShowDelay="100" ToolTipService.BetweenShowDelay="100"
ToolTipService.Placement="Relative" ToolTipService.PlacementRectangle="-16,-10,500,10000">
<TextBlock.ToolTip>
<ToolTip x:Name="ToolTipInfo" Style="{StaticResource ExtendTextToolTip}" />
</TextBlock.ToolTip>
@@ -61,6 +61,9 @@
Case "今日人品"
PageOtherTest.Jrrp()
Case "内存优化"
RunInThread(Sub() PageOtherTest.MemoryOptimize(True))
Case "清理垃圾"
PageOtherTest.RubbishClear()