Cleaned up refactor to support more extension.
This commit is contained in:
parent
e2a7c54e24
commit
97c73d133d
6 changed files with 271 additions and 95 deletions
|
|
@ -272,6 +272,12 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# Determines which order command sets begin to be assembled from.
|
||||||
|
# Accounts are usually second.
|
||||||
|
cmd_order = 50
|
||||||
|
cmd_order_error = 0
|
||||||
|
cmd_type = "account"
|
||||||
|
|
||||||
objects = AccountManager()
|
objects = AccountManager()
|
||||||
|
|
||||||
# Used by account.create_character() to choose default typeclass for characters.
|
# Used by account.create_character() to choose default typeclass for characters.
|
||||||
|
|
@ -309,6 +315,20 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase):
|
||||||
def characters(self):
|
def characters(self):
|
||||||
return CharactersHandler(self)
|
return CharactersHandler(self)
|
||||||
|
|
||||||
|
def get_command_objects(self) -> dict[str, "CommandObject"]:
|
||||||
|
"""
|
||||||
|
Overrideable method which returns a dictionary of all the kinds of CommandObjects
|
||||||
|
linked to this Account.
|
||||||
|
|
||||||
|
In all normal cases, that's just the account itself.
|
||||||
|
|
||||||
|
The cmdhandler uses this to determine available cmdsets when executing a command.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict[str, CommandObject]: The CommandObjects linked to this Account.
|
||||||
|
"""
|
||||||
|
return {"account": self}
|
||||||
|
|
||||||
def at_post_add_character(self, character: "DefaultCharacter"):
|
def at_post_add_character(self, character: "DefaultCharacter"):
|
||||||
"""
|
"""
|
||||||
Called after a character is added to this account's list of playable characters.
|
Called after a character is added to this account's list of playable characters.
|
||||||
|
|
@ -1514,17 +1534,35 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase):
|
||||||
|
|
||||||
def at_cmdset_get(self, **kwargs):
|
def at_cmdset_get(self, **kwargs):
|
||||||
"""
|
"""
|
||||||
Called just *before* cmdsets on this account are requested by
|
Called just before cmdsets on this object are requested by the
|
||||||
the command handler. The cmdsets are available as
|
command handler. If changes need to be done on the fly to the
|
||||||
`self.cmdset`. If changes need to be done on the fly to the
|
|
||||||
cmdset before passing them on to the cmdhandler, this is the
|
cmdset before passing them on to the cmdhandler, this is the
|
||||||
place to do it. This is called also if the account currently
|
place to do it. This is called also if the object currently
|
||||||
have no cmdsets. kwargs are usually not used unless the
|
have no cmdsets.
|
||||||
cmdset is generated dynamically.
|
|
||||||
|
Keyword Args:
|
||||||
|
caller (obj): The object requesting the cmdsets.
|
||||||
|
current (cmdset): The current merged cmdset.
|
||||||
|
force_init (bool): If `True`, force a re-build of the cmdset. (seems unused)
|
||||||
|
**kwargs: Arbitrary input for overloads.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def get_cmdsets(self, caller, current, **kwargs):
|
||||||
|
"""
|
||||||
|
Called by the CommandHandler to get a list of cmdsets to merge.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
caller (obj): The object requesting the cmdsets.
|
||||||
|
current (cmdset): The current merged cmdset.
|
||||||
|
**kwargs: Arbitrary input for overloads.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
tuple: A tuple of (current, cmdsets), which is probably self.cmdset.current and self.cmdset.cmdset_stack
|
||||||
|
"""
|
||||||
|
return self.cmdset.current, list(self.cmdset.cmdset_stack)
|
||||||
|
|
||||||
def at_first_login(self, **kwargs):
|
def at_first_login(self, **kwargs):
|
||||||
"""
|
"""
|
||||||
Called the very first time this account logs into the game.
|
Called the very first time this account logs into the game.
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ from twisted.internet.defer import inlineCallbacks, returnValue
|
||||||
from twisted.internet.task import deferLater
|
from twisted.internet.task import deferLater
|
||||||
|
|
||||||
from evennia.commands.command import InterruptCommand
|
from evennia.commands.command import InterruptCommand
|
||||||
|
from evennia.commands.cmdset import CmdSet
|
||||||
from evennia.utils import logger, utils
|
from evennia.utils import logger, utils
|
||||||
from evennia.utils.utils import string_suggestions
|
from evennia.utils.utils import string_suggestions
|
||||||
|
|
||||||
|
|
@ -280,10 +281,37 @@ class ErrorReported(Exception):
|
||||||
|
|
||||||
|
|
||||||
# Helper function
|
# Helper function
|
||||||
|
def generate_command_objects(called_by, session=None):
|
||||||
|
command_objects = dict()
|
||||||
|
command_objects.update(called_by.get_command_objects())
|
||||||
|
if session and session is not called_by:
|
||||||
|
command_objects.update(session.get_command_objects())
|
||||||
|
|
||||||
|
command_objects_list = list(command_objects.values())
|
||||||
|
command_objects_list.sort(key=lambda x: getattr(x, "cmd_order", 0))
|
||||||
|
# sort the dictionary by priority. This can be done because Python now cares about dictionary insert order.
|
||||||
|
command_objects = {c.cmd_type: c for c in command_objects_list}
|
||||||
|
|
||||||
|
if not command_objects:
|
||||||
|
raise RuntimeError("cmdhandler: no command objects found.")
|
||||||
|
|
||||||
|
# the caller will be the one to receive messages and excert its permissions.
|
||||||
|
# we assign the caller with preference 'bottom up'
|
||||||
|
caller = command_objects_list[-1]
|
||||||
|
|
||||||
|
command_objects_list_error = sorted(
|
||||||
|
command_objects_list, key=lambda x: getattr(x, "cmd_order_error", 0)
|
||||||
|
)
|
||||||
|
|
||||||
|
# The error_to is the default recipient for errors. Tries to make sure an account
|
||||||
|
# does not get spammed for errors while preserving character mirroring.
|
||||||
|
error_to = command_objects_list_error[-1]
|
||||||
|
|
||||||
|
return command_objects, command_objects_list, command_objects_list_error, caller, error_to
|
||||||
|
|
||||||
|
|
||||||
@inlineCallbacks
|
@inlineCallbacks
|
||||||
def get_and_merge_cmdsets(caller, session, account, obj, callertype, raw_string):
|
def get_and_merge_cmdsets(caller, command_objects, callertype, raw_string, report_to=None):
|
||||||
"""
|
"""
|
||||||
Gather all relevant cmdsets and merge them.
|
Gather all relevant cmdsets and merge them.
|
||||||
|
|
||||||
|
|
@ -293,12 +321,11 @@ def get_and_merge_cmdsets(caller, session, account, obj, callertype, raw_string)
|
||||||
when the user is not logged in, this will be a Session, when being OOC
|
when the user is not logged in, this will be a Session, when being OOC
|
||||||
it will be an Account and when puppeting an object this will (often) be
|
it will be an Account and when puppeting an object this will (often) be
|
||||||
a Character Object. In the end it depends on where the cmdset is stored.
|
a Character Object. In the end it depends on where the cmdset is stored.
|
||||||
session (Session or None): The Session associated with caller, if any.
|
command_objects (list): A list of sorted objects which provide cmdsets.
|
||||||
account (Account or None): The calling Account associated with caller, if any.
|
|
||||||
obj (Object or None): The Object associated with caller, if any.
|
|
||||||
callertype (str): This identifies caller as either "account", "object" or "session"
|
callertype (str): This identifies caller as either "account", "object" or "session"
|
||||||
to avoid having to do this check internally.
|
to avoid having to do this check internally.
|
||||||
raw_string (str): The input string. This is only used for error reporting.
|
raw_string (str): The input string. This is only used for error reporting.
|
||||||
|
report_to (Object, optional): If given, this object will receive error messages
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
cmdset (Deferred): This deferred fires with the merged cmdset
|
cmdset (Deferred): This deferred fires with the merged cmdset
|
||||||
|
|
@ -366,78 +393,47 @@ def get_and_merge_cmdsets(caller, session, account, obj, callertype, raw_string)
|
||||||
raise ErrorReported(raw_string)
|
raise ErrorReported(raw_string)
|
||||||
|
|
||||||
@inlineCallbacks
|
@inlineCallbacks
|
||||||
def _get_cmdsets(obj):
|
def _get_cmdsets(obj, current):
|
||||||
"""
|
"""
|
||||||
Helper method; Get cmdset while making sure to trigger all
|
Helper method; Get cmdset while making sure to trigger all
|
||||||
hooks safely. Returns the stack and the valid options.
|
hooks safely. Returns the stack and the valid options.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
yield obj.at_cmdset_get()
|
yield obj.at_cmdset_get(caller=caller, current=current)
|
||||||
except Exception:
|
except Exception:
|
||||||
_msg_err(caller, _ERROR_CMDSETS)
|
_msg_err(caller, _ERROR_CMDSETS)
|
||||||
raise ErrorReported(raw_string)
|
raise ErrorReported(raw_string)
|
||||||
try:
|
try:
|
||||||
returnValue((obj.cmdset.current, list(obj.cmdset.cmdset_stack)))
|
returnValue(obj.get_cmdsets(caller=caller, current=current))
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
returnValue(((None, None, None), []))
|
returnValue(((None, None, None), []))
|
||||||
|
|
||||||
local_obj_cmdsets = []
|
local_obj_cmdsets = []
|
||||||
if callertype == "session":
|
|
||||||
# we are calling the command from the session level
|
current_cmdset = CmdSet()
|
||||||
report_to = session
|
object_cmdsets = list()
|
||||||
current, cmdsets = yield _get_cmdsets(session)
|
for cmdobj in command_objects:
|
||||||
if account: # this automatically implies logged-in
|
current, cur_cmdsets = yield _get_cmdsets(cmdobj, current_cmdset)
|
||||||
pcurrent, account_cmdsets = yield _get_cmdsets(account)
|
if current:
|
||||||
cmdsets += account_cmdsets
|
current_cmdset = current_cmdset + current
|
||||||
current = current + pcurrent
|
if cur_cmdsets:
|
||||||
if obj:
|
object_cmdsets += cur_cmdsets
|
||||||
ocurrent, obj_cmdsets = yield _get_cmdsets(obj)
|
match cmdobj.cmd_type:
|
||||||
current = current + ocurrent
|
case "object":
|
||||||
cmdsets += obj_cmdsets
|
|
||||||
if not current.no_objs:
|
if not current.no_objs:
|
||||||
local_obj_cmdsets = yield _get_local_obj_cmdsets(obj)
|
local_obj_cmdsets = yield _get_local_obj_cmdsets(cmdobj)
|
||||||
if current.no_exits:
|
if current.no_exits:
|
||||||
# filter out all exits
|
# filter out all exits
|
||||||
local_obj_cmdsets = [
|
local_obj_cmdsets = [
|
||||||
cmdset for cmdset in local_obj_cmdsets if cmdset.key != "ExitCmdSet"
|
cmdset for cmdset in local_obj_cmdsets if cmdset.key != "ExitCmdSet"
|
||||||
]
|
]
|
||||||
cmdsets += local_obj_cmdsets
|
object_cmdsets += local_obj_cmdsets
|
||||||
|
|
||||||
elif callertype == "account":
|
|
||||||
# we are calling the command from the account level
|
|
||||||
report_to = account
|
|
||||||
current, cmdsets = yield _get_cmdsets(account)
|
|
||||||
if obj:
|
|
||||||
ocurrent, obj_cmdsets = yield _get_cmdsets(obj)
|
|
||||||
current = current + ocurrent
|
|
||||||
cmdsets += obj_cmdsets
|
|
||||||
if not current.no_objs:
|
|
||||||
local_obj_cmdsets = yield _get_local_obj_cmdsets(obj)
|
|
||||||
if current.no_exits:
|
|
||||||
# filter out all exits
|
|
||||||
local_obj_cmdsets = [
|
|
||||||
cmdset for cmdset in local_obj_cmdsets if cmdset.key != "ExitCmdSet"
|
|
||||||
]
|
|
||||||
cmdsets += local_obj_cmdsets
|
|
||||||
|
|
||||||
elif callertype == "object":
|
|
||||||
# we are calling the command from the object level
|
|
||||||
report_to = obj
|
|
||||||
current, cmdsets = yield _get_cmdsets(obj)
|
|
||||||
if not current.no_objs:
|
|
||||||
local_obj_cmdsets = yield _get_local_obj_cmdsets(obj)
|
|
||||||
if current.no_exits:
|
|
||||||
# filter out all exits
|
|
||||||
local_obj_cmdsets = [
|
|
||||||
cmdset for cmdset in local_obj_cmdsets if cmdset.key != "ExitCmdSet"
|
|
||||||
]
|
|
||||||
cmdsets += yield local_obj_cmdsets
|
|
||||||
else:
|
|
||||||
raise Exception("get_and_merge_cmdsets: callertype %s is not valid." % callertype)
|
|
||||||
|
|
||||||
# weed out all non-found sets
|
# weed out all non-found sets
|
||||||
cmdsets = yield [cmdset for cmdset in cmdsets if cmdset and cmdset.key != "_EMPTY_CMDSET"]
|
cmdsets = yield [
|
||||||
|
cmdset for cmdset in object_cmdsets if cmdset and cmdset.key != "_EMPTY_CMDSET"
|
||||||
|
]
|
||||||
# report cmdset errors to user (these should already have been logged)
|
# report cmdset errors to user (these should already have been logged)
|
||||||
yield [
|
yield [
|
||||||
report_to.msg(cmdset.errmessage) for cmdset in cmdsets if cmdset.key == "_CMDSET_ERROR"
|
report_to.msg(cmdset.errmessage) for cmdset in cmdsets if cmdset.key == "_CMDSET_ERROR"
|
||||||
|
|
@ -552,7 +548,7 @@ def cmdhandler(
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@inlineCallbacks
|
@inlineCallbacks
|
||||||
def _run_command(cmd, cmdname, args, raw_cmdname, cmdset, session, account):
|
def _run_command(cmd, cmdname, args, raw_cmdname, cmdset, session, account, command_objects):
|
||||||
"""
|
"""
|
||||||
Helper function: This initializes and runs the Command
|
Helper function: This initializes and runs the Command
|
||||||
instance once the parser has identified it as either a normal
|
instance once the parser has identified it as either a normal
|
||||||
|
|
@ -568,6 +564,7 @@ def cmdhandler(
|
||||||
cmdset (CmdSet): Command sert the command belongs to (if any)..
|
cmdset (CmdSet): Command sert the command belongs to (if any)..
|
||||||
session (Session): Session of caller (if any).
|
session (Session): Session of caller (if any).
|
||||||
account (Account): Account of caller (if any).
|
account (Account): Account of caller (if any).
|
||||||
|
command_objects (dict): Dictionary of all command objects.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
deferred (Deferred): this will fire with the return of the
|
deferred (Deferred): this will fire with the return of the
|
||||||
|
|
@ -586,6 +583,7 @@ def cmdhandler(
|
||||||
cmd.cmdstring = cmdname # deprecated
|
cmd.cmdstring = cmdname # deprecated
|
||||||
cmd.args = args
|
cmd.args = args
|
||||||
cmd.cmdset = cmdset
|
cmd.cmdset = cmdset
|
||||||
|
cmd.command_objects = command_objects.copy()
|
||||||
cmd.session = session
|
cmd.session = session
|
||||||
cmd.account = account
|
cmd.account = account
|
||||||
cmd.raw_string = unformatted_raw_string
|
cmd.raw_string = unformatted_raw_string
|
||||||
|
|
@ -655,25 +653,15 @@ def cmdhandler(
|
||||||
finally:
|
finally:
|
||||||
_COMMAND_NESTING[called_by] -= 1
|
_COMMAND_NESTING[called_by] -= 1
|
||||||
|
|
||||||
session, account, obj = session, None, None
|
(
|
||||||
if callertype == "session":
|
command_objects,
|
||||||
session = called_by
|
command_objects_list,
|
||||||
account = session.account
|
command_objects_list_error,
|
||||||
obj = session.puppet
|
caller,
|
||||||
elif callertype == "account":
|
error_to,
|
||||||
account = called_by
|
) = generate_command_objects(called_by, session=session)
|
||||||
if session:
|
|
||||||
obj = yield session.puppet
|
account = command_objects.get("account", None)
|
||||||
elif callertype == "object":
|
|
||||||
obj = called_by
|
|
||||||
else:
|
|
||||||
raise RuntimeError("cmdhandler: callertype %s is not valid." % callertype)
|
|
||||||
# the caller will be the one to receive messages and excert its permissions.
|
|
||||||
# we assign the caller with preference 'bottom up'
|
|
||||||
caller = obj or account or session
|
|
||||||
# The error_to is the default recipient for errors. Tries to make sure an account
|
|
||||||
# does not get spammed for errors while preserving character mirroring.
|
|
||||||
error_to = obj or session or account
|
|
||||||
|
|
||||||
try: # catch bugs in cmdhandler itself
|
try: # catch bugs in cmdhandler itself
|
||||||
try: # catch special-type commands
|
try: # catch special-type commands
|
||||||
|
|
@ -691,7 +679,7 @@ def cmdhandler(
|
||||||
else:
|
else:
|
||||||
# no explicit cmdobject given, figure it out
|
# no explicit cmdobject given, figure it out
|
||||||
cmdset = yield get_and_merge_cmdsets(
|
cmdset = yield get_and_merge_cmdsets(
|
||||||
caller, session, account, obj, callertype, raw_string
|
caller, command_objects_list, callertype, raw_string
|
||||||
)
|
)
|
||||||
if not cmdset:
|
if not cmdset:
|
||||||
# this is bad and shouldn't happen.
|
# this is bad and shouldn't happen.
|
||||||
|
|
@ -764,7 +752,9 @@ def cmdhandler(
|
||||||
cmd = copy(cmd)
|
cmd = copy(cmd)
|
||||||
|
|
||||||
# A normal command.
|
# A normal command.
|
||||||
ret = yield _run_command(cmd, cmdname, args, raw_cmdname, cmdset, session, account)
|
ret = yield _run_command(
|
||||||
|
cmd, cmdname, args, raw_cmdname, cmdset, session, account, command_objects
|
||||||
|
)
|
||||||
returnValue(ret)
|
returnValue(ret)
|
||||||
|
|
||||||
except ErrorReported as exc:
|
except ErrorReported as exc:
|
||||||
|
|
@ -780,7 +770,14 @@ def cmdhandler(
|
||||||
|
|
||||||
if syscmd:
|
if syscmd:
|
||||||
ret = yield _run_command(
|
ret = yield _run_command(
|
||||||
syscmd, syscmd.key, sysarg, unformatted_raw_string, cmdset, session, account
|
syscmd,
|
||||||
|
syscmd.key,
|
||||||
|
sysarg,
|
||||||
|
unformatted_raw_string,
|
||||||
|
cmdset,
|
||||||
|
session,
|
||||||
|
account,
|
||||||
|
command_objects,
|
||||||
)
|
)
|
||||||
returnValue(ret)
|
returnValue(ret)
|
||||||
elif sysarg:
|
elif sysarg:
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ from django.db.models import Max, Min, Q
|
||||||
|
|
||||||
import evennia
|
import evennia
|
||||||
from evennia import InterruptCommand
|
from evennia import InterruptCommand
|
||||||
from evennia.commands.cmdhandler import get_and_merge_cmdsets
|
from evennia.commands.cmdhandler import get_and_merge_cmdsets, generate_command_objects
|
||||||
from evennia.locks.lockhandler import LockException
|
from evennia.locks.lockhandler import LockException
|
||||||
from evennia.objects.models import ObjectDB
|
from evennia.objects.models import ObjectDB
|
||||||
from evennia.prototypes import menus as olc_menus
|
from evennia.prototypes import menus as olc_menus
|
||||||
|
|
@ -3122,8 +3122,16 @@ class CmdExamine(ObjManipCommand):
|
||||||
def _get_cmdset_callback(current_cmdset):
|
def _get_cmdset_callback(current_cmdset):
|
||||||
self.msg(self.format_output(obj, current_cmdset).strip())
|
self.msg(self.format_output(obj, current_cmdset).strip())
|
||||||
|
|
||||||
|
(
|
||||||
|
command_objects,
|
||||||
|
command_objects_list,
|
||||||
|
command_objects_list_error,
|
||||||
|
caller,
|
||||||
|
error_to,
|
||||||
|
) = generate_command_objects(obj, session=session)
|
||||||
|
|
||||||
get_and_merge_cmdsets(
|
get_and_merge_cmdsets(
|
||||||
obj, session, account, objct, mergemode, self.raw_string
|
obj, command_objects_list, mergemode, self.raw_string, error_to
|
||||||
).addCallback(_get_cmdset_callback)
|
).addCallback(_get_cmdset_callback)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -1020,8 +1020,16 @@ class TestGetAndMergeCmdSets(TwistedTestCase, BaseEvenniaTest):
|
||||||
a = self.cmdset_a
|
a = self.cmdset_a
|
||||||
a.no_channels = True
|
a.no_channels = True
|
||||||
self.set_cmdsets(self.session, a)
|
self.set_cmdsets(self.session, a)
|
||||||
|
(
|
||||||
|
command_objects,
|
||||||
|
command_objects_list,
|
||||||
|
command_objects_list_error,
|
||||||
|
caller,
|
||||||
|
error_to,
|
||||||
|
) = cmdhandler.generate_command_objects(self.session)
|
||||||
|
|
||||||
deferred = cmdhandler.get_and_merge_cmdsets(
|
deferred = cmdhandler.get_and_merge_cmdsets(
|
||||||
self.session, self.session, None, None, "session", ""
|
self.session, [self.session], "session", "", error_to
|
||||||
)
|
)
|
||||||
|
|
||||||
def _callback(cmdset):
|
def _callback(cmdset):
|
||||||
|
|
@ -1036,8 +1044,16 @@ class TestGetAndMergeCmdSets(TwistedTestCase, BaseEvenniaTest):
|
||||||
a = self.cmdset_a
|
a = self.cmdset_a
|
||||||
a.no_channels = True
|
a.no_channels = True
|
||||||
self.set_cmdsets(self.account, a)
|
self.set_cmdsets(self.account, a)
|
||||||
|
(
|
||||||
|
command_objects,
|
||||||
|
command_objects_list,
|
||||||
|
command_objects_list_error,
|
||||||
|
caller,
|
||||||
|
error_to,
|
||||||
|
) = cmdhandler.generate_command_objects(self.account)
|
||||||
|
|
||||||
deferred = cmdhandler.get_and_merge_cmdsets(
|
deferred = cmdhandler.get_and_merge_cmdsets(
|
||||||
self.account, None, self.account, None, "account", ""
|
self.account, command_objects_list, "account", "", error_to
|
||||||
)
|
)
|
||||||
# get_and_merge_cmdsets converts to lower-case internally.
|
# get_and_merge_cmdsets converts to lower-case internally.
|
||||||
|
|
||||||
|
|
@ -1053,7 +1069,17 @@ class TestGetAndMergeCmdSets(TwistedTestCase, BaseEvenniaTest):
|
||||||
|
|
||||||
def test_from_object(self):
|
def test_from_object(self):
|
||||||
self.set_cmdsets(self.obj1, self.cmdset_a)
|
self.set_cmdsets(self.obj1, self.cmdset_a)
|
||||||
deferred = cmdhandler.get_and_merge_cmdsets(self.obj1, None, None, self.obj1, "object", "")
|
(
|
||||||
|
command_objects,
|
||||||
|
command_objects_list,
|
||||||
|
command_objects_list_error,
|
||||||
|
caller,
|
||||||
|
error_to,
|
||||||
|
) = cmdhandler.generate_command_objects(self.obj1)
|
||||||
|
|
||||||
|
deferred = cmdhandler.get_and_merge_cmdsets(
|
||||||
|
self.obj1, command_objects_list, "object", "", error_to
|
||||||
|
)
|
||||||
# get_and_merge_cmdsets converts to lower-case internally.
|
# get_and_merge_cmdsets converts to lower-case internally.
|
||||||
|
|
||||||
def _callback(cmdset):
|
def _callback(cmdset):
|
||||||
|
|
@ -1069,8 +1095,16 @@ class TestGetAndMergeCmdSets(TwistedTestCase, BaseEvenniaTest):
|
||||||
a.no_exits = True
|
a.no_exits = True
|
||||||
a.no_channels = True
|
a.no_channels = True
|
||||||
self.set_cmdsets(self.obj1, a, b, c, d)
|
self.set_cmdsets(self.obj1, a, b, c, d)
|
||||||
|
(
|
||||||
deferred = cmdhandler.get_and_merge_cmdsets(self.obj1, None, None, self.obj1, "object", "")
|
command_objects,
|
||||||
|
command_objects_list,
|
||||||
|
command_objects_list_error,
|
||||||
|
caller,
|
||||||
|
error_to,
|
||||||
|
) = cmdhandler.generate_command_objects(self.obj1)
|
||||||
|
deferred = cmdhandler.get_and_merge_cmdsets(
|
||||||
|
self.obj1, command_objects_list, "object", "", error_to
|
||||||
|
)
|
||||||
|
|
||||||
def _callback(cmdset):
|
def _callback(cmdset):
|
||||||
self.assertTrue(cmdset.no_exits)
|
self.assertTrue(cmdset.no_exits)
|
||||||
|
|
@ -1087,7 +1121,17 @@ class TestGetAndMergeCmdSets(TwistedTestCase, BaseEvenniaTest):
|
||||||
b.duplicates = True
|
b.duplicates = True
|
||||||
d.duplicates = True
|
d.duplicates = True
|
||||||
self.set_cmdsets(self.obj1, a, b, c, d)
|
self.set_cmdsets(self.obj1, a, b, c, d)
|
||||||
deferred = cmdhandler.get_and_merge_cmdsets(self.obj1, None, None, self.obj1, "object", "")
|
(
|
||||||
|
command_objects,
|
||||||
|
command_objects_list,
|
||||||
|
command_objects_list_error,
|
||||||
|
caller,
|
||||||
|
error_to,
|
||||||
|
) = cmdhandler.generate_command_objects(self.obj1, session=None)
|
||||||
|
|
||||||
|
deferred = cmdhandler.get_and_merge_cmdsets(
|
||||||
|
self.obj1, command_objects_list, "object", "", error_to
|
||||||
|
)
|
||||||
|
|
||||||
def _callback(cmdset):
|
def _callback(cmdset):
|
||||||
self.assertEqual(len(cmdset.commands), 9)
|
self.assertEqual(len(cmdset.commands), 9)
|
||||||
|
|
|
||||||
|
|
@ -204,6 +204,12 @@ class DefaultObject(ObjectDB, metaclass=TypeclassBase):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# Determines which order command sets begin to be assembled from.
|
||||||
|
# Objects are usually third.
|
||||||
|
cmd_order = 100
|
||||||
|
cmd_order_error = 100
|
||||||
|
cmd_type = "object"
|
||||||
|
|
||||||
# Used for sorting / filtering in inventories / room contents.
|
# Used for sorting / filtering in inventories / room contents.
|
||||||
_content_types = ("object",)
|
_content_types = ("object",)
|
||||||
|
|
||||||
|
|
@ -256,6 +262,24 @@ class DefaultObject(ObjectDB, metaclass=TypeclassBase):
|
||||||
"""
|
"""
|
||||||
return self.sessions.count()
|
return self.sessions.count()
|
||||||
|
|
||||||
|
def get_command_objects(self) -> dict[str, "CommandObject"]:
|
||||||
|
"""
|
||||||
|
Overrideable method which returns a dictionary of all the kinds of CommandObjects
|
||||||
|
linked to this Object.
|
||||||
|
|
||||||
|
In all normal cases, that's the Object itself, and maybe an Account if the Object
|
||||||
|
is being puppeted.
|
||||||
|
|
||||||
|
The cmdhandler uses this to determine available cmdsets when executing a command.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict[str, CommandObject]: The CommandObjects linked to this Object.
|
||||||
|
"""
|
||||||
|
out = {"object": self}
|
||||||
|
if self.account:
|
||||||
|
out["account"] = self.account
|
||||||
|
return out
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_superuser(self):
|
def is_superuser(self):
|
||||||
"""
|
"""
|
||||||
|
|
@ -1601,12 +1625,28 @@ class DefaultObject(ObjectDB, metaclass=TypeclassBase):
|
||||||
have no cmdsets.
|
have no cmdsets.
|
||||||
|
|
||||||
Keyword Args:
|
Keyword Args:
|
||||||
caller (Session, Object or Account): The caller requesting
|
caller (obj): The object requesting the cmdsets.
|
||||||
this cmdset.
|
current (cmdset): The current merged cmdset.
|
||||||
|
force_init (bool): If `True`, force a re-build of the cmdset. (seems unused)
|
||||||
|
**kwargs: Arbitrary input for overloads.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def get_cmdsets(self, caller, current, **kwargs):
|
||||||
|
"""
|
||||||
|
Called by the CommandHandler to get a list of cmdsets to merge.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
caller (obj): The object requesting the cmdsets.
|
||||||
|
current (cmdset): The current merged cmdset.
|
||||||
|
**kwargs: Arbitrary input for overloads.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
tuple: A tuple of (current, cmdsets), which is probably self.cmdset.current and self.cmdset.cmdset_stack
|
||||||
|
"""
|
||||||
|
return self.cmdset.current, list(self.cmdset.cmdset_stack)
|
||||||
|
|
||||||
def at_pre_puppet(self, account, session=None, **kwargs):
|
def at_pre_puppet(self, account, session=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
Called just before an Account connects to this object to puppet
|
Called just before an Account connects to this object to puppet
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,12 @@ class ServerSession(_BASE_SESSION_CLASS):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# Determines which order command sets begin to be assembled from.
|
||||||
|
# Sessions are usually first.
|
||||||
|
cmd_order = 0
|
||||||
|
cmd_order_error = 50
|
||||||
|
cmd_type = "session"
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
"""
|
"""
|
||||||
Initiate to avoid AttributeErrors down the line
|
Initiate to avoid AttributeErrors down the line
|
||||||
|
|
@ -64,6 +70,26 @@ class ServerSession(_BASE_SESSION_CLASS):
|
||||||
|
|
||||||
cmdset_storage = property(__cmdset_storage_get, __cmdset_storage_set)
|
cmdset_storage = property(__cmdset_storage_get, __cmdset_storage_set)
|
||||||
|
|
||||||
|
def get_command_objects(self) -> dict[str, "CommandObject"]:
|
||||||
|
"""
|
||||||
|
Overrideable method which returns a dictionary of all the kinds of CommandObjects
|
||||||
|
linked to this ServerSession.
|
||||||
|
|
||||||
|
In all normal cases, that's the Session itself, and possibly an account and puppeted
|
||||||
|
object.
|
||||||
|
|
||||||
|
The cmdhandler uses this to determine available cmdsets when executing a command.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict[str, CommandObject]: The CommandObjects linked to this Object.
|
||||||
|
"""
|
||||||
|
out = {"session": self}
|
||||||
|
if self.account:
|
||||||
|
out["account"] = self.account
|
||||||
|
if self.puppet:
|
||||||
|
out["puppet"] = self.puppet
|
||||||
|
return out
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def id(self):
|
def id(self):
|
||||||
return self.sessid
|
return self.sessid
|
||||||
|
|
@ -376,12 +402,35 @@ class ServerSession(_BASE_SESSION_CLASS):
|
||||||
|
|
||||||
def at_cmdset_get(self, **kwargs):
|
def at_cmdset_get(self, **kwargs):
|
||||||
"""
|
"""
|
||||||
A dummy hook all objects with cmdsets need to have
|
Called just before cmdsets on this object are requested by the
|
||||||
|
command handler. If changes need to be done on the fly to the
|
||||||
|
cmdset before passing them on to the cmdhandler, this is the
|
||||||
|
place to do it. This is called also if the object currently
|
||||||
|
have no cmdsets.
|
||||||
|
|
||||||
|
Keyword Args:
|
||||||
|
caller (obj): The object requesting the cmdsets.
|
||||||
|
current (cmdset): The current merged cmdset.
|
||||||
|
force_init (bool): If `True`, force a re-build of the cmdset. (seems unused)
|
||||||
|
**kwargs: Arbitrary input for overloads.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def get_cmdsets(self, caller, current, **kwargs):
|
||||||
|
"""
|
||||||
|
Called by the CommandHandler to get a list of cmdsets to merge.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
caller (obj): The object requesting the cmdsets.
|
||||||
|
current (cmdset): The current merged cmdset.
|
||||||
|
**kwargs: Arbitrary input for overloads.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
tuple: A tuple of (current, cmdsets), which is probably self.cmdset.current and self.cmdset.cmdset_stack
|
||||||
|
"""
|
||||||
|
return self.cmdset.current, list(self.cmdset.cmdset_stack)
|
||||||
|
|
||||||
# Mock db/ndb properties for allowing easy storage on the session
|
# Mock db/ndb properties for allowing easy storage on the session
|
||||||
# (note that no databse is involved at all here. session.db.attr =
|
# (note that no databse is involved at all here. session.db.attr =
|
||||||
# value just saves a normal property in memory, just like ndb).
|
# value just saves a normal property in memory, just like ndb).
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue