Use #0:do_match to resolve nouns in commands#16
Open
Conversation
added 6 commits
September 5, 2012 08:52
The plan is to have the command line parsing retain the existing taskid when calling in-DB functions for processing the command string. This should avoid breaking things that rely on command-related verb calls all coming in with the same taskid (paging in LambdaCore, for example).
The intent is to add a branch to match_object that tries matching via an in-server callback, then falls back to server-side matching if in-server matching fails outside of prescribed ways.
Following the same general rules as #0:do_command, this allows DBs to replace the server's name-to-object matching, supporting a few use cases: * Adding uniform support for new kinds of names (such as LambdaMOO's `*mailing-list` convention), rather than hacking it into commands on the player or room classes. * Supporting smarter disambiguation protocols. * Allowing in-DB matching to behave IDENTICALLY to command matching, rather than requiring a parallel implementation within the DB. * Restricting players from using "privileged" names - object numbers and dollar names - in game-like servers. The server still parses out pronouns and slots strings into dobjstr/iobjstr, but delegates to #0:do_match to match strings to objects. Server-side matching can return negative object numbers to indicate failed or ambiguous matches. Returning a non-object value, raising an uncaught exception, suspending, or waiting for input in $do_match() will cause the server to continue with the built-in matching protocol.
Through the entire do_match, do_command, actual verb, do_huh sequence, the input task maintains a consistent task_id. I un-stitched run_server_command_setting_id since it was unusable outside of tasks.c anyways (types used in its declaration are only in tasks.c anyways) in the process. We now have run_server_command (which starts a new taskid) and run_server_command_in_current_id (which uses the current taskid).
Players connected via listen()-registered handlers now get do_match from their listener's handler, not from #0, to be consistent with do_command and do_login_command.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This change permits in-DB code to override the server's noun-to-object matching by providing a hook (
do_match) on the player's connection handler. As with other in-server command parsing hooks (do_command,do_login_command), the handler is controlled using thelistenbuilt-in.do_matchhooks are called with one argument (the string to be matched to a noun), and can either return non-object values to instruct the server to continue with built-in matching or return any object number to indicate matching success. To indicate a failed match, return#-1($nothingin LambdaMOO),#-2($ambiguous_match), or#-3($failed_match) as appropriate, not0. Raising an exception, suspending, or stopping to read input will also cause built-in noun matching to proceed.The
do_matchhooks are invoked beforedo_command, and share a taskid with the rest of the input task pipeline (do_command, command verbs, andhuhcalls).This was motivated by a few scenarios:
$do_matchmakes this kind of checking more consistent and streamlines error handling (returning$nothingrather than invokinghuhdirectly, for example).*nameconvention for mailing lists is handled by special-case matching in mailing list commands, which have to reside on players or in the player's feature chain rather than on the mailing list object itself. Matching*nameto mailing lists early in command parsing means mailing list verbs can live on the mailing lists themselves, and that other commands can interact with mailing lists consistently.@verb Bob:look_self tnt rxd,Bob:look_selfis a "compound" noun containing both the location of the verb (Bob) and the name of the verb. Matching the location to an object has to be done in-DB, as there's no way to invoke the server's matcher. Having the server also use an in-DB matcher means it's easier to get this kind of object matching to work consistently with command verbs than it would be by reimplementing the stock matcher in MOO. (If you think this is easy, then, without looking, do you know if$namestrings are supported? Do you know if room contents are matched before or after player inventories?)This change also restructures the
run_server_task…family of functions a bit: the_setting_idfunction is gone, replaced with astart_new_task()function intasks.c, and a new_in_current_idfunction permits hook calls to reuse the ongoing input task ID.run_server_taskitself still starts a new taskid before calling any verbs.An appropriate sample implementation for LambdaMOO might be
It is possible to render your database unusable with this hook. The
do_matchhook is also invoked for the.programbuiltin and for the emergency wizard mode recovery commands. If yourdo_matchhook renders its location unresolvable by anyone, the followingevalcommand may be able to help you recover:It is possible to make command-handling very slow with this hook. The hook is invoked for each of the direct and indirect objects with a full execution quota each time. This means that under the default settings, commands that need to resolve both objects can add up to ten seconds to command handling. This is unlikely, but it's a thing to be aware of when implementing this hook. The
do_matchhook is also evaluated beforedo_commandif both are present.