So in thinking through the use-cases of commands w.r.t. Sponge I came uo with an algorithm for dealing with /command word conflicts.
I'm going to gloss over a few details that prepare the data structures in Sponge that hold information about the mapping of "command" to "plugin" off for a moment. I have another idea there... but for the problem scope limited to just de-conflicting:
Imagine each plugin is a node in a BST (binary search tree).
Finding the appropriate plugin is a search is then really faster than a linear search, O(log n). fine.
But when the tree is traversed, the nodes that expose "I know that command", then this algorithm takes over:
If the useage of the command from the Player is for example /cmd OptA OptB
Then this hashes (via some h()) into a key. The hash function looks at just the following properties of how a command is entered:
HashValue hash = hashCommandLine( /* psuedo code */ line.ArgumentCount() +
line.ArgumentTypes() );
Candidate plugins that offer support for /cmd have already received hash values because of the (TBD defined algorithm to INSERT them into the data structure).
So without even much fuss, if two commands are /cmd
and one PluginA offers
only /cmd STRING
and another offers /cmd STRING STRING
Eg., one PluginA rquires that /cmd
have ONE "STRING" argument and PluginB
requires /cmd
have two "STRING" arguments then these commands have
fundamentally differnet hash values. (again Hash f() TBD)
So the users command line is decomposed from /cmd fart into a type based representation through the CommandParser as /cmd STRING
The arguments are hashed, and lo and behold a match is found because PluginB cannot be the winner (it required two arguments). Comparing a single integer hash value is far easier/faster than re-analyzing each Plugin's response to "is this successful command for you?".
The heuristic is:
When in conflict, compare hash values of the candidates if hash match, you found the Plugin, then resolve it. else if (tabCompletionEnabled) provide tab completed command with the assisting message. else Conflicted but no resolution can be made on the fly, report Logger error and tell user
So examples:
case 1, two plugins each with /cmd
(one is protyped as /cmd STRING
and the
other plugin is protyyped the command /cmd STRING STRING
)
user types /cmd arg
CommandShell finds PluginA as the owner, done.
case 2: two plugins each with /cmd STRING STRING
prototype:
user types /cmd arg1 arg2
presses enter.
Sponge warns "conflict" and rewrites the prefix in the GUI to:
[PluginA_ShortName]/cmd arg1 arg2
User presses TAB
Sponge rewrites the prefix in the GUI to:
[PluginB_ShortName]/cmd arg1 arg2
TAB is a toggle through any set of Plugin A, B, C .. keeps scrolling them
until: User presses ENTER or cancels.