Improve category matching
This commit is contained in:
@@ -119,6 +119,7 @@ public class AddonCategoryConfigurationWindow : NativeAddon
|
||||
listNode.AddOption(newWrapper);
|
||||
|
||||
RefreshSelectionList();
|
||||
System.AddonInventoryWindow.ManualInventoryRefresh();
|
||||
}
|
||||
|
||||
private void OnRemoveCategory(CategoryWrapper categoryWrapper)
|
||||
@@ -134,6 +135,7 @@ public class AddonCategoryConfigurationWindow : NativeAddon
|
||||
{
|
||||
OnOptionChanged(null);
|
||||
}
|
||||
System.AddonInventoryWindow.ManualInventoryRefresh();
|
||||
}
|
||||
|
||||
private void RefreshSelectionList()
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
using AetherBags.Configuration;
|
||||
using AetherBags.Inventory;
|
||||
using Dalamud.Game.Text.SeStringHandling;
|
||||
using KamiToolKit.Premade;
|
||||
using SeStringBuilder = Lumina.Text.SeStringBuilder;
|
||||
|
||||
namespace AetherBags.Addons;
|
||||
|
||||
@@ -13,7 +16,8 @@ public class CategoryWrapper(UserCategoryDefinition categoryDefinition) : IInfoN
|
||||
}
|
||||
|
||||
public string GetSubLabel() {
|
||||
return CategoryDefinition!.Enabled ? "Enabled" : "Disabled";
|
||||
if(UserCategoryMatcher.IsCatchAll(CategoryDefinition!)) return " No valid rules!";
|
||||
return CategoryDefinition!.Enabled ? "✓ Enabled" : " Disabled";
|
||||
}
|
||||
|
||||
public uint? GetId() => null;
|
||||
|
||||
@@ -54,6 +54,13 @@ public static class CategoryBucketManager
|
||||
for (int i = 0; i < sortedScratch.Count; i++)
|
||||
{
|
||||
UserCategoryDefinition category = sortedScratch[i];
|
||||
|
||||
if (!category.Enabled)
|
||||
continue;
|
||||
|
||||
if (UserCategoryMatcher.IsCatchAll(category))
|
||||
continue;
|
||||
|
||||
uint bucketKey = MakeUserCategoryKey(category.Order);
|
||||
|
||||
if (!bucketsByKey.TryGetValue(bucketKey, out CategoryBucket? bucket))
|
||||
|
||||
@@ -11,6 +11,44 @@ internal static class UserCategoryMatcher
|
||||
{
|
||||
var rules = userCategory.Rules;
|
||||
|
||||
bool hasIdentificationFilters = rules.AllowedItemIds.Count > 0 || rules.AllowedItemNamePatterns.Count > 0;
|
||||
|
||||
if (hasIdentificationFilters)
|
||||
{
|
||||
bool matchesAnyIdentification = false;
|
||||
|
||||
if (rules.AllowedItemIds.Count > 0 && rules.AllowedItemIds.Contains(item.Item.ItemId))
|
||||
{
|
||||
matchesAnyIdentification = true;
|
||||
}
|
||||
|
||||
if (!matchesAnyIdentification && rules.AllowedItemNamePatterns.Count > 0)
|
||||
{
|
||||
for (int i = 0; i < rules.AllowedItemNamePatterns.Count; i++)
|
||||
{
|
||||
string pattern = rules.AllowedItemNamePatterns[i];
|
||||
if (string.IsNullOrWhiteSpace(pattern))
|
||||
continue;
|
||||
|
||||
try
|
||||
{
|
||||
if (Regex.IsMatch(item.Name, pattern, RegexOptions.CultureInvariant | RegexOptions.IgnoreCase))
|
||||
{
|
||||
matchesAnyIdentification = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Invalid regex: ignore it.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!matchesAnyIdentification)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (rules.AllowedUiCategoryIds.Count > 0)
|
||||
{
|
||||
uint uiCategoryId = item.UiCategory.RowId;
|
||||
@@ -18,9 +56,6 @@ internal static class UserCategoryMatcher
|
||||
return false;
|
||||
}
|
||||
|
||||
if (rules.AllowedItemIds.Count > 0 && !rules.AllowedItemIds.Contains(item.Item.ItemId))
|
||||
return false;
|
||||
|
||||
if (rules.AllowedRarities.Count > 0 && !rules.AllowedRarities.Contains(item.Rarity))
|
||||
return false;
|
||||
|
||||
@@ -39,40 +74,46 @@ internal static class UserCategoryMatcher
|
||||
if (!MatchesToggle(rules.Dyeable, item.IsDyeable)) return false;
|
||||
if (!MatchesToggle(rules.Repairable, item.IsRepairable)) return false;
|
||||
|
||||
if (rules.AllowedItemNamePatterns.Count > 0)
|
||||
{
|
||||
bool any = false;
|
||||
for (int i = 0; i < rules.AllowedItemNamePatterns.Count; i++)
|
||||
{
|
||||
string pattern = rules.AllowedItemNamePatterns[i];
|
||||
if (string.IsNullOrWhiteSpace(pattern))
|
||||
continue;
|
||||
|
||||
// Treat patterns as regex for now.
|
||||
try
|
||||
{
|
||||
if (Regex.IsMatch(item.Name, pattern, RegexOptions.CultureInvariant | RegexOptions.IgnoreCase))
|
||||
{
|
||||
any = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Invalid regex: ignore it.
|
||||
}
|
||||
}
|
||||
|
||||
if (!any)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool InRange<T>(T value, T min, T max) where T : struct, IComparable<T>
|
||||
=> value.CompareTo(min) >= 0 && value.CompareTo(max) <= 0;
|
||||
|
||||
public static bool IsCatchAll(UserCategoryDefinition userCategory)
|
||||
{
|
||||
var rules = userCategory.Rules;
|
||||
|
||||
if (rules.AllowedItemIds.Count > 0)
|
||||
return false;
|
||||
if (rules.AllowedItemNamePatterns.Count > 0)
|
||||
return false;
|
||||
if (rules.AllowedUiCategoryIds.Count > 0)
|
||||
return false;
|
||||
if (rules.AllowedRarities.Count > 0)
|
||||
return false;
|
||||
|
||||
if (rules.Level.Enabled)
|
||||
return false;
|
||||
if (rules.ItemLevel.Enabled)
|
||||
return false;
|
||||
if (rules.VendorPrice.Enabled)
|
||||
return false;
|
||||
|
||||
if (rules.Untradable.ToggleState != ToggleFilterState.Ignored)
|
||||
return false;
|
||||
if (rules.Unique.ToggleState != ToggleFilterState.Ignored)
|
||||
return false;
|
||||
if (rules.Collectable.ToggleState != ToggleFilterState.Ignored)
|
||||
return false;
|
||||
if (rules.Dyeable.ToggleState != ToggleFilterState.Ignored)
|
||||
return false;
|
||||
if (rules.Repairable.ToggleState != ToggleFilterState.Ignored)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool MatchesToggle(StateFilter filter, bool itemHasProperty)
|
||||
=> filter.ToggleState switch
|
||||
{
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Numerics;
|
||||
using AetherBags.Configuration;
|
||||
using AetherBags.Inventory;
|
||||
using AetherBags.Nodes.Color;
|
||||
using Dalamud.Utility;
|
||||
using FFXIVClientStructs.FFXIV.Component.GUI;
|
||||
@@ -8,6 +9,7 @@ using KamiToolKit.Classes;
|
||||
using KamiToolKit.Nodes;
|
||||
using Lumina.Excel;
|
||||
using Lumina.Excel.Sheets;
|
||||
using Lumina.Text;
|
||||
using Action = System.Action;
|
||||
|
||||
namespace AetherBags.Nodes.Configuration.Category;
|
||||
@@ -65,6 +67,17 @@ public sealed class CategoryDefinitionConfigurationNode : VerticalListNode
|
||||
FitContents = true;
|
||||
ItemSpacing = 4.0f;
|
||||
|
||||
var catchAllWarningNode = new TextNode
|
||||
{
|
||||
Size = new Vector2(300, 40),
|
||||
TextFlags = TextFlags.MultiLine | TextFlags.AutoAdjustNodeSize,
|
||||
SeString = new SeStringBuilder().Append(" Warning: No rules configured\nThis category won't match anything!").ToReadOnlySeString(),
|
||||
TextColor = ColorHelper.GetColor(17),
|
||||
LineSpacing = 20,
|
||||
IsVisible = UserCategoryMatcher.IsCatchAll(CategoryDefinition),
|
||||
};
|
||||
AddNode(catchAllWarningNode);
|
||||
|
||||
AddNode(CreateSectionHeader("Basic Settings"));
|
||||
|
||||
_enabledCheckbox = new CheckboxNode
|
||||
@@ -297,7 +310,7 @@ public sealed class CategoryDefinitionConfigurationNode : VerticalListNode
|
||||
|
||||
private static void NotifyChanged()
|
||||
{
|
||||
System.AddonInventoryWindow?.ManualInventoryRefresh();
|
||||
System.AddonInventoryWindow.ManualInventoryRefresh();
|
||||
}
|
||||
|
||||
private void NotifyCategoryPropertyChanged()
|
||||
|
||||
@@ -87,7 +87,7 @@ public sealed class InventoryNotificationNode : SimpleComponentNode
|
||||
|
||||
Timeline?.PlayAnimation(101);
|
||||
}
|
||||
} = new("sdsdsd", "sdsd");
|
||||
}
|
||||
|
||||
// Future Zeff, this always goes on a parent
|
||||
private Timeline ParentLabels => new TimelineBuilder()
|
||||
|
||||
Reference in New Issue
Block a user