diff --git a/Projects/UOContent/Commands/Generic/Commands/Commands.cs b/Projects/UOContent/Commands/Generic/Commands/Commands.cs index d1607ffae..752c2e116 100644 --- a/Projects/UOContent/Commands/Generic/Commands/Commands.cs +++ b/Projects/UOContent/Commands/Generic/Commands/Commands.cs @@ -538,7 +538,7 @@ namespace Server.Commands.Generic } else { - e.Mobile.SendGump(new AddGump(e.Mobile, match, 0, AddGump.Match(match).ToArray(), true)); + e.Mobile.SendGump(new AddGump(e.Mobile, match, 0, AddGump.Match(match), true)); } } else diff --git a/Projects/UOContent/Commands/Object Creation/AddGump.cs b/Projects/UOContent/Commands/Object Creation/AddGump.cs index 6ba1d00c9..84e3523a4 100644 --- a/Projects/UOContent/Commands/Object Creation/AddGump.cs +++ b/Projects/UOContent/Commands/Object Creation/AddGump.cs @@ -112,14 +112,14 @@ namespace Server.Gumps } else { - types = Match(val).ToArray(); + types = Match(val); explicitSearch = true; } e.Mobile.SendGump(new AddGump(e.Mobile, val, 0, types, explicitSearch)); } - private static void Match(string match, Type[] types, List results) + private static void Match(string match, Type[] types, HashSet results) { if (match.Length == 0) { @@ -128,31 +128,44 @@ namespace Server.Gumps match = match.ToLower(); - for (var i = 0; i < types.Length; ++i) + for (var i = 0; i < types.Length; i++) { var t = types[i]; - if ((typeofMobile.IsAssignableFrom(t) || typeofItem.IsAssignableFrom(t)) && - t.Name.InsensitiveContains(match) && !results.Contains(t)) + if (!(typeofMobile.IsAssignableFrom(t) || typeofItem.IsAssignableFrom(t)) || + !t.Name.InsensitiveContains(match) || results.Contains(t)) { - var ctors = t.GetConstructors(); + continue; + } - for (var j = 0; j < ctors.Length; ++j) + var ctors = t.GetConstructors(); + + for (var j = 0; j < ctors.Length; j++) + { + var ctor = ctors[j]; + var isEmptyCtor = true; + var paramsList = ctor.GetParameters(); + for (var k = 0; k < paramsList.Length; k++) { - if (ctors[j].GetParameters().Length == 0 && - ctors[j].IsDefined(typeof(ConstructibleAttribute), false)) + if (!paramsList[k].HasDefaultValue) { - results.Add(t); + isEmptyCtor = false; break; } } + + if (isEmptyCtor && ctors[j].IsDefined(typeof(ConstructibleAttribute), false)) + { + results.Add(t); + break; + } } } } - public static List Match(string match) + public static Type[] Match(string match) { - var results = new List(); + var results = new HashSet(); Type[] types; var asms = AssemblyHandler.Assemblies; @@ -166,9 +179,20 @@ namespace Server.Gumps types = AssemblyHandler.GetTypeCache(Core.Assembly).Types; Match(match, types, results); - results.Sort(new TypeNameComparer()); + if (results.Count == 0) + { + return Array.Empty(); + } - return results; + var finalResults = new Type[results.Count]; + var index = 0; + foreach (var t in results) + { + finalResults[index++] = t; + } + + Array.Sort(finalResults, TypeNameComparer.Instance); + return finalResults; } public override void OnResponse(NetState sender, RelayInfo info) @@ -189,7 +213,7 @@ namespace Server.Gumps } else { - from.SendGump(new AddGump(from, match, 0, Match(match).ToArray(), true)); + from.SendGump(new AddGump(from, match, 0, Match(match), true)); } break; @@ -234,6 +258,7 @@ namespace Server.Gumps private class TypeNameComparer : IComparer { + public static readonly TypeNameComparer Instance = new(); public int Compare(Type x, Type y) => string.CompareOrdinal(x?.Name, y?.Name); } diff --git a/Projects/UOContent/Spells/Base/SpellRegistry.cs b/Projects/UOContent/Spells/Base/SpellRegistry.cs index 9ddbd25db..a56ae4b13 100644 --- a/Projects/UOContent/Spells/Base/SpellRegistry.cs +++ b/Projects/UOContent/Spells/Base/SpellRegistry.cs @@ -156,9 +156,9 @@ namespace Server.Spells for (var i = 0; i < m_CircleNames.Length; ++i) { - var t = - AssemblyHandler.FindTypeByName($"Server.Spells.{m_CircleNames[i]}.{name}") ?? - AssemblyHandler.FindTypeByName($"Server.Spells.{m_CircleNames[i]}.{name}Spell"); + var t = name.InsensitiveEndsWith("spell") ? + AssemblyHandler.FindTypeByFullName($"Server.Spells.{m_CircleNames[i]}.{name}") : + AssemblyHandler.FindTypeByFullName($"Server.Spells.{m_CircleNames[i]}.{name}Spell"); if (t?.IsSubclassOf(typeof(SpecialMove)) == false) {