Commit a1e13a9e authored by ElderLich's avatar ElderLich

Bug Fix: JP IME full-width EN input fails in deck search box

Japanese users typing in JP-EN IME mode can enter full-width Latin/numeric characters that look like normal English, but MDPro3 search treats them as different characters. Because search matching was width-sensitive, valid queries in the deck search box returned no results or incorrect filtering.
parent d341b7f6
...@@ -6,6 +6,7 @@ using Mono.Data.Sqlite; ...@@ -6,6 +6,7 @@ using Mono.Data.Sqlite;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Data; using System.Data;
using System.Globalization;
using System.IO; using System.IO;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using YGOSharp.OCGWrapper; using YGOSharp.OCGWrapper;
...@@ -20,6 +21,9 @@ namespace MDPro3.Duel.YGOSharp ...@@ -20,6 +21,9 @@ namespace MDPro3.Duel.YGOSharp
public static IDictionary<int, Card> _cards = new Dictionary<int, Card>(); public static IDictionary<int, Card> _cards = new Dictionary<int, Card>();
public static IDictionary<int, Card> _cardsForRender = new Dictionary<int, Card>(); public static IDictionary<int, Card> _cardsForRender = new Dictionary<int, Card>();
private static readonly CompareInfo SearchCompareInfo = CultureInfo.InvariantCulture.CompareInfo;
private const CompareOptions SearchCompareOptions =
CompareOptions.IgnoreCase | CompareOptions.IgnoreWidth | CompareOptions.IgnoreKanaType;
public static List<string> setNameHead = new() public static List<string> setNameHead = new()
{ {
...@@ -269,6 +273,30 @@ namespace MDPro3.Duel.YGOSharp ...@@ -269,6 +273,30 @@ namespace MDPro3.Duel.YGOSharp
return returnValue; return returnValue;
} }
private static bool MatchWithSearchOptions(string source, string keyword)
{
if (string.IsNullOrEmpty(source) || string.IsNullOrEmpty(keyword))
return false;
try
{
if (Regex.Replace(source, keyword, "miaowu", RegexOptions.IgnoreCase) != source)
return true;
}
catch (ArgumentException)
{
// Keep searching with a literal fallback when regex input is invalid.
}
return SearchCompareInfo.IndexOf(source, keyword, SearchCompareOptions) >= 0;
}
private static bool MatchCardId(int cardId, string keyword)
{
return !string.IsNullOrEmpty(keyword)
&& SearchCompareInfo.Compare(cardId.ToString(), keyword, SearchCompareOptions) == 0;
}
internal static List<Card> Search internal static List<Card> Search
( (
string getName, string getName,
...@@ -278,7 +306,7 @@ namespace MDPro3.Duel.YGOSharp ...@@ -278,7 +306,7 @@ namespace MDPro3.Duel.YGOSharp
) )
{ {
var returnValue = new List<Card>(); var returnValue = new List<Card>();
string[] strings = getName.Split(' '); string[] strings = getName.Split(new[] { ' ', '\u3000' }, StringSplitOptions.None);
nameInSearch = getName; nameInSearch = getName;
foreach (var item in _cards) foreach (var item in _cards)
{ {
...@@ -290,7 +318,7 @@ namespace MDPro3.Duel.YGOSharp ...@@ -290,7 +318,7 @@ namespace MDPro3.Duel.YGOSharp
{ {
if (s.StartsWith("@")) if (s.StartsWith("@"))
{ {
if (Regex.Replace(card.strSetName, s.Substring(1, s.Length - 1), "miaowu", RegexOptions.IgnoreCase) == card.strSetName) if (!MatchWithSearchOptions(card.strSetName, s.Substring(1, s.Length - 1)))
{ {
pass = false; pass = false;
break; break;
...@@ -298,10 +326,10 @@ namespace MDPro3.Duel.YGOSharp ...@@ -298,10 +326,10 @@ namespace MDPro3.Duel.YGOSharp
} }
else if ( else if (
s != "" s != ""
&& Regex.Replace(card.Name, s, "miaowu", RegexOptions.IgnoreCase) == card.Name && !MatchWithSearchOptions(card.Name, s)
&& Regex.Replace(card.Desc, s, "miaowu", RegexOptions.IgnoreCase) == card.Desc && !MatchWithSearchOptions(card.Desc, s)
&& Regex.Replace(card.strSetName, s, "miaowu", RegexOptions.IgnoreCase) == card.strSetName && !MatchWithSearchOptions(card.strSetName, s)
&& card.Id.ToString() != s && !MatchCardId(card.Id, s)
) )
{ {
pass = false; pass = false;
...@@ -553,9 +581,9 @@ namespace MDPro3.Duel.YGOSharp ...@@ -553,9 +581,9 @@ namespace MDPro3.Duel.YGOSharp
{ {
Card card = item.Value; Card card = item.Value;
if(announced == "" if(announced == ""
|| Regex.Replace(card.Name, announced, "miaowu", RegexOptions.IgnoreCase) != card.Name || MatchWithSearchOptions(card.Name, announced)
|| Regex.Replace(card.strSetName, announced, "miaowu", RegexOptions.IgnoreCase) != card.strSetName || MatchWithSearchOptions(card.strSetName, announced)
|| card.Id.ToString() == announced) || MatchCardId(card.Id, announced))
{ {
if(searchCodes.Count == 0 || IsDeclarable(card, searchCodes)) if(searchCodes.Count == 0 || IsDeclarable(card, searchCodes))
returnValue.Add(card); returnValue.Add(card);
...@@ -2409,4 +2437,4 @@ namespace MDPro3.Duel.YGOSharp ...@@ -2409,4 +2437,4 @@ namespace MDPro3.Duel.YGOSharp
} }
} }
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment