From ea2c57385f256f0757fcec62b6343ff1affc849e Mon Sep 17 00:00:00 2001 From: Kurt Date: Thu, 25 Feb 2021 08:48:24 -0800 Subject: [PATCH] Update item parsing for symbol sensitivity ? block block need to return "block" if the input string is "block", and not the symbol-whitespace skipped "? block". https://github.com/kwsch/SysBot.AnimalCrossing/issues/10 --- NHSE.Core/Editing/ItemRequest/ItemParser.cs | 26 +++++++++++++++++---- NHSE.Tests/ItemParsingTests.cs | 2 ++ 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/NHSE.Core/Editing/ItemRequest/ItemParser.cs b/NHSE.Core/Editing/ItemRequest/ItemParser.cs index cff8408..0f35c14 100644 --- a/NHSE.Core/Editing/ItemRequest/ItemParser.cs +++ b/NHSE.Core/Editing/ItemRequest/ItemParser.cs @@ -239,7 +239,15 @@ private static Item FinalizeItem(int requestIndex, IConfigItem config, ItemDesti } private static readonly CompareInfo Comparer = CultureInfo.InvariantCulture.CompareInfo; - private const CompareOptions opt = CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace | CompareOptions.IgnoreSymbols | CompareOptions.IgnoreWidth; + private const CompareOptions optIncludeSymbols = CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace | CompareOptions.IgnoreWidth; + private const CompareOptions optIgnoreSymbols = CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace | CompareOptions.IgnoreSymbols | CompareOptions.IgnoreWidth; + + /// + /// Gets a sensitive compare option, depending on the input string's qualities. + /// + /// Input string + /// Default options if no symbols, + private static CompareOptions GetCompareOption(string str) => str.Any(ch => !char.IsLetterOrDigit(ch) && !char.IsWhiteSpace(ch)) ? optIgnoreSymbols & ~CompareOptions.IgnoreSymbols : optIgnoreSymbols; /// /// Gets the first item name-value that contains the (case insensitive). @@ -259,7 +267,7 @@ public static Item GetItem(string itemName, string lang = "en") /// Requested Item /// Game strings /// Returns if no match found. - public static Item GetItem(string itemName, IEnumerable strings) + public static Item GetItem(string itemName, ICollection strings) { if (TryGetItem(itemName, strings, out var id)) return new Item(id); @@ -273,7 +281,14 @@ public static Item GetItem(string itemName, IEnumerable strings) /// List of item name-values /// Item ID, if found. Otherwise, 0 /// True if found, false if none. - public static bool TryGetItem(string itemName, IEnumerable strings, out ushort value) + public static bool TryGetItem(string itemName, ICollection strings, out ushort value) + { + if (TryGetItem(itemName, strings, out value, optIncludeSymbols)) + return true; + return TryGetItem(itemName, strings, out value, optIgnoreSymbols); + } + + private static bool TryGetItem(string itemName, IEnumerable strings, out ushort value, CompareOptions opt) { foreach (var item in strings) { @@ -294,8 +309,9 @@ public static bool TryGetItem(string itemName, IEnumerable strings, o /// /// Item name /// Item names (and their Item ID values) - public static IEnumerable GetItemsMatching(string itemName, IReadOnlyList strings) + public static IEnumerable GetItemsMatching(string itemName, IEnumerable strings) { + var opt = GetCompareOption(itemName); foreach (var item in strings) { var result = Comparer.IndexOf(item.Text, itemName, opt); @@ -313,7 +329,7 @@ public static IEnumerable GetItemsMatching(string itemName, IReadOnly /// /// Item name /// Item names (and their Item ID values) - public static IEnumerable GetItemsMatchingOrdered(string itemName, IReadOnlyList strings) + public static IEnumerable GetItemsMatchingOrdered(string itemName, IEnumerable strings) { var matches = GetItemsMatching(itemName, strings); return GetItemsClosestOrdered(itemName, matches); diff --git a/NHSE.Tests/ItemParsingTests.cs b/NHSE.Tests/ItemParsingTests.cs index 55d5e95..6fd1ed2 100644 --- a/NHSE.Tests/ItemParsingTests.cs +++ b/NHSE.Tests/ItemParsingTests.cs @@ -9,6 +9,8 @@ public static class ItemParsingTests { [Theory] [InlineData("diner sofa", 0x102D)] + [InlineData("? block", 0x35FD)] + [InlineData("block", 0x35FE)] public static void ParseItem(string name, ushort id) { // single