From 6705444fb44377e4d36f6025015912e3a8d7bbb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BE=99=E8=85=BE=E7=8C=AB=E8=B7=83?= <1043137532@qq.com> Date: Mon, 18 Dec 2023 04:56:23 +0800 Subject: [PATCH] 2.6.12 --- Plain Craft Launcher 2/Application.xaml | 2 +- Plain Craft Launcher 2/Controls/MyCard.vb | 4 +- Plain Craft Launcher 2/Controls/MyMenuItem.vb | 2 + .../Controls/MyScrollViewer.vb | 2 +- .../Controls/MySlider.xaml.vb | 4 +- Plain Craft Launcher 2/FormMain.xaml | 15 +- Plain Craft Launcher 2/FormMain.xaml.vb | 229 ++++++++++-------- .../Images/Icons/Disabled.png | Bin 701 -> 1990 bytes .../Images/Icons/Unavaliable.png | Bin 982 -> 2277 bytes .../Modules/Base/ModAnimation.vb | 24 +- .../Modules/Base/ModBase.vb | 23 +- .../Modules/Base/ModLoader.vb | 2 +- Plain Craft Launcher 2/Modules/Base/ModNet.vb | 10 +- .../Modules/Base/MyBitmap.vb | 1 + .../Modules/Minecraft/ModComp.vb | 14 +- .../Modules/Minecraft/ModMinecraft.vb | 20 +- .../Modules/Minecraft/ModMod.vb | 165 +++++++------ .../Modules/Minecraft/MyCompItem.xaml.vb | 35 +-- .../Modules/Minecraft/MyLocalModItem.xaml | 2 +- .../Modules/Minecraft/MyLocalModItem.xaml.vb | 47 ++-- Plain Craft Launcher 2/Modules/ModMusic.vb | 9 +- .../My Project/AssemblyInfo.vb | 4 +- .../Pages/PageDownload/ModDownloadLib.vb | 46 ++-- .../PageDownloadCompDetail.xaml.vb | 12 +- .../Pages/PageDownload/PageDownloadMod.xaml | 1 + .../Pages/PageDownload/PageDownloadPack.xaml | 1 + .../Pages/PageLaunch/MySkin.xaml.vb | 2 +- .../Pages/PageLaunch/PageLaunchRight.xaml.vb | 2 +- .../Pages/PageSetup/PageSetupLaunch.xaml.vb | 2 +- .../Pages/PageVersion/PageVersionMod.xaml | 8 +- .../Pages/PageVersion/PageVersionMod.xaml.vb | 176 +++++++++----- .../PageVersion/PageVersionSetup.xaml.vb | 2 +- Plain Craft Launcher 2/Resources/Help.zip | Bin 76255 -> 75159 bytes 33 files changed, 490 insertions(+), 376 deletions(-) diff --git a/Plain Craft Launcher 2/Application.xaml b/Plain Craft Launcher 2/Application.xaml index c10b711..d5dc1df 100644 --- a/Plain Craft Launcher 2/Application.xaml +++ b/Plain Craft Launcher 2/Application.xaml @@ -293,7 +293,7 @@ - + diff --git a/Plain Craft Launcher 2/Controls/MyCard.vb b/Plain Craft Launcher 2/Controls/MyCard.vb index b1e32d0..9674ca8 100644 --- a/Plain Craft Launcher 2/Controls/MyCard.vb +++ b/Plain Craft Launcher 2/Controls/MyCard.vb @@ -209,7 +209,7 @@ Dim AnimList As New List(Of AniData) If DeltaHeight > 10 OrElse (DeltaHeight < -10 AndAlso Not IsNothing(SwapControl)) Then '如果不是需要折叠的卡片,高度减小时的弹跳会吞掉按钮下边框 '高度增加较大,使用弹起动画 - Dim Delta As Double = MathRange(Math.Abs(DeltaHeight) * 0.05, 3, 10) * Math.Sign(DeltaHeight) + Dim Delta As Double = MathClamp(Math.Abs(DeltaHeight) * 0.05, 3, 10) * Math.Sign(DeltaHeight) AnimList.AddRange({ AaHeight(Me, DeltaHeight + Delta, 300, If(IsLoadAnimation, 30, 0), If(DeltaHeight > FrmMain.Height, New AniEaseInFluent(AniEasePower.ExtraStrong), New AniEaseOutFluent(AniEasePower.ExtraStrong))), AaHeight(Me, -Delta, 150, 260, Ease:=New AniEaseOutFluent(AniEasePower.Strong)) @@ -217,7 +217,7 @@ Else '普通的改变就行啦 AnimList.AddRange({ - AaHeight(Me, DeltaHeight, MathRange(Math.Abs(DeltaHeight) * 4, 150, 250),, New AniEaseOutFluent) + AaHeight(Me, DeltaHeight, MathClamp(Math.Abs(DeltaHeight) * 4, 150, 250),, New AniEaseOutFluent) }) End If AnimList.Add(AaCode(Sub() diff --git a/Plain Craft Launcher 2/Controls/MyMenuItem.vb b/Plain Craft Launcher 2/Controls/MyMenuItem.vb index fbf8082..5f24795 100644 --- a/Plain Craft Launcher 2/Controls/MyMenuItem.vb +++ b/Plain Craft Launcher 2/Controls/MyMenuItem.vb @@ -6,6 +6,8 @@ Dim IconControl As Shapes.Path = GetTemplateChild("Icon") If IconControl IsNot Nothing Then IconControl.Data = (New GeometryConverter).ConvertFromString(Icon) End If + '对父级设置透明度 + CType(Parent, ContextMenu).Opacity = Setup.Get("UiLauncherTransparent") / 1000 + 0.4 End Sub '基础 diff --git a/Plain Craft Launcher 2/Controls/MyScrollViewer.vb b/Plain Craft Launcher 2/Controls/MyScrollViewer.vb index 1187052..b341275 100644 --- a/Plain Craft Launcher 2/Controls/MyScrollViewer.vb +++ b/Plain Craft Launcher 2/Controls/MyScrollViewer.vb @@ -24,7 +24,7 @@ End Sub Public Sub PerformVerticalOffsetDelta(Delta As Double) AniStart(AaDouble(Sub(AnimDelta As Double) - RealOffset = MathRange(RealOffset + AnimDelta, 0, ExtentHeight - ActualHeight) + RealOffset = MathClamp(RealOffset + AnimDelta, 0, ExtentHeight - ActualHeight) ScrollToVerticalOffset(RealOffset) End Sub, Delta * DeltaMuity, 300,, New AniEaseOutFluent(6))) End Sub diff --git a/Plain Craft Launcher 2/Controls/MySlider.xaml.vb b/Plain Craft Launcher 2/Controls/MySlider.xaml.vb index 22c3610..0a6ff76 100644 --- a/Plain Craft Launcher 2/Controls/MySlider.xaml.vb +++ b/Plain Craft Launcher 2/Controls/MySlider.xaml.vb @@ -28,7 +28,7 @@ Set(newValue As Integer) Try - newValue = MathRange(newValue, 0, MaxValue) + newValue = MathClamp(newValue, 0, MaxValue) If _Value = newValue Then Exit Property '触发 Preview 事件,修改新值 @@ -88,7 +88,7 @@ AniStop("MySlider KeyPopup " & Uuid) End Sub Public Sub DragDoing() - Dim Percent As Double = MathRange((Mouse.GetPosition(PanMain).X - ShapeDot.Width / 2) / (ActualWidth - ShapeDot.Width), 0, 1) + Dim Percent As Double = MathClamp((Mouse.GetPosition(PanMain).X - ShapeDot.Width / 2) / (ActualWidth - ShapeDot.Width), 0, 1) Dim NewValue As Integer = Percent * MaxValue If Not NewValue = Value Then Value = NewValue diff --git a/Plain Craft Launcher 2/FormMain.xaml b/Plain Craft Launcher 2/FormMain.xaml index c54903e..331d370 100644 --- a/Plain Craft Launcher 2/FormMain.xaml +++ b/Plain Craft Launcher 2/FormMain.xaml @@ -1,10 +1,13 @@  + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:local="clr-namespace:PCL" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" + x:Name="WindMain" x:Class="FormMain" Style="{StaticResource MyWindow}" + AllowDrop="True" Topmost="True" Title="Plain Craft Launcher " AllowsTransparency="True" MinHeight="470" MinWidth="810" + ScrollViewer.VerticalScrollBarVisibility="Disabled" Icon="/Plain Craft Launcher 2;component/Images/icon.ico" WindowStyle="None" + ResizeMode="CanMinimize" Background="{x:Null}" d:DesignWidth="870" d:DesignHeight="520" Width="850" Height="500" + RenderTransformOrigin="0.5,0.5"> diff --git a/Plain Craft Launcher 2/FormMain.xaml.vb b/Plain Craft Launcher 2/FormMain.xaml.vb index cfcff52..16f5309 100644 --- a/Plain Craft Launcher 2/FormMain.xaml.vb +++ b/Plain Craft Launcher 2/FormMain.xaml.vb @@ -11,6 +11,14 @@ Public Class FormMain Dim FeatureList As New List(Of KeyValuePair(Of Integer, String)) '统计更新日志条目 #If BETA Then + If LastVersion < 311 Then 'Release 2.6.12 + FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "Mod 管理页面将显示 Mod 的中文名、图标、标签等信息")) + FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "从 Mod 管理页面查看 Mod 信息时会跳转到其下载详情页面")) + FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "重新设计 Mod 管理页面的交互与样式")) + FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复无法安装 Forge 1.18.3+ 的 Bug")) + FeatureCount += 27 + BugCount += 25 + End If If LastVersion < 308 Then 'Release 2.6.10 FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "为版本独立设置添加忽略 Java 兼容性警告选项")) FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复开始或结束游戏时可能报错的 Bug")) @@ -135,7 +143,13 @@ Public Class FormMain '3:BUG+ IMP* FEAT- '2:BUG* IMP- '1:BUG- - If LastVersion < 307 Then 'Snapshot 2.6.11 + If LastVersion < 310 Then 'Snapshot 2.6.12 + If LastVersion = 309 Then FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "Mod 管理页面添加启用、禁用单个 Mod 的快捷按钮")) + FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复无法安装 Forge 1.18.3+ 的 Bug")) + FeatureCount += 13 + BugCount += 12 + End If + If LastVersion < 309 Then 'Snapshot 2.6.11 FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "Mod 管理页面将显示 Mod 的中文名、图标、标签等信息")) FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "从 Mod 管理页面查看 Mod 信息时会跳转到其下载详情页面")) FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "重新设计 Mod 管理页面的交互与样式")) @@ -399,7 +413,7 @@ Public Class FormMain #If DEBUG Then Hint("[开发者模式] PCL 正以开发者模式运行,这可能会造成严重的性能下降,请务必立即向开发者反馈此问题!", HintType.Critical) #End If - If ModeDebug Then Hint("[调试模式] PCL 正以调试模式运行,这可能会造成性能的下降,若无必要请不要开启!") + If ModeDebug Then Hint("[调试模式] PCL 正以调试模式运行,这可能会导致性能下降,若无必要请不要开启!") '尽早执行的加载池 McFolderListLoader.Start(0) '为了让下载已存在文件检测可以正常运行,必须跑一次;为了让启动按钮尽快可用,需要尽早执行;为了与 PageLaunchLeft 联动,需要为 0 而不是 GetUuid @@ -466,8 +480,8 @@ Public Class FormMain End Sub, , True) }, "Form Show") 'Timer 启动 - AniStartRun() - TimerMainStartRun() + AniStart() + TimerMainStart() '加载池 RunInNewThread(Sub() 'EULA 提示 @@ -855,6 +869,11 @@ Public Class FormMain '正在主页,需要刷新左边栏 FrmLaunchLeft.RefreshPage(True, False) End If + ElseIf Str.StartsWith("file:///") Then + '文件拖拽(例如从浏览器下载窗口拖入) + Dim FilePath = Net.WebUtility.UrlDecode(Str).Substring("file:///".Length).Replace("/", "\") + e.Handled = True + FileDrag(New List(Of String) From {FilePath}) End If Catch ex As Exception Log(ex, "无法接取文本拖拽事件", LogLevel.Developer) @@ -867,108 +886,113 @@ Public Class FormMain Hint("请将文件解压后再拖入!", HintType.Critical) Exit Sub End If - Dim FilePathList As New List(Of String)(CType(FilePathRaw, IEnumerable(Of String))) e.Handled = True - If Directory.Exists(FilePathList.First) AndAlso Not File.Exists(FilePathList.First) Then - Hint("请拖入一个文件,而非文件夹!", HintType.Critical) - Exit Sub - End If - '多文件拖拽 - If FilePathList.Count > 1 Then - '必须要求全部为 jar 文件 - For Each File In FilePathList - Dim Extension As String = File.Split(".").Last.ToLower - If Not {"jar", "litemod", "disabled"}.Contains(Extension) Then - Hint("一次请只拖入一个文件!", HintType.Critical) - Exit Sub - End If - Next - End If - '实际执行事件 - Dim FilePath As String = FilePathList.First - Log("[System] 接受文件拖拽:" & FilePath, LogLevel.Developer) - RunInNewThread(Sub() - Dim Extension As String = FilePath.Split(".").Last.ToLower - '自定义主页 - If Extension = "xaml" Then - Log("[System] 文件后缀为 XAML,作为自定义主页加载") - If File.Exists(Path & "PCL\Custom.xaml") Then - If MyMsgBox("已存在一个自定义主页文件,是否要将它覆盖?", "覆盖确认", "覆盖", "取消") = 2 Then - Exit Sub - End If - End If - CopyFile(FilePath, Path & "PCL\Custom.xaml") - RunInUi(Sub() - Setup.Set("UiCustomType", 1) - FrmLaunchRight.ForceRefresh() - Hint("已加载主页自定义文件!", HintType.Finish) - End Sub) - Exit Sub - End If - 'Mod 安装 - If {"jar", "litemod", "disabled"}.Any(Function(t) t = Extension) Then - Log("[System] 文件为 jar/litemod 格式,尝试作为 Mod 安装") - '获取并检查目标版本 - Dim TargetVersion As McVersion = McVersionCurrent - If PageCurrent = PageType.VersionSetup Then TargetVersion = PageVersionLeft.Version - If PageCurrent = PageType.VersionSelect OrElse TargetVersion Is Nothing OrElse Not TargetVersion.Modable Then - '正在选择版本,或当前版本不能安装 Mod - Hint("若要安装 Mod,请先选择一个可以安装 Mod 的版本!") - ElseIf Not (PageCurrent = PageType.VersionSetup AndAlso PageCurrentSub = PageSubType.VersionMod) Then - '未处于 Mod 管理页面 - If MyMsgBox($"是否要将这些文件作为 Mod 安装到 {TargetVersion.Name}?", "Mod 安装确认", "确定", "取消") = 1 Then GoTo Install - Else - '处于 Mod 管理页面 -Install: - Try - For Each ModFile In FilePathList - CopyFile(ModFile, TargetVersion.PathIndie & "mods\" & GetFileNameFromPath(ModFile)) - Next - If FilePathList.Count = 1 Then - Hint($"已安装 {GetFileNameFromPath(FilePathList.First)}!", HintType.Finish) - Else - Hint($"已安装 {FilePathList.Count} 个 Mod!", HintType.Finish) - End If - '刷新列表 - If PageCurrent = PageType.VersionSetup AndAlso PageCurrentSub = PageSubType.VersionMod Then - LoaderFolderRun(McModLoader, TargetVersion.PathIndie & "mods\", LoaderFolderRunType.ForceRun) - End If - Catch ex As Exception - Log(ex, "复制 Mod 文件失败", LogLevel.Msgbox) - End Try - End If - Exit Sub - End If - '安装整合包 - If {"zip", "rar", "mrpack"}.Any(Function(t) t = Extension) Then '部分压缩包是 zip 格式但后缀为 rar,总之试一试 - Log("[System] 文件为压缩包,尝试作为整合包安装") - If ModpackInstall(FilePath, ShowHint:=False) Then Exit Sub - End If - 'RAR 处理 - If Extension = "rar" Then - Hint("PCL 无法处理 rar 格式的压缩包,请在解压后重新压缩为 zip 格式再试!") - Exit Sub - End If - '错误报告分析 - Try - Log("[System] 尝试进行错误报告分析") - Dim Analyzer As New CrashAnalyzer(GetUuid()) - Analyzer.Import(FilePath) - If Analyzer.Prepare() = 0 Then Exit Try - Analyzer.Analyze() - Analyzer.Output(True, New List(Of String)) - Exit Sub - Catch ex As Exception - Log(ex, "自主错误报告分析失败", LogLevel.Feedback) - End Try - '未知操作 - Hint("PCL 无法确定应当执行的文件拖拽操作……") - End Sub, "文件拖拽") + FileDrag(CType(FilePathRaw, IEnumerable(Of String))) End If Catch ex As Exception Log(ex, "接取拖拽事件失败", LogLevel.Feedback) End Try End Sub + Private Sub FileDrag(FilePathList As IEnumerable(Of String)) + RunInNewThread( + Sub() + Dim FilePath As String = FilePathList.First + Log("[System] 接受文件拖拽:" & FilePath & If(FilePathList.Count > 0, $" 等 {FilePathList.Count} 个文件", ""), LogLevel.Developer) + '基础检查 + If Directory.Exists(FilePathList.First) AndAlso Not File.Exists(FilePathList.First) Then + Hint("请拖入一个文件,而非文件夹!", HintType.Critical) + Exit Sub + ElseIf Not File.Exists(FilePathList.First) Then + Hint("拖入的文件不存在:" & FilePathList.First, HintType.Critical) + Exit Sub + End If + '多文件拖拽 + If FilePathList.Count > 1 Then + '必须要求全部为 jar 文件 + For Each File In FilePathList + If Not {"jar", "litemod", "disabled", "old"}.Contains(File.Split(".").Last.ToLower) Then + Hint("一次请只拖入一个文件!", HintType.Critical) + Exit Sub + End If + Next + End If + '自定义主页 + Dim Extension As String = FilePath.Split(".").Last.ToLower + If Extension = "xaml" Then + Log("[System] 文件后缀为 XAML,作为自定义主页加载") + If File.Exists(Path & "PCL\Custom.xaml") Then + If MyMsgBox("已存在一个自定义主页文件,是否要将它覆盖?", "覆盖确认", "覆盖", "取消") = 2 Then + Exit Sub + End If + End If + CopyFile(FilePath, Path & "PCL\Custom.xaml") + RunInUi(Sub() + Setup.Set("UiCustomType", 1) + FrmLaunchRight.ForceRefresh() + Hint("已加载主页自定义文件!", HintType.Finish) + End Sub) + Exit Sub + End If + 'Mod 安装 + If {"jar", "litemod", "disabled", "old"}.Any(Function(t) t = Extension) Then + Log("[System] 文件为 jar/litemod 格式,尝试作为 Mod 安装") + '获取并检查目标版本 + Dim TargetVersion As McVersion = McVersionCurrent + If PageCurrent = PageType.VersionSetup Then TargetVersion = PageVersionLeft.Version + If PageCurrent = PageType.VersionSelect OrElse TargetVersion Is Nothing OrElse Not TargetVersion.Modable Then + '正在选择版本,或当前版本不能安装 Mod + Hint("若要安装 Mod,请先选择一个可以安装 Mod 的版本!") + ElseIf Not (PageCurrent = PageType.VersionSetup AndAlso PageCurrentSub = PageSubType.VersionMod) Then + '未处于 Mod 管理页面 + If MyMsgBox($"是否要将这些文件作为 Mod 安装到 {TargetVersion.Name}?", "Mod 安装确认", "确定", "取消") = 1 Then GoTo Install + Else + '处于 Mod 管理页面 +Install: + Try + For Each ModFile In FilePathList + CopyFile(ModFile, TargetVersion.PathIndie & "mods\" & GetFileNameFromPath(ModFile)) + Next + If FilePathList.Count = 1 Then + Hint($"已安装 {GetFileNameFromPath(FilePathList.First)}!", HintType.Finish) + Else + Hint($"已安装 {FilePathList.Count} 个 Mod!", HintType.Finish) + End If + '刷新列表 + If PageCurrent = PageType.VersionSetup AndAlso PageCurrentSub = PageSubType.VersionMod Then + LoaderFolderRun(McModLoader, TargetVersion.PathIndie & "mods\", LoaderFolderRunType.ForceRun) + End If + Catch ex As Exception + Log(ex, "复制 Mod 文件失败", LogLevel.Msgbox) + End Try + End If + Exit Sub + End If + '安装整合包 + If {"zip", "rar", "mrpack"}.Any(Function(t) t = Extension) Then '部分压缩包是 zip 格式但后缀为 rar,总之试一试 + Log("[System] 文件为压缩包,尝试作为整合包安装") + If ModpackInstall(FilePath, ShowHint:=False) Then Exit Sub + End If + 'RAR 处理 + If Extension = "rar" Then + Hint("PCL 无法处理 rar 格式的压缩包,请在解压后重新压缩为 zip 格式再试!") + Exit Sub + End If + '错误报告分析 + Try + Log("[System] 尝试进行错误报告分析") + Dim Analyzer As New CrashAnalyzer(GetUuid()) + Analyzer.Import(FilePath) + If Analyzer.Prepare() = 0 Then Exit Try + Analyzer.Analyze() + Analyzer.Output(True, New List(Of String)) + Exit Sub + Catch ex As Exception + Log(ex, "自主错误报告分析失败", LogLevel.Feedback) + End Try + '未知操作 + Hint("PCL 无法确定应当执行的文件拖拽操作……") + End Sub, "文件拖拽") + End Sub '接受到 Windows 窗体事件 Public IsSystemTimeChanged As Boolean = False @@ -1170,6 +1194,10 @@ Install: ''' Public PageCurrent As PageStackData = PageType.Launch ''' + ''' 上一个主页面。 + ''' + Public PageLast As PageStackData = PageType.Launch + ''' ''' 当前的子页面。 ''' Public ReadOnly Property PageCurrentSub As PageSubType @@ -1347,6 +1375,7 @@ Install: #End Region #Region "实际更改页面框架 UI" + PageLast = PageCurrent PageCurrent = Stack Select Case Stack.Page Case PageType.Launch '启动 diff --git a/Plain Craft Launcher 2/Images/Icons/Disabled.png b/Plain Craft Launcher 2/Images/Icons/Disabled.png index b335561190529640721007e14a806dec60d50319..f5203728554032c96014f26977ef5917b116d4b0 100644 GIT binary patch literal 1990 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 W^P3+Go(TNJaMDt=%Ic(z+kXTzNM>6A delta 975 zcmV;=12FvM5!MGGiBL{Q4GJ0x0000DNk~Le0000S0000S2nGNE0CElAl#wA9e*=g~ zL_t(Y$E{XPNE=ZQ7X1HLQ2ar?`Y$4ws363H7mpt7wMN8?2t}=U@KB5wy{L$Y5=D9u zJ&K@W5`U6?eUzTIrn4Rm1GY~Gvs-kX_kc0vFkBnVX! zRTJ$Z`i^J=(ehw?$l0VKI!V+HfBwb(vZqEi;7VwyKwnP22*Jw|QH6v*|A6HEt&}I* z?k-$TO~Gk@Kb#E?f@N+FY$lUG;6_=1k@;p7kuf9Im%+Ck1E~&V7qS4U3BKZ&y zkUU!jHzKFsDlGI1Bv#yOGaAL9YDqwhJG<*@W(GF0vSfpCiZ&Q(k(5gTe=c#Wx2vnL zo|#D<7?P4;GcOOeOG;oZEe%$}!UO=gzFk@hy9x!h(S?UoP|PwqhWL0m zXlQ_2g8?264&ZEPhytTiTwl+~fS)}*@N|6*uA3V;8y<%B^mIPFqMWK&KrQz#76^BG zJTZdsh8_>x@9%@Ls)~aBf9UQ8uiMRgbQ~SQR&geuvVc6PHwy}QgVp3@>ePLI z58(CkmQJ%7E+!_xOAf#bS;yS5c}HK2I5TtkeOAF}Z;w0^`D>2d~3ve|h1-`enfy-+3xt;srfv#ai z%LNP=QUp8d=m3w?DH%?@F;eDpZLLrK{DrifZDoS|5eFEq=es)r$dkoFdG{Ju4_N2t z;Zts|51^<4C^=eOe{uhCJkmu(P!eB^jrmaGTXQoUcXoo?ZWrY8xV;?=2??*gmH1-B z!t!ujOniNGG#C;SVZW}9=NaDYt6EL@xsja>XCos#J@9$b+sn5^3F40jY;6drkBNbu zvNHIyxCpkrJup^QzTSZJ)UBc-Fl)8oJU@ra>1kL?O{ItAe@HLNyGq==m)Yix9RqWS zpt`6i$qJ;6IwuEA)z$P#4?_-uw?rR-nzx|i@Si8*1i>h%L8 x69Z_?%aH2`B>?gm^dKx#D@3FI8@2-F=wJIp;5KoBoe2N{002ovPDHLkV1oPIy@CJ$ diff --git a/Plain Craft Launcher 2/Modules/Base/ModAnimation.vb b/Plain Craft Launcher 2/Modules/Base/ModAnimation.vb index eea7562..08dbcef 100644 --- a/Plain Craft Launcher 2/Modules/Base/ModAnimation.vb +++ b/Plain Craft Launcher 2/Modules/Base/ModAnimation.vb @@ -577,10 +577,10 @@ Public Module ModAnimation Public Class AniEaseLinear Inherits AniEase Public Overrides Function GetValue(t As Double) As Double - Return MathRange(t, 0, 1) + Return MathClamp(t, 0, 1) End Function Public Overrides Function GetDelta(t1 As Double, t0 As Double) As Double - Return MathRange(t1, 0, 1) - MathRange(t0, 0, 1) + Return MathClamp(t1, 0, 1) - MathClamp(t0, 0, 1) End Function End Class @@ -595,7 +595,7 @@ Public Module ModAnimation p = Power End Sub Public Overrides Function GetValue(t As Double) As Double - Return MathRange(t, 0, 1) ^ p + Return MathClamp(t, 0, 1) ^ p End Function End Class ''' @@ -608,7 +608,7 @@ Public Module ModAnimation p = Power End Sub Public Overrides Function GetValue(t As Double) As Double - Return 1 - MathRange(1 - t, 0, 1) ^ p + Return 1 - MathClamp(1 - t, 0, 1) ^ p End Function End Class ''' @@ -636,7 +636,7 @@ Public Module ModAnimation p = 3 - Power * 0.5 End Sub Public Overrides Function GetValue(t As Double) As Double - t = MathRange(t, 0, 1) + t = MathClamp(t, 0, 1) Return t ^ p * Math.Cos(1.5 * Math.PI * (1 - t)) End Function End Class @@ -650,7 +650,7 @@ Public Module ModAnimation p = 3 - Power * 0.5 End Sub Public Overrides Function GetValue(t As Double) As Double - t = MathRange(t, 0, 1) + t = MathClamp(t, 0, 1) Return 1 - (1 - t) ^ p * Math.Cos(1.5 * Math.PI * t) End Function End Class @@ -694,7 +694,7 @@ Public Module ModAnimation p = Power + 4 End Sub Public Overrides Function GetValue(t As Double) As Double - t = MathRange(t, 0, 1) + t = MathClamp(t, 0, 1) Return t ^ ((p - 1) * 0.25) * Math.Cos((p - 3.5) * Math.PI * (1 - t) ^ 1.5) End Function End Class @@ -708,7 +708,7 @@ Public Module ModAnimation p = Power + 4 End Sub Public Overrides Function GetValue(t As Double) As Double - t = 1 - MathRange(t, 0, 1) + t = 1 - MathClamp(t, 0, 1) Return 1 - t ^ ((p - 1) * 0.25) * Math.Cos((p - 3.5) * Math.PI * (1 - t) ^ 1.5) End Function End Class @@ -766,7 +766,7 @@ Public Module ModAnimation ''' ''' 开始动画执行。 ''' - Public Sub AniStartRun() + Public Sub AniStart() '初始化计时器 AniLastTick = GetTimeTick() AniFPSTimer = AniLastTick @@ -777,12 +777,12 @@ Public Module ModAnimation Log("[Animation] 动画线程开始") Do While True '两帧之间的间隔时间 - Dim DeltaTime As Long = MathRange(GetTimeTick() - AniLastTick, 0, 100000) + Dim DeltaTime As Long = MathClamp(GetTimeTick() - AniLastTick, 0, 100000) If DeltaTime < 3 Then GoTo Sleeper AniLastTick = GetTimeTick() '记录 FPS If ModeDebug Then - If MathRange(AniLastTick - AniFPSTimer, 0, 100000) >= 500 Then + If MathClamp(AniLastTick - AniFPSTimer, 0, 100000) >= 500 Then AniFPS = AniFPSCounter AniFPSCounter = 0 AniFPSTimer = AniLastTick @@ -904,7 +904,7 @@ NextAni: Case AniTypeSub.Y DeltaTop(Ani.Obj, Delta) Case AniTypeSub.Opacity - Ani.Obj.Opacity = MathRange(Ani.Obj.Opacity + Delta, 0, 1) + Ani.Obj.Opacity = MathClamp(Ani.Obj.Opacity + Delta, 0, 1) Case AniTypeSub.Width Dim Obj As FrameworkElement = Ani.Obj Obj.Width = Math.Max(If(Double.IsNaN(Obj.Width), Obj.ActualWidth, Obj.Width) + Delta, 0) diff --git a/Plain Craft Launcher 2/Modules/Base/ModBase.vb b/Plain Craft Launcher 2/Modules/Base/ModBase.vb index f84b474..81e82d0 100644 --- a/Plain Craft Launcher 2/Modules/Base/ModBase.vb +++ b/Plain Craft Launcher 2/Modules/Base/ModBase.vb @@ -11,12 +11,12 @@ Public Module ModBase #Region "声明" '下列版本信息由更新器自动修改 - Public Const VersionBaseName As String = "2.6.11" '不含分支前缀的显示用版本名 - Public Const VersionStandardCode As String = "2.6.11." & VersionBranchCode '标准格式的四段式版本号 + Public Const VersionBaseName As String = "2.6.12" '不含分支前缀的显示用版本名 + Public Const VersionStandardCode As String = "2.6.12." & VersionBranchCode '标准格式的四段式版本号 #If BETA Then Public Const VersionCode As Integer = 308 'Release #Else - Public Const VersionCode As Integer = 309 'Snapshot + Public Const VersionCode As Integer = 310 'Snapshot #End If '自动生成的版本信息 Public Const VersionDisplayName As String = VersionBranchName & " " & VersionBaseName @@ -46,7 +46,7 @@ Public Module ModBase ''' ''' 程序内嵌图片文件夹路径,以“/”结尾。 ''' - Public PathImage As String = "pack://application:,,,/images/" + Public PathImage As String = "pack://application:,,,/Plain Craft Launcher 2;component/Images/" ''' ''' 当前程序的语言。 ''' @@ -521,7 +521,6 @@ Public Module ModBase ''' 获取两数间的百分比。小数点精确到 6 位。 ''' ''' - ''' Public Function MathPercent(ValueA As Double, ValueB As Double, Percent As Double) As Double Return Math.Round(ValueA * (1 - Percent) + ValueB * Percent, 6) '解决 Double 计算错误 End Function @@ -535,7 +534,7 @@ Public Module ModBase ''' ''' 将数值限定在某个范围内。 ''' - Public Function MathRange(value As Double, min As Double, max As Double) As Double + Public Function MathClamp(value As Double, min As Double, max As Double) As Double Return Math.Max(min, Math.Min(max, value)) End Function @@ -1325,8 +1324,10 @@ Re: ''' ''' 遍历文件夹中的所有文件。 ''' - Public Function EnumerateFiles(Directory As String) As List(Of FileInfo) - Return New DirectoryInfo(Directory).EnumerateFiles("*", SearchOption.AllDirectories).ToList + Public Function EnumerateFiles(Directory As String) As IEnumerable(Of FileInfo) + Dim Info As New DirectoryInfo(Directory) + If Not Info.Exists Then Return New List(Of FileInfo) + Return Info.EnumerateFiles("*", SearchOption.AllDirectories) End Function #End Region @@ -1456,15 +1457,15 @@ Re: ElseIf FileSize < 1024 * 1000 Then 'K 级 Dim RoundResult As String = Math.Round(FileSize / 1024) - Return If(IsNegative, "-", "") & Math.Round(FileSize / 1024, CInt(MathRange(3 - RoundResult.Length, 0, 2))) & " K" + Return If(IsNegative, "-", "") & Math.Round(FileSize / 1024, CInt(MathClamp(3 - RoundResult.Length, 0, 2))) & " K" ElseIf FileSize < 1024 * 1024 * 1000 Then 'M 级 Dim RoundResult As String = Math.Round(FileSize / 1024 / 1024) - Return If(IsNegative, "-", "") & Math.Round(FileSize / 1024 / 1024, CInt(MathRange(3 - RoundResult.Length, 0, 2))) & " M" + Return If(IsNegative, "-", "") & Math.Round(FileSize / 1024 / 1024, CInt(MathClamp(3 - RoundResult.Length, 0, 2))) & " M" Else 'G 级 Dim RoundResult As String = Math.Round(FileSize / 1024 / 1024 / 1024) - Return If(IsNegative, "-", "") & Math.Round(FileSize / 1024 / 1024 / 1024, CInt(MathRange(3 - RoundResult.Length, 0, 2))) & " G" + Return If(IsNegative, "-", "") & Math.Round(FileSize / 1024 / 1024 / 1024, CInt(MathClamp(3 - RoundResult.Length, 0, 2))) & " G" End If End Function diff --git a/Plain Craft Launcher 2/Modules/Base/ModLoader.vb b/Plain Craft Launcher 2/Modules/Base/ModLoader.vb index 852541d..a11be25 100644 --- a/Plain Craft Launcher 2/Modules/Base/ModLoader.vb +++ b/Plain Craft Launcher 2/Modules/Base/ModLoader.vb @@ -634,7 +634,7 @@ Restart: Next End SyncLock If Count = 0 Then Return 1 - Return MathRange(Total / Count, 0, 1) + Return MathClamp(Total / Count, 0, 1) Catch ex As Exception Log(ex, "获取任务栏进度出错", LogLevel.Feedback) Return 0.5 diff --git a/Plain Craft Launcher 2/Modules/Base/ModNet.vb b/Plain Craft Launcher 2/Modules/Base/ModNet.vb index c65e748..e24d043 100644 --- a/Plain Craft Launcher 2/Modules/Base/ModNet.vb +++ b/Plain Craft Launcher 2/Modules/Base/ModNet.vb @@ -1206,7 +1206,7 @@ SourceBreak: Info.Source.Ex = ex '根据情况判断,是否在多线程下禁用下载源(连续错误过多,或不支持断点续传) If ex.Message.Contains("该下载源不支持") OrElse ex.Message.Contains("未能解析") OrElse ex.Message.Contains("(404)") OrElse ex.Message.Contains("(403)") OrElse ex.Message.Contains("(502)") OrElse ex.Message.Contains("无返回数据") OrElse ex.Message.Contains("空间不足") OrElse - (Info.Source.FailCount >= MathRange(NetTaskThreadLimit, 5, 40) AndAlso DownloadDone < 1) OrElse + (Info.Source.FailCount >= MathClamp(NetTaskThreadLimit, 5, 40) AndAlso DownloadDone < 1) OrElse Info.Source.FailCount > NetTaskThreadLimit Then Dim IsThisFail As Boolean = False SyncLock LockSource @@ -1862,9 +1862,9 @@ Retry: Dim IsSuccess As Boolean = False Dim NewThreadCount As Integer '确定最大线程追加数 - NewThreadCount = Math.Max(FileRemain, MathRange(NetTaskThreadCount / 2, 1, 4)) + NewThreadCount = Math.Max(FileRemain, MathClamp(NetTaskThreadCount / 2, 1, 4)) NewThreadCount = Math.Floor(NewThreadCount / 2) '双线程启用减半 - NewThreadCount = MathRange(NewThreadCount, 1, NetTaskThreadLimit) + NewThreadCount = MathClamp(NewThreadCount, 1, NetTaskThreadLimit) '循环追加 Do IsSuccess = False @@ -1919,9 +1919,9 @@ Retry: Dim IsSuccess As Boolean = False Dim NewThreadCount As Integer '确定最大线程追加数 - NewThreadCount = Math.Max(FileRemain, MathRange(NetTaskThreadCount / 2, 1, 4)) + NewThreadCount = Math.Max(FileRemain, MathClamp(NetTaskThreadCount / 2, 1, 4)) NewThreadCount = Math.Floor(NewThreadCount / 2) '双线程启用减半 - NewThreadCount = MathRange(NewThreadCount, 1, NetTaskThreadLimit) + NewThreadCount = MathClamp(NewThreadCount, 1, NetTaskThreadLimit) '循环追加 Do IsSuccess = False diff --git a/Plain Craft Launcher 2/Modules/Base/MyBitmap.vb b/Plain Craft Launcher 2/Modules/Base/MyBitmap.vb index 1c25959..a5b9a33 100644 --- a/Plain Craft Launcher 2/Modules/Base/MyBitmap.vb +++ b/Plain Craft Launcher 2/Modules/Base/MyBitmap.vb @@ -54,6 +54,7 @@ Public Class MyBitmap End Sub Public Sub New(FilePathOrResourceName As String) Try + FilePathOrResourceName = FilePathOrResourceName.Replace("pack://application:,,,/images/", PathImage) If FilePathOrResourceName.StartsWith(PathImage) Then '使用缓存 If BitmapCache.ContainsKey(FilePathOrResourceName) Then diff --git a/Plain Craft Launcher 2/Modules/Minecraft/ModComp.vb b/Plain Craft Launcher 2/Modules/Minecraft/ModComp.vb index dcefb92..ac09d8f 100644 --- a/Plain Craft Launcher 2/Modules/Minecraft/ModComp.vb +++ b/Plain Craft Launcher 2/Modules/Minecraft/ModComp.vb @@ -536,7 +536,7 @@ End Function Public Function GetControlLogo() As String If LogoUrl Is Nothing Then - Return "pack://application:,,,/images/Icons/NoIcon.png" + Return PathImage & "Icons/NoIcon.png" Else Return LogoUrl End If @@ -1279,13 +1279,13 @@ Retry: End If 'GameVersions Dim RawVersions As List(Of String) = Data("game_versions").Select(Function(t) t.ToString.Trim.ToLower).ToList - GameVersions = RawVersions.Where(Function(v) v.StartsWith("1.")). - Select(Function(v) If(v.Contains("-"), v.Split("-").First & " 快照", v)).ToList + GameVersions = RawVersions.Where(Function(v) v.StartsWith("1.") OrElse v.StartsWith("b1.")). + Select(Function(v) If(v.Contains("-"), v.Split("-").First & " 快照", If(v.StartsWith("b1."), "远古版本", v))).ToList If GameVersions.Count > 1 Then GameVersions = Sort(GameVersions, AddressOf VersionSortBoolean).ToList If Type = CompType.ModPack Then GameVersions = New List(Of String) From {GameVersions(0)} ElseIf GameVersions.Count = 1 Then - GameVersions = GameVersions.ToList + '无需处理 ElseIf RawVersions.Any(Function(v) RegexCheck(v, "[0-9]{2}w[0-9]{2}[a-z]{1}")) Then GameVersions = RawVersions.Where(Function(v) RegexCheck(v, "[0-9]{2}w[0-9]{2}[a-z]{1}")).ToList Else @@ -1332,11 +1332,11 @@ Retry: } Select Case Status Case CompFileStatus.Release - NewItem.Logo = "pack://application:,,,/images/Icons/R.png" + NewItem.Logo = PathImage & "Icons/R.png" Case CompFileStatus.Beta - NewItem.Logo = "pack://application:,,,/images/Icons/B.png" + NewItem.Logo = PathImage & "Icons/B.png" Case Else 'Alpha - NewItem.Logo = "pack://application:,,,/images/Icons/A.png" + NewItem.Logo = PathImage & "Icons/A.png" End Select AddHandler NewItem.Click, OnClick diff --git a/Plain Craft Launcher 2/Modules/Minecraft/ModMinecraft.vb b/Plain Craft Launcher 2/Modules/Minecraft/ModMinecraft.vb index 84288a8..88cc06e 100644 --- a/Plain Craft Launcher 2/Modules/Minecraft/ModMinecraft.vb +++ b/Plain Craft Launcher 2/Modules/Minecraft/ModMinecraft.vb @@ -716,23 +716,23 @@ ExitDataLoad: If Logo = "" OrElse Not CType(ReadIni(Path & "PCL\Setup.ini", "LogoCustom", False), Boolean) Then Select Case State Case McVersionState.Original - Logo = "pack://application:,,,/images/Blocks/Grass.png" + Logo = PathImage & "Blocks/Grass.png" Case McVersionState.Snapshot - Logo = "pack://application:,,,/images/Blocks/CommandBlock.png" + Logo = PathImage & "Blocks/CommandBlock.png" Case McVersionState.Old - Logo = "pack://application:,,,/images/Blocks/CobbleStone.png" + Logo = PathImage & "Blocks/CobbleStone.png" Case McVersionState.Forge - Logo = "pack://application:,,,/images/Blocks/Anvil.png" + Logo = PathImage & "Blocks/Anvil.png" Case McVersionState.Fabric - Logo = "pack://application:,,,/images/Blocks/Fabric.png" + Logo = PathImage & "Blocks/Fabric.png" Case McVersionState.OptiFine - Logo = "pack://application:,,,/images/Blocks/GrassPath.png" + Logo = PathImage & "Blocks/GrassPath.png" Case McVersionState.LiteLoader - Logo = "pack://application:,,,/images/Blocks/Egg.png" + Logo = PathImage & "Blocks/Egg.png" Case McVersionState.Fool - Logo = "pack://application:,,,/images/Blocks/GoldBlock.png" + Logo = PathImage & "Blocks/GoldBlock.png" Case Else - Logo = "pack://application:,,,/images/Blocks/RedstoneBlock.png" + Logo = PathImage & "Blocks/RedstoneBlock.png" End Select End If '确定版本描述 @@ -791,7 +791,7 @@ ExitDataLoad: End If Catch ex As Exception Info = "未知错误:" & GetExceptionSummary(ex) - Logo = "pack://application:,,,/images/Blocks/RedstoneBlock.png" + Logo = PathImage & "Blocks/RedstoneBlock.png" State = McVersionState.Error Log(ex, "加载版本失败(" & Name & ")", LogLevel.Feedback) Finally diff --git a/Plain Craft Launcher 2/Modules/Minecraft/ModMod.vb b/Plain Craft Launcher 2/Modules/Minecraft/ModMod.vb index 8789d74..85d935a 100644 --- a/Plain Craft Launcher 2/Modules/Minecraft/ModMod.vb +++ b/Plain Craft Launcher 2/Modules/Minecraft/ModMod.vb @@ -24,11 +24,11 @@ Public Module ModMod End Property ''' - ''' Mod 的完整文件名,去除最后的 .disabled。 + ''' Mod 的完整文件名,去除最后的 .disabled 和 .old。 ''' Public ReadOnly Property RawFileName As String Get - Return FileName.Replace(".disabled", "") + Return FileName.Replace(".disabled", "").Replace(".old", "") End Get End Property @@ -40,7 +40,7 @@ Public Module ModMod Load() If Not IsFileAvailable Then Return McModState.Unavaliable - ElseIf Path.EndsWith(".disabled") Then + ElseIf Path.EndsWith(".disabled") OrElse Path.EndsWith(".old") Then Return McModState.Disabled Else Return McModState.Fine @@ -365,6 +365,56 @@ Public Module ModMod Log(ex, "读取 mcmod.info 时出现未知错误(" & Path & ")", LogLevel.Developer) End Try #End Region +#Region "尝试使用 fabric.mod.json" + Try + '获取 fabric.mod.json 文件 + Dim FabricEntry As ZipArchiveEntry = Jar.GetEntry("fabric.mod.json") + Dim FabricText As String = Nothing + If FabricEntry IsNot Nothing Then + FabricText = ReadFile(FabricEntry.Open(), Encoding.UTF8) + If Not FabricText.Contains("schemaVersion") Then FabricText = Nothing + End If + If FabricText Is Nothing Then Exit Try + Dim FabricObject As JObject = GetJson(FabricText) +GotFabric: + '从文件中获取 Mod 信息项 + If FabricObject.ContainsKey("name") Then Name = FabricObject("name") + If FabricObject.ContainsKey("version") Then Version = FabricObject("version") + If FabricObject.ContainsKey("description") Then Description = FabricObject("description") + If FabricObject.ContainsKey("id") Then ModId = FabricObject("id") + If FabricObject.ContainsKey("contact") Then Url = If(FabricObject("contact")("homepage"), "") + Dim AuthorJson As JArray = FabricObject("authors") + If AuthorJson IsNot Nothing Then + Dim Author As New List(Of String) + For Each Token In AuthorJson + Author.Add(Token.ToString) + Next + If Author.Count > 0 Then Authors = Join(Author, ", ") + End If + 'If (Not FabricObject.ContainsKey("serverSideOnly")) OrElse FabricObject("serverSideOnly")("value").ToObject(Of Boolean) = False Then + ' '添加 Minecraft 依赖 + ' Dim DepMinecraft As String = If(If(FabricObject("acceptedMinecraftVersions") IsNot Nothing, FabricObject("acceptedMinecraftVersions")("value"), ""), "") + ' If DepMinecraft <> "" Then AddDependency("minecraft", DepMinecraft) + ' '添加其他依赖 + ' Dim Deps As String = If(If(FabricObject("dependencies") IsNot Nothing, FabricObject("dependencies")("value"), ""), "") + ' If Deps <> "" Then + ' For Each Dep In Deps.Split(";") + ' If Dep = "" OrElse Not Dep.StartsWith("required-") Then Continue For + ' Dep = Dep.Substring(Dep.IndexOf(":") + 1) + ' If Dep.Contains("@") Then + ' AddDependency(Dep.Split("@")(0), Dep.Split("@")(1)) + ' Else + ' AddDependency(Dep) + ' End If + ' Next + ' End If + 'End If + '加载成功 + GoTo Finished + Catch ex As Exception + Log(ex, "读取 fabric.mod.json 时出现未知错误(" & Path & ")", LogLevel.Developer) + End Try +#End Region #Region "尝试使用 mods.toml" Try '获取 mods.toml 文件 @@ -467,56 +517,6 @@ Public Module ModMod Log(ex, "读取 mods.toml 时出现未知错误(" & Path & ")", LogLevel.Developer) End Try #End Region -#Region "尝试使用 fabric.mod.json" - Try - '获取 fabric.mod.json 文件 - Dim FabricEntry As ZipArchiveEntry = Jar.GetEntry("fabric.mod.json") - Dim FabricText As String = Nothing - If FabricEntry IsNot Nothing Then - FabricText = ReadFile(FabricEntry.Open(), Encoding.UTF8) - If Not FabricText.Contains("schemaVersion") Then FabricText = Nothing - End If - If FabricText Is Nothing Then Exit Try - Dim FabricObject As JObject = GetJson(FabricText) -GotFabric: - '从文件中获取 Mod 信息项 - If FabricObject.ContainsKey("name") Then Name = FabricObject("name") - If FabricObject.ContainsKey("version") Then Version = FabricObject("version") - If FabricObject.ContainsKey("description") Then Description = FabricObject("description") - If FabricObject.ContainsKey("id") Then ModId = FabricObject("id") - If FabricObject.ContainsKey("contact") Then Url = If(FabricObject("contact")("homepage"), "") - Dim AuthorJson As JArray = FabricObject("authors") - If AuthorJson IsNot Nothing Then - Dim Author As New List(Of String) - For Each Token In AuthorJson - Author.Add(Token.ToString) - Next - If Author.Count > 0 Then Authors = Join(Author, ", ") - End If - 'If (Not FabricObject.ContainsKey("serverSideOnly")) OrElse FabricObject("serverSideOnly")("value").ToObject(Of Boolean) = False Then - ' '添加 Minecraft 依赖 - ' Dim DepMinecraft As String = If(If(FabricObject("acceptedMinecraftVersions") IsNot Nothing, FabricObject("acceptedMinecraftVersions")("value"), ""), "") - ' If DepMinecraft <> "" Then AddDependency("minecraft", DepMinecraft) - ' '添加其他依赖 - ' Dim Deps As String = If(If(FabricObject("dependencies") IsNot Nothing, FabricObject("dependencies")("value"), ""), "") - ' If Deps <> "" Then - ' For Each Dep In Deps.Split(";") - ' If Dep = "" OrElse Not Dep.StartsWith("required-") Then Continue For - ' Dep = Dep.Substring(Dep.IndexOf(":") + 1) - ' If Dep.Contains("@") Then - ' AddDependency(Dep.Split("@")(0), Dep.Split("@")(1)) - ' Else - ' AddDependency(Dep) - ' End If - ' Next - ' End If - 'End If - '加载成功 - GoTo Finished - Catch ex As Exception - Log(ex, "读取 fabric.mod.json 时出现未知错误(" & Path & ")", LogLevel.Developer) - End Try -#End Region #Region "尝试使用 fml_cache_annotation.json" Try '获取 fml_cache_annotation.json 文件 @@ -774,7 +774,7 @@ VersionFindFail: ''' 是否可能为前置 Mod。 ''' Public Function IsPresetMod() As Boolean - Return Dependencies.Count = 0 AndAlso (Name IsNot Nothing) AndAlso (Name.ToLower.Contains("core") OrElse Name.ToLower.Contains("lib")) + Return Dependencies.Count = 0 AndAlso Name IsNot Nothing AndAlso (Name.ToLower.Contains("core") OrElse Name.ToLower.Contains("lib")) End Function ''' @@ -784,7 +784,8 @@ VersionFindFail: If Path Is Nothing OrElse Not Path.Contains(".") Then Return False Path = Path.ToLower If Path.EndsWith(".jar") OrElse Path.EndsWith(".zip") OrElse Path.EndsWith(".litemod") OrElse - Path.EndsWith(".jar.disabled") OrElse Path.EndsWith(".zip.disabled") OrElse Path.EndsWith(".litemod.disabled") Then Return True + Path.EndsWith(".jar.disabled") OrElse Path.EndsWith(".zip.disabled") OrElse Path.EndsWith(".litemod.disabled") OrElse + Path.EndsWith(".jar.old") OrElse Path.EndsWith(".zip.old") OrElse Path.EndsWith(".litemod.old") Then Return True Return False End Function @@ -920,18 +921,19 @@ VersionFindFail: Log($"[Mod] 从 Modrinth 获取到 {ModrinthUpdate.Count} 个本地 Mod 的对应信息") '步骤 2:尝试读取工程信息缓存,构建其他 Mod 的对应关系 If ModrinthUpdate.Count = 0 Then Exit Sub - Dim ModrinthMapping As New Dictionary(Of String, McMod) + Dim ModrinthMapping As New Dictionary(Of String, List(Of McMod)) For Each ModEntity In Mods If Not ModrinthUpdate.ContainsKey(ModEntity.ModrinthHash) Then Continue For Dim ProjectId = ModrinthUpdate(ModEntity.ModrinthHash)("project_id").ToString If CompProjectCache.ContainsKey(ProjectId) Then ModEntity.Comp = CompProjectCache(ProjectId) Else - ModrinthMapping.Add(ProjectId, ModEntity) + If Not ModrinthMapping.ContainsKey(ProjectId) Then ModrinthMapping(ProjectId) = New List(Of McMod) + ModrinthMapping(ProjectId).Add(ModEntity) End If Next If Loader.IsAbortedWithThread(MainThread) Then Exit Sub - Log($"[Mod] 读取缓存后还需要从 Modrinth 获取 {ModrinthMapping.Count} 个本地 Mod 的工程信息") + Log($"[Mod] 读取缓存后还需要从 Modrinth 获取 {ModrinthMapping.Count} 类本地 Mod 的工程信息") '步骤 3:获取工程信息 If Not ModrinthMapping.Any() Then Exit Sub Dim ModrinthProject = CType(GetJson(NetRequestRetry( @@ -939,12 +941,13 @@ VersionFindFail: "GET", "", "application/json")), JArray) For Each ProjectJson In ModrinthProject Dim Project As New CompProject(ProjectJson) - Dim Entry = ModrinthMapping(Project.Id) - If Entry.Comp IsNot Nothing AndAlso Not Entry.IsCompFromModrinth Then - Project.LogoUrl = Entry.Comp.LogoUrl 'Modrinth 部分 Logo 加载不出来 - End If - Entry.IsCompFromModrinth = True - Entry.Comp = Project + For Each Entry In ModrinthMapping(Project.Id) + If Entry.Comp IsNot Nothing AndAlso Not Entry.IsCompFromModrinth Then + Project.LogoUrl = Entry.Comp.LogoUrl 'Modrinth 部分 Logo 加载不出来 + End If + Entry.IsCompFromModrinth = True + Entry.Comp = Project + Next Next Log($"[Mod] 从 Modrinth 获取本地 Mod 信息结束") Catch ex As Exception @@ -968,16 +971,19 @@ VersionFindFail: Log($"[Mod] 从 CurseForge 获取到 {CurseForgeRaw.Count} 个本地 Mod 的对应信息") '步骤 2:尝试读取工程信息缓存,构建其他 Mod 的对应关系 If CurseForgeRaw.Count = 0 Then Exit Sub - Dim CurseForgeMapping As New Dictionary(Of Integer, McMod) + Dim CurseForgeMapping As New Dictionary(Of Integer, List(Of McMod)) For Each Project In CurseForgeRaw Dim ProjectId = Project("id").ToString Dim Hash As UInteger = Project("file")("fileFingerprint") - Dim ModEntity = Mods.Find(Function(m) m.CurseForgeHash = Hash) - If CompProjectCache.ContainsKey(ProjectId) Then - ModEntity.Comp = CompProjectCache(ProjectId) - Else - CurseForgeMapping.Add(ProjectId, ModEntity) - End If + For Each Entry In Mods + If Entry.CurseForgeHash <> Hash Then Continue For + If CompProjectCache.ContainsKey(ProjectId) Then + Entry.Comp = CompProjectCache(ProjectId) + Else + If Not CurseForgeMapping.ContainsKey(ProjectId) Then CurseForgeMapping(ProjectId) = New List(Of McMod) + CurseForgeMapping(ProjectId).Add(Entry) + End If + Next Next If Loader.IsAbortedWithThread(MainThread) Then Exit Sub Log($"[Mod] 读取缓存后还需要从 CurseForge 获取 {CurseForgeMapping.Count} 个本地 Mod 的工程信息") @@ -987,14 +993,15 @@ VersionFindFail: $"{{""modIds"": [{CurseForgeMapping.Keys.Join(",")}]}}", "application/json")), JObject)("data") For Each ProjectJson In CurseForgeProject Dim Project As New CompProject(ProjectJson) - Dim Entry = CurseForgeMapping(Project.Id) '倒查防止 CurseForge 返回的内容有漏 - If Entry.Comp IsNot Nothing AndAlso Entry.IsCompFromModrinth Then - Entry.Comp.LogoUrl = Project.LogoUrl 'Modrinth 部分 Logo 加载不出来 - Entry.Comp = Entry.Comp '再次触发修改事件 - Continue For - End If - Entry.IsCompFromModrinth = False - Entry.Comp = Project + For Each Entry In CurseForgeMapping(Project.Id) '倒查防止 CurseForge 返回的内容有漏 + If Entry.Comp IsNot Nothing AndAlso Entry.IsCompFromModrinth Then + Entry.Comp.LogoUrl = Project.LogoUrl 'Modrinth 部分 Logo 加载不出来 + Entry.Comp = Entry.Comp '再次触发修改事件 + Continue For + End If + Entry.IsCompFromModrinth = False + Entry.Comp = Project + Next Next Log($"[Mod] 从 CurseForge 获取本地 Mod 信息结束") Catch ex As Exception diff --git a/Plain Craft Launcher 2/Modules/Minecraft/MyCompItem.xaml.vb b/Plain Craft Launcher 2/Modules/Minecraft/MyCompItem.xaml.vb index 052a24e..36371f7 100644 --- a/Plain Craft Launcher 2/Modules/Minecraft/MyCompItem.xaml.vb +++ b/Plain Craft Launcher 2/Modules/Minecraft/MyCompItem.xaml.vb @@ -20,9 +20,9 @@ PathLogo.Source = New MyBitmap(FileAddress) ElseIf _Logo.ToLower.EndsWith(".webp") Then 'Modrinth 林业 Mod 使用了不支持的 WebP 格式 Logo Log($"[Comp] 发现不支持的 WebP 格式图标,已更改为默认图标:{_Logo}") - PathLogo.Source = New MyBitmap("pack://application:,,,/images/Icons/NoIcon.png") + PathLogo.Source = New MyBitmap(PathImage & "Icons/NoIcon.png") Else - PathLogo.Source = New MyBitmap("pack://application:,,,/images/Icons/NoIcon.png") + PathLogo.Source = New MyBitmap(PathImage & "Icons/NoIcon.png") RunInNewThread(Sub() LogoLoader(FileAddress), "Comp Logo Loader " & Uuid & "#", ThreadPriority.BelowNormal) End If Else @@ -77,7 +77,7 @@ RetryStart: GoTo RetryStart Else Log(ex, $"下载资源工程图标失败({_Logo})") - RunInUi(Sub() PathLogo.Source = New MyBitmap("pack://application:,,,/images/Icons/NoIcon.png")) + RunInUi(Sub() PathLogo.Source = New MyBitmap(PathImage & "Icons/NoIcon.png")) End If End Try End Sub @@ -172,19 +172,24 @@ RetryStart: FrmMain.PageCurrent.Additional(1) = Titles End If '打开详情页 - Dim TargetVersion As String, TargetLoader As CompModLoaderType - Select Case CType(sender.Tag, CompProject).Type - Case CompType.Mod - TargetVersion = If(PageDownloadMod.Loader.Input.GameVersion, "") - Case CompType.ModPack - TargetVersion = If(PageDownloadPack.Loader.Input.GameVersion, "") - Case Else 'CompType.ResourcePack - 'FUTURE: Res - TargetVersion = "" 'If(PageDownloadResource.Loader.Input.GameVersion, "") - End Select - If CType(sender.Tag, CompProject).Type = CompType.Mod AndAlso PageDownloadMod.Loader.Input.ModLoader <> CompModLoaderType.Any Then - TargetLoader = PageDownloadMod.Loader.Input.ModLoader + Dim TargetVersion As String + Dim TargetLoader As CompModLoaderType + If FrmMain.PageCurrent.Page = FormMain.PageType.CompDetail Then + TargetVersion = FrmMain.PageCurrent.Additional(2) + TargetLoader = FrmMain.PageCurrent.Additional(3) + Else + Select Case CType(sender.Tag, CompProject).Type + Case CompType.Mod + TargetVersion = If(PageDownloadMod.Loader.Input.GameVersion, "") + TargetLoader = PageDownloadMod.Loader.Input.ModLoader + Case CompType.ModPack + TargetVersion = If(PageDownloadPack.Loader.Input.GameVersion, "") + Case Else 'CompType.ResourcePack + 'FUTURE: Res + TargetVersion = "" 'If(PageDownloadResource.Loader.Input.GameVersion, "") + End Select End If + If CType(sender.Tag, CompProject).Type <> CompType.Mod Then TargetLoader = CompModLoaderType.Any FrmMain.PageChange(New FormMain.PageStackData With {.Page = FormMain.PageType.CompDetail, .Additional = {sender.Tag, New List(Of String), TargetVersion, TargetLoader}}) End Sub diff --git a/Plain Craft Launcher 2/Modules/Minecraft/MyLocalModItem.xaml b/Plain Craft Launcher 2/Modules/Minecraft/MyLocalModItem.xaml index f7470c2..8438648 100644 --- a/Plain Craft Launcher 2/Modules/Minecraft/MyLocalModItem.xaml +++ b/Plain Craft Launcher 2/Modules/Minecraft/MyLocalModItem.xaml @@ -28,7 +28,7 @@ - + diff --git a/Plain Craft Launcher 2/Modules/Minecraft/MyLocalModItem.xaml.vb b/Plain Craft Launcher 2/Modules/Minecraft/MyLocalModItem.xaml.vb index 6eaf88e..fd7d699 100644 --- a/Plain Craft Launcher 2/Modules/Minecraft/MyLocalModItem.xaml.vb +++ b/Plain Craft Launcher 2/Modules/Minecraft/MyLocalModItem.xaml.vb @@ -22,9 +22,9 @@ Public Class MyLocalModItem PathLogo.Source = New MyBitmap(FileAddress) ElseIf _Logo.ToLower.EndsWith(".webp") Then 'Modrinth 林业 Mod 使用了不支持的 WebP 格式 Logo Log($"[LocalModItem] 发现不支持的 WebP 格式图标,已更改为默认图标:{_Logo}") - PathLogo.Source = New MyBitmap("pack://application:,,,/images/Icons/NoIcon.png") + PathLogo.Source = New MyBitmap(PathImage & "Icons/NoIcon.png") Else - PathLogo.Source = New MyBitmap("pack://application:,,,/images/Icons/NoIcon.png") + PathLogo.Source = New MyBitmap(PathImage & "Icons/NoIcon.png") RunInNewThread(Sub() LogoLoader(FileAddress), "Comp Logo Loader " & Uuid & "#", ThreadPriority.BelowNormal) End If Else @@ -79,7 +79,7 @@ RetryStart: GoTo RetryStart Else Log(ex, $"下载本地 Mod 图标失败({_Logo})") - RunInUi(Sub() PathLogo.Source = New MyBitmap("pack://application:,,,/images/Icons/NoIcon.png")) + RunInUi(Sub() PathLogo.Source = New MyBitmap(PathImage & "Icons/NoIcon.png")) End If End Try End Sub @@ -93,9 +93,12 @@ RetryStart: Set(value As String) Dim RawValue = value Select Case Entry.State + Case McMod.McModState.Fine + LabTitle.TextDecorations = Nothing Case McMod.McModState.Disabled - value &= " [禁用]" + LabTitle.TextDecorations = TextDecorations.Strikethrough Case McMod.McModState.Unavaliable + LabTitle.TextDecorations = TextDecorations.Strikethrough value &= " [错误]" End Select If LabTitle.Text = value Then Exit Property @@ -154,17 +157,6 @@ RetryStart: End Set End Property - '前景色绑定 - Public Property Foreground As Brush - Get - Return GetValue(ForegroundProperty) - End Get - Set(value As Brush) - SetValue(ForegroundProperty, value) - End Set - End Property - Public Shared ReadOnly ForegroundProperty As DependencyProperty = DependencyProperty.Register("Foreground", GetType(Brush), GetType(MyLocalModItem), New PropertyMetadata(CType(Color1, SolidColorBrush))) - #End Region #Region "点击与勾选" @@ -229,13 +221,13 @@ RetryStart: Anim.Add(AaOpacity(RectCheck, 1 - RectCheck.Opacity, 30)) RectCheck.VerticalAlignment = VerticalAlignment.Center RectCheck.Margin = New Thickness(-3, 0, 0, 0) - Anim.Add(AaColor(Me, ForegroundProperty, "ColorBrush2", 200)) + Anim.Add(AaColor(LabTitle, TextBlock.ForegroundProperty, If(Entry.State = McMod.McModState.Fine, "ColorBrush2", "ColorBrush5"), 200)) Else '由有变无 Anim.Add(AaHeight(RectCheck, -RectCheck.ActualHeight, 120,, New AniEaseInFluent(AniEasePower.Weak))) Anim.Add(AaOpacity(RectCheck, -RectCheck.Opacity, 70, 40)) RectCheck.VerticalAlignment = VerticalAlignment.Center - Anim.Add(AaColor(Me, ForegroundProperty, "ColorBrush1", 120)) + Anim.Add(AaColor(LabTitle, TextBlock.ForegroundProperty, If(LabTitle.TextDecorations Is Nothing, "ColorBrush1", "ColorBrushGray4"), 120)) End If AniStart(Anim, "MyLocalModItem Checked " & Uuid) Else @@ -245,23 +237,19 @@ RetryStart: If Checked Then RectCheck.Height = 32 RectCheck.Opacity = 1 - Foreground = CType(FindResource("ColorBrush2"), SolidColorBrush) + LabTitle.SetResourceReference(TextBlock.ForegroundProperty, If(Entry.State = McMod.McModState.Fine, "ColorBrush2", "ColorBrush5")) Else RectCheck.Height = 0 RectCheck.Opacity = 0 - Foreground = CType(FindResource("ColorBrush1"), SolidColorBrush) + LabTitle.SetResourceReference(TextBlock.ForegroundProperty, If(Entry.State = McMod.McModState.Fine, "ColorBrush1", "ColorBrushGray4")) End If AniStop("MyLocalModItem Checked " & Uuid) End If - Catch ex As Exception Log(ex, "设置 Checked 失败") End Try End Set End Property - Private Sub ColorInit(sender As Object, e As RoutedEventArgs) Handles Me.Loaded - SetResourceReference(ForegroundProperty, "ColorBrush1") - End Sub #End Region @@ -361,13 +349,18 @@ RetryStart: Title = Titles.Key SubTitle = Titles.Value & If(Entry.Version Is Nothing, "", " | " & Entry.Version) End If + If Checked Then + LabTitle.SetResourceReference(TextBlock.ForegroundProperty, If(Entry.State = McMod.McModState.Fine, "ColorBrush2", "ColorBrush5")) + Else + LabTitle.SetResourceReference(TextBlock.ForegroundProperty, If(Entry.State = McMod.McModState.Fine, "ColorBrush1", "ColorBrushGray4")) + End If '描述 Dim NewDescription As String Select Case Entry.State Case McMod.McModState.Fine NewDescription = GetFileNameWithoutExtentionFromPath(Entry.Path) Case McMod.McModState.Disabled - NewDescription = GetFileNameWithoutExtentionFromPath(Entry.Path.Substring(0, Entry.Path.Count - ".disabled".Count)) + NewDescription = GetFileNameWithoutExtentionFromPath(Entry.Path.Replace(".disabled", "").Replace(".old", "")) Case Else 'McMod.McModState.Unavaliable NewDescription = GetFileNameFromPath(Entry.Path) End Select @@ -380,7 +373,7 @@ RetryStart: End If Description = NewDescription '主 Logo - Logo = If(Entry.Comp Is Nothing, "pack://application:,,,/images/Icons/NoIcon.png", Entry.Comp.GetControlLogo()) + Logo = If(Entry.Comp Is Nothing, PathImage & "Icons/NoIcon.png", Entry.Comp.GetControlLogo()) '图标右下角的 Logo If Entry.State = McMod.McModState.Fine Then If ImgState IsNot Nothing Then @@ -390,7 +383,7 @@ RetryStart: Else If ImgState Is Nothing Then ImgState = New Image With { - .Width = 17, .Height = 17, .Margin = New Thickness(0, 0, -4, -3), .IsHitTestVisible = False, + .Width = 20, .Height = 20, .Margin = New Thickness(0, 0, -5, -3), .IsHitTestVisible = False, .HorizontalAlignment = HorizontalAlignment.Right, .VerticalAlignment = VerticalAlignment.Bottom } RenderOptions.SetBitmapScalingMode(ImgState, BitmapScalingMode.HighQuality) @@ -401,7 +394,7 @@ RetryStart: ' HorizontalAlignment="Right" VerticalAlignment="Bottom" ' Source="/Images/Icons/Unavaliable.png" /> End If - ImgState.Source = New MyBitmap($"pack://application:,,,/images/Icons/{Entry.State}.png") + ImgState.Source = New MyBitmap(PathImage & $"Icons/{Entry.State}.png") End If '标签 If Entry.Comp IsNot Nothing Then Tags = Entry.Comp.Tags diff --git a/Plain Craft Launcher 2/Modules/ModMusic.vb b/Plain Craft Launcher 2/Modules/ModMusic.vb index ed1a234..b9fa956 100644 --- a/Plain Craft Launcher 2/Modules/ModMusic.vb +++ b/Plain Craft Launcher 2/Modules/ModMusic.vb @@ -22,12 +22,11 @@ If MusicAllList Is Nothing Then MusicAllList = New List(Of String) Directory.CreateDirectory(Path & "PCL\Musics\") - For Each File In My.Computer.FileSystem.GetFiles(Path & "PCL\Musics\", FileIO.SearchOption.SearchAllSubDirectories, "*.*") + For Each File In EnumerateFiles(Path & "PCL\Musics\") '文件夹可能会被加入 .ini 文件夹配置文件、一些乱七八糟的 .jpg 文件啥的 - Dim Extend As String = File.Split(".").Last.ToLower - If Not (Extend = "ini" OrElse Extend = "jpg" OrElse Extend = "txt" OrElse Extend = "cfg" OrElse Extend = "lrc" OrElse Extend = "db" OrElse Extend = "png") Then - MusicAllList.Add(File) - End If + Dim Ext As String = File.Extension.ToLower + If {"ini", "jpg", "txt", "cfg", "lrc", "db", "png"}.Contains(Ext) Then Continue For + MusicAllList.Add(File.FullName) Next End If '打乱顺序播放 diff --git a/Plain Craft Launcher 2/My Project/AssemblyInfo.vb b/Plain Craft Launcher 2/My Project/AssemblyInfo.vb index 147e981..83ad00c 100644 --- a/Plain Craft Launcher 2/My Project/AssemblyInfo.vb +++ b/Plain Craft Launcher 2/My Project/AssemblyInfo.vb @@ -51,6 +51,6 @@ Imports System.Runtime.InteropServices ' 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号 ' 方法是按如下所示使用“*” - - + + diff --git a/Plain Craft Launcher 2/Pages/PageDownload/ModDownloadLib.vb b/Plain Craft Launcher 2/Pages/PageDownload/ModDownloadLib.vb index 3c51c07..4168646 100644 --- a/Plain Craft Launcher 2/Pages/PageDownload/ModDownloadLib.vb +++ b/Plain Craft Launcher 2/Pages/PageDownload/ModDownloadLib.vb @@ -181,13 +181,13 @@ Public Module ModDownloadLib Dim Logo As String Select Case Entry("type") Case "release" - Logo = "pack://application:,,,/images/Blocks/Grass.png" + Logo = PathImage & "Blocks/Grass.png" Case "snapshot" - Logo = "pack://application:,,,/images/Blocks/CommandBlock.png" + Logo = PathImage & "Blocks/CommandBlock.png" Case "special" - Logo = "pack://application:,,,/images/Blocks/GoldBlock.png" + Logo = PathImage & "Blocks/GoldBlock.png" Case Else - Logo = "pack://application:,,,/images/Blocks/CobbleStone.png" + Logo = PathImage & "Blocks/CobbleStone.png" End Select '建立控件 Dim NewItem As New MyListItem With {.Logo = Logo, .SnapsToDevicePixels = True, .Title = Entry("id").ToString, .Height = 42, .Type = MyListItem.CheckType.Clickable, .Tag = Entry} @@ -722,7 +722,7 @@ Retry: .Info = If(Entry.IsPreview, "测试版", "正式版") & If(Entry.ReleaseTime = "", "", ",发布于 " & Entry.ReleaseTime) & If(Entry.RequiredForgeVersion Is Nothing, ",不兼容 Forge", If(Entry.RequiredForgeVersion = "", "", ",推荐 Forge 版本:" & Entry.RequiredForgeVersion)), - .Logo = "pack://application:,,,/images/Blocks/GrassPath.png" + .Logo = PathImage & "Blocks/GrassPath.png" } AddHandler NewItem.Click, OnClick '建立菜单 @@ -951,7 +951,7 @@ Retry: Dim NewItem As New MyListItem With { .Title = Entry.Inherit, .SnapsToDevicePixels = True, .Height = 42, .Type = MyListItem.CheckType.Clickable, .Tag = Entry, .Info = If(Entry.IsPreview, "测试版", "稳定版") & If(Entry.ReleaseTime = "", "", ",发布于 " & Entry.ReleaseTime), - .Logo = "pack://application:,,,/images/Blocks/Egg.png" + .Logo = PathImage & "Blocks/Egg.png" } AddHandler NewItem.Click, OnClick '建立菜单 @@ -1349,18 +1349,20 @@ Retry: If Json("data") IsNot Nothing AndAlso Json("data")("MOJMAPS") IsNot Nothing Then '下载原版 Json 文件 Task.Progress = 0.4 - Log("[Download] 需要 Mappings 下载信息,开始获取原版 Json 文件") Dim RawJson As JObject = GetJson(NetGetCodeByDownload(DlSourceLauncherOrMetaGet(DlClientListGet(Inherit)), IsJson:=True)) - '[net.minecraft:client:1.17.1-20210706.113038:mappings@txt] + '[net.minecraft:client:1.17.1-20210706.113038:mappings@txt] 或 @tsrg] Dim OriginalName As String = Json("data")("MOJMAPS")("client").ToString.Trim("[]".ToCharArray()).Split("@")(0) - Dim Address = McLibGet(OriginalName).Replace(".jar", "-mappings.txt") + Dim Address = McLibGet(OriginalName).Replace(".jar", "-mappings." & Json("data")("MOJMAPS")("client").ToString.Trim("[]".ToCharArray()).Split("@")(1)) Libs.Add(New McLibToken With {.IsJumpLoader = False, .IsNatives = False, .LocalPath = Address, .OriginalName = OriginalName, .Url = RawJson("downloads")("client_mappings")("url"), .Size = RawJson("downloads")("client_mappings")("size"), .SHA1 = RawJson("downloads")("client_mappings")("sha1")}) + Log("[Download] 需要下载 Mappings:" & Address) End If Task.Progress = 0.8 '去除其中的原始 Forge 项 For i = 0 To Libs.Count - 1 - If Libs(i).LocalPath.EndsWith("forge-" & Inherit & "-" & Version & ".jar") Then + If Libs(i).LocalPath.EndsWith("forge-" & Inherit & "-" & Version & ".jar") OrElse + Libs(i).LocalPath.EndsWith("forge-" & Inherit & "-" & Version & "-client.jar") Then + Log("[Download] 已从待下载 Forge 支持库中移除:" & Libs(i).LocalPath, LogLevel.Debug) Libs.RemoveAt(i) Exit For End If @@ -1420,9 +1422,8 @@ Retry: Try Log("[Download] 开始进行新版方式 Forge 安装:" & InstallerAddress) '记录当前文件夹列表(在新建目标文件夹之前) - Dim OldList = New DirectoryInfo(McFolder & "versions\").EnumerateDirectories.Select(Function(Info As DirectoryInfo) As String - Return Info.FullName - End Function).ToList() + Dim OldList = New DirectoryInfo(McFolder & "versions\").EnumerateDirectories. + Select(Function(i) i.FullName).ToList() '解压并获取信息 Installer = New ZipArchive(New FileStream(InstallerAddress, FileMode.Open)) Dim Json As JObject = GetJson(ReadFile(Installer.GetEntry("install_profile.json").Open)) @@ -1452,11 +1453,12 @@ Retry: End If End Try '拷贝新增的版本 Json - Dim DeltaList = New DirectoryInfo(McFolder & "versions\").EnumerateDirectories.SkipWhile(Function(Info As DirectoryInfo) As Boolean - Return OldList.Contains(Info.FullName) - End Function).ToList() - If DeltaList.Count > 1 Then '它可能和 OptiFine 安装同时运行,导致增加的文件不止一个(这导致了 #151) - DeltaList = New List(Of DirectoryInfo) From {DeltaList.Where(Function(l) l.Name.Contains("forge")).First} + Dim DeltaList = New DirectoryInfo(McFolder & "versions\").EnumerateDirectories. + SkipWhile(Function(i) OldList.Contains(i.FullName)).ToList() + If DeltaList.Count > 1 Then + '它可能和 OptiFine 安装同时运行,导致增加的文件不止一个(这导致了 #151) + '也可能是因为 Forge 安装器的 Bug,生成了一个名字错误的文件夹,所以需要检查文件夹是否为空 + DeltaList = DeltaList.Where(Function(l) l.Name.Contains("forge") AndAlso l.EnumerateFiles.Any).ToList End If If DeltaList.Count = 1 Then '如果没有新增文件夹,那么预测的文件夹名就是正确的 Dim JsonFile As FileInfo = DeltaList(0).EnumerateFiles.First() @@ -1580,7 +1582,7 @@ Retry: .Info = If(Entry.ReleaseTime = "", If(ModeDebug, "种类:" & Entry.Category & If(Entry.Branch Is Nothing, "", ",开发分支:" & Entry.Branch), ""), "发布于 " & Entry.ReleaseTime & If(ModeDebug, ",种类:" & Entry.Category & If(Entry.Branch Is Nothing, "", ",开发分支:" & Entry.Branch), "")), - .Logo = "pack://application:,,,/images/Blocks/Anvil.png" + .Logo = PathImage & "Blocks/Anvil.png" } AddHandler NewItem.Click, OnClick '建立菜单 @@ -1785,7 +1787,7 @@ Retry: Dim NewItem As New MyListItem With { .Title = Entry("version").ToString.Replace("+build", ""), .SnapsToDevicePixels = True, .Height = 42, .Type = MyListItem.CheckType.Clickable, .Tag = Entry, .Info = If(Entry("stable").ToObject(Of Boolean), "稳定版", "测试版"), - .Logo = "pack://application:,,,/images/Blocks/Fabric.png" + .Logo = PathImage & "Blocks/Fabric.png" } AddHandler NewItem.Click, OnClick '结束 @@ -1796,7 +1798,7 @@ Retry: Dim NewItem As New MyListItem With { .Title = Entry.DisplayName.Split("]")(1).Replace("Fabric API ", "").Replace(" build ", ".").Split("+").First.Trim, .SnapsToDevicePixels = True, .Height = 42, .Type = MyListItem.CheckType.Clickable, .Tag = Entry, .Info = Entry.StatusDescription & ",发布于 " & Entry.ReleaseDate.ToString("yyyy/MM/dd HH:mm"), - .Logo = "pack://application:,,,/images/Blocks/Fabric.png" + .Logo = PathImage & "Blocks/Fabric.png" } AddHandler NewItem.Click, OnClick '结束 @@ -1807,7 +1809,7 @@ Retry: Dim NewItem As New MyListItem With { .Title = Entry.DisplayName.ToLower.Replace("optifabric-", "").Replace(".jar", "").Trim.TrimStart("v"), .SnapsToDevicePixels = True, .Height = 42, .Type = MyListItem.CheckType.Clickable, .Tag = Entry, .Info = Entry.StatusDescription & ",发布于 " & Entry.ReleaseDate.ToString("yyyy/MM/dd HH:mm"), - .Logo = "pack://application:,,,/images/Blocks/OptiFabric.png" + .Logo = PathImage & "Blocks/OptiFabric.png" } AddHandler NewItem.Click, OnClick '结束 diff --git a/Plain Craft Launcher 2/Pages/PageDownload/PageDownloadCompDetail.xaml.vb b/Plain Craft Launcher 2/Pages/PageDownload/PageDownloadCompDetail.xaml.vb index b113f75..4197cb2 100644 --- a/Plain Craft Launcher 2/Pages/PageDownload/PageDownloadCompDetail.xaml.vb +++ b/Plain Craft Launcher 2/Pages/PageDownload/PageDownloadCompDetail.xaml.vb @@ -13,6 +13,12 @@ TargetLoader = FrmMain.PageCurrent.Additional(3) PageLoaderInit(Load, PanLoad, PanMain, CardIntro, CompFileLoader, AddressOf Load_OnFinish) End Sub + Private Sub PageDownloadCompDetail_Loaded(sender As Object, e As EventArgs) Handles Me.Loaded + 'Initialized 只会执行一次 + Project = FrmMain.PageCurrent.Additional(0) + TargetVersion = FrmMain.PageCurrent.Additional(2) + TargetLoader = FrmMain.PageCurrent.Additional(3) + End Sub Private Project As CompProject Private TargetVersion As String, TargetLoader As CompModLoaderType '自动重试 @@ -55,10 +61,10 @@ TargetCard = "未知版本" ElseIf GameVersion.Contains("w") OrElse GameVersion.Contains("pre") OrElse GameVersion.Contains("rc") Then TargetCard = "快照版本" - ElseIf GameVersion.Split(".").Count >= 2 Then - TargetCard = GameVersion + ElseIf GameVersion.StartsWith("1.0") Then + TargetCard = "远古版本" Else - TargetCard = "未知版本" + TargetCard = GameVersion End If '实际进行添加 If Not Dict.ContainsKey(TargetCard) Then Dict.Add(TargetCard, New List(Of CompFile)) diff --git a/Plain Craft Launcher 2/Pages/PageDownload/PageDownloadMod.xaml b/Plain Craft Launcher 2/Pages/PageDownload/PageDownloadMod.xaml index 6aab1a8..15c5fcd 100644 --- a/Plain Craft Launcher 2/Pages/PageDownload/PageDownloadMod.xaml +++ b/Plain Craft Launcher 2/Pages/PageDownload/PageDownloadMod.xaml @@ -33,6 +33,7 @@ + diff --git a/Plain Craft Launcher 2/Pages/PageDownload/PageDownloadPack.xaml b/Plain Craft Launcher 2/Pages/PageDownload/PageDownloadPack.xaml index c3e3cc4..ecd5c63 100644 --- a/Plain Craft Launcher 2/Pages/PageDownload/PageDownloadPack.xaml +++ b/Plain Craft Launcher 2/Pages/PageDownload/PageDownloadPack.xaml @@ -32,6 +32,7 @@ + diff --git a/Plain Craft Launcher 2/Pages/PageLaunch/MySkin.xaml.vb b/Plain Craft Launcher 2/Pages/PageLaunch/MySkin.xaml.vb index 6ee13ca..098c2ce 100644 --- a/Plain Craft Launcher 2/Pages/PageLaunch/MySkin.xaml.vb +++ b/Plain Craft Launcher 2/Pages/PageLaunch/MySkin.xaml.vb @@ -237,7 +237,7 @@ Retry: {"Translator-Chinese", "Crowdin 中文翻译者披风"}, {"Translator", "Crowdin 翻译者披风"}, {"Cobalt", "Cobalt 披风"}, {"Vanilla", "原版披风"}, {"Minecon2011", "Minecon 2011 参与者披风"}, {"Minecon2012", "Minecon 2012 参与者披风"}, {"Minecon2013", "Minecon 2013 参与者披风"}, {"Minecon2015", "Minecon 2015 参与者披风"}, {"Minecon2016", "Minecon 2016 参与者披风"}, - {"Cherry Blossom Cape", "樱花披风"}, {"CherryBlossomCape", "樱花披风"} + {"Cherry Blossom", "樱花披风"} } Dim SelectionControl As New List(Of IMyRadio) From {New MyRadioBox With {.Text = "无披风"}} For Each Cape In SkinData("capes") diff --git a/Plain Craft Launcher 2/Pages/PageLaunch/PageLaunchRight.xaml.vb b/Plain Craft Launcher 2/Pages/PageLaunch/PageLaunchRight.xaml.vb index 8a51c7d..98b3fef 100644 --- a/Plain Craft Launcher 2/Pages/PageLaunch/PageLaunchRight.xaml.vb +++ b/Plain Craft Launcher 2/Pages/PageLaunch/PageLaunchRight.xaml.vb @@ -90,7 +90,7 @@ Download: GoTo Download Case 3 '简单主页 Log("[Page] 主页预设:简单主页") - Url = "https://cdn.wearclub.online/PCL/Custom.xaml" + Url = "https://gitee.com/mfn233/PCL-Mainpage/raw/main/Custom.xaml" GoTo Download Case 4 '历史上的今天 Log("[Page] 主页预设:历史上的今天") diff --git a/Plain Craft Launcher 2/Pages/PageSetup/PageSetupLaunch.xaml.vb b/Plain Craft Launcher 2/Pages/PageSetup/PageSetupLaunch.xaml.vb index a9a511e..3be6dfa 100644 --- a/Plain Craft Launcher 2/Pages/PageSetup/PageSetupLaunch.xaml.vb +++ b/Plain Craft Launcher 2/Pages/PageSetup/PageSetupLaunch.xaml.vb @@ -196,7 +196,7 @@ Dim RamAvailable As Double = Math.Round(My.Computer.Info.AvailablePhysicalMemory / 1024 / 1024 / 1024 * 10) / 10 Dim RamGameActual As Double = Math.Min(RamGame, RamAvailable) Dim RamUsed As Double = RamTotal - RamAvailable - Dim RamEmpty As Double = Math.Round(MathRange(RamTotal - RamUsed - RamGame, 0, 1000) * 10) / 10 + Dim RamEmpty As Double = Math.Round(MathClamp(RamTotal - RamUsed - RamGame, 0, 1000) * 10) / 10 '设置最大可用内存 If RamTotal <= 1.5 Then SliderRamCustom.MaxValue = Math.Max(Math.Floor((RamTotal - 0.3) / 0.1), 1) diff --git a/Plain Craft Launcher 2/Pages/PageVersion/PageVersionMod.xaml b/Plain Craft Launcher 2/Pages/PageVersion/PageVersionMod.xaml index 6f37548..b8e8f3a 100644 --- a/Plain Craft Launcher 2/Pages/PageVersion/PageVersionMod.xaml +++ b/Plain Craft Launcher 2/Pages/PageVersion/PageVersionMod.xaml @@ -8,7 +8,7 @@ - + @@ -19,7 +19,7 @@ - + @@ -35,7 +35,7 @@ - + @@ -53,7 +53,7 @@ + LogoScale="1" Logo="M508 990.4c-261.6 0-474.4-212-474.4-474.4S246.4 41.6 508 41.6s474.4 212 474.4 474.4S769.6 990.4 508 990.4zM508 136.8c-209.6 0-379.2 169.6-379.2 379.2 0 209.6 169.6 379.2 379.2 379.2s379.2-169.6 379.2-379.2C887.2 306.4 717.6 136.8 508 136.8zM697.6 563.2 318.4 563.2c-26.4 0-47.2-21.6-47.2-47.2 0-26.4 21.6-47.2 47.2-47.2l379.2 0c26.4 0 47.2 21.6 47.2 47.2C744.8 542.4 724 563.2 697.6 563.2z" /> FormMain.PageType.CompDetail Then PanBack.ScrollToHome() AniControlEnabled += 1 SelectedMods.Clear() RefreshList() @@ -122,7 +122,26 @@ ToolTipService.SetHorizontalOffset(BtnCont, 2) AddHandler BtnCont.Click, AddressOf Info_Click AddHandler sender.MouseRightButtonDown, AddressOf Info_Click - sender.Buttons = {BtnCont, BtnOpen} + Dim BtnDelete As New MyIconButton With {.LogoScale = 1.1, .Logo = Logo.IconButtonDelete, .Tag = sender} + BtnDelete.ToolTip = "删除" + ToolTipService.SetPlacement(BtnDelete, Primitives.PlacementMode.Center) + ToolTipService.SetVerticalOffset(BtnDelete, 30) + ToolTipService.SetHorizontalOffset(BtnDelete, 2) + AddHandler BtnDelete.Click, AddressOf Delete_Click + Dim BtnED As New MyIconButton With {.LogoScale = 1.1, .Logo = If(sender.Entry.State = McMod.McModState.Fine, + "M508 990.4c-261.6 0-474.4-212-474.4-474.4S246.4 41.6 508 41.6s474.4 212 474.4 474.4S769.6 990.4 508 990.4zM508 136.8c-209.6 0-379.2 169.6-379.2 379.2 0 209.6 169.6 379.2 379.2 379.2s379.2-169.6 379.2-379.2C887.2 306.4 717.6 136.8 508 136.8zM697.6 563.2 318.4 563.2c-26.4 0-47.2-21.6-47.2-47.2 0-26.4 21.6-47.2 47.2-47.2l379.2 0c26.4 0 47.2 21.6 47.2 47.2C744.8 542.4 724 563.2 697.6 563.2z", + "M512 0a512 512 0 1 0 512 512A512 512 0 0 0 512 0z m0 921.6a409.6 409.6 0 1 1 409.6-409.6 409.6 409.6 0 0 1-409.6 409.6z M716.8 339.968l-256 253.44L328.192 460.8A51.2 51.2 0 0 0 256 532.992l168.448 168.96a51.2 51.2 0 0 0 72.704 0l289.28-289.792A51.2 51.2 0 0 0 716.8 339.968z"), + .Tag = sender} + BtnED.ToolTip = If(sender.Entry.State = McMod.McModState.Fine, "禁用", "启用") + ToolTipService.SetPlacement(BtnED, Primitives.PlacementMode.Center) + ToolTipService.SetVerticalOffset(BtnED, 30) + ToolTipService.SetHorizontalOffset(BtnED, 2) + AddHandler BtnED.Click, AddressOf ED_Click + If sender.Entry.State = McMod.McModState.Unavaliable Then + sender.Buttons = {BtnCont, BtnOpen, BtnDelete} + Else + sender.Buttons = {BtnCont, BtnOpen, BtnED, BtnDelete} + End If End Sub #End Region @@ -170,6 +189,13 @@ End If End Sub + ''' + ''' 安装 Mod。 + ''' + Private Sub BtnManageInstall_Click(sender As Object, e As MouseButtonEventArgs) Handles BtnManageInstall.Click + Hint("将 Mod 文件直接拖入 PCL 窗口即可安装!") + End Sub + #End Region #Region "选择" @@ -304,17 +330,21 @@ #Region "下边栏" '启用 / 禁用 - Private Sub BtnSelectEorD_Click(sender As MyIconTextButton, e As RouteEventArgs) Handles BtnSelectEnable.Click, BtnSelectDisable.Click + Private Sub BtnSelectED_Click(sender As MyIconTextButton, e As RouteEventArgs) Handles BtnSelectEnable.Click, BtnSelectDisable.Click + EDMods(McModLoader.Output.Where(Function(m) SelectedMods.Contains(m.RawFileName)).ToList(), + Not sender.Equals(BtnSelectDisable)) + ChangeAllSelected(False) + End Sub + Private Sub EDMods(ModList As List(Of McMod), IsEnable As Boolean) Dim IsSuccessful As Boolean = True - Dim IsDisable As Boolean = sender.Equals(BtnSelectDisable) - For Each ModEntity In McModLoader.Output.Where(Function(m) SelectedMods.Contains(m.RawFileName)).ToList() + For Each ModEntity In ModList Dim NewPath As String = Nothing - If ModEntity.State = McMod.McModState.Fine And IsDisable Then + If ModEntity.State = McMod.McModState.Fine AndAlso Not IsEnable Then '禁用 NewPath = ModEntity.Path & ".disabled" - ElseIf ModEntity.State = McMod.McModState.Disabled AndAlso Not IsDisable Then + ElseIf ModEntity.State = McMod.McModState.Disabled AndAlso IsEnable Then '启用 - NewPath = ModEntity.Path.Substring(0, ModEntity.Path.Count - ".disabled".Count) + NewPath = ModEntity.Path.Replace(".disabled", "").Replace(".old", "") Else Continue For End If @@ -328,7 +358,7 @@ RefreshList(True) Return Catch ex As Exception - Log(ex, $"批量重命名 Mod 失败({If(ModEntity.Path, "null")})") + Log(ex, $"重命名 Mod 失败({If(ModEntity.Path, "null")})") IsSuccessful = False End Try '更改 Loader 和 UI 中的列表 @@ -350,61 +380,82 @@ LoaderFolderRun(McModLoader, PageVersionLeft.Version.PathIndie & "mods\", LoaderFolderRunType.UpdateOnly) End If If Not IsSuccessful Then - Hint("由于文件被占用,部分 Mod 的状态切换失败,请尝试关闭正在运行的游戏后再试!", HintType.Critical) + Hint("由于文件被占用,Mod 的状态切换失败,请尝试关闭正在运行的游戏后再试!", HintType.Critical) RefreshList(True) Else - ChangeAllSelected(False) + RefreshBottomBar() End If End Sub '删除 Private Sub BtnSelectDelete_Click() Handles BtnSelectDelete.Click - Dim IsSuccessful As Boolean = True - Dim IsShiftPressed As Boolean = My.Computer.Keyboard.ShiftKeyDown Dim DeleteList As List(Of McMod) = McModLoader.Output.Where(Function(m) SelectedMods.Contains(m.RawFileName)).ToList() - For Each ModEntity In DeleteList - '删除 - Try - If IsShiftPressed Then - File.Delete(ModEntity.Path) - Else - My.Computer.FileSystem.DeleteFile(ModEntity.Path, FileIO.UIOption.OnlyErrorDialogs, FileIO.RecycleOption.SendToRecycleBin) - End If - Catch ex As OperationCanceledException - Log(ex, "批量删除 Mod 被主动取消") - RefreshList(True) - Return - Catch ex As Exception - Log(ex, $"批量删除 Mod 失败({ModEntity.Path})", LogLevel.Msgbox) - IsSuccessful = False - End Try - '更改 Loader 和 UI 中的列表 - McModLoader.Output.Remove(ModEntity) - Dim Parent As StackPanel = If(IsSearching, PanSearchList, PanItems) - Dim IndexOfUi As Integer = Parent.Children.IndexOf(Parent.Children.OfType(Of MyLocalModItem).First(Function(i) i.Entry Is ModEntity)) - Parent.Children.RemoveAt(IndexOfUi) - Next - If Not IsSearching Then - '改变禁用数量的显示 - CType(PanItems.Parent, MyCard).Title = McModGetTitle(McModLoader.Output) - '更新加载器状态 - LoaderFolderRun(McModLoader, PageVersionLeft.Version.PathIndie & "mods\", LoaderFolderRunType.UpdateOnly) - End If - If Not IsSuccessful Then - Hint("由于文件被占用,部分 Mod 删除失败,请尝试关闭正在运行的游戏后再试!", HintType.Critical) - RefreshList(True) - ElseIf If(IsSearching, PanSearchList, PanItems).Children.Count = 0 Then - RefreshList(True) - Else - ChangeAllSelected(False) - End If - If IsSuccessful Then - If IsShiftPressed Then - Hint($"已彻底删除 {DeleteList.Count} 个文件!", HintType.Finish) - Else - Hint($"已将 {DeleteList.Count} 个文件删除到回收站!", HintType.Finish) + DeleteMods(DeleteList) + End Sub + Private Sub DeleteMods(ModList As IEnumerable(Of McMod)) + Try + Dim IsSuccessful As Boolean = True + Dim IsShiftPressed As Boolean = My.Computer.Keyboard.ShiftKeyDown + For Each ModEntity In ModList + '删除 + Try + If IsShiftPressed Then + File.Delete(ModEntity.Path) + Else + My.Computer.FileSystem.DeleteFile(ModEntity.Path, FileIO.UIOption.OnlyErrorDialogs, FileIO.RecycleOption.SendToRecycleBin) + End If + Catch ex As OperationCanceledException + Log(ex, "删除 Mod 被主动取消") + RefreshList(True) + Return + Catch ex As Exception + Log(ex, $"删除 Mod 失败({ModEntity.Path})", LogLevel.Msgbox) + IsSuccessful = False + End Try + '取消选中 + SelectedMods.Remove(ModEntity.RawFileName) + '更改 Loader 和 UI 中的列表 + McModLoader.Output.Remove(ModEntity) + Dim Parent As StackPanel = If(IsSearching, PanSearchList, PanItems) + Dim IndexOfUi As Integer = Parent.Children.IndexOf(Parent.Children.OfType(Of MyLocalModItem).First(Function(i) i.Entry Is ModEntity)) + Parent.Children.RemoveAt(IndexOfUi) + Next + If Not IsSearching Then + '改变禁用数量的显示 + CType(PanItems.Parent, MyCard).Title = McModGetTitle(McModLoader.Output) + '更新加载器状态 + LoaderFolderRun(McModLoader, PageVersionLeft.Version.PathIndie & "mods\", LoaderFolderRunType.UpdateOnly) End If - End If + If Not IsSuccessful Then + Hint("由于文件被占用,Mod 删除失败,请尝试关闭正在运行的游戏后再试!", HintType.Critical) + RefreshList(True) + ElseIf If(IsSearching, PanSearchList, PanItems).Children.Count = 0 Then + RefreshList(True) + Else + RefreshBottomBar() + End If + '显示结果提示 + If Not IsSuccessful Then Exit Sub + If IsShiftPressed Then + If ModList.Count = 1 Then + Hint($"已彻底删除 {ModList.Single.FileName}!", HintType.Finish) + Else + Hint($"已彻底删除 {ModList.Count} 个文件!", HintType.Finish) + End If + Else + If ModList.Count = 1 Then + Hint($"已将 {ModList.Single.FileName} 删除到回收站!", HintType.Finish) + Else + Hint($"已将 {ModList.Count} 个文件删除到回收站!", HintType.Finish) + End If + End If + Catch ex As OperationCanceledException + Log(ex, "删除 Mod 被主动取消") + RefreshList(True) + Catch ex As Exception + Log(ex, "删除 Mod 出现未知错误", LogLevel.Feedback) + RefreshList(True) + End Try End Sub '取消选择 @@ -494,6 +545,16 @@ Log(ex, "打开 Mod 文件位置失败", LogLevel.Feedback) End Try End Sub + '删除 + Public Sub Delete_Click(sender As MyIconButton, e As EventArgs) + Dim ListItem As MyLocalModItem = sender.Tag + DeleteMods({ListItem.Entry}) + End Sub + '启用 / 禁用 + Public Sub ED_Click(sender As MyIconButton, e As EventArgs) + Dim ListItem As MyLocalModItem = sender.Tag + EDMods(New List(Of McMod) From {ListItem.Entry}, ListItem.Entry.State = McMod.McModState.Disabled) + End Sub #End Region @@ -513,7 +574,9 @@ Dim SearchSource As New List(Of KeyValuePair(Of String, Double)) SearchSource.Add(New KeyValuePair(Of String, Double)(Entry.Name, 1)) SearchSource.Add(New KeyValuePair(Of String, Double)(Entry.FileName, 1)) - If Entry.Version IsNot Nothing Then SearchSource.Add(New KeyValuePair(Of String, Double)(Entry.Version, 0.2)) + If Entry.Version IsNot Nothing Then + SearchSource.Add(New KeyValuePair(Of String, Double)(Entry.Version, 0.2)) + End If If Entry.Description IsNot Nothing AndAlso Entry.Description <> "" Then SearchSource.Add(New KeyValuePair(Of String, Double)(Entry.Description, 0.4)) End If @@ -521,6 +584,7 @@ If Entry.Comp.RawName <> Entry.Name Then SearchSource.Add(New KeyValuePair(Of String, Double)(Entry.Comp.RawName, 1)) If Entry.Comp.TranslatedName <> Entry.Comp.RawName Then SearchSource.Add(New KeyValuePair(Of String, Double)(Entry.Comp.TranslatedName, 1)) If Entry.Comp.Description <> Entry.Description Then SearchSource.Add(New KeyValuePair(Of String, Double)(Entry.Comp.Description, 0.4)) + SearchSource.Add(New KeyValuePair(Of String, Double)(String.Join("", Entry.Comp.Tags), 0.2)) End If QueryList.Add(New SearchEntry(Of McMod) With {.Item = Entry, .SearchSource = SearchSource}) Next diff --git a/Plain Craft Launcher 2/Pages/PageVersion/PageVersionSetup.xaml.vb b/Plain Craft Launcher 2/Pages/PageVersion/PageVersionSetup.xaml.vb index f26b544..187fd03 100644 --- a/Plain Craft Launcher 2/Pages/PageVersion/PageVersionSetup.xaml.vb +++ b/Plain Craft Launcher 2/Pages/PageVersion/PageVersionSetup.xaml.vb @@ -154,7 +154,7 @@ Dim RamAvailable As Double = Math.Round(My.Computer.Info.AvailablePhysicalMemory / 1024 / 1024 / 1024 * 10) / 10 Dim RamGameActual As Double = Math.Min(RamGame, RamAvailable) Dim RamUsed As Double = RamTotal - RamAvailable - Dim RamEmpty As Double = Math.Round(MathRange(RamTotal - RamUsed - RamGame, 0, 1000) * 10) / 10 + Dim RamEmpty As Double = Math.Round(MathClamp(RamTotal - RamUsed - RamGame, 0, 1000) * 10) / 10 '设置最大可用内存 If RamTotal <= 1.5 Then SliderRamCustom.MaxValue = Math.Max(Math.Floor((RamTotal - 0.3) / 0.1), 1) diff --git a/Plain Craft Launcher 2/Resources/Help.zip b/Plain Craft Launcher 2/Resources/Help.zip index 5d452eaac638db227d2bab161d94b441f9dfbb51..23362398a84faad7577517ac242411f10073db96 100644 GIT binary patch delta 43104 zcmZ5{Q*dU{x@~ORwr$%+$F}YKv7K~m+vwP~ZQD*dxA!@9tM0y4^Q*O9R@L`3*3jHt z1WTI)gIAIT1w#V@f&v1f3ye#ICr9}A(1dLKHM9l<1oQ!vC?ub}c8`*nkI&K^Vw!qX z9Hb_w$8tGdt2gU@<+(Ed<2o9LIf-kaVDRcZ50@^Iwsde*I2DvM^~G2Jka&v^a^|0m z08FG{2;ozvk$Q?*f)<>!wfgS6`j?W|9kd0b4C8kRM*p^!RsxI)O3hJLMp~wBO1efN z+NAm;Gxry z8XZl~9cKhSKVP2D8i^WW9M4C(-6dWMb-G9#HEli5d$e(e$GP$JmRPK^vqzIBKZmt& ztt|jUGo5m?=$rK1L+eVC3BHG2%eS0Z?OB+0Yr1(!fE$d>G(wWM_N@x0tLv=1(nE$!7G2}62Y~h!C)?a7|=ON z!BDbe*e_R^?e&7gvmC*JSGzME=@USzSSWH2%9}lNUnJAJN48=EvBjV{4~QJ6re;uC zX+;sGRk)%;Yk>kaSyMoafwFf{TDF3~-1Xb~bCaySJC#cOBG~-7lUHVT?Q9N1TN9uq zD+(K9pH1ym>cCK%EET;#X|PdQn} zy|<3m7cheJWN=*^cJ>|Quf#;*q)R{y($N@4!nQuqon7@S z5jH(r!^OFjaSy3lR-BmnCJhi6{Kt>1Vff-l)3e|}B4;=c>~GD$h8;=PyyV-dxOw9P33kD5sGx^z4V z%~$;qoSl&4pvu|_MpDzM2hk!m_6i|410w9aQ*nISAn8L}gudii1%s%6UOsykca~&B z7a22LDqyWA+sJEa?*@AN2S0!{NGZVW?e_Vu zJ9`g_`c=?4mYv3gQVv9ssvu5mH*yg%VE)ZN4oxqKPPuK9l2nGC|IoiCT3Q4T3JQ(q`c zZ;2JOj~0)x%#=1>4hPVlooTR0;q2)NT~_GnDZYKKDeJOld6q|rKSvKjASF-V8r7zc z155j%0@j5k&)7_9ln|&8XMa~s2TqF@P*^sUha^^A($rk`1<@$=ukfnZHhXQOts9t|9QI)cMN|V+>r*( z|4op~jB4xo77UoB?E5;CkWzXh2y7o6KUqBX>b~1cNKrrhj6Q>;Zd z_h(vyP}dBtG#75G+h-No5HxAEKT4s_RTGVD`;@X`BlJxvXy=9pOA~{@UWdN>nh{wRbnYG_QGl&+d34q>KW5+SJDiC1`MAVSe(DY*x+QbC(Voek!Q6ni;PTQiq1h6s2K&}5m zG1-9DATEVgcDnS1pw1bJi=1_C?CB8k#-H>E^ufgk{alu+8`7)(I7__DHwVVk!X>+G z2oE@~_mOf~{(|bRKs>n<$x9sDA4Z{$lD~z_1&wk@q7!}kex1HWrXKrT+_>m+Ghsi@ zg^!qC77GP#ZZVjRGTLyu~UIJLmkrb!mTr7I6!O>6NE1^s{lO}~|L&5mB zaFq?`9iHnI{?!%saUwiz;(D)A-)VDtB8ox~Ut0oYH<)ALJu^74LvAEIN(+k0fDCfL zBnM~iC)%Ya$@rum0!N2}idm&~>EH9gL9>iCHGKs_EzfUm$0C1i2a9NPPi_(LI0V4$ zT_SqDw84DFym^2NA;=8i&m0Aef&GDvBe&G_;oCYZ$?aj{h*Op67Ufd3?R-tM34_%K zsf|@pptnuB8Q%c0$~+oGI)≠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 delta 44157 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

270Pqa^kUrV^ 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 R2YtmF0Z0>^!G-w4{to~zJ!=2}