Rework at_before_say/at_say to handle whispers and using kwargs.
This commit is contained in:
commit
c43059c75f
153 changed files with 4418 additions and 2931 deletions
|
|
@ -1,7 +1,7 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
This sub-package contains Evennia's command system. It handles
|
||||
everything related to parsing input from the player, building cmdsets
|
||||
everything related to parsing input from the account, building cmdsets
|
||||
and executing the code associated with a found command class.
|
||||
|
||||
commands.default contains all the default "mux-like" commands of
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ command line. The processing of a command works as follows:
|
|||
- object cmdsets: all objects at caller's location are scanned for non-empty
|
||||
cmdsets. This includes cmdsets on exits.
|
||||
- caller: the caller is searched for its own currently active cmdset.
|
||||
- player: lastly the cmdsets defined on caller.player are added.
|
||||
- account: lastly the cmdsets defined on caller.account are added.
|
||||
3. The collected cmdsets are merged together to a combined, current cmdset.
|
||||
4. If the input string is empty -> check for CMD_NOINPUT command in
|
||||
current cmdset or fallback to error message. Exit.
|
||||
|
|
@ -85,7 +85,7 @@ CMD_LOGINSTART = "__unloggedin_look_command"
|
|||
_SEARCH_AT_RESULT = utils.variable_from_module(*settings.SEARCH_AT_RESULT.rsplit('.', 1))
|
||||
|
||||
# Output strings. The first is the IN_GAME_ERRORS return, the second
|
||||
# is the normal "production message to echo to the player.
|
||||
# is the normal "production message to echo to the account.
|
||||
|
||||
_ERROR_UNTRAPPED = (
|
||||
"""
|
||||
|
|
@ -128,7 +128,7 @@ likely file a bug report with the Evennia project.
|
|||
""")
|
||||
|
||||
_ERROR_RECURSION_LIMIT = "Command recursion limit ({recursion_limit}) " \
|
||||
"reached for '{raw_string}' ({cmdclass})."
|
||||
"reached for '{raw_cmdname}' ({cmdclass})."
|
||||
|
||||
|
||||
# delayed imports
|
||||
|
|
@ -210,7 +210,7 @@ def _process_input(caller, prompt, result, cmd, generator):
|
|||
part of yielding from a Command's `func`.
|
||||
|
||||
Args:
|
||||
caller (Character, Player or Session): the caller.
|
||||
caller (Character, Account or Session): the caller.
|
||||
prompt (basestring): The sent prompt.
|
||||
result (basestring): The unprocessed answer.
|
||||
cmd (Command): The command itself.
|
||||
|
|
@ -248,20 +248,20 @@ class ErrorReported(Exception):
|
|||
# Helper function
|
||||
|
||||
@inlineCallbacks
|
||||
def get_and_merge_cmdsets(caller, session, player, obj, callertype, raw_string):
|
||||
def get_and_merge_cmdsets(caller, session, account, obj, callertype, raw_string):
|
||||
"""
|
||||
Gather all relevant cmdsets and merge them.
|
||||
|
||||
Args:
|
||||
caller (Session, Player or Object): The entity executing the command. Which
|
||||
caller (Session, Account or Object): The entity executing the command. Which
|
||||
type of object this is depends on the current game state; for example
|
||||
when the user is not logged in, this will be a Session, when being OOC
|
||||
it will be a Player 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.
|
||||
session (Session or None): The Session associated with caller, if any.
|
||||
player (Player or None): The calling Player associated with caller, if any.
|
||||
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 "player", "object" or "session"
|
||||
callertype (str): This identifies caller as either "account", "object" or "session"
|
||||
to avoid having to do this check internally.
|
||||
raw_string (str): The input string. This is only used for error reporting.
|
||||
|
||||
|
|
@ -272,18 +272,18 @@ def get_and_merge_cmdsets(caller, session, player, obj, callertype, raw_string):
|
|||
Notes:
|
||||
The cdmsets are merged in order or generality, so that the
|
||||
Object's cmdset is merged last (and will thus take precedence
|
||||
over same-named and same-prio commands on Player and Session).
|
||||
over same-named and same-prio commands on Account and Session).
|
||||
|
||||
"""
|
||||
try:
|
||||
@inlineCallbacks
|
||||
def _get_channel_cmdset(player_or_obj):
|
||||
def _get_channel_cmdset(account_or_obj):
|
||||
"""
|
||||
Helper-method; Get channel-cmdsets
|
||||
"""
|
||||
# Create cmdset for all player's available channels
|
||||
# Create cmdset for all account's available channels
|
||||
try:
|
||||
channel_cmdset = yield CHANNELHANDLER.get_cmdset(player_or_obj)
|
||||
channel_cmdset = yield CHANNELHANDLER.get_cmdset(account_or_obj)
|
||||
returnValue([channel_cmdset])
|
||||
except Exception:
|
||||
_msg_err(caller, _ERROR_CMDSETS)
|
||||
|
|
@ -313,8 +313,8 @@ def get_and_merge_cmdsets(caller, session, player, obj, callertype, raw_string):
|
|||
_GA(lobj, "at_cmdset_get")(caller=caller)
|
||||
except Exception:
|
||||
logger.log_trace()
|
||||
# the call-type lock is checked here, it makes sure a player
|
||||
# is not seeing e.g. the commands on a fellow player (which is why
|
||||
# the call-type lock is checked here, it makes sure an account
|
||||
# is not seeing e.g. the commands on a fellow account (which is why
|
||||
# the no_superuser_bypass must be True)
|
||||
local_obj_cmdsets = \
|
||||
yield list(chain.from_iterable(
|
||||
|
|
@ -355,9 +355,9 @@ def get_and_merge_cmdsets(caller, session, player, obj, callertype, raw_string):
|
|||
# we are calling the command from the session level
|
||||
report_to = session
|
||||
current, cmdsets = yield _get_cmdsets(session)
|
||||
if player: # this automatically implies logged-in
|
||||
pcurrent, player_cmdsets = yield _get_cmdsets(player)
|
||||
cmdsets += player_cmdsets
|
||||
if account: # this automatically implies logged-in
|
||||
pcurrent, account_cmdsets = yield _get_cmdsets(account)
|
||||
cmdsets += account_cmdsets
|
||||
current = current + pcurrent
|
||||
if obj:
|
||||
ocurrent, obj_cmdsets = yield _get_cmdsets(obj)
|
||||
|
|
@ -374,13 +374,13 @@ def get_and_merge_cmdsets(caller, session, player, obj, callertype, raw_string):
|
|||
channel_cmdsets = yield _get_channel_cmdset(obj)
|
||||
cmdsets += channel_cmdsets
|
||||
if not current.no_channels:
|
||||
channel_cmdsets = yield _get_channel_cmdset(player)
|
||||
channel_cmdsets = yield _get_channel_cmdset(account)
|
||||
cmdsets += channel_cmdsets
|
||||
|
||||
elif callertype == "player":
|
||||
# we are calling the command from the player level
|
||||
report_to = player
|
||||
current, cmdsets = yield _get_cmdsets(player)
|
||||
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
|
||||
|
|
@ -395,7 +395,7 @@ def get_and_merge_cmdsets(caller, session, player, obj, callertype, raw_string):
|
|||
# also objs may have channels
|
||||
cmdsets += yield _get_channel_cmdset(obj)
|
||||
if not current.no_channels:
|
||||
cmdsets += yield _get_channel_cmdset(player)
|
||||
cmdsets += yield _get_channel_cmdset(account)
|
||||
|
||||
elif callertype == "object":
|
||||
# we are calling the command from the object level
|
||||
|
|
@ -472,22 +472,22 @@ def cmdhandler(called_by, raw_string, _testing=False, callertype="session", sess
|
|||
This is the main mechanism that handles any string sent to the engine.
|
||||
|
||||
Args:
|
||||
called_by (Session, Player or Object): Object from which this
|
||||
called_by (Session, Account or Object): Object from which this
|
||||
command was called. which this was called from. What this is
|
||||
depends on the game state.
|
||||
raw_string (str): The command string as given on the command line.
|
||||
_testing (bool, optional): Used for debug purposes and decides if we
|
||||
should actually execute the command or not. If True, the
|
||||
command instance will be returned.
|
||||
callertype (str, optional): One of "session", "player" or
|
||||
callertype (str, optional): One of "session", "account" or
|
||||
"object". These are treated in decending order, so when the
|
||||
Session is the caller, it will merge its own cmdset into
|
||||
cmdsets from both Player and eventual puppeted Object (and
|
||||
cmdsets in its room etc). A Player will only include its own
|
||||
cmdsets from both Account and eventual puppeted Object (and
|
||||
cmdsets in its room etc). An Account will only include its own
|
||||
cmdset and the Objects and so on. Merge order is the same
|
||||
order, so that Object cmdsets are merged in last, giving them
|
||||
precendence for same-name and same-prio commands.
|
||||
session (Session, optional): Relevant if callertype is "player" - the session will help
|
||||
session (Session, optional): Relevant if callertype is "account" - the session will help
|
||||
retrieve the correct cmdsets from puppeted objects.
|
||||
cmdobj (Command, optional): If given a command instance, this will be executed using
|
||||
`called_by` as the caller, `raw_string` representing its arguments and (optionally)
|
||||
|
|
@ -513,20 +513,22 @@ def cmdhandler(called_by, raw_string, _testing=False, callertype="session", sess
|
|||
"""
|
||||
|
||||
@inlineCallbacks
|
||||
def _run_command(cmd, cmdname, args, raw_string, cmdset, session, player):
|
||||
def _run_command(cmd, cmdname, args, raw_cmdname, cmdset, session, account):
|
||||
"""
|
||||
Helper function: This initializes and runs the Command
|
||||
instance once the parser has identified it as either a normal
|
||||
command or one of the system commands.
|
||||
|
||||
Args:
|
||||
cmd (Command): Command object.
|
||||
cmdname (str): Name of command.
|
||||
args (str): Extra text entered after the identified command.
|
||||
raw_string (str): Full input string.
|
||||
cmd (Command): Command object
|
||||
cmdname (str): Name of command
|
||||
args (str): extra text entered after the identified command
|
||||
raw_cmdname (str): Name of Command, unaffected by eventual
|
||||
prefix-stripping (if no prefix-stripping, this is the same
|
||||
as cmdname).
|
||||
cmdset (CmdSet): Command sert the command belongs to (if any)..
|
||||
session (Session): Session of caller (if any).
|
||||
player (Player): Player of caller (if any).
|
||||
account (Account): Account of caller (if any).
|
||||
|
||||
Returns:
|
||||
deferred (Deferred): this will fire with the return of the
|
||||
|
|
@ -540,12 +542,14 @@ def cmdhandler(called_by, raw_string, _testing=False, callertype="session", sess
|
|||
try:
|
||||
# Assign useful variables to the instance
|
||||
cmd.caller = caller
|
||||
cmd.cmdstring = cmdname
|
||||
cmd.cmdname = cmdname
|
||||
cmd.raw_cmdname = raw_cmdname
|
||||
cmd.cmdstring = cmdname # deprecated
|
||||
cmd.args = args
|
||||
cmd.cmdset = cmdset
|
||||
cmd.session = session
|
||||
cmd.player = player
|
||||
cmd.raw_string = raw_string
|
||||
cmd.account = account
|
||||
cmd.raw_string = unformatted_raw_string
|
||||
#cmd.obj # set via on-object cmdset handler for each command,
|
||||
# since this may be different for every command when
|
||||
# merging multuple cmdsets
|
||||
|
|
@ -566,7 +570,7 @@ def cmdhandler(called_by, raw_string, _testing=False, callertype="session", sess
|
|||
_COMMAND_NESTING[called_by] += 1
|
||||
if _COMMAND_NESTING[called_by] > _COMMAND_RECURSION_LIMIT:
|
||||
err = _ERROR_RECURSION_LIMIT.format(recursion_limit=_COMMAND_RECURSION_LIMIT,
|
||||
raw_string=raw_string,
|
||||
raw_cmdname=raw_cmdname,
|
||||
cmdclass=cmd.__class__)
|
||||
raise RuntimeError(err)
|
||||
|
||||
|
|
@ -614,13 +618,13 @@ def cmdhandler(called_by, raw_string, _testing=False, callertype="session", sess
|
|||
|
||||
raw_string = to_unicode(raw_string, force_string=True)
|
||||
|
||||
session, player, obj = session, None, None
|
||||
session, account, obj = session, None, None
|
||||
if callertype == "session":
|
||||
session = called_by
|
||||
player = session.player
|
||||
account = session.account
|
||||
obj = session.puppet
|
||||
elif callertype == "player":
|
||||
player = called_by
|
||||
elif callertype == "account":
|
||||
account = called_by
|
||||
if session:
|
||||
obj = yield session.puppet
|
||||
elif callertype == "object":
|
||||
|
|
@ -629,32 +633,32 @@ def cmdhandler(called_by, raw_string, _testing=False, callertype="session", sess
|
|||
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 player or session
|
||||
# The error_to is the default recipient for errors. Tries to make sure a player
|
||||
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 player
|
||||
error_to = obj or session or account
|
||||
|
||||
try: # catch bugs in cmdhandler itself
|
||||
try: # catch special-type commands
|
||||
if cmdobj:
|
||||
# the command object is already given
|
||||
|
||||
cmd = cmdobj() if callable(cmdobj) else cmdobj
|
||||
cmdname = cmdobj_key if cmdobj_key else cmd.key
|
||||
args = raw_string
|
||||
unformatted_raw_string = "%s%s" % (cmdname, args)
|
||||
cmdset = None
|
||||
session = session
|
||||
player = player
|
||||
account = account
|
||||
|
||||
else:
|
||||
# no explicit cmdobject given, figure it out
|
||||
|
||||
cmdset = yield get_and_merge_cmdsets(caller, session, player, obj,
|
||||
cmdset = yield get_and_merge_cmdsets(caller, session, account, obj,
|
||||
callertype, raw_string)
|
||||
if not cmdset:
|
||||
# this is bad and shouldn't happen.
|
||||
raise NoCmdSets
|
||||
# store the completely unmodified raw string - including
|
||||
# whitespace and eventual prefixes-to-be-stripped.
|
||||
unformatted_raw_string = raw_string
|
||||
raw_string = raw_string.strip()
|
||||
if not raw_string:
|
||||
|
|
@ -685,7 +689,7 @@ def cmdhandler(called_by, raw_string, _testing=False, callertype="session", sess
|
|||
if len(matches) == 1:
|
||||
# We have a unique command match. But it may still be invalid.
|
||||
match = matches[0]
|
||||
cmdname, args, cmd = match[0], match[1], match[2]
|
||||
cmdname, args, cmd, raw_cmdname = match[0], match[1], match[2], match[5]
|
||||
|
||||
if not matches:
|
||||
# No commands match our entered command
|
||||
|
|
@ -718,7 +722,7 @@ def cmdhandler(called_by, raw_string, _testing=False, callertype="session", sess
|
|||
raise ExecSystemCommand(cmd, sysarg)
|
||||
|
||||
# A normal command.
|
||||
ret = yield _run_command(cmd, cmdname, args, unformatted_raw_string, cmdset, session, player)
|
||||
ret = yield _run_command(cmd, cmdname, args, raw_cmdname, cmdset, session, account)
|
||||
returnValue(ret)
|
||||
|
||||
except ErrorReported as exc:
|
||||
|
|
@ -734,7 +738,7 @@ def cmdhandler(called_by, raw_string, _testing=False, callertype="session", sess
|
|||
|
||||
if syscmd:
|
||||
ret = yield _run_command(syscmd, syscmd.key, sysarg,
|
||||
unformatted_raw_string, cmdset, session, player)
|
||||
unformatted_raw_string, cmdset, session, account)
|
||||
returnValue(ret)
|
||||
elif sysarg:
|
||||
# return system arg
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ from django.conf import settings
|
|||
from evennia.utils.logger import log_trace
|
||||
|
||||
_MULTIMATCH_REGEX = re.compile(settings.SEARCH_MULTIMATCH_REGEX, re.I + re.U)
|
||||
_CMD_IGNORE_PREFIXES = settings.CMD_IGNORE_PREFIXES
|
||||
|
||||
def cmdparser(raw_string, cmdset, caller, match_index=None):
|
||||
"""
|
||||
|
|
@ -21,7 +22,7 @@ def cmdparser(raw_string, cmdset, caller, match_index=None):
|
|||
Args:
|
||||
raw_string (str): The unparsed text entered by the caller.
|
||||
cmdset (CmdSet): The merged, currently valid cmdset
|
||||
caller (Session, Player or Object): The caller triggering this parsing.
|
||||
caller (Session, Account or Object): The caller triggering this parsing.
|
||||
match_index (int, optional): Index to pick a given match in a
|
||||
list of same-named command matches. If this is given, it suggests
|
||||
this is not the first time this function was called: normally
|
||||
|
|
@ -46,7 +47,7 @@ def cmdparser(raw_string, cmdset, caller, match_index=None):
|
|||
|
||||
"""
|
||||
|
||||
def create_match(cmdname, string, cmdobj):
|
||||
def create_match(cmdname, string, cmdobj, raw_cmdname):
|
||||
"""
|
||||
Builds a command match by splitting the incoming string and
|
||||
evaluating the quality of the match.
|
||||
|
|
@ -55,51 +56,79 @@ def cmdparser(raw_string, cmdset, caller, match_index=None):
|
|||
cmdname (str): Name of command to check for.
|
||||
string (str): The string to match against.
|
||||
cmdobj (str): The full Command instance.
|
||||
raw_cmdname (str, optional): If CMD_IGNORE_PREFIX is set and the cmdname starts with
|
||||
one of the prefixes to ignore, this contains the raw, unstripped cmdname,
|
||||
otherwise it is None.
|
||||
|
||||
Returns:
|
||||
match (tuple): This is on the form (cmdname, args, cmdobj, cmdlen, mratio), where
|
||||
match (tuple): This is on the form (cmdname, args, cmdobj, cmdlen, mratio, raw_cmdname), where
|
||||
`cmdname` is the command's name and `args` the rest of the incoming string,
|
||||
without said command name. `cmdobj` is the Command instance, the cmdlen is
|
||||
the same as len(cmdname) and mratio is a measure of how big a part of the
|
||||
full input string the cmdname takes up - an exact match would be 1.0.
|
||||
full input string the cmdname takes up - an exact match would be 1.0. Finally,
|
||||
the `raw_cmdname` is the cmdname unmodified by eventual prefix-stripping.
|
||||
|
||||
"""
|
||||
cmdlen, strlen = len(unicode(cmdname)), len(unicode(string))
|
||||
mratio = 1 - (strlen - cmdlen) / (1.0 * strlen)
|
||||
args = string[cmdlen:]
|
||||
return (cmdname, args, cmdobj, cmdlen, mratio)
|
||||
return (cmdname, args, cmdobj, cmdlen, mratio, raw_cmdname)
|
||||
|
||||
def build_matches(raw_string, include_prefixes=False):
|
||||
l_raw_string = raw_string.lower()
|
||||
matches = []
|
||||
try:
|
||||
if include_prefixes:
|
||||
# use the cmdname as-is
|
||||
for cmd in cmdset:
|
||||
matches.extend([create_match(cmdname, raw_string, cmd, cmdname)
|
||||
for cmdname in [cmd.key] + cmd.aliases
|
||||
if cmdname and l_raw_string.startswith(cmdname.lower())
|
||||
and (not cmd.arg_regex or
|
||||
cmd.arg_regex.match(l_raw_string[len(cmdname):]))])
|
||||
else:
|
||||
# strip prefixes set in settings
|
||||
for cmd in cmdset:
|
||||
for raw_cmdname in [cmd.key] + cmd.aliases:
|
||||
cmdname = raw_cmdname.lstrip(_CMD_IGNORE_PREFIXES) if len(raw_cmdname) > 1 else raw_cmdname
|
||||
if cmdname and l_raw_string.startswith(cmdname.lower()) and \
|
||||
(not cmd.arg_regex or cmd.arg_regex.match(l_raw_string[len(cmdname):])):
|
||||
matches.append(create_match(cmdname, raw_string, cmd, raw_cmdname))
|
||||
except Exception:
|
||||
log_trace("cmdhandler error. raw_input:%s" % raw_string)
|
||||
return matches
|
||||
|
||||
def try_num_prefixes(raw_string):
|
||||
if not matches:
|
||||
# no matches found
|
||||
num_ref_match = _MULTIMATCH_REGEX.match(raw_string)
|
||||
if num_ref_match:
|
||||
# the user might be trying to identify the command
|
||||
# with a #num-command style syntax. We expect the regex to
|
||||
# contain the groups "number" and "name".
|
||||
mindex, new_raw_string = num_ref_match.group("number"), num_ref_match.group("name")
|
||||
return mindex, new_raw_string
|
||||
return None, None
|
||||
|
||||
if not raw_string:
|
||||
return []
|
||||
|
||||
matches = []
|
||||
|
||||
# match everything that begins with a matching cmdname.
|
||||
l_raw_string = raw_string.lower()
|
||||
for cmd in cmdset:
|
||||
try:
|
||||
matches.extend([create_match(cmdname, raw_string, cmd)
|
||||
for cmdname in [cmd.key] + cmd.aliases
|
||||
if cmdname and l_raw_string.startswith(cmdname.lower())
|
||||
and (not cmd.arg_regex or
|
||||
cmd.arg_regex.match(l_raw_string[len(cmdname):]))])
|
||||
except Exception:
|
||||
log_trace("cmdhandler error. raw_input:%s" % raw_string)
|
||||
|
||||
# find mathces, first using the full name
|
||||
matches = build_matches(raw_string, include_prefixes=True)
|
||||
if not matches:
|
||||
# no matches found
|
||||
num_ref_match = _MULTIMATCH_REGEX.match(raw_string)
|
||||
if num_ref_match:
|
||||
# the user might be trying to identify the command
|
||||
# with a #num-command style syntax. We expect the regex to
|
||||
# contain the groups "number" and "name".
|
||||
mindex, new_raw_string = num_ref_match.group("number"), num_ref_match.group("name")
|
||||
return cmdparser(new_raw_string, cmdset,
|
||||
caller, match_index=int(mindex))
|
||||
# try to match a number 1-cmdname, 2-cmdname etc
|
||||
mindex, new_raw_string = try_num_prefixes(raw_string)
|
||||
if mindex is not None:
|
||||
return cmdparser(new_raw_string, cmdset, caller, match_index=int(mindex))
|
||||
if _CMD_IGNORE_PREFIXES:
|
||||
# still no match. Try to strip prefixes
|
||||
raw_string = raw_string.lstrip(_CMD_IGNORE_PREFIXES) if len(raw_string) > 1 else raw_string
|
||||
matches = build_matches(raw_string, include_prefixes=False)
|
||||
|
||||
# only select command matches we are actually allowed to call.
|
||||
matches = [match for match in matches if match[2].access(caller, 'cmd')]
|
||||
|
||||
# try to bring the number of matches down to 1
|
||||
if len(matches) > 1:
|
||||
# See if it helps to analyze the match with preserved case but only if
|
||||
# it leaves at least one match.
|
||||
|
|
@ -129,4 +158,3 @@ def cmdparser(raw_string, cmdset, caller, match_index=None):
|
|||
|
||||
# no matter what we have at this point, we have to return it.
|
||||
return matches
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ A Command Set (CmdSet) holds a set of commands. The Cmdsets can be
|
|||
merged and combined to create new sets of commands in a
|
||||
non-destructive way. This makes them very powerful for implementing
|
||||
custom game states where different commands (or different variations
|
||||
of commands) are available to the players depending on circumstance.
|
||||
of commands) are available to the accounts depending on circumstance.
|
||||
|
||||
The available merge operations are partly borrowed from mathematical
|
||||
Set theory.
|
||||
|
|
@ -110,9 +110,9 @@ class CmdSet(with_metaclass(_CmdSetMeta, object)):
|
|||
merger (i.e. A above) automatically taking
|
||||
precedence. But if allow_duplicates is true, the
|
||||
result will be a merger with more than one of each
|
||||
name match. This will usually lead to the player
|
||||
name match. This will usually lead to the account
|
||||
receiving a multiple-match error higher up the road,
|
||||
but can be good for things like cmdsets on non-player
|
||||
but can be good for things like cmdsets on non-account
|
||||
objects in a room, to allow the system to warn that
|
||||
more than one 'ball' in the room has the same 'kick'
|
||||
command defined on it, so it may offer a chance to
|
||||
|
|
@ -134,7 +134,7 @@ class CmdSet(with_metaclass(_CmdSetMeta, object)):
|
|||
commands
|
||||
no_channels - ignore the name of channels when matching against
|
||||
commands (WARNING- this is dangerous since the
|
||||
player can then not even ask staff for help if
|
||||
account can then not even ask staff for help if
|
||||
something goes wrong)
|
||||
|
||||
|
||||
|
|
@ -167,9 +167,9 @@ class CmdSet(with_metaclass(_CmdSetMeta, object)):
|
|||
Creates a new CmdSet instance.
|
||||
|
||||
Args:
|
||||
cmdsetobj (Session, Player, Object, optional): This is the database object
|
||||
cmdsetobj (Session, Account, Object, optional): This is the database object
|
||||
to which this particular instance of cmdset is related. It
|
||||
is often a character but may also be a regular object, Player
|
||||
is often a character but may also be a regular object, Account
|
||||
or Session.
|
||||
key (str, optional): The idenfier for this cmdset. This
|
||||
helps if wanting to selectively remov cmdsets.
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@ intelligent container that, when added to other CmdSet make sure that
|
|||
same-name commands are treated correctly (usually so there are no
|
||||
doublets). This temporary but up-to-date merger of CmdSet is jointly
|
||||
called the Current Cmset. It is this Current CmdSet that the
|
||||
commandhandler looks through whenever a player enters a command (it
|
||||
also adds CmdSets from objects in the room in real-time). All player
|
||||
commandhandler looks through whenever an account enters a command (it
|
||||
also adds CmdSets from objects in the room in real-time). All account
|
||||
objects have a 'default cmdset' containing all the normal in-game mud
|
||||
commands (look etc).
|
||||
|
||||
|
|
@ -19,12 +19,12 @@ So what is all this cmdset complexity good for?
|
|||
In its simplest form, a CmdSet has no commands, only a key name. In
|
||||
this case the cmdset's use is up to each individual game - it can be
|
||||
used by an AI module for example (mobs in cmdset 'roam' move from room
|
||||
to room, in cmdset 'attack' they enter combat with players).
|
||||
to room, in cmdset 'attack' they enter combat with accounts).
|
||||
|
||||
Defining commands in cmdsets offer some further powerful game-design
|
||||
consequences however. Here are some examples:
|
||||
|
||||
As mentioned above, all players always have at least the Default
|
||||
As mentioned above, all accounts always have at least the Default
|
||||
CmdSet. This contains the set of all normal-use commands in-game,
|
||||
stuff like look and @desc etc. Now assume our players end up in a dark
|
||||
room. You don't want the player to be able to do much in that dark
|
||||
|
|
@ -37,7 +37,7 @@ and have this completely replace the default cmdset.
|
|||
|
||||
Another example: Say you want your players to be able to go
|
||||
fishing. You could implement this as a 'fish' command that fails
|
||||
whenever the player has no fishing rod. Easy enough. But what if you
|
||||
whenever the account has no fishing rod. Easy enough. But what if you
|
||||
want to make fishing more complex - maybe you want four-five different
|
||||
commands for throwing your line, reeling in, etc? Most players won't
|
||||
(we assume) have fishing gear, and having all those detailed commands
|
||||
|
|
@ -48,7 +48,7 @@ for a minor thing like fishing?
|
|||
So instead you put all those detailed fishing commands into their own
|
||||
CommandSet called 'Fishing'. Whenever the player gives the command
|
||||
'fish' (presumably the code checks there is also water nearby), only
|
||||
THEN this CommandSet is added to the Cmdhandler of the player. The
|
||||
THEN this CommandSet is added to the Cmdhandler of the account. The
|
||||
'throw' command (which normally throws rocks) is replaced by the
|
||||
custom 'fishing variant' of throw. What has happened is that the
|
||||
Fishing CommandSet was merged on top of the Default ones, and due to
|
||||
|
|
@ -128,7 +128,7 @@ def import_cmdset(path, cmdsetobj, emit_to_obj=None, no_logging=False):
|
|||
Args:
|
||||
path (str): The path to the command set to load.
|
||||
cmdsetobj (CmdSet): The database object/typeclass on which this cmdset is to be
|
||||
assigned (this can be also channels and exits, as well as players
|
||||
assigned (this can be also channels and exits, as well as accounts
|
||||
but there will always be such an object)
|
||||
emit_to_obj (Object, optional): If given, error is emitted to
|
||||
this object (in addition to logging)
|
||||
|
|
|
|||
|
|
@ -152,14 +152,14 @@ class Command(with_metaclass(CommandMeta, object)):
|
|||
is_exit = False
|
||||
# define the command not only by key but by the regex form of its arguments
|
||||
arg_regex = settings.COMMAND_DEFAULT_ARG_REGEX
|
||||
# whether self.msg sends to all sessions of a related player/object (default
|
||||
# whether self.msg sends to all sessions of a related account/object (default
|
||||
# is to only send to the session sending the command).
|
||||
msg_all_sessions = settings.COMMAND_DEFAULT_MSG_ALL_SESSIONS
|
||||
|
||||
# auto-set (by Evennia on command instantiation) are:
|
||||
# obj - which object this command is defined on
|
||||
# session - which session is responsible for triggering this command. Only set
|
||||
# if triggered by a player.
|
||||
# if triggered by an account.
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
"""
|
||||
|
|
@ -307,7 +307,7 @@ class Command(with_metaclass(CommandMeta, object)):
|
|||
session=None, **kwargs):
|
||||
"""
|
||||
This is a shortcut instead of calling msg() directly on an
|
||||
object - it will detect if caller is an Object or a Player and
|
||||
object - it will detect if caller is an Object or an Account and
|
||||
also appends self.session automatically if self.msg_all_sessions is False.
|
||||
|
||||
Args:
|
||||
|
|
@ -340,7 +340,7 @@ class Command(with_metaclass(CommandMeta, object)):
|
|||
Args:
|
||||
raw_string (str): Execute this string as a command input.
|
||||
session (Session, optional): If not given, the current command's Session will be used.
|
||||
obj (Object or Player, optional): Object or Player on which to call the execute_cmd.
|
||||
obj (Object or Account, optional): Object or Account on which to call the execute_cmd.
|
||||
If not given, self.caller will be used.
|
||||
|
||||
Kwargs:
|
||||
|
|
@ -443,7 +443,7 @@ class Command(with_metaclass(CommandMeta, object)):
|
|||
commands the caller can use.
|
||||
|
||||
Args:
|
||||
caller (Object or Player): the caller asking for help on the command.
|
||||
caller (Object or Account): the caller asking for help on the command.
|
||||
cmdset (CmdSet): the command set (if you need additional commands).
|
||||
|
||||
Returns:
|
||||
|
|
|
|||
|
|
@ -1,19 +1,19 @@
|
|||
"""
|
||||
Player (OOC) commands. These are stored on the Player object
|
||||
and self.caller is thus always a Player, not an Object/Character.
|
||||
Account (OOC) commands. These are stored on the Account object
|
||||
and self.caller is thus always an Account, not an Object/Character.
|
||||
|
||||
These commands go in the PlayerCmdset and are accessible also
|
||||
These commands go in the AccountCmdset and are accessible also
|
||||
when puppeting a Character (although with lower priority)
|
||||
|
||||
These commands use the player_caller property which tells the command
|
||||
These commands use the account_caller property which tells the command
|
||||
parent (MuxCommand, usually) to setup caller correctly. They use
|
||||
self.player to make sure to always use the player object rather than
|
||||
self.account to make sure to always use the account object rather than
|
||||
self.caller (which change depending on the level you are calling from)
|
||||
The property self.character can be used to access the character when
|
||||
these commands are triggered with a connected character (such as the
|
||||
case of the @ooc command), it is None if we are OOC.
|
||||
|
||||
Note that under MULTISESSION_MODE > 2, Player commands should use
|
||||
Note that under MULTISESSION_MODE > 2, Account commands should use
|
||||
self.msg() and similar methods to reroute returns to the correct
|
||||
method. Otherwise all text will be returned to all connected sessions.
|
||||
|
||||
|
|
@ -36,7 +36,7 @@ __all__ = ("CmdOOCLook", "CmdIC", "CmdOOC", "CmdPassword", "CmdQuit",
|
|||
"CmdColorTest", "CmdQuell")
|
||||
|
||||
|
||||
class MuxPlayerLookCommand(COMMAND_DEFAULT_CLASS):
|
||||
class MuxAccountLookCommand(COMMAND_DEFAULT_CLASS):
|
||||
"""
|
||||
Custom parent (only) parsing for OOC looking, sets a "playable"
|
||||
property on the command based on the parsing.
|
||||
|
|
@ -46,19 +46,19 @@ class MuxPlayerLookCommand(COMMAND_DEFAULT_CLASS):
|
|||
def parse(self):
|
||||
"""Custom parsing"""
|
||||
|
||||
super(MuxPlayerLookCommand, self).parse()
|
||||
super(MuxAccountLookCommand, self).parse()
|
||||
|
||||
if _MULTISESSION_MODE < 2:
|
||||
# only one character allowed - not used in this mode
|
||||
self.playable = None
|
||||
return
|
||||
|
||||
playable = self.player.db._playable_characters
|
||||
playable = self.account.db._playable_characters
|
||||
if playable is not None:
|
||||
# clean up list if character object was deleted in between
|
||||
if None in playable:
|
||||
playable = [character for character in playable if character]
|
||||
self.player.db._playable_characters = playable
|
||||
self.account.db._playable_characters = playable
|
||||
# store playable property
|
||||
if self.args:
|
||||
self.playable = dict((utils.to_str(char.key.lower()), char)
|
||||
|
|
@ -67,13 +67,13 @@ class MuxPlayerLookCommand(COMMAND_DEFAULT_CLASS):
|
|||
self.playable = playable
|
||||
|
||||
|
||||
# Obs - these are all intended to be stored on the Player, and as such,
|
||||
# use self.player instead of self.caller, just to be sure. Also self.msg()
|
||||
# Obs - these are all intended to be stored on the Account, and as such,
|
||||
# use self.account instead of self.caller, just to be sure. Also self.msg()
|
||||
# is used to make sure returns go to the right session
|
||||
|
||||
# note that this is inheriting from MuxPlayerLookCommand,
|
||||
# note that this is inheriting from MuxAccountLookCommand,
|
||||
# and has the .playable property.
|
||||
class CmdOOCLook(MuxPlayerLookCommand):
|
||||
class CmdOOCLook(MuxAccountLookCommand):
|
||||
"""
|
||||
look while out-of-character
|
||||
|
||||
|
|
@ -84,7 +84,7 @@ class CmdOOCLook(MuxPlayerLookCommand):
|
|||
"""
|
||||
|
||||
# This is an OOC version of the look command. Since a
|
||||
# Player doesn't have an in-game existence, there is no
|
||||
# Account doesn't have an in-game existence, there is no
|
||||
# concept of location or "self". If we are controlling
|
||||
# a character, pass control over to normal look.
|
||||
|
||||
|
|
@ -94,7 +94,7 @@ class CmdOOCLook(MuxPlayerLookCommand):
|
|||
help_category = "General"
|
||||
|
||||
# this is used by the parent
|
||||
player_caller = True
|
||||
account_caller = True
|
||||
|
||||
def func(self):
|
||||
"""implement the ooc look command"""
|
||||
|
|
@ -104,8 +104,8 @@ class CmdOOCLook(MuxPlayerLookCommand):
|
|||
self.msg("You are out-of-character (OOC).\nUse |w@ic|n to get back into the game.")
|
||||
return
|
||||
|
||||
# call on-player look helper method
|
||||
self.msg(self.player.at_look(target=self.playable, session=self.session))
|
||||
# call on-account look helper method
|
||||
self.msg(self.account.at_look(target=self.playable, session=self.session))
|
||||
|
||||
|
||||
class CmdCharCreate(COMMAND_DEFAULT_CLASS):
|
||||
|
|
@ -121,15 +121,15 @@ class CmdCharCreate(COMMAND_DEFAULT_CLASS):
|
|||
if you want.
|
||||
"""
|
||||
key = "@charcreate"
|
||||
locks = "cmd:pperm(Players)"
|
||||
locks = "cmd:pperm(Account)"
|
||||
help_category = "General"
|
||||
|
||||
# this is used by the parent
|
||||
player_caller = True
|
||||
account_caller = True
|
||||
|
||||
def func(self):
|
||||
"""create the new character"""
|
||||
player = self.player
|
||||
account = self.account
|
||||
if not self.args:
|
||||
self.msg("Usage: @charcreate <charname> [= description]")
|
||||
return
|
||||
|
|
@ -138,9 +138,9 @@ class CmdCharCreate(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
charmax = _MAX_NR_CHARACTERS if _MULTISESSION_MODE > 1 else 1
|
||||
|
||||
if not player.is_superuser and \
|
||||
(player.db._playable_characters and
|
||||
len(player.db._playable_characters) >= charmax):
|
||||
if not account.is_superuser and \
|
||||
(account.db._playable_characters and
|
||||
len(account.db._playable_characters) >= charmax):
|
||||
self.msg("You may only create a maximum of %i characters." % charmax)
|
||||
return
|
||||
from evennia.objects.models import ObjectDB
|
||||
|
|
@ -156,19 +156,19 @@ class CmdCharCreate(COMMAND_DEFAULT_CLASS):
|
|||
# create the character
|
||||
start_location = ObjectDB.objects.get_id(settings.START_LOCATION)
|
||||
default_home = ObjectDB.objects.get_id(settings.DEFAULT_HOME)
|
||||
permissions = settings.PERMISSION_PLAYER_DEFAULT
|
||||
permissions = settings.PERMISSION_ACCOUNT_DEFAULT
|
||||
new_character = create.create_object(typeclass, key=key,
|
||||
location=start_location,
|
||||
home=default_home,
|
||||
permissions=permissions)
|
||||
# only allow creator (and immortals) to puppet this char
|
||||
new_character.locks.add("puppet:id(%i) or pid(%i) or perm(Immortals) or pperm(Immortals)" %
|
||||
(new_character.id, player.id))
|
||||
player.db._playable_characters.append(new_character)
|
||||
# only allow creator (and developers) to puppet this char
|
||||
new_character.locks.add("puppet:id(%i) or pid(%i) or perm(Developer) or pperm(Developer)" %
|
||||
(new_character.id, account.id))
|
||||
account.db._playable_characters.append(new_character)
|
||||
if desc:
|
||||
new_character.db.desc = desc
|
||||
elif not new_character.db.desc:
|
||||
new_character.db.desc = "This is a Player."
|
||||
new_character.db.desc = "This is an Account."
|
||||
self.msg("Created new character %s. Use |w@ic %s|n to enter the game as this character."
|
||||
% (new_character.key, new_character.key))
|
||||
|
||||
|
|
@ -183,19 +183,19 @@ class CmdCharDelete(COMMAND_DEFAULT_CLASS):
|
|||
Permanently deletes one of your characters.
|
||||
"""
|
||||
key = "@chardelete"
|
||||
locks = "cmd:pperm(Players)"
|
||||
locks = "cmd:pperm(Account)"
|
||||
help_category = "General"
|
||||
|
||||
def func(self):
|
||||
"""delete the character"""
|
||||
player = self.player
|
||||
account = self.account
|
||||
|
||||
if not self.args:
|
||||
self.msg("Usage: @chardelete <charactername>")
|
||||
return
|
||||
|
||||
# use the playable_characters list to search
|
||||
match = [char for char in utils.make_iter(player.db._playable_characters)
|
||||
match = [char for char in utils.make_iter(account.db._playable_characters)
|
||||
if char.key.lower() == self.args.lower()]
|
||||
if not match:
|
||||
self.msg("You have no such character to delete.")
|
||||
|
|
@ -219,9 +219,9 @@ class CmdCharDelete(COMMAND_DEFAULT_CLASS):
|
|||
del caller.ndb._char_to_delete
|
||||
|
||||
match = match[0]
|
||||
player.ndb._char_to_delete = match
|
||||
account.ndb._char_to_delete = match
|
||||
prompt = "|rThis will permanently destroy '%s'. This cannot be undone.|n Continue yes/[no]?"
|
||||
get_input(player, prompt % match.key, _callback)
|
||||
get_input(account, prompt % match.key, _callback)
|
||||
|
||||
|
||||
class CmdIC(COMMAND_DEFAULT_CLASS):
|
||||
|
|
@ -234,12 +234,12 @@ class CmdIC(COMMAND_DEFAULT_CLASS):
|
|||
Go in-character (IC) as a given Character.
|
||||
|
||||
This will attempt to "become" a different object assuming you have
|
||||
the right to do so. Note that it's the PLAYER character that puppets
|
||||
the right to do so. Note that it's the ACCOUNT character that puppets
|
||||
characters/objects and which needs to have the correct permission!
|
||||
|
||||
You cannot become an object that is already controlled by another
|
||||
player. In principle <character> can be any in-game object as long
|
||||
as you the player have access right to puppet it.
|
||||
account. In principle <character> can be any in-game object as long
|
||||
as you the account have access right to puppet it.
|
||||
"""
|
||||
|
||||
key = "@ic"
|
||||
|
|
@ -249,24 +249,24 @@ class CmdIC(COMMAND_DEFAULT_CLASS):
|
|||
help_category = "General"
|
||||
|
||||
# this is used by the parent
|
||||
player_caller = True
|
||||
account_caller = True
|
||||
|
||||
def func(self):
|
||||
"""
|
||||
Main puppet method
|
||||
"""
|
||||
player = self.player
|
||||
account = self.account
|
||||
session = self.session
|
||||
|
||||
new_character = None
|
||||
if not self.args:
|
||||
new_character = player.db._last_puppet
|
||||
new_character = account.db._last_puppet
|
||||
if not new_character:
|
||||
self.msg("Usage: @ic <character>")
|
||||
return
|
||||
if not new_character:
|
||||
# search for a matching character
|
||||
new_character = [char for char in search.object_search(self.args) if char.access(player, "puppet")]
|
||||
new_character = [char for char in search.object_search(self.args) if char.access(account, "puppet")]
|
||||
if not new_character:
|
||||
self.msg("That is not a valid character choice.")
|
||||
return
|
||||
|
|
@ -277,15 +277,15 @@ class CmdIC(COMMAND_DEFAULT_CLASS):
|
|||
else:
|
||||
new_character = new_character[0]
|
||||
try:
|
||||
player.puppet_object(session, new_character)
|
||||
player.db._last_puppet = new_character
|
||||
account.puppet_object(session, new_character)
|
||||
account.db._last_puppet = new_character
|
||||
except RuntimeError as exc:
|
||||
self.msg("|rYou cannot become |C%s|n: %s" % (new_character.name, exc))
|
||||
|
||||
|
||||
# note that this is inheriting from MuxPlayerLookCommand,
|
||||
# note that this is inheriting from MuxAccountLookCommand,
|
||||
# and as such has the .playable property.
|
||||
class CmdOOC(MuxPlayerLookCommand):
|
||||
class CmdOOC(MuxAccountLookCommand):
|
||||
"""
|
||||
stop puppeting and go ooc
|
||||
|
||||
|
|
@ -298,30 +298,30 @@ class CmdOOC(MuxPlayerLookCommand):
|
|||
"""
|
||||
|
||||
key = "@ooc"
|
||||
locks = "cmd:pperm(Players)"
|
||||
locks = "cmd:pperm(Account)"
|
||||
aliases = "@unpuppet"
|
||||
help_category = "General"
|
||||
|
||||
# this is used by the parent
|
||||
player_caller = True
|
||||
account_caller = True
|
||||
|
||||
def func(self):
|
||||
"""Implement function"""
|
||||
|
||||
player = self.player
|
||||
account = self.account
|
||||
session = self.session
|
||||
|
||||
old_char = player.get_puppet(session)
|
||||
old_char = account.get_puppet(session)
|
||||
if not old_char:
|
||||
string = "You are already OOC."
|
||||
self.msg(string)
|
||||
return
|
||||
|
||||
player.db._last_puppet = old_char
|
||||
account.db._last_puppet = old_char
|
||||
|
||||
# disconnect
|
||||
try:
|
||||
player.unpuppet_object(session)
|
||||
account.unpuppet_object(session)
|
||||
self.msg("\n|GYou go OOC.|n\n")
|
||||
|
||||
if _MULTISESSION_MODE < 2:
|
||||
|
|
@ -329,7 +329,7 @@ class CmdOOC(MuxPlayerLookCommand):
|
|||
self.msg("You are out-of-character (OOC).\nUse |w@ic|n to get back into the game.")
|
||||
return
|
||||
|
||||
self.msg(player.at_look(target=self.playable, session=session))
|
||||
self.msg(account.at_look(target=self.playable, session=session))
|
||||
|
||||
except RuntimeError as exc:
|
||||
self.msg("|rCould not unpuppet from |c%s|n: %s" % (old_char, exc))
|
||||
|
|
@ -350,19 +350,19 @@ class CmdSessions(COMMAND_DEFAULT_CLASS):
|
|||
help_category = "General"
|
||||
|
||||
# this is used by the parent
|
||||
player_caller = True
|
||||
account_caller = True
|
||||
|
||||
def func(self):
|
||||
"""Implement function"""
|
||||
player = self.player
|
||||
sessions = player.sessions.all()
|
||||
account = self.account
|
||||
sessions = account.sessions.all()
|
||||
table = evtable.EvTable("|wsessid",
|
||||
"|wprotocol",
|
||||
"|whost",
|
||||
"|wpuppet/character",
|
||||
"|wlocation")
|
||||
for sess in sorted(sessions, key=lambda x: x.sessid):
|
||||
char = player.get_puppet(sess)
|
||||
char = account.get_puppet(sess)
|
||||
table.add_row(str(sess.sessid), str(sess.protocol_key),
|
||||
type(sess.address) == tuple and sess.address[0] or sess.address,
|
||||
char and str(char) or "None",
|
||||
|
|
@ -387,27 +387,27 @@ class CmdWho(COMMAND_DEFAULT_CLASS):
|
|||
locks = "cmd:all()"
|
||||
|
||||
# this is used by the parent
|
||||
player_caller = True
|
||||
account_caller = True
|
||||
|
||||
def func(self):
|
||||
"""
|
||||
Get all connected players by polling session.
|
||||
Get all connected accounts by polling session.
|
||||
"""
|
||||
|
||||
player = self.player
|
||||
account = self.account
|
||||
session_list = SESSIONS.get_sessions()
|
||||
|
||||
session_list = sorted(session_list, key=lambda o: o.player.key)
|
||||
session_list = sorted(session_list, key=lambda o: o.account.key)
|
||||
|
||||
if self.cmdstring == "doing":
|
||||
show_session_data = False
|
||||
else:
|
||||
show_session_data = player.check_permstring("Immortals") or player.check_permstring("Wizards")
|
||||
show_session_data = account.check_permstring("Developer") or account.check_permstring("Admins")
|
||||
|
||||
nplayers = (SESSIONS.player_count())
|
||||
naccounts = (SESSIONS.account_count())
|
||||
if show_session_data:
|
||||
# privileged info
|
||||
table = evtable.EvTable("|wPlayer Name",
|
||||
table = evtable.EvTable("|wAccount Name",
|
||||
"|wOn for",
|
||||
"|wIdle",
|
||||
"|wPuppeting",
|
||||
|
|
@ -420,10 +420,10 @@ class CmdWho(COMMAND_DEFAULT_CLASS):
|
|||
continue
|
||||
delta_cmd = time.time() - session.cmd_last_visible
|
||||
delta_conn = time.time() - session.conn_time
|
||||
player = session.get_player()
|
||||
account = session.get_account()
|
||||
puppet = session.get_puppet()
|
||||
location = puppet.location.key if puppet and puppet.location else "None"
|
||||
table.add_row(utils.crop(player.name, width=25),
|
||||
table.add_row(utils.crop(account.name, width=25),
|
||||
utils.time_format(delta_conn, 0),
|
||||
utils.time_format(delta_cmd, 1),
|
||||
utils.crop(puppet.key if puppet else "None", width=25),
|
||||
|
|
@ -433,19 +433,19 @@ class CmdWho(COMMAND_DEFAULT_CLASS):
|
|||
isinstance(session.address, tuple) and session.address[0] or session.address)
|
||||
else:
|
||||
# unprivileged
|
||||
table = evtable.EvTable("|wPlayer name", "|wOn for", "|wIdle")
|
||||
table = evtable.EvTable("|wAccount name", "|wOn for", "|wIdle")
|
||||
for session in session_list:
|
||||
if not session.logged_in:
|
||||
continue
|
||||
delta_cmd = time.time() - session.cmd_last_visible
|
||||
delta_conn = time.time() - session.conn_time
|
||||
player = session.get_player()
|
||||
table.add_row(utils.crop(player.key, width=25),
|
||||
account = session.get_account()
|
||||
table.add_row(utils.crop(account.key, width=25),
|
||||
utils.time_format(delta_conn, 0),
|
||||
utils.time_format(delta_cmd, 1))
|
||||
is_one = nplayers == 1
|
||||
self.msg("|wPlayers:|n\n%s\n%s unique account%s logged in."
|
||||
% (table, "One" if is_one else nplayers, "" if is_one else "s"))
|
||||
is_one = naccounts == 1
|
||||
self.msg("|wAccounts:|n\n%s\n%s unique account%s logged in."
|
||||
% (table, "One" if is_one else naccounts, "" if is_one else "s"))
|
||||
|
||||
|
||||
class CmdOption(COMMAND_DEFAULT_CLASS):
|
||||
|
|
@ -470,7 +470,7 @@ class CmdOption(COMMAND_DEFAULT_CLASS):
|
|||
locks = "cmd:all()"
|
||||
|
||||
# this is used by the parent
|
||||
player_caller = True
|
||||
account_caller = True
|
||||
|
||||
def func(self):
|
||||
"""
|
||||
|
|
@ -585,15 +585,15 @@ class CmdOption(COMMAND_DEFAULT_CLASS):
|
|||
# a valid setting
|
||||
if "save" in self.switches:
|
||||
# save this option only
|
||||
saved_options = self.player.attributes.get("_saved_protocol_flags", default={})
|
||||
saved_options = self.account.attributes.get("_saved_protocol_flags", default={})
|
||||
saved_options.update(optiondict)
|
||||
self.player.attributes.add("_saved_protocol_flags", saved_options)
|
||||
self.account.attributes.add("_saved_protocol_flags", saved_options)
|
||||
for key in optiondict:
|
||||
self.msg("|gSaved option %s.|n" % key)
|
||||
if "clear" in self.switches:
|
||||
# clear this save
|
||||
for key in optiondict:
|
||||
self.player.attributes.get("_saved_protocol_flags", {}).pop(key, None)
|
||||
self.account.attributes.get("_saved_protocol_flags", {}).pop(key, None)
|
||||
self.msg("|gCleared saved %s." % key)
|
||||
self.session.update_flags(**optiondict)
|
||||
|
||||
|
|
@ -608,27 +608,27 @@ class CmdPassword(COMMAND_DEFAULT_CLASS):
|
|||
Changes your password. Make sure to pick a safe one.
|
||||
"""
|
||||
key = "@password"
|
||||
locks = "cmd:pperm(Players)"
|
||||
locks = "cmd:pperm(Account)"
|
||||
|
||||
# this is used by the parent
|
||||
player_caller = True
|
||||
account_caller = True
|
||||
|
||||
def func(self):
|
||||
"""hook function."""
|
||||
|
||||
player = self.player
|
||||
account = self.account
|
||||
if not self.rhs:
|
||||
self.msg("Usage: @password <oldpass> = <newpass>")
|
||||
return
|
||||
oldpass = self.lhslist[0] # Both of these are
|
||||
newpass = self.rhslist[0] # already stripped by parse()
|
||||
if not player.check_password(oldpass):
|
||||
if not account.check_password(oldpass):
|
||||
self.msg("The specified old password isn't correct.")
|
||||
elif len(newpass) < 3:
|
||||
self.msg("Passwords must be at least three characters long.")
|
||||
else:
|
||||
player.set_password(newpass)
|
||||
player.save()
|
||||
account.set_password(newpass)
|
||||
account.save()
|
||||
self.msg("Password changed.")
|
||||
|
||||
|
||||
|
|
@ -646,30 +646,29 @@ class CmdQuit(COMMAND_DEFAULT_CLASS):
|
|||
game. Use the /all switch to disconnect from all sessions.
|
||||
"""
|
||||
key = "@quit"
|
||||
aliases = "quit"
|
||||
locks = "cmd:all()"
|
||||
|
||||
# this is used by the parent
|
||||
player_caller = True
|
||||
account_caller = True
|
||||
|
||||
def func(self):
|
||||
"""hook function"""
|
||||
player = self.player
|
||||
account = self.account
|
||||
|
||||
if 'all' in self.switches:
|
||||
player.msg("|RQuitting|n all sessions. Hope to see you soon again.", session=self.session)
|
||||
for session in player.sessions.all():
|
||||
player.disconnect_session_from_player(session)
|
||||
account.msg("|RQuitting|n all sessions. Hope to see you soon again.", session=self.session)
|
||||
for session in account.sessions.all():
|
||||
account.disconnect_session_from_account(session)
|
||||
else:
|
||||
nsess = len(player.sessions.all())
|
||||
nsess = len(account.sessions.all())
|
||||
if nsess == 2:
|
||||
player.msg("|RQuitting|n. One session is still connected.", session=self.session)
|
||||
account.msg("|RQuitting|n. One session is still connected.", session=self.session)
|
||||
elif nsess > 2:
|
||||
player.msg("|RQuitting|n. %i sessions are still connected." % (nsess-1), session=self.session)
|
||||
account.msg("|RQuitting|n. %i sessions are still connected." % (nsess-1), session=self.session)
|
||||
else:
|
||||
# we are quitting the last available session
|
||||
player.msg("|RQuitting|n. Hope to see you again, soon.", session=self.session)
|
||||
player.disconnect_session_from_player(self.session)
|
||||
account.msg("|RQuitting|n. Hope to see you again, soon.", session=self.session)
|
||||
account.disconnect_session_from_account(self.session)
|
||||
|
||||
|
||||
class CmdColorTest(COMMAND_DEFAULT_CLASS):
|
||||
|
|
@ -686,12 +685,19 @@ class CmdColorTest(COMMAND_DEFAULT_CLASS):
|
|||
color - if not you will see rubbish appear.
|
||||
"""
|
||||
key = "@color"
|
||||
aliases = "color"
|
||||
locks = "cmd:all()"
|
||||
help_category = "General"
|
||||
|
||||
# this is used by the parent
|
||||
player_caller = True
|
||||
account_caller = True
|
||||
|
||||
# the slices of the ANSI_PARSER lists to use for retrieving the
|
||||
# relevant color tags to display. Replace if using another schema.
|
||||
# This command can only show one set of markup.
|
||||
slice_bright_fg = slice(7, 15) # from ANSI_PARSER.ansi_map
|
||||
slice_dark_fg = slice(15, 23) # from ANSI_PARSER.ansi_map
|
||||
slice_dark_bg = slice(-8, None) # from ANSI_PARSER.ansi_map
|
||||
slice_bright_bg = slice(None, None) # from ANSI_PARSER.ansi_xterm256_bright_bg_map
|
||||
|
||||
def table_format(self, table):
|
||||
"""
|
||||
|
|
@ -718,14 +724,16 @@ class CmdColorTest(COMMAND_DEFAULT_CLASS):
|
|||
ap = ansi.ANSI_PARSER
|
||||
# ansi colors
|
||||
# show all ansi color-related codes
|
||||
col1 = ["%s%s|n" % (code, code.replace("|", "||")) for code, _ in ap.ext_ansi_map[48:56]]
|
||||
col2 = ["%s%s|n" % (code, code.replace("|", "||")) for code, _ in ap.ext_ansi_map[56:64]]
|
||||
col3 = ["%s%s|n" % (code.replace("\\", ""), code.replace("|", "||").replace("\\", ""))
|
||||
for code, _ in ap.ext_ansi_map[-8:]]
|
||||
col4 = ["%s%s|n" % (code.replace("\\", ""), code.replace("|", "||").replace("\\", ""))
|
||||
for code, _ in ap.ansi_bright_bgs[-8:]]
|
||||
col2.extend(["" for _ in range(len(col1)-len(col2))])
|
||||
table = utils.format_table([col1, col2, col4, col3])
|
||||
bright_fg = ["%s%s|n" % (code, code.replace("|", "||"))
|
||||
for code, _ in ap.ansi_map[self.slice_bright_fg]]
|
||||
dark_fg = ["%s%s|n" % (code, code.replace("|", "||"))
|
||||
for code, _ in ap.ansi_map[self.slice_dark_fg]]
|
||||
dark_bg = ["%s%s|n" % (code.replace("\\", ""), code.replace("|", "||").replace("\\", ""))
|
||||
for code, _ in ap.ansi_map[self.slice_dark_bg]]
|
||||
bright_bg = ["%s%s|n" % (code.replace("\\", ""), code.replace("|", "||").replace("\\", ""))
|
||||
for code, _ in ap.ansi_xterm256_bright_bg_map[self.slice_bright_bg]]
|
||||
dark_fg.extend(["" for _ in range(len(bright_fg)-len(dark_fg))])
|
||||
table = utils.format_table([bright_fg, dark_fg, bright_bg, dark_bg])
|
||||
string = "ANSI colors:"
|
||||
for row in table:
|
||||
string += "\n " + " ".join(row)
|
||||
|
|
@ -776,30 +784,30 @@ class CmdColorTest(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
class CmdQuell(COMMAND_DEFAULT_CLASS):
|
||||
"""
|
||||
use character's permissions instead of player's
|
||||
use character's permissions instead of account's
|
||||
|
||||
Usage:
|
||||
quell
|
||||
unquell
|
||||
|
||||
Normally the permission level of the Player is used when puppeting a
|
||||
Normally the permission level of the Account is used when puppeting a
|
||||
Character/Object to determine access. This command will switch the lock
|
||||
system to make use of the puppeted Object's permissions instead. This is
|
||||
useful mainly for testing.
|
||||
Hierarchical permission quelling only work downwards, thus a Player cannot
|
||||
Hierarchical permission quelling only work downwards, thus an Account cannot
|
||||
use a higher-permission Character to escalate their permission level.
|
||||
Use the unquell command to revert back to normal operation.
|
||||
"""
|
||||
|
||||
key = "@quell"
|
||||
aliases = ["@unquell"]
|
||||
locks = "cmd:pperm(Players)"
|
||||
locks = "cmd:pperm(Account)"
|
||||
help_category = "General"
|
||||
|
||||
# this is used by the parent
|
||||
player_caller = True
|
||||
account_caller = True
|
||||
|
||||
def _recache_locks(self, player):
|
||||
def _recache_locks(self, account):
|
||||
"""Helper method to reset the lockhandler on an already puppeted object"""
|
||||
if self.session:
|
||||
char = self.session.puppet
|
||||
|
|
@ -808,31 +816,31 @@ class CmdQuell(COMMAND_DEFAULT_CLASS):
|
|||
# the lock caches (otherwise the superuser status change
|
||||
# won't be visible until repuppet)
|
||||
char.locks.reset()
|
||||
player.locks.reset()
|
||||
account.locks.reset()
|
||||
|
||||
def func(self):
|
||||
"""Perform the command"""
|
||||
player = self.player
|
||||
permstr = player.is_superuser and " (superuser)" or "(%s)" % (", ".join(player.permissions.all()))
|
||||
account = self.account
|
||||
permstr = account.is_superuser and " (superuser)" or "(%s)" % (", ".join(account.permissions.all()))
|
||||
if self.cmdstring == '@unquell':
|
||||
if not player.attributes.get('_quell'):
|
||||
self.msg("Already using normal Player permissions %s." % permstr)
|
||||
if not account.attributes.get('_quell'):
|
||||
self.msg("Already using normal Account permissions %s." % permstr)
|
||||
else:
|
||||
player.attributes.remove('_quell')
|
||||
self.msg("Player permissions %s restored." % permstr)
|
||||
account.attributes.remove('_quell')
|
||||
self.msg("Account permissions %s restored." % permstr)
|
||||
else:
|
||||
if player.attributes.get('_quell'):
|
||||
self.msg("Already quelling Player %s permissions." % permstr)
|
||||
if account.attributes.get('_quell'):
|
||||
self.msg("Already quelling Account %s permissions." % permstr)
|
||||
return
|
||||
player.attributes.add('_quell', True)
|
||||
account.attributes.add('_quell', True)
|
||||
puppet = self.session.puppet
|
||||
if puppet:
|
||||
cpermstr = "(%s)" % ", ".join(puppet.permissions.all())
|
||||
cpermstr = "Quelling to current puppet's permissions %s." % cpermstr
|
||||
cpermstr += "\n(Note: If this is higher than Player permissions %s," \
|
||||
cpermstr += "\n(Note: If this is higher than Account permissions %s," \
|
||||
" the lowest of the two will be used.)" % permstr
|
||||
cpermstr += "\nUse @unquell to return to normal permission usage."
|
||||
self.msg(cpermstr)
|
||||
else:
|
||||
self.msg("Quelling Player permissions%s. Use @unquell to get them back." % permstr)
|
||||
self._recache_locks(player)
|
||||
self.msg("Quelling Account permissions%s. Use @unquell to get them back." % permstr)
|
||||
self._recache_locks(account)
|
||||
|
|
@ -16,27 +16,27 @@ COMMAND_DEFAULT_CLASS = class_from_module(settings.COMMAND_DEFAULT_CLASS)
|
|||
PERMISSION_HIERARCHY = [p.lower() for p in settings.PERMISSION_HIERARCHY]
|
||||
|
||||
# limit members for API inclusion
|
||||
__all__ = ("CmdBoot", "CmdBan", "CmdUnban", "CmdDelPlayer",
|
||||
__all__ = ("CmdBoot", "CmdBan", "CmdUnban", "CmdDelAccount",
|
||||
"CmdEmit", "CmdNewPassword", "CmdPerm", "CmdWall")
|
||||
|
||||
|
||||
class CmdBoot(COMMAND_DEFAULT_CLASS):
|
||||
"""
|
||||
kick a player from the server.
|
||||
kick an account from the server.
|
||||
|
||||
Usage
|
||||
@boot[/switches] <player obj> [: reason]
|
||||
@boot[/switches] <account obj> [: reason]
|
||||
|
||||
Switches:
|
||||
quiet - Silently boot without informing player
|
||||
quiet - Silently boot without informing account
|
||||
sid - boot by session id instead of name or dbref
|
||||
|
||||
Boot a player object from the server. If a reason is
|
||||
Boot an account object from the server. If a reason is
|
||||
supplied it will be echoed to the user unless /quiet is set.
|
||||
"""
|
||||
|
||||
key = "@boot"
|
||||
locks = "cmd:perm(boot) or perm(Wizards)"
|
||||
locks = "cmd:perm(boot) or perm(Admin)"
|
||||
help_category = "Admin"
|
||||
|
||||
def func(self):
|
||||
|
|
@ -45,7 +45,7 @@ class CmdBoot(COMMAND_DEFAULT_CLASS):
|
|||
args = self.args
|
||||
|
||||
if not args:
|
||||
caller.msg("Usage: @boot[/switches] <player> [:reason]")
|
||||
caller.msg("Usage: @boot[/switches] <account> [:reason]")
|
||||
return
|
||||
|
||||
if ':' in args:
|
||||
|
|
@ -64,10 +64,10 @@ class CmdBoot(COMMAND_DEFAULT_CLASS):
|
|||
boot_list.append(sess)
|
||||
break
|
||||
else:
|
||||
# Boot by player object
|
||||
pobj = search.player_search(args)
|
||||
# Boot by account object
|
||||
pobj = search.account_search(args)
|
||||
if not pobj:
|
||||
caller.msg("Player %s was not found." % args)
|
||||
caller.msg("Account %s was not found." % args)
|
||||
return
|
||||
pobj = pobj[0]
|
||||
if not pobj.access(caller, 'boot'):
|
||||
|
|
@ -75,12 +75,12 @@ class CmdBoot(COMMAND_DEFAULT_CLASS):
|
|||
caller.msg(string)
|
||||
return
|
||||
# we have a bootable object with a connected user
|
||||
matches = SESSIONS.sessions_from_player(pobj)
|
||||
matches = SESSIONS.sessions_from_account(pobj)
|
||||
for match in matches:
|
||||
boot_list.append(match)
|
||||
|
||||
if not boot_list:
|
||||
caller.msg("No matching sessions found. The Player does not seem to be online.")
|
||||
caller.msg("No matching sessions found. The Account does not seem to be online.")
|
||||
return
|
||||
|
||||
# Carry out the booting of the sessions in the boot list.
|
||||
|
|
@ -93,7 +93,7 @@ class CmdBoot(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
for session in boot_list:
|
||||
session.msg(feedback)
|
||||
session.player.disconnect_session_from_player(session)
|
||||
session.account.disconnect_session_from_account(session)
|
||||
|
||||
|
||||
# regex matching IP addresses with wildcards, eg. 233.122.4.*
|
||||
|
|
@ -118,7 +118,7 @@ def list_bans(banlist):
|
|||
|
||||
class CmdBan(COMMAND_DEFAULT_CLASS):
|
||||
"""
|
||||
ban a player from the server
|
||||
ban an account from the server
|
||||
|
||||
Usage:
|
||||
@ban [<name or ip> [: reason]]
|
||||
|
|
@ -128,8 +128,8 @@ class CmdBan(COMMAND_DEFAULT_CLASS):
|
|||
This command bans a user from accessing the game. Supply an optional
|
||||
reason to be able to later remember why the ban was put in place.
|
||||
|
||||
It is often preferable to ban a player from the server than to
|
||||
delete a player with @delplayer. If banned by name, that player
|
||||
It is often preferable to ban an account from the server than to
|
||||
delete an account with @delaccount. If banned by name, that account
|
||||
account can no longer be logged into.
|
||||
|
||||
IP (Internet Protocol) address banning allows blocking all access
|
||||
|
|
@ -151,7 +151,7 @@ class CmdBan(COMMAND_DEFAULT_CLASS):
|
|||
"""
|
||||
key = "@ban"
|
||||
aliases = ["@bans"]
|
||||
locks = "cmd:perm(ban) or perm(Immortals)"
|
||||
locks = "cmd:perm(ban) or perm(Developer)"
|
||||
help_category = "Admin"
|
||||
|
||||
def func(self):
|
||||
|
|
@ -206,19 +206,19 @@ class CmdBan(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
class CmdUnban(COMMAND_DEFAULT_CLASS):
|
||||
"""
|
||||
remove a ban from a player
|
||||
remove a ban from an account
|
||||
|
||||
Usage:
|
||||
@unban <banid>
|
||||
|
||||
This will clear a player name/ip ban previously set with the @ban
|
||||
This will clear an account name/ip ban previously set with the @ban
|
||||
command. Use this command without an argument to view a numbered
|
||||
list of bans. Use the numbers in this list to select which one to
|
||||
unban.
|
||||
|
||||
"""
|
||||
key = "@unban"
|
||||
locks = "cmd:perm(unban) or perm(Immortals)"
|
||||
locks = "cmd:perm(unban) or perm(Developer)"
|
||||
help_category = "Admin"
|
||||
|
||||
def func(self):
|
||||
|
|
@ -249,23 +249,23 @@ class CmdUnban(COMMAND_DEFAULT_CLASS):
|
|||
(num, " ".join([s for s in ban[:2]])))
|
||||
|
||||
|
||||
class CmdDelPlayer(COMMAND_DEFAULT_CLASS):
|
||||
class CmdDelAccount(COMMAND_DEFAULT_CLASS):
|
||||
"""
|
||||
delete a player from the server
|
||||
delete an account from the server
|
||||
|
||||
Usage:
|
||||
@delplayer[/switch] <name> [: reason]
|
||||
@delaccount[/switch] <name> [: reason]
|
||||
|
||||
Switch:
|
||||
delobj - also delete the player's currently
|
||||
delobj - also delete the account's currently
|
||||
assigned in-game object.
|
||||
|
||||
Completely deletes a user from the server database,
|
||||
making their nick and e-mail again available.
|
||||
"""
|
||||
|
||||
key = "@delplayer"
|
||||
locks = "cmd:perm(delplayer) or perm(Immortals)"
|
||||
key = "@delaccount"
|
||||
locks = "cmd:perm(delaccount) or perm(Developer)"
|
||||
help_category = "Admin"
|
||||
|
||||
def func(self):
|
||||
|
|
@ -274,49 +274,49 @@ class CmdDelPlayer(COMMAND_DEFAULT_CLASS):
|
|||
caller = self.caller
|
||||
args = self.args
|
||||
|
||||
if hasattr(caller, 'player'):
|
||||
caller = caller.player
|
||||
if hasattr(caller, 'account'):
|
||||
caller = caller.account
|
||||
|
||||
if not args:
|
||||
self.msg("Usage: @delplayer <player/user name or #id> [: reason]")
|
||||
self.msg("Usage: @delaccount <account/user name or #id> [: reason]")
|
||||
return
|
||||
|
||||
reason = ""
|
||||
if ':' in args:
|
||||
args, reason = [arg.strip() for arg in args.split(':', 1)]
|
||||
|
||||
# We use player_search since we want to be sure to find also players
|
||||
# We use account_search since we want to be sure to find also accounts
|
||||
# that lack characters.
|
||||
players = search.player_search(args)
|
||||
accounts = search.account_search(args)
|
||||
|
||||
if not players:
|
||||
self.msg('Could not find a player by that name.')
|
||||
if not accounts:
|
||||
self.msg('Could not find an account by that name.')
|
||||
return
|
||||
|
||||
if len(players) > 1:
|
||||
if len(accounts) > 1:
|
||||
string = "There were multiple matches:\n"
|
||||
string += "\n".join(" %s %s" % (player.id, player.key) for player in players)
|
||||
string += "\n".join(" %s %s" % (account.id, account.key) for account in accounts)
|
||||
self.msg(string)
|
||||
return
|
||||
|
||||
# one single match
|
||||
|
||||
player = players.pop()
|
||||
account = accounts.pop()
|
||||
|
||||
if not player.access(caller, 'delete'):
|
||||
string = "You don't have the permissions to delete that player."
|
||||
if not account.access(caller, 'delete'):
|
||||
string = "You don't have the permissions to delete that account."
|
||||
self.msg(string)
|
||||
return
|
||||
|
||||
uname = player.username
|
||||
# boot the player then delete
|
||||
self.msg("Informing and disconnecting player ...")
|
||||
uname = account.username
|
||||
# boot the account then delete
|
||||
self.msg("Informing and disconnecting account ...")
|
||||
string = "\nYour account '%s' is being *permanently* deleted.\n" % uname
|
||||
if reason:
|
||||
string += " Reason given:\n '%s'" % reason
|
||||
player.msg(string)
|
||||
player.delete()
|
||||
self.msg("Player %s was successfully deleted." % uname)
|
||||
account.msg(string)
|
||||
account.delete()
|
||||
self.msg("Account %s was successfully deleted." % uname)
|
||||
|
||||
|
||||
class CmdEmit(COMMAND_DEFAULT_CLASS):
|
||||
|
|
@ -330,18 +330,18 @@ class CmdEmit(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
Switches:
|
||||
room : limit emits to rooms only (default)
|
||||
players : limit emits to players only
|
||||
accounts : limit emits to accounts only
|
||||
contents : send to the contents of matched objects too
|
||||
|
||||
Emits a message to the selected objects or to
|
||||
your immediate surroundings. If the object is a room,
|
||||
send to its contents. @remit and @pemit are just
|
||||
limited forms of @emit, for sending to rooms and
|
||||
to players respectively.
|
||||
to accounts respectively.
|
||||
"""
|
||||
key = "@emit"
|
||||
aliases = ["@pemit", "@remit"]
|
||||
locks = "cmd:perm(emit) or perm(Builders)"
|
||||
locks = "cmd:perm(emit) or perm(Builder)"
|
||||
help_category = "Admin"
|
||||
|
||||
def func(self):
|
||||
|
|
@ -359,7 +359,7 @@ class CmdEmit(COMMAND_DEFAULT_CLASS):
|
|||
return
|
||||
|
||||
rooms_only = 'rooms' in self.switches
|
||||
players_only = 'players' in self.switches
|
||||
accounts_only = 'accounts' in self.switches
|
||||
send_to_contents = 'contents' in self.switches
|
||||
|
||||
# we check which command was used to force the switches
|
||||
|
|
@ -367,7 +367,7 @@ class CmdEmit(COMMAND_DEFAULT_CLASS):
|
|||
rooms_only = True
|
||||
send_to_contents = True
|
||||
elif self.cmdstring == '@pemit':
|
||||
players_only = True
|
||||
accounts_only = True
|
||||
|
||||
if not self.rhs:
|
||||
message = self.args
|
||||
|
|
@ -384,8 +384,8 @@ class CmdEmit(COMMAND_DEFAULT_CLASS):
|
|||
if rooms_only and obj.location is not None:
|
||||
caller.msg("%s is not a room. Ignored." % objname)
|
||||
continue
|
||||
if players_only and not obj.has_player:
|
||||
caller.msg("%s has no active player. Ignored." % objname)
|
||||
if accounts_only and not obj.has_account:
|
||||
caller.msg("%s has no active account. Ignored." % objname)
|
||||
continue
|
||||
if obj.access(caller, 'tell'):
|
||||
obj.msg(message)
|
||||
|
|
@ -400,16 +400,16 @@ class CmdEmit(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
class CmdNewPassword(COMMAND_DEFAULT_CLASS):
|
||||
"""
|
||||
change the password of a player
|
||||
change the password of an account
|
||||
|
||||
Usage:
|
||||
@userpassword <user obj> = <new password>
|
||||
|
||||
Set a player's password.
|
||||
Set an account's password.
|
||||
"""
|
||||
|
||||
key = "@userpassword"
|
||||
locks = "cmd:perm(newpassword) or perm(Wizards)"
|
||||
locks = "cmd:perm(newpassword) or perm(Admin)"
|
||||
help_category = "Admin"
|
||||
|
||||
def func(self):
|
||||
|
|
@ -421,36 +421,36 @@ class CmdNewPassword(COMMAND_DEFAULT_CLASS):
|
|||
self.msg("Usage: @userpassword <user obj> = <new password>")
|
||||
return
|
||||
|
||||
# the player search also matches 'me' etc.
|
||||
player = caller.search_player(self.lhs)
|
||||
if not player:
|
||||
# the account search also matches 'me' etc.
|
||||
account = caller.search_account(self.lhs)
|
||||
if not account:
|
||||
return
|
||||
player.set_password(self.rhs)
|
||||
player.save()
|
||||
self.msg("%s - new password set to '%s'." % (player.name, self.rhs))
|
||||
if player.character != caller:
|
||||
player.msg("%s has changed your password to '%s'." % (caller.name,
|
||||
account.set_password(self.rhs)
|
||||
account.save()
|
||||
self.msg("%s - new password set to '%s'." % (account.name, self.rhs))
|
||||
if account.character != caller:
|
||||
account.msg("%s has changed your password to '%s'." % (caller.name,
|
||||
self.rhs))
|
||||
|
||||
|
||||
class CmdPerm(COMMAND_DEFAULT_CLASS):
|
||||
"""
|
||||
set the permissions of a player/object
|
||||
set the permissions of an account/object
|
||||
|
||||
Usage:
|
||||
@perm[/switch] <object> [= <permission>[,<permission>,...]]
|
||||
@perm[/switch] *<player> [= <permission>[,<permission>,...]]
|
||||
@perm[/switch] *<account> [= <permission>[,<permission>,...]]
|
||||
|
||||
Switches:
|
||||
del : delete the given permission from <object> or <player>.
|
||||
player : set permission on a player (same as adding * to name)
|
||||
del : delete the given permission from <object> or <account>.
|
||||
account : set permission on an account (same as adding * to name)
|
||||
|
||||
This command sets/clears individual permission strings on an object
|
||||
or player. If no permission is given, list all permissions on <object>.
|
||||
or account. If no permission is given, list all permissions on <object>.
|
||||
"""
|
||||
key = "@perm"
|
||||
aliases = "@setperm"
|
||||
locks = "cmd:perm(perm) or perm(Immortals)"
|
||||
locks = "cmd:perm(perm) or perm(Developer)"
|
||||
help_category = "Admin"
|
||||
|
||||
def func(self):
|
||||
|
|
@ -465,11 +465,11 @@ class CmdPerm(COMMAND_DEFAULT_CLASS):
|
|||
caller.msg(string)
|
||||
return
|
||||
|
||||
playermode = 'player' in self.switches or lhs.startswith('*')
|
||||
accountmode = 'account' in self.switches or lhs.startswith('*')
|
||||
lhs = lhs.lstrip("*")
|
||||
|
||||
if playermode:
|
||||
obj = caller.search_player(lhs)
|
||||
if accountmode:
|
||||
obj = caller.search_account(lhs)
|
||||
else:
|
||||
obj = caller.search(lhs, global_search=True)
|
||||
if not obj:
|
||||
|
|
@ -485,19 +485,19 @@ class CmdPerm(COMMAND_DEFAULT_CLASS):
|
|||
string += "<None>"
|
||||
else:
|
||||
string += ", ".join(obj.permissions.all())
|
||||
if (hasattr(obj, 'player') and
|
||||
hasattr(obj.player, 'is_superuser') and
|
||||
obj.player.is_superuser):
|
||||
if (hasattr(obj, 'account') and
|
||||
hasattr(obj.account, 'is_superuser') and
|
||||
obj.account.is_superuser):
|
||||
string += "\n(... but this object is currently controlled by a SUPERUSER! "
|
||||
string += "All access checks are passed automatically.)"
|
||||
caller.msg(string)
|
||||
return
|
||||
|
||||
# we supplied an argument on the form obj = perm
|
||||
locktype = "edit" if playermode else "control"
|
||||
locktype = "edit" if accountmode else "control"
|
||||
if not obj.access(caller, locktype):
|
||||
caller.msg("You are not allowed to edit this %s's permissions."
|
||||
% ("player" if playermode else "object"))
|
||||
% ("account" if accountmode else "object"))
|
||||
return
|
||||
|
||||
caller_result = []
|
||||
|
|
@ -528,7 +528,7 @@ class CmdPerm(COMMAND_DEFAULT_CLASS):
|
|||
caller_result.append("\nPermission '%s' is already defined on %s." % (rhs, obj.name))
|
||||
else:
|
||||
obj.permissions.add(perm)
|
||||
plystring = "the Player" if playermode else "the Object/Character"
|
||||
plystring = "the Account" if accountmode else "the Object/Character"
|
||||
caller_result.append("\nPermission '%s' given to %s (%s)." % (rhs, obj.name, plystring))
|
||||
target_result.append("\n%s gives you (%s, %s) the permission '%s'."
|
||||
% (caller.name, obj.name, plystring, rhs))
|
||||
|
|
@ -544,10 +544,10 @@ class CmdWall(COMMAND_DEFAULT_CLASS):
|
|||
Usage:
|
||||
@wall <message>
|
||||
|
||||
Announces a message to all connected players.
|
||||
Announces a message to all connected accounts.
|
||||
"""
|
||||
key = "@wall"
|
||||
locks = "cmd:perm(wall) or perm(Wizards)"
|
||||
locks = "cmd:perm(wall) or perm(Admin)"
|
||||
help_category = "Admin"
|
||||
|
||||
def func(self):
|
||||
|
|
@ -556,5 +556,5 @@ class CmdWall(COMMAND_DEFAULT_CLASS):
|
|||
self.caller.msg("Usage: @wall <message>")
|
||||
return
|
||||
message = "%s shouts \"%s\"" % (self.caller.name, self.args)
|
||||
self.msg("Announcing to all connected players ...")
|
||||
self.msg("Announcing to all connected accounts ...")
|
||||
SESSIONS.announce_all(message)
|
||||
|
|
|
|||
|
|
@ -237,7 +237,7 @@ class CmdBatchCommands(_COMMAND_DEFAULT_CLASS):
|
|||
"""
|
||||
key = "@batchcommands"
|
||||
aliases = ["@batchcommand", "@batchcmd"]
|
||||
locks = "cmd:perm(batchcommands) or superuser()"
|
||||
locks = "cmd:perm(batchcommands) or perm(Developer)"
|
||||
help_category = "Building"
|
||||
|
||||
def func(self):
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ class CmdSetObjAlias(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
key = "@alias"
|
||||
aliases = "@setobjalias"
|
||||
locks = "cmd:perm(setobjalias) or perm(Builders)"
|
||||
locks = "cmd:perm(setobjalias) or perm(Builder)"
|
||||
help_category = "Building"
|
||||
|
||||
def func(self):
|
||||
|
|
@ -196,7 +196,7 @@ class CmdCopy(ObjManipCommand):
|
|||
"""
|
||||
|
||||
key = "@copy"
|
||||
locks = "cmd:perm(copy) or perm(Builders)"
|
||||
locks = "cmd:perm(copy) or perm(Builder)"
|
||||
help_category = "Building"
|
||||
|
||||
def func(self):
|
||||
|
|
@ -276,7 +276,7 @@ class CmdCpAttr(ObjManipCommand):
|
|||
If you don't supply a source object, yourself is used.
|
||||
"""
|
||||
key = "@cpattr"
|
||||
locks = "cmd:perm(cpattr) or perm(Builders)"
|
||||
locks = "cmd:perm(cpattr) or perm(Builder)"
|
||||
help_category = "Building"
|
||||
|
||||
def check_from_attr(self, obj, attr, clear=False):
|
||||
|
|
@ -418,7 +418,7 @@ class CmdMvAttr(ObjManipCommand):
|
|||
object. If you don't supply a source object, yourself is used.
|
||||
"""
|
||||
key = "@mvattr"
|
||||
locks = "cmd:perm(mvattr) or perm(Builders)"
|
||||
locks = "cmd:perm(mvattr) or perm(Builder)"
|
||||
help_category = "Building"
|
||||
|
||||
def func(self):
|
||||
|
|
@ -466,12 +466,12 @@ class CmdCreate(ObjManipCommand):
|
|||
"""
|
||||
|
||||
key = "@create"
|
||||
locks = "cmd:perm(create) or perm(Builders)"
|
||||
locks = "cmd:perm(create) or perm(Builder)"
|
||||
help_category = "Building"
|
||||
|
||||
# lockstring of newly created objects, for easy overloading.
|
||||
# Will be formatted with the {id} of the creating object.
|
||||
new_obj_lockstring = "control:id({id}) or perm(Wizards);delete:id({id}) or perm(Wizards)"
|
||||
new_obj_lockstring = "control:id({id}) or perm(Admin);delete:id({id}) or perm(Admin)"
|
||||
|
||||
def func(self):
|
||||
"""
|
||||
|
|
@ -535,10 +535,10 @@ def _desc_quit(caller):
|
|||
|
||||
class CmdDesc(COMMAND_DEFAULT_CLASS):
|
||||
"""
|
||||
describe an object
|
||||
describe an object or the current room.
|
||||
|
||||
Usage:
|
||||
@desc [<obj> =] <description>
|
||||
@setdesc [<obj> =] <description>
|
||||
|
||||
Switches:
|
||||
edit - Open up a line editor for more advanced editing.
|
||||
|
|
@ -546,9 +546,9 @@ class CmdDesc(COMMAND_DEFAULT_CLASS):
|
|||
Sets the "desc" attribute on an object. If an object is not given,
|
||||
describe the current room.
|
||||
"""
|
||||
key = "@desc"
|
||||
key = "@setdesc"
|
||||
aliases = "@describe"
|
||||
locks = "cmd:perm(desc) or perm(Builders)"
|
||||
locks = "cmd:perm(desc) or perm(Builder)"
|
||||
help_category = "Building"
|
||||
|
||||
def edit_handler(self):
|
||||
|
|
@ -607,7 +607,7 @@ class CmdDestroy(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
switches:
|
||||
override - The @destroy command will usually avoid accidentally
|
||||
destroying player objects. This switch overrides this safety.
|
||||
destroying account objects. This switch overrides this safety.
|
||||
examples:
|
||||
@destroy house, roof, door, 44-78
|
||||
@destroy 5-10, flower, 45
|
||||
|
|
@ -618,7 +618,7 @@ class CmdDestroy(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
key = "@destroy"
|
||||
aliases = ["@delete", "@del"]
|
||||
locks = "cmd:perm(destroy) or perm(Builders)"
|
||||
locks = "cmd:perm(destroy) or perm(Builder)"
|
||||
help_category = "Building"
|
||||
|
||||
def func(self):
|
||||
|
|
@ -640,8 +640,8 @@ class CmdDestroy(COMMAND_DEFAULT_CLASS):
|
|||
objname = obj.name
|
||||
if not (obj.access(caller, "control") or obj.access(caller, 'delete')):
|
||||
return "\nYou don't have permission to delete %s." % objname
|
||||
if obj.player and not 'override' in self.switches:
|
||||
return "\nObject %s is controlled by an active player. Use /override to delete anyway." % objname
|
||||
if obj.account and not 'override' in self.switches:
|
||||
return "\nObject %s is controlled by an active account. Use /override to delete anyway." % objname
|
||||
if obj.dbid == int(settings.DEFAULT_HOME.lstrip("#")):
|
||||
return "\nYou are trying to delete |c%s|n, which is set as DEFAULT_HOME. " \
|
||||
"Re-point settings.DEFAULT_HOME to another " \
|
||||
|
|
@ -703,14 +703,14 @@ class CmdDig(ObjManipCommand):
|
|||
would be 'north;no;n'.
|
||||
"""
|
||||
key = "@dig"
|
||||
locks = "cmd:perm(dig) or perm(Builders)"
|
||||
locks = "cmd:perm(dig) or perm(Builder)"
|
||||
help_category = "Building"
|
||||
|
||||
# lockstring of newly created rooms, for easy overloading.
|
||||
# Will be formatted with the {id} of the creating object.
|
||||
new_room_lockstring = "control:id({id}) or perm(Wizards); " \
|
||||
"delete:id({id}) or perm(Wizards); " \
|
||||
"edit:id({id}) or perm(Wizards)"
|
||||
new_room_lockstring = "control:id({id}) or perm(Admin); " \
|
||||
"delete:id({id}) or perm(Admin); " \
|
||||
"edit:id({id}) or perm(Admin)"
|
||||
|
||||
def func(self):
|
||||
"Do the digging. Inherits variables from ObjManipCommand.parse()"
|
||||
|
|
@ -847,7 +847,7 @@ class CmdTunnel(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
key = "@tunnel"
|
||||
aliases = ["@tun"]
|
||||
locks = "cmd: perm(tunnel) or perm(Builders)"
|
||||
locks = "cmd: perm(tunnel) or perm(Builder)"
|
||||
help_category = "Building"
|
||||
|
||||
# store the direction, full name and its opposite
|
||||
|
|
@ -920,7 +920,7 @@ class CmdLink(COMMAND_DEFAULT_CLASS):
|
|||
"""
|
||||
|
||||
key = "@link"
|
||||
locks = "cmd:perm(link) or perm(Builders)"
|
||||
locks = "cmd:perm(link) or perm(Builder)"
|
||||
help_category = "Building"
|
||||
|
||||
def func(self):
|
||||
|
|
@ -998,7 +998,7 @@ class CmdUnLink(CmdLink):
|
|||
# this is just a child of CmdLink
|
||||
|
||||
key = "@unlink"
|
||||
locks = "cmd:perm(unlink) or perm(Builders)"
|
||||
locks = "cmd:perm(unlink) or perm(Builder)"
|
||||
help_key = "Building"
|
||||
|
||||
def func(self):
|
||||
|
|
@ -1035,9 +1035,8 @@ class CmdSetHome(CmdLink):
|
|||
If no location is given, just view the object's home location.
|
||||
"""
|
||||
|
||||
key = "@home"
|
||||
aliases = "@sethome"
|
||||
locks = "cmd:perm(@home) or perm(Builders)"
|
||||
key = "@sethome"
|
||||
locks = "cmd:perm(@home) or perm(Builder)"
|
||||
help_category = "Building"
|
||||
|
||||
def func(self):
|
||||
|
|
@ -1084,7 +1083,7 @@ class CmdListCmdSets(COMMAND_DEFAULT_CLASS):
|
|||
"""
|
||||
key = "@cmdsets"
|
||||
aliases = "@listcmsets"
|
||||
locks = "cmd:perm(listcmdsets) or perm(Builders)"
|
||||
locks = "cmd:perm(listcmdsets) or perm(Builder)"
|
||||
help_category = "Building"
|
||||
|
||||
def func(self):
|
||||
|
|
@ -1109,13 +1108,13 @@ class CmdName(ObjManipCommand):
|
|||
@name obj = name;alias1;alias2
|
||||
|
||||
Rename an object to something new. Use *obj to
|
||||
rename a player.
|
||||
rename an account.
|
||||
|
||||
"""
|
||||
|
||||
key = "@name"
|
||||
aliases = ["@rename"]
|
||||
locks = "cmd:perm(rename) or perm(Builders)"
|
||||
locks = "cmd:perm(rename) or perm(Builder)"
|
||||
help_category = "Building"
|
||||
|
||||
def func(self):
|
||||
|
|
@ -1130,22 +1129,22 @@ class CmdName(ObjManipCommand):
|
|||
if self.lhs_objs:
|
||||
objname = self.lhs_objs[0]['name']
|
||||
if objname.startswith("*"):
|
||||
# player mode
|
||||
obj = caller.player.search(objname.lstrip("*"))
|
||||
# account mode
|
||||
obj = caller.account.search(objname.lstrip("*"))
|
||||
if obj:
|
||||
if self.rhs_objs[0]['aliases']:
|
||||
caller.msg("Players can't have aliases.")
|
||||
caller.msg("Accounts can't have aliases.")
|
||||
return
|
||||
newname = self.rhs
|
||||
if not newname:
|
||||
caller.msg("No name defined!")
|
||||
return
|
||||
if not (obj.access(caller, "control") or obj.access(caller, "edit")):
|
||||
caller.msg("You don't have right to edit this player %s." % obj)
|
||||
caller.msg("You don't have right to edit this account %s." % obj)
|
||||
return
|
||||
obj.username = newname
|
||||
obj.save()
|
||||
caller.msg("Player's name changed to '%s'." % newname)
|
||||
caller.msg("Account's name changed to '%s'." % newname)
|
||||
return
|
||||
# object search, also with *
|
||||
obj = caller.search(objname)
|
||||
|
|
@ -1191,7 +1190,7 @@ class CmdOpen(ObjManipCommand):
|
|||
|
||||
"""
|
||||
key = "@open"
|
||||
locks = "cmd:perm(open) or perm(Builders)"
|
||||
locks = "cmd:perm(open) or perm(Builder)"
|
||||
help_category = "Building"
|
||||
|
||||
# a custom member method to chug out exits and do checks
|
||||
|
|
@ -1327,7 +1326,7 @@ def _convert_from_string(cmd, strobj):
|
|||
be converted to a string and a warning will be given.
|
||||
|
||||
We need to convert like this since all data being sent over the
|
||||
telnet connection by the Player is text - but we will want to
|
||||
telnet connection by the Account is text - but we will want to
|
||||
store it as the "real" python type so we can do convenient
|
||||
comparisons later (e.g. obj.db.value = 2, if value is stored as a
|
||||
string this will always fail).
|
||||
|
|
@ -1382,13 +1381,13 @@ def _convert_from_string(cmd, strobj):
|
|||
|
||||
class CmdSetAttribute(ObjManipCommand):
|
||||
"""
|
||||
set attribute on an object or player
|
||||
set attribute on an object or account
|
||||
|
||||
Usage:
|
||||
@set <obj>/<attr> = <value>
|
||||
@set <obj>/<attr> =
|
||||
@set <obj>/<attr>
|
||||
@set *<player>/attr = <value>
|
||||
@set *<account>/attr = <value>
|
||||
|
||||
Switch:
|
||||
edit: Open the line editor (string values only)
|
||||
|
|
@ -1413,14 +1412,14 @@ class CmdSetAttribute(ObjManipCommand):
|
|||
"""
|
||||
|
||||
key = "@set"
|
||||
locks = "cmd:perm(set) or perm(Builders)"
|
||||
locks = "cmd:perm(set) or perm(Builder)"
|
||||
help_category = "Building"
|
||||
|
||||
def check_obj(self, obj):
|
||||
"""
|
||||
This may be overridden by subclasses in case restrictions need to be
|
||||
placed on whether certain objects can have attributes set by certain
|
||||
players.
|
||||
accounts.
|
||||
|
||||
This function is expected to display its own error message.
|
||||
|
||||
|
|
@ -1506,7 +1505,7 @@ class CmdSetAttribute(ObjManipCommand):
|
|||
attrs = self.lhs_objattr[0]['attrs']
|
||||
|
||||
if objname.startswith('*'):
|
||||
obj = caller.search_player(objname.lstrip('*'))
|
||||
obj = caller.search_account(objname.lstrip('*'))
|
||||
else:
|
||||
obj = caller.search(objname)
|
||||
if not obj:
|
||||
|
|
@ -1595,7 +1594,7 @@ class CmdTypeclass(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
key = "@typeclass"
|
||||
aliases = ["@type", "@parent", "@swap", "@update"]
|
||||
locks = "cmd:perm(typeclass) or perm(Builders)"
|
||||
locks = "cmd:perm(typeclass) or perm(Builder)"
|
||||
help_category = "Building"
|
||||
|
||||
def func(self):
|
||||
|
|
@ -1685,7 +1684,7 @@ class CmdWipe(ObjManipCommand):
|
|||
matching the given attribute-wildcard search string.
|
||||
"""
|
||||
key = "@wipe"
|
||||
locks = "cmd:perm(wipe) or perm(Builders)"
|
||||
locks = "cmd:perm(wipe) or perm(Builder)"
|
||||
help_category = "Building"
|
||||
|
||||
def func(self):
|
||||
|
|
@ -1743,18 +1742,18 @@ class CmdLock(ObjManipCommand):
|
|||
Separator expressions need not be capitalized.
|
||||
|
||||
For example:
|
||||
'get: id(25) or perm(Wizards)'
|
||||
'get: id(25) or perm(Admin)'
|
||||
The 'get' access_type is checked by the get command and will
|
||||
an object locked with this string will only be possible to
|
||||
pick up by Wizards or by object with id 25.
|
||||
pick up by Admins or by object with id=25.
|
||||
|
||||
You can add several access_types after oneanother by separating
|
||||
them by ';', i.e:
|
||||
'get:id(25);delete:perm(Builders)'
|
||||
'get:id(25);delete:perm(Builder)'
|
||||
"""
|
||||
key = "@lock"
|
||||
aliases = ["@locks", "lock", "locks"]
|
||||
locks = "cmd: perm(locks) or perm(Builders)"
|
||||
aliases = ["@locks"]
|
||||
locks = "cmd: perm(locks) or perm(Builder)"
|
||||
help_category = "Building"
|
||||
|
||||
def func(self):
|
||||
|
|
@ -1832,26 +1831,26 @@ class CmdExamine(ObjManipCommand):
|
|||
|
||||
Usage:
|
||||
examine [<object>[/attrname]]
|
||||
examine [*<player>[/attrname]]
|
||||
examine [*<account>[/attrname]]
|
||||
|
||||
Switch:
|
||||
player - examine a Player (same as adding *)
|
||||
account - examine an Account (same as adding *)
|
||||
object - examine an Object (useful when OOC)
|
||||
|
||||
The examine command shows detailed game info about an
|
||||
object and optionally a specific attribute on it.
|
||||
If object is not specified, the current location is examined.
|
||||
|
||||
Append a * before the search string to examine a player.
|
||||
Append a * before the search string to examine an account.
|
||||
|
||||
"""
|
||||
key = "@examine"
|
||||
aliases = ["@ex","ex", "exam", "examine"]
|
||||
locks = "cmd:perm(examine) or perm(Builders)"
|
||||
aliases = ["@ex","exam"]
|
||||
locks = "cmd:perm(examine) or perm(Builder)"
|
||||
help_category = "Building"
|
||||
arg_regex = r"(/\w+?(\s|$))|\s|$"
|
||||
|
||||
player_mode = False
|
||||
account_mode = False
|
||||
|
||||
def list_attribute(self, crop, attr, value):
|
||||
"""
|
||||
|
|
@ -1911,15 +1910,15 @@ class CmdExamine(ObjManipCommand):
|
|||
for sess in obj.sessions.all()))
|
||||
if hasattr(obj, "email") and obj.email:
|
||||
string += "\n|wEmail|n: |c%s|n" % obj.email
|
||||
if hasattr(obj, "has_player") and obj.has_player:
|
||||
string += "\n|wPlayer|n: |c%s|n" % obj.player.name
|
||||
perms = obj.player.permissions.all()
|
||||
if obj.player.is_superuser:
|
||||
if hasattr(obj, "has_account") and obj.has_account:
|
||||
string += "\n|wAccount|n: |c%s|n" % obj.account.name
|
||||
perms = obj.account.permissions.all()
|
||||
if obj.account.is_superuser:
|
||||
perms = ["<Superuser>"]
|
||||
elif not perms:
|
||||
perms = ["<None>"]
|
||||
string += "\n|wPlayer Perms|n: %s" % (", ".join(perms))
|
||||
if obj.player.attributes.has("_quell"):
|
||||
string += "\n|wAccount Perms|n: %s" % (", ".join(perms))
|
||||
if obj.account.attributes.has("_quell"):
|
||||
string += " |r(quelled)|n"
|
||||
string += "\n|wTypeclass|n: %s (%s)" % (obj.typename,
|
||||
obj.typeclass_path)
|
||||
|
|
@ -1962,16 +1961,16 @@ class CmdExamine(ObjManipCommand):
|
|||
|
||||
# this gets all components of the currently merged set
|
||||
all_cmdsets = [(cmdset.key, cmdset) for cmdset in avail_cmdset.merged_from]
|
||||
# we always at least try to add player- and session sets since these are ignored
|
||||
# we always at least try to add account- and session sets since these are ignored
|
||||
# if we merge on the object level.
|
||||
if hasattr(obj, "player") and obj.player:
|
||||
all_cmdsets.extend([(cmdset.key, cmdset) for cmdset in obj.player.cmdset.all()])
|
||||
if hasattr(obj, "account") and obj.account:
|
||||
all_cmdsets.extend([(cmdset.key, cmdset) for cmdset in obj.account.cmdset.all()])
|
||||
if obj.sessions.count():
|
||||
# if there are more sessions than one on objects it's because of multisession mode 3.
|
||||
# we only show the first session's cmdset here (it is -in principle- possible that
|
||||
# different sessions have different cmdsets but for admins who want such madness
|
||||
# it is better that they overload with their own CmdExamine to handle it).
|
||||
all_cmdsets.extend([(cmdset.key, cmdset) for cmdset in obj.player.sessions.all()[0].cmdset.all()])
|
||||
all_cmdsets.extend([(cmdset.key, cmdset) for cmdset in obj.account.sessions.all()[0].cmdset.all()])
|
||||
else:
|
||||
try:
|
||||
# we have to protect this since many objects don't have sessions.
|
||||
|
|
@ -2012,7 +2011,7 @@ class CmdExamine(ObjManipCommand):
|
|||
for content in obj.contents:
|
||||
if content.destination:
|
||||
exits.append(content)
|
||||
elif content.player:
|
||||
elif content.account:
|
||||
pobjs.append(content)
|
||||
else:
|
||||
things.append(content)
|
||||
|
|
@ -2052,7 +2051,7 @@ class CmdExamine(ObjManipCommand):
|
|||
self.msg(caller.at_look(obj))
|
||||
return
|
||||
# using callback for printing result whenever function returns.
|
||||
get_and_merge_cmdsets(obj, self.session, self.player, obj, "object", self.raw_string).addCallback(get_cmdset_callback)
|
||||
get_and_merge_cmdsets(obj, self.session, self.account, obj, "object", self.raw_string).addCallback(get_cmdset_callback)
|
||||
else:
|
||||
self.msg("You need to supply a target to examine.")
|
||||
return
|
||||
|
|
@ -2064,13 +2063,13 @@ class CmdExamine(ObjManipCommand):
|
|||
obj_name = objdef['name']
|
||||
obj_attrs = objdef['attrs']
|
||||
|
||||
self.player_mode = utils.inherits_from(caller, "evennia.players.players.DefaultPlayer") or \
|
||||
"player" in self.switches or obj_name.startswith('*')
|
||||
if self.player_mode:
|
||||
self.account_mode = utils.inherits_from(caller, "evennia.accounts.accounts.DefaultAccount") or \
|
||||
"account" in self.switches or obj_name.startswith('*')
|
||||
if self.account_mode:
|
||||
try:
|
||||
obj = caller.search_player(obj_name.lstrip('*'))
|
||||
obj = caller.search_account(obj_name.lstrip('*'))
|
||||
except AttributeError:
|
||||
# this means we are calling examine from a player object
|
||||
# this means we are calling examine from an account object
|
||||
obj = caller.search(obj_name.lstrip('*'), search_object = 'object' in self.switches)
|
||||
else:
|
||||
obj = caller.search(obj_name)
|
||||
|
|
@ -2090,12 +2089,12 @@ class CmdExamine(ObjManipCommand):
|
|||
else:
|
||||
if obj.sessions.count():
|
||||
mergemode = "session"
|
||||
elif self.player_mode:
|
||||
mergemode = "player"
|
||||
elif self.account_mode:
|
||||
mergemode = "account"
|
||||
else:
|
||||
mergemode = "object"
|
||||
# using callback to print results whenever function returns.
|
||||
get_and_merge_cmdsets(obj, self.session, self.player, obj, mergemode, self.raw_string).addCallback(get_cmdset_callback)
|
||||
get_and_merge_cmdsets(obj, self.session, self.account, obj, mergemode, self.raw_string).addCallback(get_cmdset_callback)
|
||||
|
||||
|
||||
class CmdFind(COMMAND_DEFAULT_CLASS):
|
||||
|
|
@ -2103,7 +2102,7 @@ class CmdFind(COMMAND_DEFAULT_CLASS):
|
|||
search the database for objects
|
||||
|
||||
Usage:
|
||||
@find[/switches] <name or dbref or *player> [= dbrefmin[-dbrefmax]]
|
||||
@find[/switches] <name or dbref or *account> [= dbrefmin[-dbrefmax]]
|
||||
|
||||
Switches:
|
||||
room - only look for rooms (location=None)
|
||||
|
|
@ -2112,15 +2111,15 @@ class CmdFind(COMMAND_DEFAULT_CLASS):
|
|||
exact- only exact matches are returned.
|
||||
|
||||
Searches the database for an object of a particular name or exact #dbref.
|
||||
Use *playername to search for a player. The switches allows for
|
||||
Use *accountname to search for an account. The switches allows for
|
||||
limiting object matches to certain game entities. Dbrefmin and dbrefmax
|
||||
limits matches to within the given dbrefs range, or above/below if only
|
||||
one is given.
|
||||
"""
|
||||
|
||||
key = "@find"
|
||||
aliases = "find, @search, search, @locate, locate"
|
||||
locks = "cmd:perm(find) or perm(Builders)"
|
||||
aliases = "@search, @locate"
|
||||
locks = "cmd:perm(find) or perm(Builder)"
|
||||
help_category = "Building"
|
||||
|
||||
def func(self):
|
||||
|
|
@ -2149,22 +2148,22 @@ class CmdFind(COMMAND_DEFAULT_CLASS):
|
|||
high = max(low, high)
|
||||
|
||||
is_dbref = utils.dbref(searchstring)
|
||||
is_player = searchstring.startswith("*")
|
||||
is_account = searchstring.startswith("*")
|
||||
|
||||
restrictions = ""
|
||||
if self.switches:
|
||||
restrictions = ", %s" % (",".join(self.switches))
|
||||
|
||||
if is_dbref or is_player:
|
||||
if is_dbref or is_account:
|
||||
|
||||
if is_dbref:
|
||||
# a dbref search
|
||||
result = caller.search(searchstring, global_search=True, quiet=True)
|
||||
string = "|wExact dbref match|n(#%i-#%i%s):" % (low, high, restrictions)
|
||||
else:
|
||||
# a player search
|
||||
# an account search
|
||||
searchstring = searchstring.lstrip("*")
|
||||
result = caller.search_player(searchstring, quiet=True)
|
||||
result = caller.search_account(searchstring, quiet=True)
|
||||
string = "|wMatch|n(#%i-#%i%s):" % (low, high, restrictions)
|
||||
|
||||
if "room" in switches:
|
||||
|
|
@ -2182,7 +2181,7 @@ class CmdFind(COMMAND_DEFAULT_CLASS):
|
|||
result=result[0]
|
||||
string += "\n|g %s - %s|n" % (result.get_display_name(caller), result.path)
|
||||
else:
|
||||
# Not a player/dbref search but a wider search; build a queryset.
|
||||
# Not an account/dbref search but a wider search; build a queryset.
|
||||
# Searchs for key and aliases
|
||||
if "exact" in switches:
|
||||
keyquery = Q(db_key__iexact=searchstring, id__gte=low, id__lte=high)
|
||||
|
|
@ -2251,7 +2250,7 @@ class CmdTeleport(COMMAND_DEFAULT_CLASS):
|
|||
is teleported to the target location. """
|
||||
key = "@tel"
|
||||
aliases = "@teleport"
|
||||
locks = "cmd:perm(teleport) or perm(Builders)"
|
||||
locks = "cmd:perm(teleport) or perm(Builder)"
|
||||
help_category = "Building"
|
||||
|
||||
def func(self):
|
||||
|
|
@ -2275,10 +2274,10 @@ class CmdTeleport(COMMAND_DEFAULT_CLASS):
|
|||
if not obj_to_teleport:
|
||||
caller.msg("Did not find object to teleport.")
|
||||
return
|
||||
if obj_to_teleport.has_player:
|
||||
if obj_to_teleport.has_account:
|
||||
caller.msg("Cannot teleport a puppeted object "
|
||||
"(%s, puppeted by %s) to a None-location." % (
|
||||
obj_to_teleport.key, obj_to_teleport.player))
|
||||
obj_to_teleport.key, obj_to_teleport.account))
|
||||
return
|
||||
caller.msg("Teleported %s -> None-location." % obj_to_teleport)
|
||||
if obj_to_teleport.location and not tel_quietly:
|
||||
|
|
@ -2352,7 +2351,7 @@ class CmdScript(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
key = "@script"
|
||||
aliases = "@addscript"
|
||||
locks = "cmd:perm(script) or perm(Builders)"
|
||||
locks = "cmd:perm(script) or perm(Builder)"
|
||||
help_category = "Building"
|
||||
|
||||
def func(self):
|
||||
|
|
@ -2453,7 +2452,7 @@ class CmdTag(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
key = "@tag"
|
||||
aliases = ["@tags"]
|
||||
locks = "cmd:perm(tag) or perm(Builders)"
|
||||
locks = "cmd:perm(tag) or perm(Builder)"
|
||||
help_category = "Building"
|
||||
arg_regex = r"(/\w+?(\s|$))|\s|$"
|
||||
|
||||
|
|
@ -2593,8 +2592,7 @@ class CmdSpawn(COMMAND_DEFAULT_CLASS):
|
|||
"""
|
||||
|
||||
key = "@spawn"
|
||||
aliases = ["spawn"]
|
||||
locks = "cmd:perm(spawn) or perm(Builders)"
|
||||
locks = "cmd:perm(spawn) or perm(Builder)"
|
||||
help_category = "Building"
|
||||
|
||||
def func(self):
|
||||
|
|
@ -2635,8 +2633,8 @@ class CmdSpawn(COMMAND_DEFAULT_CLASS):
|
|||
return
|
||||
elif isinstance(prototype, dict):
|
||||
# we got the prototype on the command line. We must make sure to not allow
|
||||
# the 'exec' key unless we are immortals or higher.
|
||||
if "exec" in prototype and not self.caller.check_permstring("Immortals"):
|
||||
# the 'exec' key unless we are developers or higher.
|
||||
if "exec" in prototype and not self.caller.check_permstring("Developer"):
|
||||
self.caller.msg("Spawn aborted: You don't have access to use the 'exec' prototype key.")
|
||||
return
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
"""
|
||||
|
||||
This is the cmdset for Player (OOC) commands. These are
|
||||
stored on the Player object and should thus be able to handle getting
|
||||
a Player object as caller rather than a Character.
|
||||
This is the cmdset for Account (OOC) commands. These are
|
||||
stored on the Account object and should thus be able to handle getting
|
||||
an Account object as caller rather than a Character.
|
||||
|
||||
Note - in order for session-rerouting (in MULTISESSION_MODE=2) to
|
||||
function, all commands in this cmdset should use the self.msg()
|
||||
|
|
@ -11,33 +11,33 @@ command method rather than caller.msg().
|
|||
|
||||
from evennia.commands.cmdset import CmdSet
|
||||
from evennia.commands.default import help, comms, admin, system
|
||||
from evennia.commands.default import building, player
|
||||
from evennia.commands.default import building, account
|
||||
|
||||
|
||||
class PlayerCmdSet(CmdSet):
|
||||
class AccountCmdSet(CmdSet):
|
||||
"""
|
||||
Implements the player command set.
|
||||
Implements the account command set.
|
||||
"""
|
||||
|
||||
key = "DefaultPlayer"
|
||||
key = "DefaultAccount"
|
||||
priority = -10
|
||||
|
||||
def at_cmdset_creation(self):
|
||||
"Populates the cmdset"
|
||||
|
||||
# Player-specific commands
|
||||
self.add(player.CmdOOCLook())
|
||||
self.add(player.CmdIC())
|
||||
self.add(player.CmdOOC())
|
||||
self.add(player.CmdCharCreate())
|
||||
self.add(player.CmdCharDelete())
|
||||
#self.add(player.CmdSessions())
|
||||
self.add(player.CmdWho())
|
||||
self.add(player.CmdOption())
|
||||
self.add(player.CmdQuit())
|
||||
self.add(player.CmdPassword())
|
||||
self.add(player.CmdColorTest())
|
||||
self.add(player.CmdQuell())
|
||||
# Account-specific commands
|
||||
self.add(account.CmdOOCLook())
|
||||
self.add(account.CmdIC())
|
||||
self.add(account.CmdOOC())
|
||||
self.add(account.CmdCharCreate())
|
||||
self.add(account.CmdCharDelete())
|
||||
#self.add(account.CmdSessions())
|
||||
self.add(account.CmdWho())
|
||||
self.add(account.CmdOption())
|
||||
self.add(account.CmdQuit())
|
||||
self.add(account.CmdPassword())
|
||||
self.add(account.CmdColorTest())
|
||||
self.add(account.CmdQuell())
|
||||
|
||||
# testing
|
||||
self.add(building.CmdExamine())
|
||||
|
|
@ -52,7 +52,7 @@ class PlayerCmdSet(CmdSet):
|
|||
self.add(system.CmdPy())
|
||||
|
||||
# Admin commands
|
||||
self.add(admin.CmdDelPlayer())
|
||||
self.add(admin.CmdDelAccount())
|
||||
self.add(admin.CmdNewPassword())
|
||||
|
||||
# Comm commands
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
"""
|
||||
This module ties together all the commands default Character objects have
|
||||
available (i.e. IC commands). Note that some commands, such as
|
||||
communication-commands are instead put on the player level, in the
|
||||
Player cmdset. Player commands remain available also to Characters.
|
||||
communication-commands are instead put on the account level, in the
|
||||
Account cmdset. Account commands remain available also to Characters.
|
||||
"""
|
||||
from evennia.commands.cmdset import CmdSet
|
||||
from evennia.commands.default import general, help, admin, system
|
||||
|
|
@ -25,7 +25,7 @@ class CharacterCmdSet(CmdSet):
|
|||
self.add(general.CmdInventory())
|
||||
self.add(general.CmdPose())
|
||||
self.add(general.CmdNick())
|
||||
self.add(general.CmdDesc())
|
||||
self.add(general.CmdSetDesc())
|
||||
self.add(general.CmdGet())
|
||||
self.add(general.CmdDrop())
|
||||
self.add(general.CmdGive())
|
||||
|
|
@ -41,7 +41,7 @@ class CharacterCmdSet(CmdSet):
|
|||
self.add(system.CmdPy())
|
||||
self.add(system.CmdScripts())
|
||||
self.add(system.CmdObjects())
|
||||
self.add(system.CmdPlayers())
|
||||
self.add(system.CmdAccounts())
|
||||
self.add(system.CmdService())
|
||||
self.add(system.CmdAbout())
|
||||
self.add(system.CmdTime())
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
This module stores session-level commands.
|
||||
"""
|
||||
from evennia.commands.cmdset import CmdSet
|
||||
from evennia.commands.default import player
|
||||
from evennia.commands.default import account
|
||||
|
||||
class SessionCmdSet(CmdSet):
|
||||
"""
|
||||
|
|
@ -13,4 +13,4 @@ class SessionCmdSet(CmdSet):
|
|||
|
||||
def at_cmdset_creation(self):
|
||||
"Populate the cmdset"
|
||||
self.add(player.CmdSessions())
|
||||
self.add(account.CmdSessions())
|
||||
|
|
|
|||
|
|
@ -2,16 +2,16 @@
|
|||
Comsystem command module.
|
||||
|
||||
Comm commands are OOC commands and intended to be made available to
|
||||
the Player at all times (they go into the PlayerCmdSet). So we
|
||||
make sure to homogenize self.caller to always be the player object
|
||||
the Account at all times (they go into the AccountCmdSet). So we
|
||||
make sure to homogenize self.caller to always be the account object
|
||||
for easy handling.
|
||||
|
||||
"""
|
||||
from past.builtins import cmp
|
||||
from django.conf import settings
|
||||
from evennia.comms.models import ChannelDB, Msg
|
||||
from evennia.players.models import PlayerDB
|
||||
from evennia.players import bots
|
||||
from evennia.accounts.models import AccountDB
|
||||
from evennia.accounts import bots
|
||||
from evennia.comms.channelhandler import CHANNELHANDLER
|
||||
from evennia.locks.lockhandler import LockException
|
||||
from evennia.utils import create, utils, evtable
|
||||
|
|
@ -69,14 +69,14 @@ class CmdAddCom(COMMAND_DEFAULT_CLASS):
|
|||
locks = "cmd:not pperm(channel_banned)"
|
||||
|
||||
# this is used by the COMMAND_DEFAULT_CLASS parent
|
||||
player_caller = True
|
||||
account_caller = True
|
||||
|
||||
def func(self):
|
||||
"""Implement the command"""
|
||||
|
||||
caller = self.caller
|
||||
args = self.args
|
||||
player = caller
|
||||
account = caller
|
||||
|
||||
if not args:
|
||||
self.msg("Usage: addcom [alias =] channelname.")
|
||||
|
|
@ -96,21 +96,21 @@ class CmdAddCom(COMMAND_DEFAULT_CLASS):
|
|||
return
|
||||
|
||||
# check permissions
|
||||
if not channel.access(player, 'listen'):
|
||||
if not channel.access(account, 'listen'):
|
||||
self.msg("%s: You are not allowed to listen to this channel." % channel.key)
|
||||
return
|
||||
|
||||
string = ""
|
||||
if not channel.has_connection(player):
|
||||
if not channel.has_connection(account):
|
||||
# we want to connect as well.
|
||||
if not channel.connect(player):
|
||||
# if this would have returned True, the player is connected
|
||||
if not channel.connect(account):
|
||||
# if this would have returned True, the account is connected
|
||||
self.msg("%s: You are not allowed to join this channel." % channel.key)
|
||||
return
|
||||
else:
|
||||
string += "You now listen to the channel %s. " % channel.key
|
||||
else:
|
||||
if channel.unmute(player):
|
||||
if channel.unmute(account):
|
||||
string += "You unmute channel %s." % channel.key
|
||||
else:
|
||||
string += "You are already connected to channel %s." % channel.key
|
||||
|
|
@ -145,13 +145,13 @@ class CmdDelCom(COMMAND_DEFAULT_CLASS):
|
|||
locks = "cmd:not perm(channel_banned)"
|
||||
|
||||
# this is used by the COMMAND_DEFAULT_CLASS parent
|
||||
player_caller = True
|
||||
account_caller = True
|
||||
|
||||
def func(self):
|
||||
"""Implementing the command. """
|
||||
|
||||
caller = self.caller
|
||||
player = caller
|
||||
account = caller
|
||||
|
||||
if not self.args:
|
||||
self.msg("Usage: delcom <alias or channel>")
|
||||
|
|
@ -161,7 +161,7 @@ class CmdDelCom(COMMAND_DEFAULT_CLASS):
|
|||
channel = find_channel(caller, ostring, silent=True, noaliases=True)
|
||||
if channel:
|
||||
# we have given a channel name - unsubscribe
|
||||
if not channel.has_connection(player):
|
||||
if not channel.has_connection(account):
|
||||
self.msg("You are not listening to that channel.")
|
||||
return
|
||||
chkey = channel.key.lower()
|
||||
|
|
@ -171,7 +171,7 @@ class CmdDelCom(COMMAND_DEFAULT_CLASS):
|
|||
for nick in [nick for nick in make_iter(caller.nicks.get(category="channel", return_obj=True))
|
||||
if nick and nick.pk and nick.value[3].lower() == chkey]:
|
||||
nick.delete()
|
||||
disconnect = channel.disconnect(player)
|
||||
disconnect = channel.disconnect(account)
|
||||
if disconnect:
|
||||
wipednicks = " Eventual aliases were removed." if delnicks else ""
|
||||
self.msg("You stop listening to channel '%s'.%s" % (channel.key, wipednicks))
|
||||
|
|
@ -209,7 +209,7 @@ class CmdAllCom(COMMAND_DEFAULT_CLASS):
|
|||
help_category = "Comms"
|
||||
|
||||
# this is used by the COMMAND_DEFAULT_CLASS parent
|
||||
player_caller = True
|
||||
account_caller = True
|
||||
|
||||
def func(self):
|
||||
"""Runs the function"""
|
||||
|
|
@ -268,12 +268,12 @@ class CmdChannels(COMMAND_DEFAULT_CLASS):
|
|||
Use addcom/delcom to join and leave channels
|
||||
"""
|
||||
key = "@channels"
|
||||
aliases = ["@clist", "channels", "comlist", "chanlist", "channellist", "all channels"]
|
||||
aliases = ["@clist", "comlist", "chanlist", "channellist", "all channels"]
|
||||
help_category = "Comms"
|
||||
locks = "cmd: not pperm(channel_banned)"
|
||||
|
||||
# this is used by the COMMAND_DEFAULT_CLASS parent
|
||||
player_caller = True
|
||||
account_caller = True
|
||||
|
||||
def func(self):
|
||||
"""Implement function"""
|
||||
|
|
@ -345,7 +345,7 @@ class CmdCdestroy(COMMAND_DEFAULT_CLASS):
|
|||
locks = "cmd: not pperm(channel_banned)"
|
||||
|
||||
# this is used by the COMMAND_DEFAULT_CLASS parent
|
||||
player_caller = True
|
||||
account_caller = True
|
||||
|
||||
def func(self):
|
||||
"""Destroy objects cleanly."""
|
||||
|
|
@ -372,15 +372,15 @@ class CmdCdestroy(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
class CmdCBoot(COMMAND_DEFAULT_CLASS):
|
||||
"""
|
||||
kick a player from a channel you control
|
||||
kick an account from a channel you control
|
||||
|
||||
Usage:
|
||||
@cboot[/quiet] <channel> = <player> [:reason]
|
||||
@cboot[/quiet] <channel> = <account> [:reason]
|
||||
|
||||
Switches:
|
||||
quiet - don't notify the channel
|
||||
|
||||
Kicks a player or object from a channel you control.
|
||||
Kicks an account or object from a channel you control.
|
||||
|
||||
"""
|
||||
|
||||
|
|
@ -389,13 +389,13 @@ class CmdCBoot(COMMAND_DEFAULT_CLASS):
|
|||
help_category = "Comms"
|
||||
|
||||
# this is used by the COMMAND_DEFAULT_CLASS parent
|
||||
player_caller = True
|
||||
account_caller = True
|
||||
|
||||
def func(self):
|
||||
"""implement the function"""
|
||||
|
||||
if not self.args or not self.rhs:
|
||||
string = "Usage: @cboot[/quiet] <channel> = <player> [:reason]"
|
||||
string = "Usage: @cboot[/quiet] <channel> = <account> [:reason]"
|
||||
self.msg(string)
|
||||
return
|
||||
|
||||
|
|
@ -404,12 +404,12 @@ class CmdCBoot(COMMAND_DEFAULT_CLASS):
|
|||
return
|
||||
reason = ""
|
||||
if ":" in self.rhs:
|
||||
playername, reason = self.rhs.rsplit(":", 1)
|
||||
searchstring = playername.lstrip('*')
|
||||
accountname, reason = self.rhs.rsplit(":", 1)
|
||||
searchstring = accountname.lstrip('*')
|
||||
else:
|
||||
searchstring = self.rhs.lstrip('*')
|
||||
player = self.caller.search(searchstring, player=True)
|
||||
if not player:
|
||||
account = self.caller.search(searchstring, account=True)
|
||||
if not account:
|
||||
return
|
||||
if reason:
|
||||
reason = " (reason: %s)" % reason
|
||||
|
|
@ -417,20 +417,20 @@ class CmdCBoot(COMMAND_DEFAULT_CLASS):
|
|||
string = "You don't control this channel."
|
||||
self.msg(string)
|
||||
return
|
||||
if player not in channel.db_subscriptions.all():
|
||||
string = "Player %s is not connected to channel %s." % (player.key, channel.key)
|
||||
if account not in channel.db_subscriptions.all():
|
||||
string = "Account %s is not connected to channel %s." % (account.key, channel.key)
|
||||
self.msg(string)
|
||||
return
|
||||
if "quiet" not in self.switches:
|
||||
string = "%s boots %s from channel.%s" % (self.caller, player.key, reason)
|
||||
string = "%s boots %s from channel.%s" % (self.caller, account.key, reason)
|
||||
channel.msg(string)
|
||||
# find all player's nicks linked to this channel and delete them
|
||||
# find all account's nicks linked to this channel and delete them
|
||||
for nick in [nick for nick in
|
||||
player.character.nicks.get(category="channel") or []
|
||||
account.character.nicks.get(category="channel") or []
|
||||
if nick.value[3].lower() == channel.key]:
|
||||
nick.delete()
|
||||
# disconnect player
|
||||
channel.disconnect(player)
|
||||
# disconnect account
|
||||
channel.disconnect(account)
|
||||
CHANNELHANDLER.update()
|
||||
|
||||
|
||||
|
|
@ -453,11 +453,11 @@ class CmdCemit(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
key = "@cemit"
|
||||
aliases = ["@cmsg"]
|
||||
locks = "cmd: not pperm(channel_banned) and pperm(Players)"
|
||||
locks = "cmd: not pperm(channel_banned) and pperm(Account)"
|
||||
help_category = "Comms"
|
||||
|
||||
# this is used by the COMMAND_DEFAULT_CLASS parent
|
||||
player_caller = True
|
||||
account_caller = True
|
||||
|
||||
def func(self):
|
||||
"""Implement function"""
|
||||
|
|
@ -496,7 +496,7 @@ class CmdCWho(COMMAND_DEFAULT_CLASS):
|
|||
help_category = "Comms"
|
||||
|
||||
# this is used by the COMMAND_DEFAULT_CLASS parent
|
||||
player_caller = True
|
||||
account_caller = True
|
||||
|
||||
def func(self):
|
||||
"""implement function"""
|
||||
|
|
@ -530,11 +530,11 @@ class CmdChannelCreate(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
key = "@ccreate"
|
||||
aliases = "channelcreate"
|
||||
locks = "cmd:not pperm(channel_banned) and pperm(Players)"
|
||||
locks = "cmd:not pperm(channel_banned) and pperm(Account)"
|
||||
help_category = "Comms"
|
||||
|
||||
# this is used by the COMMAND_DEFAULT_CLASS parent
|
||||
player_caller = True
|
||||
account_caller = True
|
||||
|
||||
def func(self):
|
||||
"""Implement the command"""
|
||||
|
|
@ -587,7 +587,7 @@ class CmdClock(COMMAND_DEFAULT_CLASS):
|
|||
help_category = "Comms"
|
||||
|
||||
# this is used by the COMMAND_DEFAULT_CLASS parent
|
||||
player_caller = True
|
||||
account_caller = True
|
||||
|
||||
def func(self):
|
||||
"""run the function"""
|
||||
|
|
@ -639,7 +639,7 @@ class CmdCdesc(COMMAND_DEFAULT_CLASS):
|
|||
help_category = "Comms"
|
||||
|
||||
# this is used by the COMMAND_DEFAULT_CLASS parent
|
||||
player_caller = True
|
||||
account_caller = True
|
||||
|
||||
def func(self):
|
||||
"""Implement command"""
|
||||
|
|
@ -666,10 +666,10 @@ class CmdCdesc(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
class CmdPage(COMMAND_DEFAULT_CLASS):
|
||||
"""
|
||||
send a private message to another player
|
||||
send a private message to another account
|
||||
|
||||
Usage:
|
||||
page[/switches] [<player>,<player>,... = <message>]
|
||||
page[/switches] [<account>,<account>,... = <message>]
|
||||
tell ''
|
||||
page <number>
|
||||
|
||||
|
|
@ -687,12 +687,12 @@ class CmdPage(COMMAND_DEFAULT_CLASS):
|
|||
help_category = "Comms"
|
||||
|
||||
# this is used by the COMMAND_DEFAULT_CLASS parent
|
||||
player_caller = True
|
||||
account_caller = True
|
||||
|
||||
def func(self):
|
||||
"""Implement function using the Msg methods"""
|
||||
|
||||
# Since player_caller is set above, this will be a Player.
|
||||
# Since account_caller is set above, this will be an Account.
|
||||
caller = self.caller
|
||||
|
||||
# get the messages we've sent (not to channels)
|
||||
|
|
@ -718,7 +718,7 @@ class CmdPage(COMMAND_DEFAULT_CLASS):
|
|||
try:
|
||||
number = int(self.args)
|
||||
except ValueError:
|
||||
self.msg("Usage: tell [<player> = msg]")
|
||||
self.msg("Usage: tell [<account> = msg]")
|
||||
return
|
||||
|
||||
if len(pages) > number:
|
||||
|
|
@ -767,7 +767,7 @@ class CmdPage(COMMAND_DEFAULT_CLASS):
|
|||
self.msg("Noone found to page.")
|
||||
return
|
||||
|
||||
header = "|wPlayer|n |c%s|n |wpages:|n" % caller.key
|
||||
header = "|wAccount|n |c%s|n |wpages:|n" % caller.key
|
||||
message = self.rhs
|
||||
|
||||
# if message begins with a :, we assume it is a 'page-pose'
|
||||
|
|
@ -778,7 +778,7 @@ class CmdPage(COMMAND_DEFAULT_CLASS):
|
|||
create.create_message(caller, message,
|
||||
receivers=recobjs)
|
||||
|
||||
# tell the players they got a message.
|
||||
# tell the accounts they got a message.
|
||||
received = []
|
||||
rstrings = []
|
||||
for pobj in recobjs:
|
||||
|
|
@ -805,7 +805,7 @@ def _list_bots():
|
|||
bots (str): A table of bots or an error message.
|
||||
|
||||
"""
|
||||
ircbots = [bot for bot in PlayerDB.objects.filter(db_is_bot=True, username__startswith="ircbot-")]
|
||||
ircbots = [bot for bot in AccountDB.objects.filter(db_is_bot=True, username__startswith="ircbot-")]
|
||||
if ircbots:
|
||||
from evennia.utils.evtable import EvTable
|
||||
table = EvTable("|w#dbref|n", "|wbotname|n", "|wev-channel|n",
|
||||
|
|
@ -836,7 +836,7 @@ class CmdIRC2Chan(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
Example:
|
||||
@irc2chan myircchan = irc.dalnet.net 6667 #mychannel evennia-bot
|
||||
@irc2chan public = irc.freenode.net 6667 #evgaming #evbot:players.mybot.MyBot
|
||||
@irc2chan public = irc.freenode.net 6667 #evgaming #evbot:accounts.mybot.MyBot
|
||||
|
||||
This creates an IRC bot that connects to a given IRC network and
|
||||
channel. If a custom typeclass path is given, this will be used
|
||||
|
|
@ -850,7 +850,7 @@ class CmdIRC2Chan(COMMAND_DEFAULT_CLASS):
|
|||
"""
|
||||
|
||||
key = "@irc2chan"
|
||||
locks = "cmd:serversetting(IRC_ENABLED) and pperm(Immortals)"
|
||||
locks = "cmd:serversetting(IRC_ENABLED) and pperm(Developer)"
|
||||
help_category = "Comms"
|
||||
|
||||
def func(self):
|
||||
|
|
@ -868,11 +868,11 @@ class CmdIRC2Chan(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
if 'disconnect' in self.switches or 'remove' in self.switches or 'delete' in self.switches:
|
||||
botname = "ircbot-%s" % self.lhs
|
||||
matches = PlayerDB.objects.filter(db_is_bot=True, username=botname)
|
||||
matches = AccountDB.objects.filter(db_is_bot=True, username=botname)
|
||||
dbref = utils.dbref(self.lhs)
|
||||
if not matches and dbref:
|
||||
# try dbref match
|
||||
matches = PlayerDB.objects.filter(db_is_bot=True, id=dbref)
|
||||
matches = AccountDB.objects.filter(db_is_bot=True, id=dbref)
|
||||
if matches:
|
||||
matches[0].delete()
|
||||
self.msg("IRC connection destroyed.")
|
||||
|
|
@ -906,16 +906,16 @@ class CmdIRC2Chan(COMMAND_DEFAULT_CLASS):
|
|||
irc_ssl = "ssl" in self.switches
|
||||
|
||||
# create a new bot
|
||||
bot = PlayerDB.objects.filter(username__iexact=botname)
|
||||
bot = AccountDB.objects.filter(username__iexact=botname)
|
||||
if bot:
|
||||
# re-use an existing bot
|
||||
bot = bot[0]
|
||||
if not bot.is_bot:
|
||||
self.msg("Player '%s' already exists and is not a bot." % botname)
|
||||
self.msg("Account '%s' already exists and is not a bot." % botname)
|
||||
return
|
||||
else:
|
||||
try:
|
||||
bot = create.create_player(botname, None, None, typeclass=botclass)
|
||||
bot = create.create_account(botname, None, None, typeclass=botclass)
|
||||
except Exception as err:
|
||||
self.msg("|rError, could not create the bot:|n '%s'." % err)
|
||||
return
|
||||
|
|
@ -943,7 +943,7 @@ class CmdIRCStatus(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
"""
|
||||
key = "@ircstatus"
|
||||
locks = "cmd:serversetting(IRC_ENABLED) and perm(ircstatus) or perm(Builders))"
|
||||
locks = "cmd:serversetting(IRC_ENABLED) and perm(ircstatus) or perm(Builder))"
|
||||
help_category = "Comms"
|
||||
|
||||
def func(self):
|
||||
|
|
@ -963,7 +963,7 @@ class CmdIRCStatus(COMMAND_DEFAULT_CLASS):
|
|||
return
|
||||
matches = None
|
||||
if utils.dbref(botname):
|
||||
matches = PlayerDB.objects.filter(db_is_bot=True, id=utils.dbref(botname))
|
||||
matches = AccountDB.objects.filter(db_is_bot=True, id=utils.dbref(botname))
|
||||
if not matches:
|
||||
self.msg("No matching IRC-bot found. Use @ircstatus without arguments to list active bots.")
|
||||
return
|
||||
|
|
@ -981,7 +981,7 @@ class CmdIRCStatus(COMMAND_DEFAULT_CLASS):
|
|||
# an asynchronous call.
|
||||
self.caller.msg("Requesting nicklist from %s (%s:%s)." % (channel, network, port))
|
||||
ircbot.get_nicklist(self.caller)
|
||||
elif self.caller.locks.check_lockstring(self.caller, "dummy:perm(ircstatus) or perm(Immortals)"):
|
||||
elif self.caller.locks.check_lockstring(self.caller, "dummy:perm(ircstatus) or perm(Developer)"):
|
||||
# reboot the client
|
||||
self.caller.msg("Forcing a disconnect + reconnect of %s." % chtext)
|
||||
ircbot.reconnect()
|
||||
|
|
@ -1016,7 +1016,7 @@ class CmdRSS2Chan(COMMAND_DEFAULT_CLASS):
|
|||
"""
|
||||
|
||||
key = "@rss2chan"
|
||||
locks = "cmd:serversetting(RSS_ENABLED) and pperm(Immortals)"
|
||||
locks = "cmd:serversetting(RSS_ENABLED) and pperm(Developer)"
|
||||
help_category = "Comms"
|
||||
|
||||
def func(self):
|
||||
|
|
@ -1038,7 +1038,7 @@ class CmdRSS2Chan(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
if 'list' in self.switches:
|
||||
# show all connections
|
||||
rssbots = [bot for bot in PlayerDB.objects.filter(db_is_bot=True, username__startswith="rssbot-")]
|
||||
rssbots = [bot for bot in AccountDB.objects.filter(db_is_bot=True, username__startswith="rssbot-")]
|
||||
if rssbots:
|
||||
from evennia.utils.evtable import EvTable
|
||||
table = EvTable("|wdbid|n", "|wupdate rate|n", "|wev-channel",
|
||||
|
|
@ -1052,10 +1052,10 @@ class CmdRSS2Chan(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
if 'disconnect' in self.switches or 'remove' in self.switches or 'delete' in self.switches:
|
||||
botname = "rssbot-%s" % self.lhs
|
||||
matches = PlayerDB.objects.filter(db_is_bot=True, db_key=botname)
|
||||
matches = AccountDB.objects.filter(db_is_bot=True, db_key=botname)
|
||||
if not matches:
|
||||
# try dbref match
|
||||
matches = PlayerDB.objects.filter(db_is_bot=True, id=self.args.lstrip("#"))
|
||||
matches = AccountDB.objects.filter(db_is_bot=True, id=self.args.lstrip("#"))
|
||||
if matches:
|
||||
matches[0].delete()
|
||||
self.msg("RSS connection destroyed.")
|
||||
|
|
@ -1072,14 +1072,14 @@ class CmdRSS2Chan(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
botname = "rssbot-%s" % url
|
||||
# create a new bot
|
||||
bot = PlayerDB.objects.filter(username__iexact=botname)
|
||||
bot = AccountDB.objects.filter(username__iexact=botname)
|
||||
if bot:
|
||||
# re-use existing bot
|
||||
bot = bot[0]
|
||||
if not bot.is_bot:
|
||||
self.msg("Player '%s' already exists and is not a bot." % botname)
|
||||
self.msg("Account '%s' already exists and is not a bot." % botname)
|
||||
return
|
||||
else:
|
||||
bot = create.create_player(botname, None, None, typeclass=bots.RSSBot)
|
||||
bot = create.create_account(botname, None, None, typeclass=bots.RSSBot)
|
||||
bot.start(ev_channel=channel, rss_url=url, rss_rate=10)
|
||||
self.msg("RSS reporter created. Fetching RSS.")
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ COMMAND_DEFAULT_CLASS = utils.class_from_module(settings.COMMAND_DEFAULT_CLASS)
|
|||
|
||||
# limit symbol import for API
|
||||
__all__ = ("CmdHome", "CmdLook", "CmdNick",
|
||||
"CmdInventory", "CmdGet", "CmdDrop", "CmdGive",
|
||||
"CmdInventory", "CmdSetDesc", "CmdGet", "CmdDrop", "CmdGive",
|
||||
"CmdSay", "CmdWhisper", "CmdPose", "CmdAccess")
|
||||
|
||||
|
||||
|
|
@ -24,7 +24,7 @@ class CmdHome(COMMAND_DEFAULT_CLASS):
|
|||
"""
|
||||
|
||||
key = "home"
|
||||
locks = "cmd:perm(home) or perm(Builders)"
|
||||
locks = "cmd:perm(home) or perm(Builder)"
|
||||
arg_regex = r"$"
|
||||
|
||||
def func(self):
|
||||
|
|
@ -47,7 +47,7 @@ class CmdLook(COMMAND_DEFAULT_CLASS):
|
|||
Usage:
|
||||
look
|
||||
look <obj>
|
||||
look *<player>
|
||||
look *<account>
|
||||
|
||||
Observes your location or objects in your vicinity.
|
||||
"""
|
||||
|
|
@ -86,7 +86,7 @@ class CmdNick(COMMAND_DEFAULT_CLASS):
|
|||
Switches:
|
||||
inputline - replace on the inputline (default)
|
||||
object - replace on object-lookup
|
||||
player - replace on player-lookup
|
||||
account - replace on account-lookup
|
||||
delete - remove nick by name or by index given by /list
|
||||
clearall - clear all nicks
|
||||
list - show all defined aliases (also "nicks" works)
|
||||
|
|
@ -113,7 +113,7 @@ class CmdNick(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
"""
|
||||
key = "nick"
|
||||
aliases = ["nickname", "nicks", "@nick", "@nicks", "alias"]
|
||||
aliases = ["nickname", "nicks", "alias"]
|
||||
locks = "cmd:all()"
|
||||
|
||||
def func(self):
|
||||
|
|
@ -121,7 +121,7 @@ class CmdNick(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
caller = self.caller
|
||||
switches = self.switches
|
||||
nicktypes = [switch for switch in switches if switch in ("object", "player", "inputline")] or ["inputline"]
|
||||
nicktypes = [switch for switch in switches if switch in ("object", "account", "inputline")] or ["inputline"]
|
||||
|
||||
nicklist = utils.make_iter(caller.nicks.get(return_obj=True) or [])
|
||||
|
||||
|
|
@ -358,18 +358,18 @@ class CmdGive(COMMAND_DEFAULT_CLASS):
|
|||
to_give.at_give(caller, target)
|
||||
|
||||
|
||||
class CmdDesc(COMMAND_DEFAULT_CLASS):
|
||||
class CmdSetDesc(COMMAND_DEFAULT_CLASS):
|
||||
"""
|
||||
describe yourself
|
||||
|
||||
Usage:
|
||||
desc <description>
|
||||
setdesc <description>
|
||||
|
||||
Add a description to yourself. This
|
||||
will be visible to people when they
|
||||
look at you.
|
||||
"""
|
||||
key = "desc"
|
||||
key = "setdesc"
|
||||
locks = "cmd:all()"
|
||||
arg_regex = r"\s|$"
|
||||
|
||||
|
|
@ -417,7 +417,7 @@ class CmdSay(COMMAND_DEFAULT_CLASS):
|
|||
return
|
||||
|
||||
# Call the at_after_say hook on the character
|
||||
caller.at_after_say(speech)
|
||||
caller.at_say(speech)
|
||||
|
||||
class CmdWhisper(COMMAND_DEFAULT_CLASS):
|
||||
"""
|
||||
|
|
@ -439,7 +439,7 @@ class CmdWhisper(COMMAND_DEFAULT_CLASS):
|
|||
caller = self.caller
|
||||
|
||||
if not self.lhs or not self.rhs:
|
||||
caller.msg("Usage: whisper <player> = <message>")
|
||||
caller.msg("Usage: whisper <account> = <message>")
|
||||
return
|
||||
|
||||
receiver = caller.search(self.lhs)
|
||||
|
|
@ -453,14 +453,14 @@ class CmdWhisper(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
speech = self.rhs
|
||||
# Call a hook to change the speech before whispering
|
||||
speech = caller.at_before_whisper(receiver, speech)
|
||||
speech = caller.at_before_say(speech, whisper=True, receiver=receiver)
|
||||
|
||||
# If the speech is empty, abort the command
|
||||
if not speech:
|
||||
return
|
||||
|
||||
# Call the at_after_whisper hook for feedback
|
||||
caller.at_after_whisper(receiver, speech)
|
||||
caller.at_say(speech, receiver=receiver, whisper=True)
|
||||
|
||||
|
||||
class CmdPose(COMMAND_DEFAULT_CLASS):
|
||||
|
|
@ -529,15 +529,15 @@ class CmdAccess(COMMAND_DEFAULT_CLASS):
|
|||
hierarchy_full = settings.PERMISSION_HIERARCHY
|
||||
string = "\n|wPermission Hierarchy|n (climbing):\n %s" % ", ".join(hierarchy_full)
|
||||
|
||||
if self.caller.player.is_superuser:
|
||||
if self.caller.account.is_superuser:
|
||||
cperms = "<Superuser>"
|
||||
pperms = "<Superuser>"
|
||||
else:
|
||||
cperms = ", ".join(caller.permissions.all())
|
||||
pperms = ", ".join(caller.player.permissions.all())
|
||||
pperms = ", ".join(caller.account.permissions.all())
|
||||
|
||||
string += "\n|wYour access|n:"
|
||||
string += "\nCharacter |c%s|n: %s" % (caller.key, cperms)
|
||||
if hasattr(caller, 'player'):
|
||||
string += "\nPlayer |c%s|n: %s" % (caller.player.key, pperms)
|
||||
if hasattr(caller, 'account'):
|
||||
string += "\nAccount |c%s|n: %s" % (caller.account.key, pperms)
|
||||
caller.msg(string)
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ class CmdHelp(Command):
|
|||
|
||||
if self.session.protocol_key in ("websocket", "ajax/comet"):
|
||||
try:
|
||||
options = self.player.db._saved_webclient_options
|
||||
options = self.account.db._saved_webclient_options
|
||||
if options and options["helppopup"]:
|
||||
usemore = False
|
||||
except KeyError:
|
||||
|
|
@ -134,12 +134,12 @@ class CmdHelp(Command):
|
|||
Helper method. If this return True, the given cmd
|
||||
auto-help will be viewable in the help listing.
|
||||
Override this to easily select what is shown to
|
||||
the player. Note that only commands available
|
||||
the account. Note that only commands available
|
||||
in the caller's merged cmdset are available.
|
||||
|
||||
Args:
|
||||
cmd (Command): Command class from the merged cmdset
|
||||
caller (Character, Player or Session): The current caller
|
||||
caller (Character, Account or Session): The current caller
|
||||
executing the help command.
|
||||
|
||||
"""
|
||||
|
|
@ -300,9 +300,8 @@ class CmdSetHelp(COMMAND_DEFAULT_CLASS):
|
|||
is to let everyone read the help file.
|
||||
|
||||
"""
|
||||
key = "@help"
|
||||
aliases = "@sethelp"
|
||||
locks = "cmd:perm(PlayerHelpers)"
|
||||
key = "@sethelp"
|
||||
locks = "cmd:perm(Helper)"
|
||||
help_category = "Building"
|
||||
|
||||
def func(self):
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
"""
|
||||
The command template for the default MUX-style command set. There
|
||||
is also an Player/OOC version that makes sure caller is a Player object.
|
||||
is also an Account/OOC version that makes sure caller is an Account object.
|
||||
"""
|
||||
|
||||
from evennia.utils import utils
|
||||
from evennia.commands.command import Command
|
||||
|
||||
# limit symbol import for API
|
||||
__all__ = ("MuxCommand", "MuxPlayerCommand")
|
||||
__all__ = ("MuxCommand", "MuxAccountCommand")
|
||||
|
||||
|
||||
class MuxCommand(Command):
|
||||
|
|
@ -128,17 +128,17 @@ class MuxCommand(Command):
|
|||
self.rhs = rhs
|
||||
self.rhslist = rhslist
|
||||
|
||||
# if the class has the player_caller property set on itself, we make
|
||||
# sure that self.caller is always the player if possible. We also create
|
||||
# if the class has the account_caller property set on itself, we make
|
||||
# sure that self.caller is always the account if possible. We also create
|
||||
# a special property "character" for the puppeted object, if any. This
|
||||
# is convenient for commands defined on the Player only.
|
||||
if hasattr(self, "player_caller") and self.player_caller:
|
||||
# is convenient for commands defined on the Account only.
|
||||
if hasattr(self, "account_caller") and self.account_caller:
|
||||
if utils.inherits_from(self.caller, "evennia.objects.objects.DefaultObject"):
|
||||
# caller is an Object/Character
|
||||
self.character = self.caller
|
||||
self.caller = self.caller.player
|
||||
elif utils.inherits_from(self.caller, "evennia.players.players.DefaultPlayer"):
|
||||
# caller was already a Player
|
||||
self.caller = self.caller.account
|
||||
elif utils.inherits_from(self.caller, "evennia.accounts.accounts.DefaultAccount"):
|
||||
# caller was already an Account
|
||||
self.character = self.caller.get_puppet(self.session)
|
||||
else:
|
||||
self.character = None
|
||||
|
|
@ -177,32 +177,32 @@ class MuxCommand(Command):
|
|||
self.caller.msg(string)
|
||||
|
||||
|
||||
class MuxPlayerCommand(MuxCommand):
|
||||
class MuxAccountCommand(MuxCommand):
|
||||
"""
|
||||
This is an on-Player version of the MuxCommand. Since these commands sit
|
||||
on Players rather than on Characters/Objects, we need to check
|
||||
This is an on-Account version of the MuxCommand. Since these commands sit
|
||||
on Accounts rather than on Characters/Objects, we need to check
|
||||
this in the parser.
|
||||
|
||||
Player commands are available also when puppeting a Character, it's
|
||||
Account commands are available also when puppeting a Character, it's
|
||||
just that they are applied with a lower priority and are always
|
||||
available, also when disconnected from a character (i.e. "ooc").
|
||||
|
||||
This class makes sure that caller is always a Player object, while
|
||||
This class makes sure that caller is always an Account object, while
|
||||
creating a new property "character" that is set only if a
|
||||
character is actually attached to this Player and Session.
|
||||
character is actually attached to this Account and Session.
|
||||
"""
|
||||
def parse(self):
|
||||
"""
|
||||
We run the parent parser as usual, then fix the result
|
||||
"""
|
||||
super(MuxPlayerCommand, self).parse()
|
||||
super(MuxAccountCommand, self).parse()
|
||||
|
||||
if utils.inherits_from(self.caller, "evennia.objects.objects.DefaultObject"):
|
||||
# caller is an Object/Character
|
||||
self.character = self.caller
|
||||
self.caller = self.caller.player
|
||||
elif utils.inherits_from(self.caller, "evennia.players.players.DefaultPlayer"):
|
||||
# caller was already a Player
|
||||
self.caller = self.caller.account
|
||||
elif utils.inherits_from(self.caller, "evennia.accounts.accounts.DefaultAccount"):
|
||||
# caller was already an Account
|
||||
self.character = self.caller.get_puppet(self.session)
|
||||
else:
|
||||
self.character = None
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ from django.conf import settings
|
|||
from evennia.server.sessionhandler import SESSIONS
|
||||
from evennia.scripts.models import ScriptDB
|
||||
from evennia.objects.models import ObjectDB
|
||||
from evennia.players.models import PlayerDB
|
||||
from evennia.accounts.models import AccountDB
|
||||
from evennia.utils import logger, utils, gametime, create
|
||||
from evennia.utils.eveditor import EvEditor
|
||||
from evennia.utils.evtable import EvTable
|
||||
|
|
@ -47,7 +47,7 @@ class CmdReload(COMMAND_DEFAULT_CLASS):
|
|||
@reset to purge) and at_reload() hooks will be called.
|
||||
"""
|
||||
key = "@reload"
|
||||
locks = "cmd:perm(reload) or perm(Immortals)"
|
||||
locks = "cmd:perm(reload) or perm(Developer)"
|
||||
help_category = "System"
|
||||
|
||||
def func(self):
|
||||
|
|
@ -83,7 +83,7 @@ class CmdReset(COMMAND_DEFAULT_CLASS):
|
|||
"""
|
||||
key = "@reset"
|
||||
aliases = ['@reboot']
|
||||
locks = "cmd:perm(reload) or perm(Immortals)"
|
||||
locks = "cmd:perm(reload) or perm(Developer)"
|
||||
help_category = "System"
|
||||
|
||||
def func(self):
|
||||
|
|
@ -105,7 +105,7 @@ class CmdShutdown(COMMAND_DEFAULT_CLASS):
|
|||
Gracefully shut down both Server and Portal.
|
||||
"""
|
||||
key = "@shutdown"
|
||||
locks = "cmd:perm(shutdown) or perm(Immortals)"
|
||||
locks = "cmd:perm(shutdown) or perm(Developer)"
|
||||
help_category = "System"
|
||||
|
||||
def func(self):
|
||||
|
|
@ -244,7 +244,7 @@ class CmdPy(COMMAND_DEFAULT_CLASS):
|
|||
"""
|
||||
key = "@py"
|
||||
aliases = ["!"]
|
||||
locks = "cmd:perm(py) or perm(Immortals)"
|
||||
locks = "cmd:perm(py) or perm(Developer)"
|
||||
help_category = "System"
|
||||
|
||||
def func(self):
|
||||
|
|
@ -327,7 +327,7 @@ class CmdScripts(COMMAND_DEFAULT_CLASS):
|
|||
"""
|
||||
key = "@scripts"
|
||||
aliases = ["@globalscript", "@listscripts"]
|
||||
locks = "cmd:perm(listscripts) or perm(Wizards)"
|
||||
locks = "cmd:perm(listscripts) or perm(Admin)"
|
||||
help_category = "System"
|
||||
|
||||
def func(self):
|
||||
|
|
@ -409,7 +409,7 @@ class CmdObjects(COMMAND_DEFAULT_CLASS):
|
|||
"""
|
||||
key = "@objects"
|
||||
aliases = ["@listobjects", "@listobjs", '@stats', '@db']
|
||||
locks = "cmd:perm(listobjects) or perm(Builders)"
|
||||
locks = "cmd:perm(listobjects) or perm(Builder)"
|
||||
help_category = "System"
|
||||
|
||||
def func(self):
|
||||
|
|
@ -455,24 +455,24 @@ class CmdObjects(COMMAND_DEFAULT_CLASS):
|
|||
caller.msg(string)
|
||||
|
||||
|
||||
class CmdPlayers(COMMAND_DEFAULT_CLASS):
|
||||
class CmdAccounts(COMMAND_DEFAULT_CLASS):
|
||||
"""
|
||||
list all registered players
|
||||
list all registered accounts
|
||||
|
||||
Usage:
|
||||
@players [nr]
|
||||
@accounts [nr]
|
||||
|
||||
Lists statistics about the Players registered with the game.
|
||||
It will list the <nr> amount of latest registered players
|
||||
Lists statistics about the Accounts registered with the game.
|
||||
It will list the <nr> amount of latest registered accounts
|
||||
If not given, <nr> defaults to 10.
|
||||
"""
|
||||
key = "@players"
|
||||
aliases = ["@listplayers"]
|
||||
locks = "cmd:perm(listplayers) or perm(Wizards)"
|
||||
key = "@accounts"
|
||||
aliases = ["@listaccounts"]
|
||||
locks = "cmd:perm(listaccounts) or perm(Admin)"
|
||||
help_category = "System"
|
||||
|
||||
def func(self):
|
||||
"""List the players"""
|
||||
"""List the accounts"""
|
||||
|
||||
caller = self.caller
|
||||
if self.args and self.args.isdigit():
|
||||
|
|
@ -480,21 +480,21 @@ class CmdPlayers(COMMAND_DEFAULT_CLASS):
|
|||
else:
|
||||
nlim = 10
|
||||
|
||||
nplayers = PlayerDB.objects.count()
|
||||
naccounts = AccountDB.objects.count()
|
||||
|
||||
# typeclass table
|
||||
dbtotals = PlayerDB.objects.object_totals()
|
||||
dbtotals = AccountDB.objects.object_totals()
|
||||
typetable = EvTable("|wtypeclass|n", "|wcount|n", "|w%%|n", border="cells", align="l")
|
||||
for path, count in dbtotals.items():
|
||||
typetable.add_row(path, count, "%.2f" % ((float(count) / nplayers) * 100))
|
||||
typetable.add_row(path, count, "%.2f" % ((float(count) / naccounts) * 100))
|
||||
# last N table
|
||||
plyrs = PlayerDB.objects.all().order_by("db_date_created")[max(0, nplayers - nlim):]
|
||||
plyrs = AccountDB.objects.all().order_by("db_date_created")[max(0, naccounts - nlim):]
|
||||
latesttable = EvTable("|wcreated|n", "|wdbref|n", "|wname|n", "|wtypeclass|n", border="cells", align="l")
|
||||
for ply in plyrs:
|
||||
latesttable.add_row(utils.datetime_format(ply.date_created), ply.dbref, ply.key, ply.path)
|
||||
|
||||
string = "\n|wPlayer typeclass distribution:|n\n%s" % typetable
|
||||
string += "\n|wLast %s Players created:|n\n%s" % (min(nplayers, nlim), latesttable)
|
||||
string = "\n|wAccount typeclass distribution:|n\n%s" % typetable
|
||||
string += "\n|wLast %s Accounts created:|n\n%s" % (min(naccounts, nlim), latesttable)
|
||||
caller.msg(string)
|
||||
|
||||
|
||||
|
|
@ -520,7 +520,7 @@ class CmdService(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
key = "@service"
|
||||
aliases = ["@services"]
|
||||
locks = "cmd:perm(service) or perm(Immortals)"
|
||||
locks = "cmd:perm(service) or perm(Developer)"
|
||||
help_category = "System"
|
||||
|
||||
def func(self):
|
||||
|
|
@ -644,7 +644,7 @@ class CmdTime(COMMAND_DEFAULT_CLASS):
|
|||
"""
|
||||
key = "@time"
|
||||
aliases = "@uptime"
|
||||
locks = "cmd:perm(time) or perm(Players)"
|
||||
locks = "cmd:perm(time) or perm(Account)"
|
||||
help_category = "System"
|
||||
|
||||
def func(self):
|
||||
|
|
@ -702,7 +702,7 @@ class CmdServerLoad(COMMAND_DEFAULT_CLASS):
|
|||
"""
|
||||
key = "@server"
|
||||
aliases = ["@serverload", "@serverprocess"]
|
||||
locks = "cmd:perm(list) or perm(Immortals)"
|
||||
locks = "cmd:perm(list) or perm(Developer)"
|
||||
help_category = "System"
|
||||
|
||||
def func(self):
|
||||
|
|
@ -823,7 +823,7 @@ class CmdTickers(COMMAND_DEFAULT_CLASS):
|
|||
"""
|
||||
key = "@tickers"
|
||||
help_category = "System"
|
||||
locks = "cmd:perm(tickers) or perm(Builders)"
|
||||
locks = "cmd:perm(tickers) or perm(Builder)"
|
||||
|
||||
def func(self):
|
||||
from evennia import TICKER_HANDLER
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ from mock import Mock
|
|||
|
||||
from evennia.commands.default.cmdset_character import CharacterCmdSet
|
||||
from evennia.utils.test_resources import EvenniaTest
|
||||
from evennia.commands.default import help, general, system, admin, player, building, batchprocess, comms
|
||||
from evennia.commands.default import help, general, system, admin, account, building, batchprocess, comms
|
||||
from evennia.commands.command import Command, InterruptCommand
|
||||
from evennia.utils import ansi, utils
|
||||
from evennia.server.sessionhandler import SESSIONS
|
||||
|
|
@ -57,11 +57,13 @@ class CommandTest(EvenniaTest):
|
|||
caller = caller if caller else self.char1
|
||||
receiver = receiver if receiver else caller
|
||||
cmdobj.caller = caller
|
||||
cmdobj.cmdstring = cmdstring if cmdstring else cmdobj.key
|
||||
cmdobj.cmdname = cmdstring if cmdstring else cmdobj.key
|
||||
cmdobj.raw_cmdname = cmdobj.cmdname
|
||||
cmdobj.cmdstring = cmdobj.cmdname # deprecated
|
||||
cmdobj.args = args
|
||||
cmdobj.cmdset = cmdset
|
||||
cmdobj.session = SESSIONS.session_from_sessid(1)
|
||||
cmdobj.player = self.player
|
||||
cmdobj.account = self.account
|
||||
cmdobj.raw_string = cmdobj.key + " " + args
|
||||
cmdobj.obj = obj or (caller if caller else self.char1)
|
||||
# test
|
||||
|
|
@ -76,7 +78,7 @@ class CommandTest(EvenniaTest):
|
|||
except InterruptCommand:
|
||||
pass
|
||||
finally:
|
||||
# clean out prettytable sugar. We only operate on text-type
|
||||
# clean out evtable sugar. We only operate on text-type
|
||||
stored_msg = [args[0] if args and args[0] else kwargs.get("text",utils.to_str(kwargs, force_string=True))
|
||||
for name, args, kwargs in receiver.msg.mock_calls]
|
||||
# Get the first element of a tuple if msg received a tuple instead of a string
|
||||
|
|
@ -117,10 +119,10 @@ class TestGeneral(CommandTest):
|
|||
|
||||
def test_nick(self):
|
||||
self.call(general.CmdNick(), "testalias = testaliasedstring1", "Nick 'testalias' mapped to 'testaliasedstring1'.")
|
||||
self.call(general.CmdNick(), "/player testalias = testaliasedstring2", "Nick 'testalias' mapped to 'testaliasedstring2'.")
|
||||
self.call(general.CmdNick(), "/account testalias = testaliasedstring2", "Nick 'testalias' mapped to 'testaliasedstring2'.")
|
||||
self.call(general.CmdNick(), "/object testalias = testaliasedstring3", "Nick 'testalias' mapped to 'testaliasedstring3'.")
|
||||
self.assertEqual(u"testaliasedstring1", self.char1.nicks.get("testalias"))
|
||||
self.assertEqual(u"testaliasedstring2", self.char1.nicks.get("testalias", category="player"))
|
||||
self.assertEqual(u"testaliasedstring2", self.char1.nicks.get("testalias", category="account"))
|
||||
self.assertEqual(u"testaliasedstring3", self.char1.nicks.get("testalias", category="object"))
|
||||
|
||||
def test_get_and_drop(self):
|
||||
|
|
@ -170,54 +172,54 @@ class TestAdmin(CommandTest):
|
|||
self.call(admin.CmdEmit(), "Char2 = Test", "Emitted to Char2:\nTest")
|
||||
|
||||
def test_perm(self):
|
||||
self.call(admin.CmdPerm(), "Obj = Builders", "Permission 'Builders' given to Obj (the Object/Character).")
|
||||
self.call(admin.CmdPerm(), "Char2 = Builders", "Permission 'Builders' given to Char2 (the Object/Character).")
|
||||
self.call(admin.CmdPerm(), "Obj = Builder", "Permission 'Builder' given to Obj (the Object/Character).")
|
||||
self.call(admin.CmdPerm(), "Char2 = Builder", "Permission 'Builder' given to Char2 (the Object/Character).")
|
||||
|
||||
def test_wall(self):
|
||||
self.call(admin.CmdWall(), "Test", "Announcing to all connected players ...")
|
||||
self.call(admin.CmdWall(), "Test", "Announcing to all connected accounts ...")
|
||||
|
||||
def test_ban(self):
|
||||
self.call(admin.CmdBan(), "Char", "NameBan char was added.")
|
||||
|
||||
|
||||
class TestPlayer(CommandTest):
|
||||
class TestAccount(CommandTest):
|
||||
|
||||
def test_ooc_look(self):
|
||||
if settings.MULTISESSION_MODE < 2:
|
||||
self.call(player.CmdOOCLook(), "", "You are outofcharacter (OOC).", caller=self.player)
|
||||
self.call(account.CmdOOCLook(), "", "You are outofcharacter (OOC).", caller=self.account)
|
||||
if settings.MULTISESSION_MODE == 2:
|
||||
self.call(player.CmdOOCLook(), "", "Account TestPlayer (you are OutofCharacter)", caller=self.player)
|
||||
self.call(account.CmdOOCLook(), "", "Account TestAccount (you are OutofCharacter)", caller=self.account)
|
||||
|
||||
def test_ooc(self):
|
||||
self.call(player.CmdOOC(), "", "You go OOC.", caller=self.player)
|
||||
self.call(account.CmdOOC(), "", "You go OOC.", caller=self.account)
|
||||
|
||||
def test_ic(self):
|
||||
self.player.unpuppet_object(self.session)
|
||||
self.call(player.CmdIC(), "Char", "You become Char.", caller=self.player, receiver=self.char1)
|
||||
self.account.unpuppet_object(self.session)
|
||||
self.call(account.CmdIC(), "Char", "You become Char.", caller=self.account, receiver=self.char1)
|
||||
|
||||
def test_password(self):
|
||||
self.call(player.CmdPassword(), "testpassword = testpassword", "Password changed.", caller=self.player)
|
||||
self.call(account.CmdPassword(), "testpassword = testpassword", "Password changed.", caller=self.account)
|
||||
|
||||
def test_option(self):
|
||||
self.call(player.CmdOption(), "", "Client settings", caller=self.player)
|
||||
self.call(account.CmdOption(), "", "Client settings", caller=self.account)
|
||||
|
||||
def test_who(self):
|
||||
self.call(player.CmdWho(), "", "Players:", caller=self.player)
|
||||
self.call(account.CmdWho(), "", "Accounts:", caller=self.account)
|
||||
|
||||
def test_quit(self):
|
||||
self.call(player.CmdQuit(), "", "Quitting. Hope to see you again, soon.", caller=self.player)
|
||||
self.call(account.CmdQuit(), "", "Quitting. Hope to see you again, soon.", caller=self.account)
|
||||
|
||||
def test_sessions(self):
|
||||
self.call(player.CmdSessions(), "", "Your current session(s):", caller=self.player)
|
||||
self.call(account.CmdSessions(), "", "Your current session(s):", caller=self.account)
|
||||
|
||||
def test_color_test(self):
|
||||
self.call(player.CmdColorTest(), "ansi", "ANSI colors:", caller=self.player)
|
||||
self.call(account.CmdColorTest(), "ansi", "ANSI colors:", caller=self.account)
|
||||
|
||||
def test_char_create(self):
|
||||
self.call(player.CmdCharCreate(), "Test1=Test char", "Created new character Test1. Use @ic Test1 to enter the game", caller=self.player)
|
||||
self.call(account.CmdCharCreate(), "Test1=Test char", "Created new character Test1. Use @ic Test1 to enter the game", caller=self.account)
|
||||
|
||||
def test_quell(self):
|
||||
self.call(player.CmdQuell(), "", "Quelling to current puppet's permissions (immortals).", caller=self.player)
|
||||
self.call(account.CmdQuell(), "", "Quelling to current puppet's permissions (developer).", caller=self.account)
|
||||
|
||||
|
||||
class TestBuilding(CommandTest):
|
||||
|
|
@ -272,7 +274,7 @@ class TestBuilding(CommandTest):
|
|||
"Obj changed typeclass from evennia.objects.objects.DefaultObject to evennia.objects.objects.DefaultExit.")
|
||||
|
||||
def test_lock(self):
|
||||
self.call(building.CmdLock(), "Obj = test:perm(Immortals)", "Added lock 'test:perm(Immortals)' to Obj.")
|
||||
self.call(building.CmdLock(), "Obj = test:perm(Developer)", "Added lock 'test:perm(Developer)' to Obj.")
|
||||
|
||||
def test_find(self):
|
||||
self.call(building.CmdFind(), "Room2", "One Match")
|
||||
|
|
@ -288,39 +290,39 @@ class TestComms(CommandTest):
|
|||
|
||||
def setUp(self):
|
||||
super(CommandTest, self).setUp()
|
||||
self.call(comms.CmdChannelCreate(), "testchan;test=Test Channel", "Created channel testchan and connected to it.", receiver=self.player)
|
||||
self.call(comms.CmdChannelCreate(), "testchan;test=Test Channel", "Created channel testchan and connected to it.", receiver=self.account)
|
||||
|
||||
def test_toggle_com(self):
|
||||
self.call(comms.CmdAddCom(), "tc = testchan", "You are already connected to channel testchan. You can now", receiver=self.player)
|
||||
self.call(comms.CmdDelCom(), "tc", "Your alias 'tc' for channel testchan was cleared.", receiver=self.player)
|
||||
self.call(comms.CmdAddCom(), "tc = testchan", "You are already connected to channel testchan. You can now", receiver=self.account)
|
||||
self.call(comms.CmdDelCom(), "tc", "Your alias 'tc' for channel testchan was cleared.", receiver=self.account)
|
||||
|
||||
def test_channels(self):
|
||||
self.call(comms.CmdChannels(), "" ,"Available channels (use comlist,addcom and delcom to manage", receiver=self.player)
|
||||
self.call(comms.CmdChannels(), "" ,"Available channels (use comlist,addcom and delcom to manage", receiver=self.account)
|
||||
|
||||
def test_all_com(self):
|
||||
self.call(comms.CmdAllCom(), "", "Available channels (use comlist,addcom and delcom to manage", receiver=self.player)
|
||||
self.call(comms.CmdAllCom(), "", "Available channels (use comlist,addcom and delcom to manage", receiver=self.account)
|
||||
|
||||
def test_clock(self):
|
||||
self.call(comms.CmdClock(), "testchan=send:all()", "Lock(s) applied. Current locks on testchan:", receiver=self.player)
|
||||
self.call(comms.CmdClock(), "testchan=send:all()", "Lock(s) applied. Current locks on testchan:", receiver=self.account)
|
||||
|
||||
def test_cdesc(self):
|
||||
self.call(comms.CmdCdesc(), "testchan = Test Channel", "Description of channel 'testchan' set to 'Test Channel'.", receiver=self.player)
|
||||
self.call(comms.CmdCdesc(), "testchan = Test Channel", "Description of channel 'testchan' set to 'Test Channel'.", receiver=self.account)
|
||||
|
||||
def test_cemit(self):
|
||||
self.call(comms.CmdCemit(), "testchan = Test Message", "[testchan] Test Message|Sent to channel testchan: Test Message", receiver=self.player)
|
||||
self.call(comms.CmdCemit(), "testchan = Test Message", "[testchan] Test Message|Sent to channel testchan: Test Message", receiver=self.account)
|
||||
|
||||
def test_cwho(self):
|
||||
self.call(comms.CmdCWho(), "testchan", "Channel subscriptions\ntestchan:\n TestPlayer", receiver=self.player)
|
||||
self.call(comms.CmdCWho(), "testchan", "Channel subscriptions\ntestchan:\n TestAccount", receiver=self.account)
|
||||
|
||||
def test_page(self):
|
||||
self.call(comms.CmdPage(), "TestPlayer2 = Test", "TestPlayer2 is offline. They will see your message if they list their pages later.|You paged TestPlayer2 with: 'Test'.", receiver=self.player)
|
||||
self.call(comms.CmdPage(), "TestAccount2 = Test", "TestAccount2 is offline. They will see your message if they list their pages later.|You paged TestAccount2 with: 'Test'.", receiver=self.account)
|
||||
|
||||
def test_cboot(self):
|
||||
# No one else connected to boot
|
||||
self.call(comms.CmdCBoot(), "", "Usage: @cboot[/quiet] <channel> = <player> [:reason]", receiver=self.player)
|
||||
self.call(comms.CmdCBoot(), "", "Usage: @cboot[/quiet] <channel> = <account> [:reason]", receiver=self.account)
|
||||
|
||||
def test_cdestroy(self):
|
||||
self.call(comms.CmdCdestroy(), "testchan" ,"[testchan] TestPlayer: testchan is being destroyed. Make sure to change your aliases.|Channel 'testchan' was destroyed.", receiver=self.player)
|
||||
self.call(comms.CmdCdestroy(), "testchan" ,"[testchan] TestAccount: testchan is being destroyed. Make sure to change your aliases.|Channel 'testchan' was destroyed.", receiver=self.account)
|
||||
|
||||
|
||||
class TestBatchProcess(CommandTest):
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ from collections import defaultdict
|
|||
from random import getrandbits
|
||||
from django.conf import settings
|
||||
from django.contrib.auth import authenticate
|
||||
from evennia.players.models import PlayerDB
|
||||
from evennia.accounts.models import AccountDB
|
||||
from evennia.objects.models import ObjectDB
|
||||
from evennia.server.models import ServerConfig
|
||||
from evennia.comms.models import ChannelDB
|
||||
|
|
@ -25,7 +25,7 @@ MULTISESSION_MODE = settings.MULTISESSION_MODE
|
|||
CONNECTION_SCREEN_MODULE = settings.CONNECTION_SCREEN_MODULE
|
||||
|
||||
# Helper function to throttle failed connection attempts.
|
||||
# This can easily be used to limit player creation too,
|
||||
# This can easily be used to limit account creation too,
|
||||
# (just supply a different storage dictionary), but this
|
||||
# would also block dummyrunner, so it's not added as default.
|
||||
|
||||
|
|
@ -77,17 +77,17 @@ def _throttle(session, maxlim=None, timeout=None, storage=_LATEST_FAILED_LOGINS)
|
|||
return False
|
||||
|
||||
|
||||
def create_guest_player(session):
|
||||
def create_guest_account(session):
|
||||
"""
|
||||
Creates a guest player/character for this session, if one is available.
|
||||
Creates a guest account/character for this session, if one is available.
|
||||
|
||||
Args:
|
||||
session (Session): the session which will use the guest player/character.
|
||||
session (Session): the session which will use the guest account/character.
|
||||
|
||||
Returns:
|
||||
GUEST_ENABLED (boolean), player (Player):
|
||||
GUEST_ENABLED (boolean), account (Account):
|
||||
the boolean is whether guest accounts are enabled at all.
|
||||
the Player which was created from an available guest name.
|
||||
the Account which was created from an available guest name.
|
||||
"""
|
||||
# check if guests are enabled.
|
||||
if not settings.GUEST_ENABLED:
|
||||
|
|
@ -105,25 +105,25 @@ def create_guest_player(session):
|
|||
|
||||
try:
|
||||
# Find an available guest name.
|
||||
playername = None
|
||||
accountname = None
|
||||
for name in settings.GUEST_LIST:
|
||||
if not PlayerDB.objects.filter(username__iexact=playername).count():
|
||||
playername = name
|
||||
if not AccountDB.objects.filter(username__iexact=accountname).count():
|
||||
accountname = name
|
||||
break
|
||||
if not playername:
|
||||
if not accountname:
|
||||
session.msg("All guest accounts are in use. Please try again later.")
|
||||
return True, None
|
||||
else:
|
||||
# build a new player with the found guest playername
|
||||
# build a new account with the found guest accountname
|
||||
password = "%016x" % getrandbits(64)
|
||||
home = ObjectDB.objects.get_id(settings.GUEST_HOME)
|
||||
permissions = settings.PERMISSION_GUEST_DEFAULT
|
||||
typeclass = settings.BASE_CHARACTER_TYPECLASS
|
||||
ptypeclass = settings.BASE_GUEST_TYPECLASS
|
||||
new_player = _create_player(session, playername, password, permissions, ptypeclass)
|
||||
if new_player:
|
||||
_create_character(session, new_player, typeclass, home, permissions)
|
||||
return True, new_player
|
||||
new_account = _create_account(session, accountname, password, permissions, ptypeclass)
|
||||
if new_account:
|
||||
_create_character(session, new_account, typeclass, home, permissions)
|
||||
return True, new_account
|
||||
|
||||
except Exception:
|
||||
# We are in the middle between logged in and -not, so we have
|
||||
|
|
@ -134,17 +134,17 @@ def create_guest_player(session):
|
|||
raise
|
||||
|
||||
|
||||
def create_normal_player(session, name, password):
|
||||
def create_normal_account(session, name, password):
|
||||
"""
|
||||
Creates a player with the given name and password.
|
||||
Creates an account with the given name and password.
|
||||
|
||||
Args:
|
||||
session (Session): the session which is requesting to create a player.
|
||||
name (str): the name that the player wants to use for login.
|
||||
password (str): the password desired by this player, for login.
|
||||
session (Session): the session which is requesting to create an account.
|
||||
name (str): the name that the account wants to use for login.
|
||||
password (str): the password desired by this account, for login.
|
||||
|
||||
Returns:
|
||||
player (Player): the player which was created from the name and password.
|
||||
account (Account): the account which was created from the name and password.
|
||||
"""
|
||||
# check for too many login errors too quick.
|
||||
if _throttle(session, maxlim=5, timeout=5*60):
|
||||
|
|
@ -153,22 +153,22 @@ def create_normal_player(session, name, password):
|
|||
return None
|
||||
|
||||
# Match account name and check password
|
||||
player = authenticate(username=name, password=password)
|
||||
account = authenticate(username=name, password=password)
|
||||
|
||||
if not player:
|
||||
# No playername or password match
|
||||
if not account:
|
||||
# No accountname or password match
|
||||
session.msg("Incorrect login information given.")
|
||||
# this just updates the throttle
|
||||
_throttle(session)
|
||||
# calls player hook for a failed login if possible.
|
||||
player = PlayerDB.objects.get_player_from_name(name)
|
||||
if player:
|
||||
player.at_failed_login(session)
|
||||
# calls account hook for a failed login if possible.
|
||||
account = AccountDB.objects.get_account_from_name(name)
|
||||
if account:
|
||||
account.at_failed_login(session)
|
||||
return None
|
||||
|
||||
# Check IP and/or name bans
|
||||
bans = ServerConfig.objects.conf("server_bans")
|
||||
if bans and (any(tup[0] == player.name.lower() for tup in bans)
|
||||
if bans and (any(tup[0] == account.name.lower() for tup in bans)
|
||||
or
|
||||
any(tup[2].match(session.address) for tup in bans if tup[2])):
|
||||
# this is a banned IP or name!
|
||||
|
|
@ -178,7 +178,7 @@ def create_normal_player(session, name, password):
|
|||
session.sessionhandler.disconnect(session, "Good bye! Disconnecting.")
|
||||
return None
|
||||
|
||||
return player
|
||||
return account
|
||||
|
||||
|
||||
class CmdUnconnectedConnect(COMMAND_DEFAULT_CLASS):
|
||||
|
|
@ -186,8 +186,8 @@ class CmdUnconnectedConnect(COMMAND_DEFAULT_CLASS):
|
|||
connect to the game
|
||||
|
||||
Usage (at login screen):
|
||||
connect playername password
|
||||
connect "player name" "pass word"
|
||||
connect accountname password
|
||||
connect "account name" "pass word"
|
||||
|
||||
Use the create command to first create an account before logging in.
|
||||
|
||||
|
|
@ -204,7 +204,7 @@ class CmdUnconnectedConnect(COMMAND_DEFAULT_CLASS):
|
|||
have a unique position in that their func() receives
|
||||
a session object instead of a source_object like all
|
||||
other types of logged-in commands (this is because
|
||||
there is no object yet before the player has logged in)
|
||||
there is no object yet before the account has logged in)
|
||||
"""
|
||||
session = self.caller
|
||||
|
||||
|
|
@ -222,9 +222,9 @@ class CmdUnconnectedConnect(COMMAND_DEFAULT_CLASS):
|
|||
parts = parts[0].split(None, 1)
|
||||
# Guest login
|
||||
if len(parts) == 1 and parts[0].lower() == "guest":
|
||||
enabled, new_player = create_guest_player(session)
|
||||
if new_player:
|
||||
session.sessionhandler.login(session, new_player)
|
||||
enabled, new_account = create_guest_account(session)
|
||||
if new_account:
|
||||
session.sessionhandler.login(session, new_account)
|
||||
if enabled:
|
||||
return
|
||||
|
||||
|
|
@ -233,20 +233,20 @@ class CmdUnconnectedConnect(COMMAND_DEFAULT_CLASS):
|
|||
return
|
||||
|
||||
name, password = parts
|
||||
player = create_normal_player(session, name, password)
|
||||
if player:
|
||||
session.sessionhandler.login(session, player)
|
||||
account = create_normal_account(session, name, password)
|
||||
if account:
|
||||
session.sessionhandler.login(session, account)
|
||||
|
||||
|
||||
class CmdUnconnectedCreate(COMMAND_DEFAULT_CLASS):
|
||||
"""
|
||||
create a new player account
|
||||
create a new account account
|
||||
|
||||
Usage (at login screen):
|
||||
create <playername> <password>
|
||||
create "player name" "pass word"
|
||||
create <accountname> <password>
|
||||
create "account name" "pass word"
|
||||
|
||||
This creates a new player account.
|
||||
This creates a new account account.
|
||||
|
||||
If you have spaces in your name, enclose it in double quotes.
|
||||
"""
|
||||
|
|
@ -271,25 +271,25 @@ class CmdUnconnectedCreate(COMMAND_DEFAULT_CLASS):
|
|||
"\nIf <name> or <password> contains spaces, enclose it in double quotes."
|
||||
session.msg(string)
|
||||
return
|
||||
playername, password = parts
|
||||
accountname, password = parts
|
||||
|
||||
# sanity checks
|
||||
if not re.findall(r"^[\w. @+\-']+$", playername) or not (0 < len(playername) <= 30):
|
||||
if not re.findall(r"^[\w. @+\-']+$", accountname) or not (0 < len(accountname) <= 30):
|
||||
# this echoes the restrictions made by django's auth
|
||||
# module (except not allowing spaces, for convenience of
|
||||
# logging in).
|
||||
string = "\n\r Playername can max be 30 characters or fewer. Letters, spaces, digits and @/./+/-/_/' only."
|
||||
string = "\n\r Accountname can max be 30 characters or fewer. Letters, spaces, digits and @/./+/-/_/' only."
|
||||
session.msg(string)
|
||||
return
|
||||
# strip excessive spaces in playername
|
||||
playername = re.sub(r"\s+", " ", playername).strip()
|
||||
if PlayerDB.objects.filter(username__iexact=playername):
|
||||
# player already exists (we also ignore capitalization here)
|
||||
session.msg("Sorry, there is already a player with the name '%s'." % playername)
|
||||
# strip excessive spaces in accountname
|
||||
accountname = re.sub(r"\s+", " ", accountname).strip()
|
||||
if AccountDB.objects.filter(username__iexact=accountname):
|
||||
# account already exists (we also ignore capitalization here)
|
||||
session.msg("Sorry, there is already an account with the name '%s'." % accountname)
|
||||
return
|
||||
# Reserve playernames found in GUEST_LIST
|
||||
if settings.GUEST_LIST and playername.lower() in (guest.lower() for guest in settings.GUEST_LIST):
|
||||
string = "\n\r That name is reserved. Please choose another Playername."
|
||||
# Reserve accountnames found in GUEST_LIST
|
||||
if settings.GUEST_LIST and accountname.lower() in (guest.lower() for guest in settings.GUEST_LIST):
|
||||
string = "\n\r That name is reserved. Please choose another Accountname."
|
||||
session.msg(string)
|
||||
return
|
||||
if not re.findall(r"^[\w. @+\-']+$", password) or not (3 < len(password)):
|
||||
|
|
@ -301,7 +301,7 @@ class CmdUnconnectedCreate(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
# Check IP and/or name bans
|
||||
bans = ServerConfig.objects.conf("server_bans")
|
||||
if bans and (any(tup[0] == playername.lower() for tup in bans)
|
||||
if bans and (any(tup[0] == accountname.lower() for tup in bans)
|
||||
or
|
||||
any(tup[2].match(session.address) for tup in bans if tup[2])):
|
||||
# this is a banned IP or name!
|
||||
|
|
@ -311,22 +311,22 @@ class CmdUnconnectedCreate(COMMAND_DEFAULT_CLASS):
|
|||
session.sessionhandler.disconnect(session, "Good bye! Disconnecting.")
|
||||
return
|
||||
|
||||
# everything's ok. Create the new player account.
|
||||
# everything's ok. Create the new account account.
|
||||
try:
|
||||
permissions = settings.PERMISSION_PLAYER_DEFAULT
|
||||
permissions = settings.PERMISSION_ACCOUNT_DEFAULT
|
||||
typeclass = settings.BASE_CHARACTER_TYPECLASS
|
||||
new_player = _create_player(session, playername, password, permissions)
|
||||
if new_player:
|
||||
new_account = _create_account(session, accountname, password, permissions)
|
||||
if new_account:
|
||||
if MULTISESSION_MODE < 2:
|
||||
default_home = ObjectDB.objects.get_id(settings.DEFAULT_HOME)
|
||||
_create_character(session, new_player, typeclass, default_home, permissions)
|
||||
_create_character(session, new_account, typeclass, default_home, permissions)
|
||||
# tell the caller everything went well.
|
||||
string = "A new account '%s' was created. Welcome!"
|
||||
if " " in playername:
|
||||
if " " in accountname:
|
||||
string += "\n\nYou can now log in with the command 'connect \"%s\" <your password>'."
|
||||
else:
|
||||
string += "\n\nYou can now log with the command 'connect %s <your password>'."
|
||||
session.msg(string % (playername, playername))
|
||||
session.msg(string % (accountname, accountname))
|
||||
|
||||
except Exception:
|
||||
# We are in the middle between logged in and -not, so we have
|
||||
|
|
@ -344,7 +344,7 @@ class CmdUnconnectedQuit(COMMAND_DEFAULT_CLASS):
|
|||
quit
|
||||
|
||||
We maintain a different version of the quit command
|
||||
here for unconnected players for the sake of simplicity. The logged in
|
||||
here for unconnected accounts for the sake of simplicity. The logged in
|
||||
version is a bit more complicated.
|
||||
"""
|
||||
key = "quit"
|
||||
|
|
@ -516,50 +516,50 @@ class CmdUnconnectedScreenreader(COMMAND_DEFAULT_CLASS):
|
|||
self.session.sessionhandler.session_portal_sync(self.session)
|
||||
|
||||
|
||||
def _create_player(session, playername, password, permissions, typeclass=None, email=None):
|
||||
def _create_account(session, accountname, password, permissions, typeclass=None, email=None):
|
||||
"""
|
||||
Helper function, creates a player of the specified typeclass.
|
||||
Helper function, creates an account of the specified typeclass.
|
||||
"""
|
||||
try:
|
||||
new_player = create.create_player(playername, email, password, permissions=permissions, typeclass=typeclass)
|
||||
new_account = create.create_account(accountname, email, password, permissions=permissions, typeclass=typeclass)
|
||||
|
||||
except Exception as e:
|
||||
session.msg("There was an error creating the Player:\n%s\n If this problem persists, contact an admin." % e)
|
||||
session.msg("There was an error creating the Account:\n%s\n If this problem persists, contact an admin." % e)
|
||||
logger.log_trace()
|
||||
return False
|
||||
|
||||
# This needs to be set so the engine knows this player is
|
||||
# This needs to be set so the engine knows this account is
|
||||
# logging in for the first time. (so it knows to call the right
|
||||
# hooks during login later)
|
||||
new_player.db.FIRST_LOGIN = True
|
||||
new_account.db.FIRST_LOGIN = True
|
||||
|
||||
# join the new player to the public channel
|
||||
# join the new account to the public channel
|
||||
pchannel = ChannelDB.objects.get_channel(settings.DEFAULT_CHANNELS[0]["key"])
|
||||
if not pchannel or not pchannel.connect(new_player):
|
||||
string = "New player '%s' could not connect to public channel!" % new_player.key
|
||||
if not pchannel or not pchannel.connect(new_account):
|
||||
string = "New account '%s' could not connect to public channel!" % new_account.key
|
||||
logger.log_err(string)
|
||||
return new_player
|
||||
return new_account
|
||||
|
||||
|
||||
def _create_character(session, new_player, typeclass, home, permissions):
|
||||
def _create_character(session, new_account, typeclass, home, permissions):
|
||||
"""
|
||||
Helper function, creates a character based on a player's name.
|
||||
Helper function, creates a character based on an account's name.
|
||||
This is meant for Guest and MULTISESSION_MODE < 2 situations.
|
||||
"""
|
||||
try:
|
||||
new_character = create.create_object(typeclass, key=new_player.key, home=home, permissions=permissions)
|
||||
new_character = create.create_object(typeclass, key=new_account.key, home=home, permissions=permissions)
|
||||
# set playable character list
|
||||
new_player.db._playable_characters.append(new_character)
|
||||
new_account.db._playable_characters.append(new_character)
|
||||
|
||||
# allow only the character itself and the player to puppet this character (and Immortals).
|
||||
new_character.locks.add("puppet:id(%i) or pid(%i) or perm(Immortals) or pperm(Immortals)" %
|
||||
(new_character.id, new_player.id))
|
||||
# allow only the character itself and the account to puppet this character (and Developers).
|
||||
new_character.locks.add("puppet:id(%i) or pid(%i) or perm(Developer) or pperm(Developer)" %
|
||||
(new_character.id, new_account.id))
|
||||
|
||||
# If no description is set, set a default description
|
||||
if not new_character.db.desc:
|
||||
new_character.db.desc = "This is a Player."
|
||||
new_character.db.desc = "This is an Account."
|
||||
# We need to set this to have @ic auto-connect to this character
|
||||
new_player.db._last_puppet = new_character
|
||||
new_account.db._last_puppet = new_character
|
||||
except Exception as e:
|
||||
session.msg("There was an error creating the Character:\n%s\n If this problem persists, contact an admin." % e)
|
||||
logger.log_trace()
|
||||
|
|
|
|||
|
|
@ -266,15 +266,15 @@ class TestGetAndMergeCmdSets(TwistedTestCase, EvenniaTest):
|
|||
deferred.addCallback(_callback)
|
||||
return deferred
|
||||
|
||||
def test_from_player(self):
|
||||
from evennia.commands.default.cmdset_player import PlayerCmdSet
|
||||
def test_from_account(self):
|
||||
from evennia.commands.default.cmdset_account import AccountCmdSet
|
||||
a = self.cmdset_a
|
||||
a.no_channels = True
|
||||
self.set_cmdsets(self.player, a)
|
||||
deferred = cmdhandler.get_and_merge_cmdsets(self.player, None, self.player, None, "player", "")
|
||||
self.set_cmdsets(self.account, a)
|
||||
deferred = cmdhandler.get_and_merge_cmdsets(self.account, None, self.account, None, "account", "")
|
||||
# get_and_merge_cmdsets converts to lower-case internally.
|
||||
def _callback(cmdset):
|
||||
pcmdset = PlayerCmdSet()
|
||||
pcmdset = AccountCmdSet()
|
||||
pcmdset.at_cmdset_creation()
|
||||
pcmds = [cmd.key for cmd in pcmdset.commands] + ["a", "b", "c", "d"]
|
||||
self.assertTrue(all(cmd.key in pcmds for cmd in cmdset.commands))
|
||||
|
|
@ -305,18 +305,18 @@ class TestGetAndMergeCmdSets(TwistedTestCase, EvenniaTest):
|
|||
|
||||
def test_autocmdsets(self):
|
||||
import evennia
|
||||
from evennia.commands.default.cmdset_player import PlayerCmdSet
|
||||
from evennia.commands.default.cmdset_account import AccountCmdSet
|
||||
from evennia.comms.channelhandler import CHANNEL_HANDLER
|
||||
testchannel = evennia.create_channel("channeltest", locks="listen:all();send:all()")
|
||||
CHANNEL_HANDLER.add(testchannel)
|
||||
CHANNEL_HANDLER.update()
|
||||
self.assertTrue(testchannel.connect(self.player))
|
||||
self.assertTrue(testchannel.has_connection(self.player))
|
||||
self.assertTrue(testchannel.connect(self.account))
|
||||
self.assertTrue(testchannel.has_connection(self.account))
|
||||
a, b, c, d = self.cmdset_a, self.cmdset_b, self.cmdset_c, self.cmdset_d
|
||||
self.set_cmdsets(self.player, a, b, c, d)
|
||||
deferred = cmdhandler.get_and_merge_cmdsets(self.session, self.session, self.player, self.char1, "session", "")
|
||||
self.set_cmdsets(self.account, a, b, c, d)
|
||||
deferred = cmdhandler.get_and_merge_cmdsets(self.session, self.session, self.account, self.char1, "session", "")
|
||||
def _callback(cmdset):
|
||||
pcmdset = PlayerCmdSet()
|
||||
pcmdset = AccountCmdSet()
|
||||
pcmdset.at_cmdset_creation()
|
||||
pcmds = [cmd.key for cmd in pcmdset.commands] + ["a", "b", "c", "d"] + ["out"]
|
||||
self.assertTrue(all(cmd.key or hasattr(cmd, "is_channel") in pcmds for cmd in cmdset.commands))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue