diff --git a/Plain Craft Launcher 2/Modules/Minecraft/ModComp.vb b/Plain Craft Launcher 2/Modules/Minecraft/ModComp.vb
index 0a76bf394..827360bbf 100644
--- a/Plain Craft Launcher 2/Modules/Minecraft/ModComp.vb
+++ b/Plain Craft Launcher 2/Modules/Minecraft/ModComp.vb
@@ -807,8 +807,8 @@ NoSubtitle:
'''
Public ReadOnly Property CanContinue As Boolean
Get
- If Tag.StartsWithF("/") OrElse Not Source.HasFlag(CompSourceType.CurseForge) Then Storage.CurseForgeTotal = 0
- If Tag.EndsWithF("/") OrElse Not Source.HasFlag(CompSourceType.Modrinth) Then Storage.ModrinthTotal = 0
+ If Tag.NotSupportCf OrElse Not Source.HasFlag(CompSourceType.CurseForge) Then Storage.CurseForgeTotal = 0
+ If Tag.NotSupportMr OrElse Not Source.HasFlag(CompSourceType.Modrinth) Then Storage.ModrinthTotal = 0
If Storage.CurseForgeTotal = -1 OrElse Storage.ModrinthTotal = -1 Then Return True
Return Storage.CurseForgeOffset < Storage.CurseForgeTotal OrElse Storage.ModrinthOffset < Storage.ModrinthTotal
End Get
@@ -821,9 +821,9 @@ NoSubtitle:
'''
Public Type As CompType
'''
- ''' 筛选资源标签。空字符串代表不限制。格式例如 "406/worldgen",分别是 CurseForge 和 Modrinth 的 ID。
+ ''' 筛选资源标签。
'''
- Public Tag As String = ""
+ Public Tag As PageComp.FilterTag
'''
''' 筛选 Mod 加载器类别。
'''
@@ -856,7 +856,7 @@ NoSubtitle:
'''
Public Function GetCurseForgeAddress() As String
If Not Source.HasFlag(CompSourceType.CurseForge) Then Return Nothing
- If Tag.StartsWithF("/") Then Storage.CurseForgeTotal = 0
+ If Tag.NotSupportCf Then Storage.CurseForgeTotal = 0
If Storage.CurseForgeTotal > -1 AndAlso Storage.CurseForgeTotal <= Storage.CurseForgeOffset Then Return Nothing
'应用筛选参数
Dim Address As String = $"https://api.curseforge.com/v1/mods/search?gameId=432&sortField=2&sortOrder=desc&pageSize={CompPageSize}"
@@ -872,7 +872,7 @@ NoSubtitle:
Case CompType.ResourcePack
Address += "&classId=12"
End Select
- Address += "&categoryId=" & If(Tag = "", "0", Tag.BeforeFirst("/"))
+ Address += "&categoryId=" & If(Not Tag.HasFilter, "0", Tag.CfValue)
If ModLoader <> CompModLoaderType.Any Then Address += "&modLoaderType=" & CType(ModLoader, Integer)
If Not String.IsNullOrEmpty(GameVersion) Then Address += "&gameVersion=" & GameVersion
If Not String.IsNullOrEmpty(SearchText) Then Address += "&searchFilter=" & Net.WebUtility.UrlEncode(SearchText)
@@ -884,7 +884,7 @@ NoSubtitle:
'''
Public Function GetModrinthAddress() As String
If Not Source.HasFlag(CompSourceType.Modrinth) Then Return Nothing
- If Tag.EndsWithF("/") Then Storage.ModrinthTotal = 0
+ If Tag.NotSupportMr Then Storage.ModrinthTotal = 0
If Storage.ModrinthTotal > -1 AndAlso Storage.ModrinthTotal <= Storage.ModrinthOffset Then Return Nothing
'应用筛选参数
Dim Address As String = $"https://api.modrinth.com/v2/search?limit={CompPageSize}&index=relevance"
@@ -893,7 +893,7 @@ NoSubtitle:
'facets=[["categories:'game-mechanics'"],["categories:'forge'"],["versions:1.19.3"],["project_type:mod"]]
Dim Facets As New List(Of String)
Facets.Add($"[""project_type:{GetStringFromEnum(Type).ToLower}""]")
- If Not String.IsNullOrEmpty(Tag) Then Facets.Add($"[""categories:'{Tag.AfterLast("/")}'""]")
+ If Tag.HasFilter Then Facets.Add($"[""categories:'{Tag.MrValue}'""]")
If ModLoader <> CompModLoaderType.Any Then Facets.Add($"[""categories:'{GetStringFromEnum(ModLoader).ToLower}'""]")
If Not String.IsNullOrEmpty(GameVersion) Then Facets.Add($"[""versions:'{GameVersion}'""]")
Address += "&facets=[" & String.Join(",", Facets) & "]"
@@ -905,7 +905,7 @@ NoSubtitle:
Dim request = TryCast(obj, CompProjectRequest)
Return request IsNot Nothing AndAlso
Type = request.Type AndAlso TargetResultCount = request.TargetResultCount AndAlso
- Tag = request.Tag AndAlso ModLoader = request.ModLoader AndAlso Source = request.Source AndAlso
+ Tag.Equals(request.Tag) AndAlso ModLoader = request.ModLoader AndAlso Source = request.Source AndAlso
GameVersion = request.GameVersion AndAlso SearchText = request.SearchText
End Function
Public Shared Operator =(left As CompProjectRequest, right As CompProjectRequest) As Boolean
@@ -1145,9 +1145,9 @@ Retry:
Else
If IsChineseSearch AndAlso Not (Request.Type = CompType.Mod OrElse Request.Type = CompType.DataPack) Then
Throw New Exception("没有搜索结果,请尝试使用英文搜索")
- ElseIf Request.Source = CompSourceType.CurseForge AndAlso Request.Tag.StartsWithF("/") Then
+ ElseIf Request.Source = CompSourceType.CurseForge AndAlso Request.Tag.NotSupportCf Then
Throw New Exception("CurseForge 不兼容所选的类型")
- ElseIf Request.Source = CompSourceType.Modrinth AndAlso Request.Tag.EndsWithF("/") Then
+ ElseIf Request.Source = CompSourceType.Modrinth AndAlso Request.Tag.NotSupportMr Then
Throw New Exception("Modrinth 不兼容所选的类型")
Else
Throw New Exception("没有搜索结果")
diff --git a/Plain Craft Launcher 2/Pages/PageDownload/Comp/PageComp.xaml.vb b/Plain Craft Launcher 2/Pages/PageDownload/Comp/PageComp.xaml.vb
index 3ad75d4a9..27c953301 100644
--- a/Plain Craft Launcher 2/Pages/PageDownload/Comp/PageComp.xaml.vb
+++ b/Plain Craft Launcher 2/Pages/PageDownload/Comp/PageComp.xaml.vb
@@ -1,4 +1,6 @@
-Imports System.Windows.Markup
+Imports System.ComponentModel
+Imports System.Globalization
+Imports System.Windows.Markup
Public Class PageComp
@@ -104,6 +106,64 @@ Public Class PageComp
CType(Parent, MyPageRight).PageLoaderInit(Load, PanLoad, PanContent, PanAlways, Loader, AddressOf Load_OnFinish, AddressOf LoaderInput)
If McVersionHighest = -1 Then McVersionHighest = Math.Max(McVersionHighest, Integer.Parse(CType(TextSearchVersion.Items(1), MyComboBoxItem).Content.ToString.Split(".")(1)))
End Sub
+
+
+#Region "FilterTag"
+ Public Shared Function GetFilterTag(element As DependencyObject) As FilterTag
+ If element Is Nothing Then Throw New ArgumentNullException("element")
+ Return element.GetValue(FilterTagProperty)
+ End Function
+ Public Shared Sub SetFilterTag(element As DependencyObject, value As FilterTag)
+ If element Is Nothing Then Throw New ArgumentNullException("element")
+ element.SetValue(FilterTagProperty, value)
+ End Sub
+ Public Shared ReadOnly FilterTagProperty As DependencyProperty =
+ DependencyProperty.RegisterAttached("FilterTag", GetType(FilterTag), GetType(PageComp), New PropertyMetadata(New FilterTag))
+ '''
+ ''' 搜索工程时的 Tag 筛选器,xaml 中的书写格式例如 "406/worldgen",分别是 CurseForge 和 Modrinth 的 ID。
+ '''
+
+ Public Structure FilterTag
+ Public ReadOnly HasFilter As Boolean '调无参构造的时候 HasFilter 就是 False,代表着不做任何筛选
+ Public ReadOnly CfValue As String '调有参构造的话这两个一定非 Nothing,为 String.Empty 时代表着筛选器不支持对应的搜索来源
+ Public ReadOnly MrValue As String
+ Public ReadOnly Property NotSupportCf As Boolean
+ Get
+ Return HasFilter AndAlso String.IsNullOrEmpty(CfValue)
+ End Get
+ End Property
+ Public ReadOnly Property NotSupportMr As Boolean
+ Get
+ Return HasFilter AndAlso String.IsNullOrEmpty(MrValue)
+ End Get
+ End Property
+ Public Sub New(CfValue As String, MrValue As String)
+ HasFilter = True
+ Me.CfValue = If(CfValue, "")
+ Me.MrValue = If(MrValue, "")
+ End Sub
+ Public Overrides Function ToString() As String
+ Return If(HasFilter, $"{CfValue}/{MrValue}", "")
+ End Function
+ End Structure
+ Public Class FilterTagTypeConverter
+ Inherits TypeConverter
+ Public Overrides Function CanConvertFrom(context As ITypeDescriptorContext, sourceType As Type) As Boolean
+ Return (sourceType Is GetType(String)) OrElse MyBase.CanConvertFrom(context, sourceType)
+ End Function
+ Public Overrides Function ConvertFrom(context As ITypeDescriptorContext, culture As CultureInfo, value As Object) As Object
+ If TypeOf value Is String Then
+ With CType(value, String)
+ If .Length = 0 Then Return New FilterTag
+ Dim Splited As String() = .Split("/"c)
+ If Splited.Length = 2 Then Return New FilterTag(Splited(0), Splited(1))
+ End With
+ End If
+ Return MyBase.ConvertFrom(context, culture, value)
+ End Function
+ End Class
+#End Region
+
Private Function LoaderInput() As CompProjectRequest
Dim Request As New CompProjectRequest(PageType, Storage, (Page + 1) * PageSize)
Dim GameVersion As String = If(TextSearchVersion.Text = "全部 (也可自行输入)", Nothing,
@@ -111,7 +171,7 @@ Public Class PageComp
With Request
.SearchText = TextSearchName.Text
.GameVersion = GameVersion
- .Tag = ComboSearchTag.SelectedItem.Tag
+ .Tag = GetFilterTag(ComboSearchTag.SelectedItem)
.ModLoader = If(PageType = CompType.Mod, Val(ComboSearchLoader.SelectedItem.Tag), CompModLoaderType.Any)
.Source = CType(Val(ComboSearchSource.SelectedItem.Tag), CompSourceType)
End With
diff --git a/Plain Craft Launcher 2/Pages/PageDownload/Comp/PageDownloadDataPack.xaml b/Plain Craft Launcher 2/Pages/PageDownload/Comp/PageDownloadDataPack.xaml
index f7c01e924..60490d990 100644
--- a/Plain Craft Launcher 2/Pages/PageDownload/Comp/PageDownloadDataPack.xaml
+++ b/Plain Craft Launcher 2/Pages/PageDownload/Comp/PageDownloadDataPack.xaml
@@ -5,22 +5,22 @@
mc:Ignorable="d" x:Class="PageDownloadDataPack"
PanScroll="{Binding ElementName=Content}">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Plain Craft Launcher 2/Pages/PageDownload/Comp/PageDownloadMod.xaml b/Plain Craft Launcher 2/Pages/PageDownload/Comp/PageDownloadMod.xaml
index c7914d975..8790f7117 100644
--- a/Plain Craft Launcher 2/Pages/PageDownload/Comp/PageDownloadMod.xaml
+++ b/Plain Craft Launcher 2/Pages/PageDownload/Comp/PageDownloadMod.xaml
@@ -5,31 +5,31 @@
mc:Ignorable="d" x:Class="PageDownloadMod"
PanScroll="{Binding ElementName=Content}">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Plain Craft Launcher 2/Pages/PageDownload/Comp/PageDownloadPack.xaml b/Plain Craft Launcher 2/Pages/PageDownload/Comp/PageDownloadPack.xaml
index 51f04d644..141ad7f81 100644
--- a/Plain Craft Launcher 2/Pages/PageDownload/Comp/PageDownloadPack.xaml
+++ b/Plain Craft Launcher 2/Pages/PageDownload/Comp/PageDownloadPack.xaml
@@ -5,24 +5,24 @@
mc:Ignorable="d" x:Class="PageDownloadPack"
PanScroll="{Binding ElementName=Content}">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Plain Craft Launcher 2/Pages/PageDownload/Comp/PageDownloadResourcePack.xaml b/Plain Craft Launcher 2/Pages/PageDownload/Comp/PageDownloadResourcePack.xaml
index 91932d587..28402a160 100644
--- a/Plain Craft Launcher 2/Pages/PageDownload/Comp/PageDownloadResourcePack.xaml
+++ b/Plain Craft Launcher 2/Pages/PageDownload/Comp/PageDownloadResourcePack.xaml
@@ -5,41 +5,41 @@
mc:Ignorable="d" x:Class="PageDownloadResourcePack"
PanScroll="{Binding ElementName=Content}">
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
diff --git a/Plain Craft Launcher 2/Pages/PageDownload/Comp/PageDownloadShader.xaml b/Plain Craft Launcher 2/Pages/PageDownload/Comp/PageDownloadShader.xaml
index 123ce1b45..80a117bfe 100644
--- a/Plain Craft Launcher 2/Pages/PageDownload/Comp/PageDownloadShader.xaml
+++ b/Plain Craft Launcher 2/Pages/PageDownload/Comp/PageDownloadShader.xaml
@@ -5,30 +5,30 @@
mc:Ignorable="d" x:Class="PageDownloadShader"
PanScroll="{Binding ElementName=Content}">
-
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+