Merge conflicts against master, including cmdhandler support for direct cmdobject input together with prefix-ignore mechanism from devel.
This commit is contained in:
commit
a648433db8
69 changed files with 2617 additions and 1771 deletions
|
|
@ -124,7 +124,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})."
|
||||
|
||||
|
||||
def _msg_err(receiver, stringtuple):
|
||||
|
|
@ -235,7 +235,7 @@ def get_and_merge_cmdsets(caller, session, player, obj, callertype, raw_string):
|
|||
for lobj in local_objlist:
|
||||
try:
|
||||
# call hook in case we need to do dynamic changing to cmdset
|
||||
_GA(lobj, "at_cmdset_get")()
|
||||
_GA(lobj, "at_cmdset_get")(caller=caller)
|
||||
except Exception:
|
||||
logger.log_trace()
|
||||
# the call-type lock is checked here, it makes sure a player
|
||||
|
|
@ -391,7 +391,8 @@ def get_and_merge_cmdsets(caller, session, player, obj, callertype, raw_string):
|
|||
|
||||
|
||||
@inlineCallbacks
|
||||
def cmdhandler(called_by, raw_string, _testing=False, callertype="session", session=None, **kwargs):
|
||||
def cmdhandler(called_by, raw_string, _testing=False, callertype="session", session=None,
|
||||
cmdobj=None, cmdobj_key=None, **kwargs):
|
||||
"""
|
||||
This is the main mechanism that handles any string sent to the engine.
|
||||
|
||||
|
|
@ -413,6 +414,15 @@ def cmdhandler(called_by, raw_string, _testing=False, callertype="session", sess
|
|||
precendence for same-name and same-prio commands.
|
||||
session (Session, optional): Relevant if callertype is "player" - 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)
|
||||
`cmdobj_key` as its input command name. No cmdset lookup will be performed but
|
||||
all other options apply as normal. This allows for running a specific Command
|
||||
within the command system mechanism.
|
||||
cmdobj_key (string, optional): Used together with `cmdobj` keyword to specify
|
||||
which cmdname should be assigned when calling the specified Command instance. This
|
||||
is made available as `self.cmdstring` when the Command runs.
|
||||
If not given, the command will be assumed to be called as `cmdobj.key`.
|
||||
|
||||
Kwargs:
|
||||
kwargs (any): other keyword arguments will be assigned as named variables on the
|
||||
|
|
@ -428,7 +438,7 @@ def cmdhandler(called_by, raw_string, _testing=False, callertype="session", sess
|
|||
"""
|
||||
|
||||
@inlineCallbacks
|
||||
def _run_command(cmd, cmdname, raw_cmdname, args):
|
||||
def _run_command(cmd, cmdname, args, raw_cmdname, cmdset, session, player):
|
||||
"""
|
||||
Helper function: This initializes and runs the Command
|
||||
instance once the parser has identified it as either a normal
|
||||
|
|
@ -437,10 +447,13 @@ def cmdhandler(called_by, raw_string, _testing=False, callertype="session", sess
|
|||
Args:
|
||||
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).
|
||||
args (str): extra text entered after the identified command
|
||||
cmdset (CmdSet): Command sert the command belongs to (if any)..
|
||||
session (Session): Session of caller (if any).
|
||||
player (Player): Player of caller (if any).
|
||||
|
||||
Returns:
|
||||
deferred (Deferred): this will fire with the return of the
|
||||
|
|
@ -482,7 +495,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=unformatted_raw_string,
|
||||
raw_cmdname=raw_cmdname,
|
||||
cmdclass=cmd.__class__)
|
||||
raise RuntimeError(err)
|
||||
|
||||
|
|
@ -543,78 +556,89 @@ def cmdhandler(called_by, raw_string, _testing=False, callertype="session", sess
|
|||
|
||||
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
|
||||
|
||||
cmdset = yield get_and_merge_cmdsets(caller, session, player, 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:
|
||||
# Empty input. Test for system command instead.
|
||||
syscmd = yield cmdset.get(CMD_NOINPUT)
|
||||
sysarg = ""
|
||||
raise ExecSystemCommand(syscmd, sysarg)
|
||||
# Parse the input string and match to available cmdset.
|
||||
# This also checks for permissions, so all commands in match
|
||||
# are commands the caller is allowed to call.
|
||||
matches = yield _COMMAND_PARSER(raw_string, cmdset, caller)
|
||||
else:
|
||||
# no explicit cmdobject given, figure it out
|
||||
cmdset = yield get_and_merge_cmdsets(caller, session, player, 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:
|
||||
# Empty input. Test for system command instead.
|
||||
syscmd = yield cmdset.get(CMD_NOINPUT)
|
||||
sysarg = ""
|
||||
raise ExecSystemCommand(syscmd, sysarg)
|
||||
# Parse the input string and match to available cmdset.
|
||||
# This also checks for permissions, so all commands in match
|
||||
# are commands the caller is allowed to call.
|
||||
matches = yield _COMMAND_PARSER(raw_string, cmdset, caller)
|
||||
|
||||
# Deal with matches
|
||||
# Deal with matches
|
||||
|
||||
if len(matches) > 1:
|
||||
# We have a multiple-match
|
||||
syscmd = yield cmdset.get(CMD_MULTIMATCH)
|
||||
sysarg = _("There were multiple matches.")
|
||||
if syscmd:
|
||||
# use custom CMD_MULTIMATCH
|
||||
syscmd.matches = matches
|
||||
else:
|
||||
# fall back to default error handling
|
||||
sysarg = yield _SEARCH_AT_RESULT([match[2] for match in matches], caller, query=matches[0][0])
|
||||
raise ExecSystemCommand(syscmd, sysarg)
|
||||
|
||||
cmdname, args, cmd = "", "", None
|
||||
if len(matches) == 1:
|
||||
# We have a unique command match. But it may still be invalid.
|
||||
match = matches[0]
|
||||
cmdname, args, cmd, raw_cmdname = match[0], match[1], match[2], match[5]
|
||||
|
||||
if not matches:
|
||||
# No commands match our entered command
|
||||
syscmd = yield cmdset.get(CMD_NOMATCH)
|
||||
if syscmd:
|
||||
# use custom CMD_NOMATCH command
|
||||
sysarg = raw_string
|
||||
else:
|
||||
# fallback to default error text
|
||||
sysarg = _("Command '%s' is not available.") % raw_string
|
||||
suggestions = string_suggestions(raw_string,
|
||||
cmdset.get_all_cmd_keys_and_aliases(caller),
|
||||
cutoff=0.7, maxnum=3)
|
||||
if suggestions:
|
||||
sysarg += _(" Maybe you meant %s?") % utils.list_to_string(suggestions, _('or'), addquote=True)
|
||||
if len(matches) > 1:
|
||||
# We have a multiple-match
|
||||
syscmd = yield cmdset.get(CMD_MULTIMATCH)
|
||||
sysarg = _("There were multiple matches.")
|
||||
if syscmd:
|
||||
# use custom CMD_MULTIMATCH
|
||||
syscmd.matches = matches
|
||||
else:
|
||||
sysarg += _(" Type \"help\" for help.")
|
||||
raise ExecSystemCommand(syscmd, sysarg)
|
||||
# fall back to default error handling
|
||||
sysarg = yield _SEARCH_AT_RESULT([match[2] for match in matches], caller, query=matches[0][0])
|
||||
raise ExecSystemCommand(syscmd, sysarg)
|
||||
|
||||
# Check if this is a Channel-cmd match.
|
||||
if hasattr(cmd, 'is_channel') and cmd.is_channel:
|
||||
# even if a user-defined syscmd is not defined, the
|
||||
# found cmd is already a system command in its own right.
|
||||
syscmd = yield cmdset.get(CMD_CHANNEL)
|
||||
if syscmd:
|
||||
# replace system command with custom version
|
||||
cmd = syscmd
|
||||
cmd.session = session
|
||||
sysarg = "%s:%s" % (cmdname, args)
|
||||
raise ExecSystemCommand(cmd, sysarg)
|
||||
cmdname, args, cmd = "", "", None
|
||||
if len(matches) == 1:
|
||||
# We have a unique command match. But it may still be invalid.
|
||||
match = matches[0]
|
||||
cmdname, args, cmd, raw_cmdname = match[0], match[1], match[2], match[5]
|
||||
|
||||
if not matches:
|
||||
# No commands match our entered command
|
||||
syscmd = yield cmdset.get(CMD_NOMATCH)
|
||||
if syscmd:
|
||||
# use custom CMD_NOMATCH command
|
||||
sysarg = raw_string
|
||||
else:
|
||||
# fallback to default error text
|
||||
sysarg = _("Command '%s' is not available.") % raw_string
|
||||
suggestions = string_suggestions(raw_string,
|
||||
cmdset.get_all_cmd_keys_and_aliases(caller),
|
||||
cutoff=0.7, maxnum=3)
|
||||
if suggestions:
|
||||
sysarg += _(" Maybe you meant %s?") % utils.list_to_string(suggestions, _('or'), addquote=True)
|
||||
else:
|
||||
sysarg += _(" Type \"help\" for help.")
|
||||
raise ExecSystemCommand(syscmd, sysarg)
|
||||
|
||||
# Check if this is a Channel-cmd match.
|
||||
if hasattr(cmd, 'is_channel') and cmd.is_channel:
|
||||
# even if a user-defined syscmd is not defined, the
|
||||
# found cmd is already a system command in its own right.
|
||||
syscmd = yield cmdset.get(CMD_CHANNEL)
|
||||
if syscmd:
|
||||
# replace system command with custom version
|
||||
cmd = syscmd
|
||||
cmd.session = session
|
||||
sysarg = "%s:%s" % (cmdname, args)
|
||||
raise ExecSystemCommand(cmd, sysarg)
|
||||
|
||||
# A normal command.
|
||||
ret = yield _run_command(cmd, cmdname, raw_cmdname, args)
|
||||
ret = yield _run_command(cmd, cmdname, args, raw_cmdname, cmdset, session, player)
|
||||
returnValue(ret)
|
||||
|
||||
except ErrorReported as exc:
|
||||
|
|
@ -629,7 +653,8 @@ def cmdhandler(called_by, raw_string, _testing=False, callertype="session", sess
|
|||
sysarg = exc.sysarg
|
||||
|
||||
if syscmd:
|
||||
ret = yield _run_command(syscmd, syscmd.key, syscmd, sysarg)
|
||||
ret = yield _run_command(syscmd, syscmd.key, sysarg,
|
||||
unformatted_raw_string, cmdset, session, player)
|
||||
returnValue(ret)
|
||||
elif sysarg:
|
||||
# return system arg
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ def _init_command(cls, **kwargs):
|
|||
if cls.aliases and not is_iter(cls.aliases):
|
||||
try:
|
||||
cls.aliases = [str(alias).strip().lower()
|
||||
for alias in cls.aliases.split(',')]
|
||||
for alias in cls.aliases.split(',')]
|
||||
except Exception:
|
||||
cls.aliases = []
|
||||
cls.aliases = list(set(alias for alias in cls.aliases
|
||||
|
|
@ -57,7 +57,7 @@ def _init_command(cls, **kwargs):
|
|||
if not hasattr(cls, 'locks'):
|
||||
# default if one forgets to define completely
|
||||
cls.locks = "cmd:all()"
|
||||
if not "cmd:" in cls.locks:
|
||||
if "cmd:" not in cls.locks:
|
||||
cls.locks = "cmd:all();" + cls.locks
|
||||
for lockstring in cls.locks.split(';'):
|
||||
if lockstring and not ':' in lockstring:
|
||||
|
|
@ -197,7 +197,6 @@ class Command(with_metaclass(CommandMeta, object)):
|
|||
try:
|
||||
# first assume input is a command (the most common case)
|
||||
return self._matchset.intersection(cmd._matchset)
|
||||
#return cmd.key in self._matchset
|
||||
except AttributeError:
|
||||
# probably got a string
|
||||
return cmd in self._matchset
|
||||
|
|
@ -211,9 +210,8 @@ class Command(with_metaclass(CommandMeta, object)):
|
|||
"""
|
||||
try:
|
||||
return self._matchset.isdisjoint(cmd._matchset)
|
||||
#return not cmd.key in self._matcheset
|
||||
except AttributeError:
|
||||
return not cmd in self._matchset
|
||||
return cmd not in self._matchset
|
||||
|
||||
def __contains__(self, query):
|
||||
"""
|
||||
|
|
@ -308,7 +306,7 @@ class Command(with_metaclass(CommandMeta, object)):
|
|||
def msg(self, text=None, to_obj=None, from_obj=None,
|
||||
session=None, **kwargs):
|
||||
"""
|
||||
This is a shortcut instad of calling msg() directly on an
|
||||
This is a shortcut instead of calling msg() directly on an
|
||||
object - it will detect if caller is an Object or a Player and
|
||||
also appends self.session automatically if self.msg_all_sessions is False.
|
||||
|
||||
|
|
@ -398,17 +396,18 @@ class Command(with_metaclass(CommandMeta, object)):
|
|||
"""
|
||||
# a simple test command to show the available properties
|
||||
string = "-" * 50
|
||||
string += "\n{w%s{n - Command variables from evennia:\n" % self.key
|
||||
string += "\n|w%s|n - Command variables from evennia:\n" % self.key
|
||||
string += "-" * 50
|
||||
string += "\nname of cmd (self.key): {w%s{n\n" % self.key
|
||||
string += "cmd aliases (self.aliases): {w%s{n\n" % self.aliases
|
||||
string += "cmd locks (self.locks): {w%s{n\n" % self.locks
|
||||
string += "help category (self.help_category): {w%s{n\n" % self.help_category.capitalize()
|
||||
string += "object calling (self.caller): {w%s{n\n" % self.caller
|
||||
string += "object storing cmdset (self.obj): {w%s{n\n" % self.obj
|
||||
string += "command string given (self.cmdstring): {w%s{n\n" % self.cmdstring
|
||||
string += "\nname of cmd (self.key): |w%s|n\n" % self.key
|
||||
string += "cmd aliases (self.aliases): |w%s|n\n" % self.aliases
|
||||
string += "cmd locks (self.locks): |w%s|n\n" % self.locks
|
||||
string += "help category (self.help_category): |w%s|n\n" % self.help_category.capitalize()
|
||||
string += "object calling (self.caller): |w%s|n\n" % self.caller
|
||||
string += "object storing cmdset (self.obj): |w%s|n\n" % self.obj
|
||||
string += "command string given (self.cmdstring): |w%s|n\n" % self.cmdstring
|
||||
# show cmdset.key instead of cmdset to shorten output
|
||||
string += fill("current cmdset (self.cmdset): {w%s{n\n" % (self.cmdset.key if self.cmdset.key else self.cmdset.__class__))
|
||||
string += fill("current cmdset (self.cmdset): |w%s|n\n" %
|
||||
(self.cmdset.key if self.cmdset.key else self.cmdset.__class__))
|
||||
|
||||
self.caller.msg(string)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,21 +0,0 @@
|
|||
#
|
||||
# This is Evennia's default connection screen. It is imported
|
||||
# and run from server/conf/connection_screens.py.
|
||||
#
|
||||
|
||||
from django.conf import settings
|
||||
from evennia.utils import utils
|
||||
|
||||
DEFAULT_SCREEN = \
|
||||
"""{b=============================================================={n
|
||||
Welcome to {g%s{n, version %s!
|
||||
|
||||
If you have an existing account, connect to it by typing:
|
||||
{wconnect <username> <password>{n
|
||||
If you need to create an account, type (without the <>'s):
|
||||
{wcreate <username> <password>{n
|
||||
|
||||
If you have spaces in your username, enclose it in double quotes.
|
||||
Enter {whelp{n for more info. {wlook{n will re-show this screen.
|
||||
{b=============================================================={n""" \
|
||||
% (settings.SERVERNAME, utils.get_evennia_version())
|
||||
|
|
@ -9,7 +9,7 @@ import re
|
|||
from django.conf import settings
|
||||
from evennia.server.sessionhandler import SESSIONS
|
||||
from evennia.server.models import ServerConfig
|
||||
from evennia.utils import prettytable, search, class_from_module
|
||||
from evennia.utils import evtable, search, class_from_module
|
||||
|
||||
COMMAND_DEFAULT_CLASS = class_from_module(settings.COMMAND_DEFAULT_CLASS)
|
||||
|
||||
|
|
@ -40,7 +40,7 @@ class CmdBoot(COMMAND_DEFAULT_CLASS):
|
|||
help_category = "Admin"
|
||||
|
||||
def func(self):
|
||||
"Implementing the function"
|
||||
"""Implementing the function"""
|
||||
caller = self.caller
|
||||
args = self.args
|
||||
|
||||
|
|
@ -86,7 +86,7 @@ class CmdBoot(COMMAND_DEFAULT_CLASS):
|
|||
# Carry out the booting of the sessions in the boot list.
|
||||
|
||||
feedback = None
|
||||
if not 'quiet' in self.switches:
|
||||
if 'quiet' not in self.switches:
|
||||
feedback = "You have been disconnected by %s.\n" % caller.name
|
||||
if reason:
|
||||
feedback += "\nReason given: %s" % reason
|
||||
|
|
@ -108,13 +108,12 @@ def list_bans(banlist):
|
|||
if not banlist:
|
||||
return "No active bans were found."
|
||||
|
||||
table = prettytable.PrettyTable(["{wid", "{wname/ip", "{wdate", "{wreason"])
|
||||
table = evtable.EvTable("|wid", "|wname/ip", "|wdate", "|wreason")
|
||||
for inum, ban in enumerate(banlist):
|
||||
table.add_row([str(inum + 1),
|
||||
ban[0] and ban[0] or ban[1],
|
||||
ban[3], ban[4]])
|
||||
string = "{wActive bans:{n\n%s" % table
|
||||
return string
|
||||
table.add_row(str(inum + 1),
|
||||
ban[0] and ban[0] or ban[1],
|
||||
ban[3], ban[4])
|
||||
return "|wActive bans:|n\n%s" % table
|
||||
|
||||
|
||||
class CmdBan(COMMAND_DEFAULT_CLASS):
|
||||
|
|
@ -174,7 +173,7 @@ class CmdBan(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
if not self.args or (self.switches
|
||||
and not any(switch in ('ip', 'name')
|
||||
for switch in self.switches)):
|
||||
for switch in self.switches)):
|
||||
self.caller.msg(list_bans(banlist))
|
||||
return
|
||||
|
||||
|
|
@ -202,7 +201,7 @@ class CmdBan(COMMAND_DEFAULT_CLASS):
|
|||
# save updated banlist
|
||||
banlist.append(bantup)
|
||||
ServerConfig.objects.conf('server_bans', banlist)
|
||||
self.caller.msg("%s-Ban {w%s{n was added." % (typ, ban))
|
||||
self.caller.msg("%s-Ban |w%s|n was added." % (typ, ban))
|
||||
|
||||
|
||||
class CmdUnban(COMMAND_DEFAULT_CLASS):
|
||||
|
|
@ -223,7 +222,7 @@ class CmdUnban(COMMAND_DEFAULT_CLASS):
|
|||
help_category = "Admin"
|
||||
|
||||
def func(self):
|
||||
"Implement unbanning"
|
||||
"""Implement unbanning"""
|
||||
|
||||
banlist = ServerConfig.objects.conf('server_bans')
|
||||
|
||||
|
|
@ -240,14 +239,14 @@ class CmdUnban(COMMAND_DEFAULT_CLASS):
|
|||
if not banlist:
|
||||
self.caller.msg("There are no bans to clear.")
|
||||
elif not (0 < num < len(banlist) + 1):
|
||||
self.caller.msg("Ban id {w%s{x was not found." % self.args)
|
||||
self.caller.msg("Ban id |w%s|x was not found." % self.args)
|
||||
else:
|
||||
# all is ok, clear ban
|
||||
ban = banlist[num - 1]
|
||||
del banlist[num - 1]
|
||||
ServerConfig.objects.conf('server_bans', banlist)
|
||||
self.caller.msg("Cleared ban %s: %s" %
|
||||
(num, " ".join([s for s in ban[:2]])))
|
||||
(num, " ".join([s for s in ban[:2]])))
|
||||
|
||||
|
||||
class CmdDelPlayer(COMMAND_DEFAULT_CLASS):
|
||||
|
|
@ -270,7 +269,7 @@ class CmdDelPlayer(COMMAND_DEFAULT_CLASS):
|
|||
help_category = "Admin"
|
||||
|
||||
def func(self):
|
||||
"Implements the command."
|
||||
"""Implements the command."""
|
||||
|
||||
caller = self.caller
|
||||
args = self.args
|
||||
|
|
@ -346,7 +345,7 @@ class CmdEmit(COMMAND_DEFAULT_CLASS):
|
|||
help_category = "Admin"
|
||||
|
||||
def func(self):
|
||||
"Implement the command"
|
||||
"""Implement the command"""
|
||||
|
||||
caller = self.caller
|
||||
args = self.args
|
||||
|
|
@ -382,7 +381,7 @@ class CmdEmit(COMMAND_DEFAULT_CLASS):
|
|||
obj = caller.search(objname, global_search=True)
|
||||
if not obj:
|
||||
return
|
||||
if rooms_only and not obj.location is None:
|
||||
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:
|
||||
|
|
@ -414,7 +413,7 @@ class CmdNewPassword(COMMAND_DEFAULT_CLASS):
|
|||
help_category = "Admin"
|
||||
|
||||
def func(self):
|
||||
"Implement the function."
|
||||
"""Implement the function."""
|
||||
|
||||
caller = self.caller
|
||||
|
||||
|
|
@ -455,7 +454,7 @@ class CmdPerm(COMMAND_DEFAULT_CLASS):
|
|||
help_category = "Admin"
|
||||
|
||||
def func(self):
|
||||
"Implement function"
|
||||
"""Implement function"""
|
||||
|
||||
caller = self.caller
|
||||
switches = self.switches
|
||||
|
|
@ -481,36 +480,37 @@ class CmdPerm(COMMAND_DEFAULT_CLASS):
|
|||
caller.msg("You are not allowed to examine this object.")
|
||||
return
|
||||
|
||||
string = "Permissions on {w%s{n: " % obj.key
|
||||
string = "Permissions on |w%s|n: " % obj.key
|
||||
if not obj.permissions.all():
|
||||
string += "<None>"
|
||||
else:
|
||||
string += ", ".join(obj.permissions.all())
|
||||
if (hasattr(obj, 'player') and
|
||||
hasattr(obj.player, 'is_superuser') and
|
||||
obj.player.is_superuser):
|
||||
obj.player.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
|
||||
|
||||
if not obj.access(caller, 'control'):
|
||||
caller.msg("You are not allowed to edit this object's permissions.")
|
||||
locktype = "edit" if playermode 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"))
|
||||
return
|
||||
|
||||
cstring = ""
|
||||
tstring = ""
|
||||
caller_result = []
|
||||
target_result = []
|
||||
if 'del' in switches:
|
||||
# delete the given permission(s) from object.
|
||||
for perm in self.rhslist:
|
||||
obj.permissions.remove(perm)
|
||||
if obj.permissions.get(perm):
|
||||
cstring += "\nPermissions %s could not be removed from %s." % (perm, obj.name)
|
||||
caller_result.append("\nPermissions %s could not be removed from %s." % (perm, obj.name))
|
||||
else:
|
||||
cstring += "\nPermission %s removed from %s (if they existed)." % (perm, obj.name)
|
||||
tstring += "\n%s revokes the permission(s) %s from you." % (caller.name, perm)
|
||||
caller_result.append("\nPermission %s removed from %s (if they existed)." % (perm, obj.name))
|
||||
target_result.append("\n%s revokes the permission(s) %s from you." % (caller.name, perm))
|
||||
else:
|
||||
# add a new permission
|
||||
permissions = obj.permissions.all()
|
||||
|
|
@ -525,15 +525,16 @@ class CmdPerm(COMMAND_DEFAULT_CLASS):
|
|||
return
|
||||
|
||||
if perm in permissions:
|
||||
cstring += "\nPermission '%s' is already defined on %s." % (rhs, obj.name)
|
||||
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"
|
||||
cstring += "\nPermission '%s' given to %s (%s)." % (rhs, obj.name, plystring)
|
||||
tstring += "\n%s gives you (%s, %s) the permission '%s'." % (caller.name, obj.name, plystring, rhs)
|
||||
caller.msg(cstring.strip())
|
||||
if tstring:
|
||||
obj.msg(tstring.strip())
|
||||
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))
|
||||
caller.msg("".join(caller_result).strip())
|
||||
if target_result:
|
||||
obj.msg("".join(target_result).strip())
|
||||
|
||||
|
||||
class CmdWall(COMMAND_DEFAULT_CLASS):
|
||||
|
|
@ -550,7 +551,7 @@ class CmdWall(COMMAND_DEFAULT_CLASS):
|
|||
help_category = "Admin"
|
||||
|
||||
def func(self):
|
||||
"Implements command"
|
||||
"""Implements command"""
|
||||
if not self.args:
|
||||
self.caller.msg("Usage: @wall <message>")
|
||||
return
|
||||
|
|
|
|||
|
|
@ -29,15 +29,13 @@ from evennia.utils import logger, utils
|
|||
_RE_COMMENT = re.compile(r"^#.*?$", re.MULTILINE + re.DOTALL)
|
||||
_RE_CODE_START = re.compile(r"^# batchcode code:", re.MULTILINE)
|
||||
_COMMAND_DEFAULT_CLASS = utils.class_from_module(settings.COMMAND_DEFAULT_CLASS)
|
||||
#from evennia.commands.default.muxcommand import _COMMAND_DEFAULT_CLASS
|
||||
|
||||
# limit symbols for API inclusion
|
||||
__all__ = ("CmdBatchCommands", "CmdBatchCode")
|
||||
|
||||
_HEADER_WIDTH = 70
|
||||
_UTF8_ERROR = \
|
||||
"""
|
||||
{rDecode error in '%s'.{n
|
||||
_UTF8_ERROR = """
|
||||
|rDecode error in '%s'.|n
|
||||
|
||||
This file contains non-ascii character(s). This is common if you
|
||||
wrote some input in a language that has more letters and special
|
||||
|
|
@ -83,9 +81,9 @@ print "leaving run ..."
|
|||
"""
|
||||
|
||||
|
||||
#------------------------------------------------------------
|
||||
# -------------------------------------------------------------
|
||||
# Helper functions
|
||||
#------------------------------------------------------------
|
||||
# -------------------------------------------------------------
|
||||
|
||||
def format_header(caller, entry):
|
||||
"""
|
||||
|
|
@ -100,7 +98,7 @@ def format_header(caller, entry):
|
|||
header = utils.crop(entry, width=width)
|
||||
ptr = caller.ndb.batch_stackptr + 1
|
||||
stacklen = len(caller.ndb.batch_stack)
|
||||
header = "{w%02i/%02i{G: %s{n" % (ptr, stacklen, header)
|
||||
header = "|w%02i/%02i|G: %s|n" % (ptr, stacklen, header)
|
||||
# add extra space to the side for padding.
|
||||
header = "%s%s" % (header, " " * (width - len(header)))
|
||||
header = header.replace('\n', '\\n')
|
||||
|
|
@ -114,7 +112,7 @@ def format_code(entry):
|
|||
"""
|
||||
code = ""
|
||||
for line in entry.split('\n'):
|
||||
code += "\n{G>>>{n %s" % line
|
||||
code += "\n|G>>>|n %s" % line
|
||||
return code.strip()
|
||||
|
||||
|
||||
|
|
@ -164,9 +162,9 @@ def step_pointer(caller, step=1):
|
|||
stack = caller.ndb.batch_stack
|
||||
nstack = len(stack)
|
||||
if ptr + step <= 0:
|
||||
caller.msg("{RBeginning of batch file.")
|
||||
caller.msg("|RBeginning of batch file.")
|
||||
if ptr + step >= nstack:
|
||||
caller.msg("{REnd of batch file.")
|
||||
caller.msg("|REnd of batch file.")
|
||||
caller.ndb.batch_stackptr = max(0, min(nstack - 1, ptr + step))
|
||||
|
||||
|
||||
|
|
@ -186,10 +184,10 @@ def show_curr(caller, showall=False):
|
|||
|
||||
string = format_header(caller, entry)
|
||||
codeall = entry.strip()
|
||||
string += "{G(hh for help)"
|
||||
string += "|G(hh for help)"
|
||||
if showall:
|
||||
for line in codeall.split('\n'):
|
||||
string += "\n{G|{n %s" % line
|
||||
string += "\n|G||n %s" % line
|
||||
caller.msg(string)
|
||||
|
||||
|
||||
|
|
@ -217,9 +215,9 @@ def purge_processor(caller):
|
|||
|
||||
caller.scripts.validate() # this will purge interactive mode
|
||||
|
||||
#------------------------------------------------------------
|
||||
# -------------------------------------------------------------
|
||||
# main access commands
|
||||
#------------------------------------------------------------
|
||||
# -------------------------------------------------------------
|
||||
|
||||
|
||||
class CmdBatchCommands(_COMMAND_DEFAULT_CLASS):
|
||||
|
|
@ -243,7 +241,7 @@ class CmdBatchCommands(_COMMAND_DEFAULT_CLASS):
|
|||
help_category = "Building"
|
||||
|
||||
def func(self):
|
||||
"Starts the processor."
|
||||
"""Starts the processor."""
|
||||
|
||||
caller = self.caller
|
||||
|
||||
|
|
@ -253,7 +251,7 @@ class CmdBatchCommands(_COMMAND_DEFAULT_CLASS):
|
|||
return
|
||||
python_path = self.args
|
||||
|
||||
#parse indata file
|
||||
# parse indata file
|
||||
|
||||
try:
|
||||
commands = BATCHCMD.parse_file(python_path)
|
||||
|
|
@ -289,7 +287,8 @@ class CmdBatchCommands(_COMMAND_DEFAULT_CLASS):
|
|||
caller.msg("\nBatch-command processor - Interactive mode for %s ..." % python_path)
|
||||
show_curr(caller)
|
||||
else:
|
||||
caller.msg("Running Batch-command processor - Automatic mode for %s (this might take some time) ..." % python_path)
|
||||
caller.msg("Running Batch-command processor - Automatic mode for %s (this might take some time) ..."
|
||||
% python_path)
|
||||
|
||||
procpool = False
|
||||
if "PythonProcPool" in utils.server_services():
|
||||
|
|
@ -301,11 +300,11 @@ class CmdBatchCommands(_COMMAND_DEFAULT_CLASS):
|
|||
if procpool:
|
||||
# run in parallel process
|
||||
def callback(r):
|
||||
caller.msg(" {GBatchfile '%s' applied." % python_path)
|
||||
caller.msg(" |GBatchfile '%s' applied." % python_path)
|
||||
purge_processor(caller)
|
||||
|
||||
def errback(e):
|
||||
caller.msg(" {RError from processor: '%s'" % e)
|
||||
caller.msg(" |RError from processor: '%s'" % e)
|
||||
purge_processor(caller)
|
||||
|
||||
utils.run_async(_PROCPOOL_BATCHCMD_SOURCE,
|
||||
|
|
@ -315,7 +314,7 @@ class CmdBatchCommands(_COMMAND_DEFAULT_CLASS):
|
|||
at_err=errback)
|
||||
else:
|
||||
# run in-process (might block)
|
||||
for inum in range(len(commands)):
|
||||
for _ in range(len(commands)):
|
||||
# loop through the batch file
|
||||
if not batch_cmd_exec(caller):
|
||||
return
|
||||
|
|
@ -323,7 +322,7 @@ class CmdBatchCommands(_COMMAND_DEFAULT_CLASS):
|
|||
# clean out the safety cmdset and clean out all other
|
||||
# temporary attrs.
|
||||
string = " Batchfile '%s' applied." % python_path
|
||||
caller.msg("{G%s" % string)
|
||||
caller.msg("|G%s" % string)
|
||||
purge_processor(caller)
|
||||
|
||||
|
||||
|
|
@ -352,7 +351,7 @@ class CmdBatchCode(_COMMAND_DEFAULT_CLASS):
|
|||
help_category = "Building"
|
||||
|
||||
def func(self):
|
||||
"Starts the processor."
|
||||
"""Starts the processor."""
|
||||
|
||||
caller = self.caller
|
||||
|
||||
|
|
@ -363,7 +362,7 @@ class CmdBatchCode(_COMMAND_DEFAULT_CLASS):
|
|||
python_path = self.args
|
||||
debug = 'debug' in self.switches
|
||||
|
||||
#parse indata file
|
||||
# parse indata file
|
||||
try:
|
||||
codes = BATCHCODE.parse_file(python_path)
|
||||
except UnicodeDecodeError as err:
|
||||
|
|
@ -410,11 +409,11 @@ class CmdBatchCode(_COMMAND_DEFAULT_CLASS):
|
|||
if procpool:
|
||||
# run in parallel process
|
||||
def callback(r):
|
||||
caller.msg(" {GBatchfile '%s' applied." % python_path)
|
||||
caller.msg(" |GBatchfile '%s' applied." % python_path)
|
||||
purge_processor(caller)
|
||||
|
||||
def errback(e):
|
||||
caller.msg(" {RError from processor: '%s'" % e)
|
||||
caller.msg(" |RError from processor: '%s'" % e)
|
||||
purge_processor(caller)
|
||||
utils.run_async(_PROCPOOL_BATCHCODE_SOURCE,
|
||||
codes=codes,
|
||||
|
|
@ -423,7 +422,7 @@ class CmdBatchCode(_COMMAND_DEFAULT_CLASS):
|
|||
at_err=errback)
|
||||
else:
|
||||
# un in-process (will block)
|
||||
for inum in range(len(codes)):
|
||||
for _ in range(len(codes)):
|
||||
# loop through the batch file
|
||||
if not batch_code_exec(caller):
|
||||
return
|
||||
|
|
@ -431,14 +430,14 @@ class CmdBatchCode(_COMMAND_DEFAULT_CLASS):
|
|||
# clean out the safety cmdset and clean out all other
|
||||
# temporary attrs.
|
||||
string = " Batchfile '%s' applied." % python_path
|
||||
caller.msg("{G%s" % string)
|
||||
caller.msg("|G%s" % string)
|
||||
purge_processor(caller)
|
||||
|
||||
|
||||
#------------------------------------------------------------
|
||||
# -------------------------------------------------------------
|
||||
# State-commands for the interactive batch processor modes
|
||||
# (these are the same for both processors)
|
||||
#------------------------------------------------------------
|
||||
# -------------------------------------------------------------
|
||||
|
||||
class CmdStateAbort(_COMMAND_DEFAULT_CLASS):
|
||||
"""
|
||||
|
|
@ -453,7 +452,7 @@ class CmdStateAbort(_COMMAND_DEFAULT_CLASS):
|
|||
locks = "cmd:perm(batchcommands)"
|
||||
|
||||
def func(self):
|
||||
"Exit back to default."
|
||||
"""Exit back to default."""
|
||||
purge_processor(self.caller)
|
||||
self.caller.msg("Exited processor and reset out active cmdset back to the default one.")
|
||||
|
||||
|
|
@ -472,6 +471,7 @@ class CmdStateLL(_COMMAND_DEFAULT_CLASS):
|
|||
def func(self):
|
||||
show_curr(self.caller, showall=True)
|
||||
|
||||
|
||||
class CmdStatePP(_COMMAND_DEFAULT_CLASS):
|
||||
"""
|
||||
pp
|
||||
|
|
@ -644,7 +644,7 @@ class CmdStateSS(_COMMAND_DEFAULT_CLASS):
|
|||
else:
|
||||
step = 1
|
||||
|
||||
for istep in range(step):
|
||||
for _ in range(step):
|
||||
if caller.ndb.batch_batchmode == "batch_code":
|
||||
batch_code_exec(caller)
|
||||
else:
|
||||
|
|
@ -673,7 +673,7 @@ class CmdStateSL(_COMMAND_DEFAULT_CLASS):
|
|||
else:
|
||||
step = 1
|
||||
|
||||
for istep in range(step):
|
||||
for _ in range(step):
|
||||
if caller.ndb.batch_batchmode == "batch_code":
|
||||
batch_code_exec(caller)
|
||||
else:
|
||||
|
|
@ -699,7 +699,7 @@ class CmdStateCC(_COMMAND_DEFAULT_CLASS):
|
|||
ptr = caller.ndb.batch_stackptr
|
||||
step = nstack - ptr
|
||||
|
||||
for istep in range(step):
|
||||
for _ in range(step):
|
||||
if caller.ndb.batch_batchmode == "batch_code":
|
||||
batch_code_exec(caller)
|
||||
else:
|
||||
|
|
@ -775,7 +775,7 @@ class CmdStateQQ(_COMMAND_DEFAULT_CLASS):
|
|||
|
||||
|
||||
class CmdStateHH(_COMMAND_DEFAULT_CLASS):
|
||||
"Help command"
|
||||
"""Help command"""
|
||||
|
||||
key = "hh"
|
||||
help_category = "BatchProcess"
|
||||
|
|
@ -810,12 +810,12 @@ class CmdStateHH(_COMMAND_DEFAULT_CLASS):
|
|||
self.caller.msg(string)
|
||||
|
||||
|
||||
#------------------------------------------------------------
|
||||
# -------------------------------------------------------------
|
||||
#
|
||||
# Defining the cmdsets for the interactive batchprocessor
|
||||
# mode (same for both processors)
|
||||
#
|
||||
#------------------------------------------------------------
|
||||
# -------------------------------------------------------------
|
||||
|
||||
class BatchSafeCmdSet(CmdSet):
|
||||
"""
|
||||
|
|
@ -827,7 +827,7 @@ class BatchSafeCmdSet(CmdSet):
|
|||
priority = 150 # override other cmdsets.
|
||||
|
||||
def at_cmdset_creation(self):
|
||||
"Init the cmdset"
|
||||
"""Init the cmdset"""
|
||||
self.add(CmdStateAbort())
|
||||
|
||||
|
||||
|
|
@ -839,7 +839,7 @@ class BatchInteractiveCmdSet(CmdSet):
|
|||
priority = 104
|
||||
|
||||
def at_cmdset_creation(self):
|
||||
"init the cmdset"
|
||||
"""init the cmdset"""
|
||||
self.add(CmdStateAbort())
|
||||
self.add(CmdStateLL())
|
||||
self.add(CmdStatePP())
|
||||
|
|
|
|||
|
|
@ -591,9 +591,11 @@ class CmdDesc(COMMAND_DEFAULT_CLASS):
|
|||
if not obj:
|
||||
return
|
||||
desc = self.args
|
||||
|
||||
obj.db.desc = desc
|
||||
caller.msg("The description was set on %s." % obj.get_display_name(caller))
|
||||
if obj.access(caller, "edit"):
|
||||
obj.db.desc = desc
|
||||
caller.msg("The description was set on %s." % obj.get_display_name(caller))
|
||||
else:
|
||||
caller.msg("You don't have permission to edit the description of %s." % obj.key)
|
||||
|
||||
|
||||
class CmdDestroy(COMMAND_DEFAULT_CLASS):
|
||||
|
|
@ -1138,7 +1140,7 @@ class CmdName(ObjManipCommand):
|
|||
caller.msg("No name defined!")
|
||||
return
|
||||
if not (obj.access(caller, "control") or obj.access(caller, "edit")):
|
||||
caller.mgs("You don't have right to edit this player %s." % obj)
|
||||
caller.msg("You don't have right to edit this player %s." % obj)
|
||||
return
|
||||
obj.username = newname
|
||||
obj.save()
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ class CharacterCmdSet(CmdSet):
|
|||
self.add(general.CmdDrop())
|
||||
self.add(general.CmdGive())
|
||||
self.add(general.CmdSay())
|
||||
self.add(general.CmdWhisper())
|
||||
self.add(general.CmdAccess())
|
||||
|
||||
# The help system
|
||||
|
|
|
|||
|
|
@ -60,16 +60,17 @@ class CmdLook(COMMAND_DEFAULT_CLASS):
|
|||
"""
|
||||
Handle the looking.
|
||||
"""
|
||||
caller = self.caller
|
||||
if not self.args:
|
||||
target = self.caller.location
|
||||
target = caller.location
|
||||
if not target:
|
||||
self.caller.msg("You have no location to look at!")
|
||||
caller.msg("You have no location to look at!")
|
||||
return
|
||||
else:
|
||||
target = self.caller.search(self.args)
|
||||
target = caller.search(self.args, use_dbref=caller.check_permstring("Builders"))
|
||||
if not target:
|
||||
return
|
||||
self.msg(self.caller.at_look(target))
|
||||
self.msg(caller.at_look(target))
|
||||
|
||||
|
||||
class CmdNick(COMMAND_DEFAULT_CLASS):
|
||||
|
|
@ -175,10 +176,9 @@ class CmdNick(COMMAND_DEFAULT_CLASS):
|
|||
errstring += "Not a valid nick index."
|
||||
else:
|
||||
errstring += "Nick not found."
|
||||
|
||||
if "delete" in switches or "del" in switches:
|
||||
# clear the nick
|
||||
if caller.nicks.has(old_nickstring, category=nicktype):
|
||||
if old_nickstring and caller.nicks.has(old_nickstring, category=nicktype):
|
||||
caller.nicks.remove(old_nickstring, category=nicktype)
|
||||
string += "\nNick removed: '|w%s|n' -> |w%s|n." % (old_nickstring, old_replstring)
|
||||
else:
|
||||
|
|
@ -354,6 +354,8 @@ class CmdGive(COMMAND_DEFAULT_CLASS):
|
|||
caller.msg("You give %s to %s." % (to_give.key, target.key))
|
||||
to_give.move_to(target, quiet=True)
|
||||
target.msg("%s gives you %s." % (caller.key, to_give.key))
|
||||
# Call the object script's at_give() method.
|
||||
to_give.at_give(caller, target)
|
||||
|
||||
|
||||
class CmdSetDesc(COMMAND_DEFAULT_CLASS):
|
||||
|
|
@ -415,7 +417,50 @@ class CmdSay(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
# Build the string to emit to neighbors.
|
||||
emit_string = '%s says, "%s|n"' % (caller.name, speech)
|
||||
caller.location.msg_contents(emit_string, exclude=caller, from_obj=caller)
|
||||
caller.location.msg_contents(text=(emit_string, {"type": "say"}),
|
||||
exclude=caller, from_obj=caller)
|
||||
|
||||
|
||||
class CmdWhisper(COMMAND_DEFAULT_CLASS):
|
||||
"""
|
||||
Speak privately as your character to another
|
||||
|
||||
Usage:
|
||||
whisper <player> = <message>
|
||||
|
||||
Talk privately to those in your current location, without
|
||||
others being informed.
|
||||
"""
|
||||
|
||||
key = "whisper"
|
||||
locks = "cmd:all()"
|
||||
|
||||
def func(self):
|
||||
"""Run the whisper command"""
|
||||
|
||||
caller = self.caller
|
||||
|
||||
if not self.lhs or not self.rhs:
|
||||
caller.msg("Usage: whisper <player> = <message>")
|
||||
return
|
||||
|
||||
receiver = caller.search(self.lhs)
|
||||
|
||||
if not receiver:
|
||||
return
|
||||
|
||||
if caller == receiver:
|
||||
caller.msg("You can't whisper to yourself.")
|
||||
return
|
||||
|
||||
speech = self.rhs
|
||||
|
||||
# Feedback for the object doing the talking.
|
||||
caller.msg('You whisper to %s, "%s|n"' % (receiver.key, speech))
|
||||
|
||||
# Build the string to emit to receiver.
|
||||
emit_string = '%s whispers, "%s|n"' % (caller.name, speech)
|
||||
receiver.msg(text=(emit_string, {"type": "whisper"}), from_obj=caller)
|
||||
|
||||
|
||||
class CmdPose(COMMAND_DEFAULT_CLASS):
|
||||
|
|
@ -458,7 +503,8 @@ class CmdPose(COMMAND_DEFAULT_CLASS):
|
|||
self.caller.msg(msg)
|
||||
else:
|
||||
msg = "%s%s" % (self.caller.name, self.args)
|
||||
self.caller.location.msg_contents(msg, from_obj=self.caller)
|
||||
self.caller.location.msg_contents(text=(msg, {"type": "pose"}),
|
||||
from_obj=self.caller)
|
||||
|
||||
|
||||
class CmdAccess(COMMAND_DEFAULT_CLASS):
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ class CmdHelp(Command):
|
|||
|
||||
if self.session.protocol_key in ("websocket", "ajax/comet"):
|
||||
try:
|
||||
options = self.caller.player.db._saved_webclient_options
|
||||
options = self.player.db._saved_webclient_options
|
||||
if options and options["helppopup"]:
|
||||
usemore = False
|
||||
except KeyError:
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ from evennia.commands.command import Command
|
|||
# limit symbol import for API
|
||||
__all__ = ("MuxCommand", "MuxPlayerCommand")
|
||||
|
||||
|
||||
class MuxCommand(Command):
|
||||
"""
|
||||
This sets up the basis for a MUX command. The idea
|
||||
|
|
@ -98,7 +99,7 @@ class MuxCommand(Command):
|
|||
|
||||
# split out switches
|
||||
switches = []
|
||||
if args and len(args) > 1 and args[0] == "/":
|
||||
if args and len(args) > 1 and raw[0] == "/":
|
||||
# we have a switch, or a set of switches. These end with a space.
|
||||
switches = args[1:].split(None, 1)
|
||||
if len(switches) > 1:
|
||||
|
|
@ -150,33 +151,32 @@ class MuxCommand(Command):
|
|||
"""
|
||||
# a simple test command to show the available properties
|
||||
string = "-" * 50
|
||||
string += "\n{w%s{n - Command variables from evennia:\n" % self.key
|
||||
string += "\n|w%s|n - Command variables from evennia:\n" % self.key
|
||||
string += "-" * 50
|
||||
string += "\nname of cmd (self.key): {w%s{n\n" % self.key
|
||||
string += "cmd aliases (self.aliases): {w%s{n\n" % self.aliases
|
||||
string += "cmd locks (self.locks): {w%s{n\n" % self.locks
|
||||
string += "help category (self.help_category): {w%s{n\n" % self.help_category
|
||||
string += "object calling (self.caller): {w%s{n\n" % self.caller
|
||||
string += "object storing cmdset (self.obj): {w%s{n\n" % self.obj
|
||||
string += "command string given (self.cmdstring): {w%s{n\n" % self.cmdstring
|
||||
string += "\nname of cmd (self.key): |w%s|n\n" % self.key
|
||||
string += "cmd aliases (self.aliases): |w%s|n\n" % self.aliases
|
||||
string += "cmd locks (self.locks): |w%s|n\n" % self.locks
|
||||
string += "help category (self.help_category): |w%s|n\n" % self.help_category
|
||||
string += "object calling (self.caller): |w%s|n\n" % self.caller
|
||||
string += "object storing cmdset (self.obj): |w%s|n\n" % self.obj
|
||||
string += "command string given (self.cmdstring): |w%s|n\n" % self.cmdstring
|
||||
# show cmdset.key instead of cmdset to shorten output
|
||||
string += utils.fill("current cmdset (self.cmdset): {w%s{n\n" % self.cmdset)
|
||||
|
||||
|
||||
string += utils.fill("current cmdset (self.cmdset): |w%s|n\n" % self.cmdset)
|
||||
string += "\n" + "-" * 50
|
||||
string += "\nVariables from MuxCommand baseclass\n"
|
||||
string += "\nVariables from MuxCommand baseclass\n"
|
||||
string += "-" * 50
|
||||
string += "\nraw argument (self.raw): {w%s{n \n" % self.raw
|
||||
string += "cmd args (self.args): {w%s{n\n" % self.args
|
||||
string += "cmd switches (self.switches): {w%s{n\n" % self.switches
|
||||
string += "space-separated arg list (self.arglist): {w%s{n\n" % self.arglist
|
||||
string += "lhs, left-hand side of '=' (self.lhs): {w%s{n\n" % self.lhs
|
||||
string += "lhs, comma separated (self.lhslist): {w%s{n\n" % self.lhslist
|
||||
string += "rhs, right-hand side of '=' (self.rhs): {w%s{n\n" % self.rhs
|
||||
string += "rhs, comma separated (self.rhslist): {w%s{n\n" % self.rhslist
|
||||
string += "\nraw argument (self.raw): |w%s|n \n" % self.raw
|
||||
string += "cmd args (self.args): |w%s|n\n" % self.args
|
||||
string += "cmd switches (self.switches): |w%s|n\n" % self.switches
|
||||
string += "space-separated arg list (self.arglist): |w%s|n\n" % self.arglist
|
||||
string += "lhs, left-hand side of '=' (self.lhs): |w%s|n\n" % self.lhs
|
||||
string += "lhs, comma separated (self.lhslist): |w%s|n\n" % self.lhslist
|
||||
string += "rhs, right-hand side of '=' (self.rhs): |w%s|n\n" % self.rhs
|
||||
string += "rhs, comma separated (self.rhslist): |w%s|n\n" % self.rhslist
|
||||
string += "-" * 50
|
||||
self.caller.msg(string)
|
||||
|
||||
|
||||
class MuxPlayerCommand(MuxCommand):
|
||||
"""
|
||||
This is an on-Player version of the MuxCommand. Since these commands sit
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ 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, Player 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.
|
||||
|
||||
|
|
@ -23,7 +23,7 @@ from builtins import range
|
|||
import time
|
||||
from django.conf import settings
|
||||
from evennia.server.sessionhandler import SESSIONS
|
||||
from evennia.utils import utils, create, search, prettytable, evtable
|
||||
from evennia.utils import utils, create, search, evtable
|
||||
|
||||
COMMAND_DEFAULT_CLASS = utils.class_from_module(settings.COMMAND_DEFAULT_CLASS)
|
||||
|
||||
|
|
@ -44,7 +44,7 @@ class MuxPlayerLookCommand(COMMAND_DEFAULT_CLASS):
|
|||
"""
|
||||
|
||||
def parse(self):
|
||||
"Custom parsing"
|
||||
"""Custom parsing"""
|
||||
|
||||
super(MuxPlayerLookCommand, self).parse()
|
||||
|
||||
|
|
@ -62,7 +62,7 @@ class MuxPlayerLookCommand(COMMAND_DEFAULT_CLASS):
|
|||
# store playable property
|
||||
if self.args:
|
||||
self.playable = dict((utils.to_str(char.key.lower()), char)
|
||||
for char in playable).get(self.args.lower(), None)
|
||||
for char in playable).get(self.args.lower(), None)
|
||||
else:
|
||||
self.playable = playable
|
||||
|
||||
|
|
@ -83,10 +83,10 @@ class CmdOOCLook(MuxPlayerLookCommand):
|
|||
Look in the ooc state.
|
||||
"""
|
||||
|
||||
#This is an OOC version of the look command. Since a
|
||||
#Player 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.
|
||||
# This is an OOC version of the look command. Since a
|
||||
# Player 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.
|
||||
|
||||
key = "look"
|
||||
aliases = ["l", "ls"]
|
||||
|
|
@ -97,11 +97,11 @@ class CmdOOCLook(MuxPlayerLookCommand):
|
|||
player_caller = True
|
||||
|
||||
def func(self):
|
||||
"implement the ooc look command"
|
||||
"""implement the ooc look command"""
|
||||
|
||||
if _MULTISESSION_MODE < 2:
|
||||
# only one character allowed
|
||||
self.msg("You are out-of-character (OOC).\nUse {w@ic{n to get back into the game.")
|
||||
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
|
||||
|
|
@ -128,7 +128,7 @@ class CmdCharCreate(COMMAND_DEFAULT_CLASS):
|
|||
player_caller = True
|
||||
|
||||
def func(self):
|
||||
"create the new character"
|
||||
"""create the new character"""
|
||||
player = self.player
|
||||
if not self.args:
|
||||
self.msg("Usage: @charcreate <charname> [= description]")
|
||||
|
|
@ -139,8 +139,8 @@ 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):
|
||||
(player.db._playable_characters and
|
||||
len(player.db._playable_characters) >= charmax):
|
||||
self.msg("You may only create a maximum of %i characters." % charmax)
|
||||
return
|
||||
from evennia.objects.models import ObjectDB
|
||||
|
|
@ -150,15 +150,13 @@ class CmdCharCreate(COMMAND_DEFAULT_CLASS):
|
|||
# check if this Character already exists. Note that we are only
|
||||
# searching the base character typeclass here, not any child
|
||||
# classes.
|
||||
self.msg("{rA character named '{w%s{r' already exists.{n" % key)
|
||||
self.msg("|rA character named '|w%s|r' already exists.|n" % key)
|
||||
return
|
||||
|
||||
# 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
|
||||
|
||||
|
||||
new_character = create.create_object(typeclass, key=key,
|
||||
location=start_location,
|
||||
home=default_home,
|
||||
|
|
@ -171,7 +169,8 @@ class CmdCharCreate(COMMAND_DEFAULT_CLASS):
|
|||
new_character.db.desc = desc
|
||||
elif not new_character.db.desc:
|
||||
new_character.db.desc = "This is a Player."
|
||||
self.msg("Created new character %s. Use {w@ic %s{n to enter the game as this character." % (new_character.key, new_character.key))
|
||||
self.msg("Created new character %s. Use |w@ic %s|n to enter the game as this character."
|
||||
% (new_character.key, new_character.key))
|
||||
|
||||
|
||||
class CmdCharDelete(COMMAND_DEFAULT_CLASS):
|
||||
|
|
@ -188,7 +187,7 @@ class CmdCharDelete(COMMAND_DEFAULT_CLASS):
|
|||
help_category = "General"
|
||||
|
||||
def func(self):
|
||||
"delete the character"
|
||||
"""delete the character"""
|
||||
player = self.player
|
||||
|
||||
if not self.args:
|
||||
|
|
@ -196,23 +195,23 @@ class CmdCharDelete(COMMAND_DEFAULT_CLASS):
|
|||
return
|
||||
|
||||
# use the playable_characters list to search
|
||||
match = [char for char in utils.make_iter(player.db._playable_characters) if char.key.lower() == self.args.lower()]
|
||||
match = [char for char in utils.make_iter(player.db._playable_characters)
|
||||
if char.key.lower() == self.args.lower()]
|
||||
if not match:
|
||||
self.msg("You have no such character to delete.")
|
||||
return
|
||||
elif len(match) > 1:
|
||||
self.msg("Aborting - there are two characters with the same name. Ask an admin to delete the right one.")
|
||||
return
|
||||
else: # one match
|
||||
else: # one match
|
||||
from evennia.utils.evmenu import get_input
|
||||
|
||||
def _callback(caller, prompt, result):
|
||||
def _callback(caller, callback_prompt, result):
|
||||
if result.lower() == "yes":
|
||||
# only take action
|
||||
delobj = caller.ndb._char_to_delete
|
||||
key = delobj.key
|
||||
caller.db._playable_characters = [char for char
|
||||
in caller.db._playable_characters if char != delobj]
|
||||
caller.db._playable_characters = [pc for pc in caller.db._playable_characters if pc != delobj]
|
||||
delobj.delete()
|
||||
self.msg("Character '%s' was permanently deleted." % key)
|
||||
else:
|
||||
|
|
@ -272,7 +271,8 @@ class CmdIC(COMMAND_DEFAULT_CLASS):
|
|||
self.msg("That is not a valid character choice.")
|
||||
return
|
||||
if len(new_character) > 1:
|
||||
self.msg("Multiple targets with the same name:\n %s" % ", ".join("%s(#%s)" % (obj.key, obj.id) for obj in new_character))
|
||||
self.msg("Multiple targets with the same name:\n %s"
|
||||
% ", ".join("%s(#%s)" % (obj.key, obj.id) for obj in new_character))
|
||||
return
|
||||
else:
|
||||
new_character = new_character[0]
|
||||
|
|
@ -280,7 +280,7 @@ class CmdIC(COMMAND_DEFAULT_CLASS):
|
|||
player.puppet_object(session, new_character)
|
||||
player.db._last_puppet = new_character
|
||||
except RuntimeError as exc:
|
||||
self.msg("{rYou cannot become {C%s{n: %s" % (new_character.name, exc))
|
||||
self.msg("|rYou cannot become |C%s|n: %s" % (new_character.name, exc))
|
||||
|
||||
|
||||
# note that this is inheriting from MuxPlayerLookCommand,
|
||||
|
|
@ -306,7 +306,7 @@ class CmdOOC(MuxPlayerLookCommand):
|
|||
player_caller = True
|
||||
|
||||
def func(self):
|
||||
"Implement function"
|
||||
"""Implement function"""
|
||||
|
||||
player = self.player
|
||||
session = self.session
|
||||
|
|
@ -322,17 +322,18 @@ class CmdOOC(MuxPlayerLookCommand):
|
|||
# disconnect
|
||||
try:
|
||||
player.unpuppet_object(session)
|
||||
self.msg("\n{GYou go OOC.{n\n")
|
||||
self.msg("\n|GYou go OOC.|n\n")
|
||||
|
||||
if _MULTISESSION_MODE < 2:
|
||||
# only one character allowed
|
||||
self.msg("You are out-of-character (OOC).\nUse {w@ic{n to get back into the game.")
|
||||
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))
|
||||
|
||||
except RuntimeError as exc:
|
||||
self.msg("{rCould not unpuppet from {c%s{n: %s" % (old_char, exc))
|
||||
self.msg("|rCould not unpuppet from |c%s|n: %s" % (old_char, exc))
|
||||
|
||||
|
||||
class CmdSessions(COMMAND_DEFAULT_CLASS):
|
||||
"""
|
||||
|
|
@ -352,23 +353,21 @@ class CmdSessions(COMMAND_DEFAULT_CLASS):
|
|||
player_caller = True
|
||||
|
||||
def func(self):
|
||||
"Implement function"
|
||||
"""Implement function"""
|
||||
player = self.player
|
||||
sessions = player.sessions.all()
|
||||
|
||||
table = prettytable.PrettyTable(["{wsessid",
|
||||
"{wprotocol",
|
||||
"{whost",
|
||||
"{wpuppet/character",
|
||||
"{wlocation"])
|
||||
table = evtable.EvTable("|wsessid",
|
||||
"|wprotocol",
|
||||
"|whost",
|
||||
"|wpuppet/character",
|
||||
"|wlocation")
|
||||
for sess in sorted(sessions, key=lambda x: x.sessid):
|
||||
char = player.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",
|
||||
char and str(char.location) or "N/A"])
|
||||
string = "{wYour current session(s):{n\n%s" % table
|
||||
self.msg(string)
|
||||
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",
|
||||
char and str(char.location) or "N/A")
|
||||
self.msg("|wYour current session(s):|n\n%s" % table)
|
||||
|
||||
|
||||
class CmdWho(COMMAND_DEFAULT_CLASS):
|
||||
|
|
@ -408,45 +407,45 @@ class CmdWho(COMMAND_DEFAULT_CLASS):
|
|||
nplayers = (SESSIONS.player_count())
|
||||
if show_session_data:
|
||||
# privileged info
|
||||
table = prettytable.PrettyTable(["{wPlayer Name",
|
||||
"{wOn for",
|
||||
"{wIdle",
|
||||
"{wPuppeting",
|
||||
"{wRoom",
|
||||
"{wCmds",
|
||||
"{wProtocol",
|
||||
"{wHost"])
|
||||
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()
|
||||
puppet = session.get_puppet()
|
||||
location = puppet.location.key if puppet and puppet.location else "None"
|
||||
table.add_row([utils.crop(player.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),
|
||||
utils.crop(location, width=25),
|
||||
session.cmd_total,
|
||||
session.protocol_key,
|
||||
isinstance(session.address, tuple) and session.address[0] or session.address])
|
||||
else:
|
||||
# unprivileged
|
||||
table = prettytable.PrettyTable(["{wPlayer name", "{wOn for", "{wIdle"])
|
||||
table = evtable.EvTable("|wPlayer Name",
|
||||
"|wOn for",
|
||||
"|wIdle",
|
||||
"|wPuppeting",
|
||||
"|wRoom",
|
||||
"|wCmds",
|
||||
"|wProtocol",
|
||||
"|wHost")
|
||||
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),
|
||||
utils.time_format(delta_conn, 0),
|
||||
utils.time_format(delta_cmd, 1)])
|
||||
|
||||
isone = nplayers == 1
|
||||
string = "{wPlayers:{n\n%s\n%s unique account%s logged in." % (table, "One" if isone else nplayers, "" if isone else "s")
|
||||
self.msg(string)
|
||||
puppet = session.get_puppet()
|
||||
location = puppet.location.key if puppet and puppet.location else "None"
|
||||
table.add_row(utils.crop(player.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),
|
||||
utils.crop(location, width=25),
|
||||
session.cmd_total,
|
||||
session.protocol_key,
|
||||
isinstance(session.address, tuple) and session.address[0] or session.address)
|
||||
else:
|
||||
# unprivileged
|
||||
table = evtable.EvTable("|wPlayer 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),
|
||||
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"))
|
||||
|
||||
|
||||
class CmdOption(COMMAND_DEFAULT_CLASS):
|
||||
|
|
@ -489,13 +488,13 @@ class CmdOption(COMMAND_DEFAULT_CLASS):
|
|||
if "save" in self.switches:
|
||||
# save all options
|
||||
self.caller.db._saved_protocol_flags = flags
|
||||
self.msg("{gSaved all options. Use @option/clear to remove.{n")
|
||||
self.msg("|gSaved all options. Use @option/clear to remove.|n")
|
||||
if "clear" in self.switches:
|
||||
# clear all saves
|
||||
self.caller.db._saved_protocol_flags = {}
|
||||
self.msg("{gCleared all saved options.")
|
||||
self.msg("|gCleared all saved options.")
|
||||
|
||||
options = dict(flags) # make a copy of the flag dict
|
||||
options = dict(flags) # make a copy of the flag dict
|
||||
saved_options = dict(self.caller.attributes.get("_saved_protocol_flags", default={}))
|
||||
|
||||
if "SCREENWIDTH" in options:
|
||||
|
|
@ -503,7 +502,7 @@ class CmdOption(COMMAND_DEFAULT_CLASS):
|
|||
options["SCREENWIDTH"] = options["SCREENWIDTH"][0]
|
||||
else:
|
||||
options["SCREENWIDTH"] = " \n".join("%s : %s" % (screenid, size)
|
||||
for screenid, size in options["SCREENWIDTH"].iteritems())
|
||||
for screenid, size in options["SCREENWIDTH"].iteritems())
|
||||
if "SCREENHEIGHT" in options:
|
||||
if len(options["SCREENHEIGHT"]) == 1:
|
||||
options["SCREENHEIGHT"] = options["SCREENHEIGHT"][0]
|
||||
|
|
@ -521,8 +520,7 @@ class CmdOption(COMMAND_DEFAULT_CLASS):
|
|||
changed = "|y*|n" if key in saved_options and flags[key] != saved_options[key] else ""
|
||||
row.append("%s%s" % (saved, changed))
|
||||
table.add_row(*row)
|
||||
|
||||
self.msg("{wClient settings (%s):|n\n%s|n" % (self.session.protocol_key, table))
|
||||
self.msg("|wClient settings (%s):|n\n%s|n" % (self.session.protocol_key, table))
|
||||
|
||||
return
|
||||
|
||||
|
|
@ -532,30 +530,30 @@ class CmdOption(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
# Try to assign new values
|
||||
|
||||
def validate_encoding(val):
|
||||
def validate_encoding(new_encoding):
|
||||
# helper: change encoding
|
||||
try:
|
||||
utils.to_str(utils.to_unicode("test-string"), encoding=val)
|
||||
utils.to_str(utils.to_unicode("test-string"), encoding=new_encoding)
|
||||
except LookupError:
|
||||
raise RuntimeError("The encoding '|w%s|n' is invalid. " % val)
|
||||
raise RuntimeError("The encoding '|w%s|n' is invalid. " % new_encoding)
|
||||
return val
|
||||
|
||||
def validate_size(val):
|
||||
return {0: int(val)}
|
||||
def validate_size(new_size):
|
||||
return {0: int(new_size)}
|
||||
|
||||
def validate_bool(val):
|
||||
return True if val.lower() in ("true", "on", "1") else False
|
||||
def validate_bool(new_bool):
|
||||
return True if new_bool.lower() in ("true", "on", "1") else False
|
||||
|
||||
def update(name, val, validator):
|
||||
def update(new_name, new_val, validator):
|
||||
# helper: update property and report errors
|
||||
try:
|
||||
old_val = flags[name]
|
||||
new_val = validator(val)
|
||||
flags[name] = new_val
|
||||
self.msg("Option |w%s|n was changed from '|w%s|n' to '|w%s|n'." % (name, old_val, new_val))
|
||||
return {name: new_val}
|
||||
old_val = flags.get(new_name, False)
|
||||
new_val = validator(new_val)
|
||||
flags[new_name] = new_val
|
||||
self.msg("Option |w%s|n was changed from '|w%s|n' to '|w%s|n'." % (new_name, old_val, new_val))
|
||||
return {new_name: new_val}
|
||||
except Exception, err:
|
||||
self.msg("|rCould not set option |w%s|r:|n %s" % (name, err))
|
||||
self.msg("|rCould not set option |w%s|r:|n %s" % (new_name, err))
|
||||
return False
|
||||
|
||||
validators = {"ANSI": validate_bool,
|
||||
|
|
@ -590,16 +588,15 @@ class CmdOption(COMMAND_DEFAULT_CLASS):
|
|||
saved_options.update(optiondict)
|
||||
self.player.attributes.add("_saved_protocol_flags", saved_options)
|
||||
for key in optiondict:
|
||||
self.msg("{gSaved option %s.{n" % key)
|
||||
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.msg("{gCleared saved %s." % key)
|
||||
|
||||
|
||||
self.msg("|gCleared saved %s." % key)
|
||||
self.session.update_flags(**optiondict)
|
||||
|
||||
|
||||
class CmdPassword(COMMAND_DEFAULT_CLASS):
|
||||
"""
|
||||
change your password
|
||||
|
|
@ -616,14 +613,14 @@ class CmdPassword(COMMAND_DEFAULT_CLASS):
|
|||
player_caller = True
|
||||
|
||||
def func(self):
|
||||
"hook function."
|
||||
"""hook function."""
|
||||
|
||||
player = self.player
|
||||
if not self.rhs:
|
||||
self.msg("Usage: @password <oldpass> = <newpass>")
|
||||
return
|
||||
oldpass = self.lhslist[0] # this is already stripped by parse()
|
||||
newpass = self.rhslist[0] # ''
|
||||
oldpass = self.lhslist[0] # Both of these are
|
||||
newpass = self.rhslist[0] # already stripped by parse()
|
||||
if not player.check_password(oldpass):
|
||||
self.msg("The specified old password isn't correct.")
|
||||
elif len(newpass) < 3:
|
||||
|
|
@ -654,11 +651,11 @@ class CmdQuit(COMMAND_DEFAULT_CLASS):
|
|||
player_caller = True
|
||||
|
||||
def func(self):
|
||||
"hook function"
|
||||
"""hook function"""
|
||||
player = self.player
|
||||
|
||||
if 'all' in self.switches:
|
||||
player.msg("{RQuitting{n all sessions. Hope to see you soon again.", session=self.session)
|
||||
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)
|
||||
else:
|
||||
|
|
@ -673,7 +670,6 @@ class CmdQuit(COMMAND_DEFAULT_CLASS):
|
|||
player.disconnect_session_from_player(self.session)
|
||||
|
||||
|
||||
|
||||
class CmdColorTest(COMMAND_DEFAULT_CLASS):
|
||||
"""
|
||||
testing which colors your client support
|
||||
|
|
@ -695,23 +691,23 @@ class CmdColorTest(COMMAND_DEFAULT_CLASS):
|
|||
player_caller = True
|
||||
|
||||
def table_format(self, table):
|
||||
"""
|
||||
Helper method to format the ansi/xterm256 tables.
|
||||
Takes a table of columns [[val,val,...],[val,val,...],...]
|
||||
"""
|
||||
if not table:
|
||||
return [[]]
|
||||
"""
|
||||
Helper method to format the ansi/xterm256 tables.
|
||||
Takes a table of columns [[val,val,...],[val,val,...],...]
|
||||
"""
|
||||
if not table:
|
||||
return [[]]
|
||||
|
||||
extra_space = 1
|
||||
max_widths = [max([len(str(val)) for val in col]) for col in table]
|
||||
ftable = []
|
||||
for irow in range(len(table[0])):
|
||||
ftable.append([str(col[irow]).ljust(max_widths[icol]) + " " * extra_space
|
||||
for icol, col in enumerate(table)])
|
||||
return ftable
|
||||
extra_space = 1
|
||||
max_widths = [max([len(str(val)) for val in col]) for col in table]
|
||||
ftable = []
|
||||
for irow in range(len(table[0])):
|
||||
ftable.append([str(col[irow]).ljust(max_widths[icol]) + " " *
|
||||
extra_space for icol, col in enumerate(table)])
|
||||
return ftable
|
||||
|
||||
def func(self):
|
||||
"Show color tables"
|
||||
"""Show color tables"""
|
||||
|
||||
if self.args.startswith("a"):
|
||||
# show ansi 16-color table
|
||||
|
|
@ -721,9 +717,11 @@ class CmdColorTest(COMMAND_DEFAULT_CLASS):
|
|||
# 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 i in range(len(col1)-len(col2))])
|
||||
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])
|
||||
string = "ANSI colors:"
|
||||
for row in table:
|
||||
|
|
@ -742,9 +740,8 @@ class CmdColorTest(COMMAND_DEFAULT_CLASS):
|
|||
# foreground table
|
||||
table[ir].append("|%i%i%i%s|n" % (ir, ig, ib, "||%i%i%i" % (ir, ig, ib)))
|
||||
# background table
|
||||
table[6+ir].append("|%i%i%i|[%i%i%i%s|n" % (5 - ir, 5 - ig, 5 - ib,
|
||||
ir, ig, ib,
|
||||
"||[%i%i%i" % (ir, ig, ib)))
|
||||
table[6+ir].append("|%i%i%i|[%i%i%i%s|n"
|
||||
% (5 - ir, 5 - ig, 5 - ib, ir, ig, ib, "||[%i%i%i" % (ir, ig, ib)))
|
||||
table = self.table_format(table)
|
||||
string = "Xterm256 colors (if not all hues show, your client might not report that it can handle xterm256):"
|
||||
string += "\n" + "\n".join("".join(row) for row in table)
|
||||
|
|
@ -753,15 +750,15 @@ class CmdColorTest(COMMAND_DEFAULT_CLASS):
|
|||
for igray in range(6):
|
||||
letter = chr(97 + (ibatch*6 + igray))
|
||||
inverse = chr(122 - (ibatch*6 + igray))
|
||||
table[0 + igray].append("|=%s%s |n" % (letter, "||=%s" % (letter)))
|
||||
table[6 + igray].append("|=%s|[=%s%s |n" % (inverse, letter, "||[=%s" % (letter)))
|
||||
table[0 + igray].append("|=%s%s |n" % (letter, "||=%s" % letter))
|
||||
table[6 + igray].append("|=%s|[=%s%s |n" % (inverse, letter, "||[=%s" % letter))
|
||||
for igray in range(6):
|
||||
# the last row (y, z) has empty columns
|
||||
if igray < 2:
|
||||
letter = chr(121 + igray)
|
||||
inverse = chr(98 - igray)
|
||||
fg = "|=%s%s |n" % (letter, "||=%s" % (letter))
|
||||
bg = "|=%s|[=%s%s |n" % (inverse, letter, "||[=%s" % (letter))
|
||||
fg = "|=%s%s |n" % (letter, "||=%s" % letter)
|
||||
bg = "|=%s|[=%s%s |n" % (inverse, letter, "||[=%s" % letter)
|
||||
else:
|
||||
fg, bg = " ", " "
|
||||
table[0 + igray].append(fg)
|
||||
|
|
@ -800,7 +797,7 @@ class CmdQuell(COMMAND_DEFAULT_CLASS):
|
|||
player_caller = True
|
||||
|
||||
def _recache_locks(self, player):
|
||||
"Helper method to reset the lockhandler on an already puppeted object"
|
||||
"""Helper method to reset the lockhandler on an already puppeted object"""
|
||||
if self.session:
|
||||
char = self.session.puppet
|
||||
if char:
|
||||
|
|
@ -811,25 +808,26 @@ class CmdQuell(COMMAND_DEFAULT_CLASS):
|
|||
player.locks.reset()
|
||||
|
||||
def func(self):
|
||||
"Perform the command"
|
||||
"""Perform the command"""
|
||||
player = self.player
|
||||
permstr = player.is_superuser and " (superuser)" or " (%s)" % (", ".join(player.permissions.all()))
|
||||
permstr = player.is_superuser and " (superuser)" or "(%s)" % (", ".join(player.permissions.all()))
|
||||
if self.cmdstring == '@unquell':
|
||||
if not player.attributes.get('_quell'):
|
||||
self.msg("Already using normal Player permissions%s." % permstr)
|
||||
self.msg("Already using normal Player permissions %s." % permstr)
|
||||
else:
|
||||
player.attributes.remove('_quell')
|
||||
self.msg("Player permissions%s restored." % permstr)
|
||||
self.msg("Player permissions %s restored." % permstr)
|
||||
else:
|
||||
if player.attributes.get('_quell'):
|
||||
self.msg("Already quelling Player%s permissions." % permstr)
|
||||
self.msg("Already quelling Player %s permissions." % permstr)
|
||||
return
|
||||
player.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, the lowest of the two will be used.)" % permstr
|
||||
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," \
|
||||
" the lowest of the two will be used.)" % permstr
|
||||
cpermstr += "\nUse @unquell to return to normal permission usage."
|
||||
self.msg(cpermstr)
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ class CmdShutdown(COMMAND_DEFAULT_CLASS):
|
|||
help_category = "System"
|
||||
|
||||
def func(self):
|
||||
"Define function"
|
||||
"""Define function"""
|
||||
# Only allow shutdown if caller has session
|
||||
if not self.caller.sessions.get():
|
||||
return
|
||||
|
|
@ -126,6 +126,7 @@ class CmdShutdown(COMMAND_DEFAULT_CLASS):
|
|||
def _py_load(caller):
|
||||
return ""
|
||||
|
||||
|
||||
def _py_code(caller, buf):
|
||||
"""
|
||||
Execute the buffer.
|
||||
|
|
@ -139,10 +140,12 @@ def _py_code(caller, buf):
|
|||
show_input=False)
|
||||
return True
|
||||
|
||||
|
||||
def _py_quit(caller):
|
||||
del caller.db._py_measure_time
|
||||
caller.msg("Exited the code editor.")
|
||||
|
||||
|
||||
def _run_code_snippet(caller, pycode, mode="eval", measure_time=False,
|
||||
show_input=True):
|
||||
"""
|
||||
|
|
@ -174,9 +177,9 @@ def _run_code_snippet(caller, pycode, mode="eval", measure_time=False,
|
|||
if show_input:
|
||||
try:
|
||||
caller.msg(">>> %s" % pycode, session=session,
|
||||
options={"raw":True})
|
||||
options={"raw": True})
|
||||
except TypeError:
|
||||
caller.msg(">>> %s" % pycode, options={"raw":True})
|
||||
caller.msg(">>> %s" % pycode, options={"raw": True})
|
||||
|
||||
try:
|
||||
try:
|
||||
|
|
@ -204,9 +207,10 @@ def _run_code_snippet(caller, pycode, mode="eval", measure_time=False,
|
|||
ret = "\n".join("%s" % line for line in errlist if line)
|
||||
|
||||
try:
|
||||
caller.msg(ret, session=session, options={"raw":True})
|
||||
caller.msg(ret, session=session, options={"raw": True})
|
||||
except TypeError:
|
||||
caller.msg(ret, options={"raw":True})
|
||||
caller.msg(ret, options={"raw": True})
|
||||
|
||||
|
||||
class CmdPy(COMMAND_DEFAULT_CLASS):
|
||||
"""
|
||||
|
|
@ -234,8 +238,8 @@ class CmdPy(COMMAND_DEFAULT_CLASS):
|
|||
You can explore The evennia API from inside the game by calling
|
||||
evennia.help(), evennia.managers.help() etc.
|
||||
|
||||
{rNote: In the wrong hands this command is a severe security risk.
|
||||
It should only be accessible by trusted server admins/superusers.{n
|
||||
|rNote: In the wrong hands this command is a severe security risk.
|
||||
It should only be accessible by trusted server admins/superusers.|n
|
||||
|
||||
"""
|
||||
key = "@py"
|
||||
|
|
@ -244,7 +248,7 @@ class CmdPy(COMMAND_DEFAULT_CLASS):
|
|||
help_category = "System"
|
||||
|
||||
def func(self):
|
||||
"hook function"
|
||||
"""hook function"""
|
||||
|
||||
caller = self.caller
|
||||
pycode = self.args
|
||||
|
|
@ -266,13 +270,14 @@ class CmdPy(COMMAND_DEFAULT_CLASS):
|
|||
# helper function. Kept outside so it can be imported and run
|
||||
# by other commands.
|
||||
|
||||
|
||||
def format_script_list(scripts):
|
||||
"Takes a list of scripts and formats the output."
|
||||
"""Takes a list of scripts and formats the output."""
|
||||
if not scripts:
|
||||
return "<No scripts>"
|
||||
|
||||
table = EvTable("{wdbref{n", "{wobj{n", "{wkey{n", "{wintval{n", "{wnext{n",
|
||||
"{wrept{n", "{wdb", "{wtypeclass{n", "{wdesc{n",
|
||||
table = EvTable("|wdbref|n", "|wobj|n", "|wkey|n", "|wintval|n", "|wnext|n",
|
||||
"|wrept|n", "|wdb", "|wtypeclass|n", "|wdesc|n",
|
||||
align='r', border="tablecols")
|
||||
for script in scripts:
|
||||
nextrep = script.time_until_next_repeat()
|
||||
|
|
@ -326,12 +331,11 @@ class CmdScripts(COMMAND_DEFAULT_CLASS):
|
|||
help_category = "System"
|
||||
|
||||
def func(self):
|
||||
"implement method"
|
||||
"""implement method"""
|
||||
|
||||
caller = self.caller
|
||||
args = self.args
|
||||
|
||||
string = ""
|
||||
if args:
|
||||
if "start" in self.switches:
|
||||
# global script-start mode
|
||||
|
|
@ -374,9 +378,9 @@ class CmdScripts(COMMAND_DEFAULT_CLASS):
|
|||
else:
|
||||
string = "Stopping script '%s'." % scripts[0].key
|
||||
scripts[0].stop()
|
||||
#import pdb
|
||||
#pdb.set_trace()
|
||||
ScriptDB.objects.validate() #just to be sure all is synced
|
||||
# import pdb # DEBUG
|
||||
# pdb.set_trace() # DEBUG
|
||||
ScriptDB.objects.validate() # just to be sure all is synced
|
||||
else:
|
||||
# multiple matches.
|
||||
string = "Multiple script matches. Please refine your search:\n"
|
||||
|
|
@ -409,26 +413,21 @@ class CmdObjects(COMMAND_DEFAULT_CLASS):
|
|||
help_category = "System"
|
||||
|
||||
def func(self):
|
||||
"Implement the command"
|
||||
"""Implement the command"""
|
||||
|
||||
caller = self.caller
|
||||
|
||||
if self.args and self.args.isdigit():
|
||||
nlim = int(self.args)
|
||||
else:
|
||||
nlim = 10
|
||||
|
||||
nlim = int(self.args) if self.args and self.args.isdigit() else 10
|
||||
nobjs = ObjectDB.objects.count()
|
||||
base_char_typeclass = settings.BASE_CHARACTER_TYPECLASS
|
||||
nchars = ObjectDB.objects.filter(db_typeclass_path=base_char_typeclass).count()
|
||||
nrooms = ObjectDB.objects.filter(db_location__isnull=True).exclude(db_typeclass_path=base_char_typeclass).count()
|
||||
nrooms = ObjectDB.objects.filter(db_location__isnull=True).exclude(
|
||||
db_typeclass_path=base_char_typeclass).count()
|
||||
nexits = ObjectDB.objects.filter(db_location__isnull=False, db_destination__isnull=False).count()
|
||||
nother = nobjs - nchars - nrooms - nexits
|
||||
|
||||
nobjs = nobjs or 1 # fix zero-div error with empty database
|
||||
nobjs = nobjs or 1 # fix zero-div error with empty database
|
||||
|
||||
# total object sum table
|
||||
totaltable = EvTable("{wtype{n", "{wcomment{n", "{wcount{n", "{w%%{n", border="table", align="l")
|
||||
totaltable = EvTable("|wtype|n", "|wcomment|n", "|wcount|n", "|w%%|n", border="table", align="l")
|
||||
totaltable.align = 'l'
|
||||
totaltable.add_row("Characters", "(BASE_CHARACTER_TYPECLASS)", nchars, "%.2f" % ((float(nchars) / nobjs) * 100))
|
||||
totaltable.add_row("Rooms", "(location=None)", nrooms, "%.2f" % ((float(nrooms) / nobjs) * 100))
|
||||
|
|
@ -436,7 +435,7 @@ class CmdObjects(COMMAND_DEFAULT_CLASS):
|
|||
totaltable.add_row("Other", "", nother, "%.2f" % ((float(nother) / nobjs) * 100))
|
||||
|
||||
# typeclass table
|
||||
typetable = EvTable("{wtypeclass{n", "{wcount{n", "{w%%{n", border="table", align="l")
|
||||
typetable = EvTable("|wtypeclass|n", "|wcount|n", "|w%%|n", border="table", align="l")
|
||||
typetable.align = 'l'
|
||||
dbtotals = ObjectDB.objects.object_totals()
|
||||
for path, count in dbtotals.items():
|
||||
|
|
@ -444,15 +443,15 @@ class CmdObjects(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
# last N table
|
||||
objs = ObjectDB.objects.all().order_by("db_date_created")[max(0, nobjs - nlim):]
|
||||
latesttable = EvTable("{wcreated{n", "{wdbref{n", "{wname{n", "{wtypeclass{n", align="l", border="table")
|
||||
latesttable = EvTable("|wcreated|n", "|wdbref|n", "|wname|n", "|wtypeclass|n", align="l", border="table")
|
||||
latesttable.align = 'l'
|
||||
for obj in objs:
|
||||
latesttable.add_row(utils.datetime_format(obj.date_created),
|
||||
obj.dbref, obj.key, obj.path)
|
||||
|
||||
string = "\n{wObject subtype totals (out of %i Objects):{n\n%s" % (nobjs, totaltable)
|
||||
string += "\n{wObject typeclass distribution:{n\n%s" % typetable
|
||||
string += "\n{wLast %s Objects created:{n\n%s" % (min(nobjs, nlim), latesttable)
|
||||
string = "\n|wObject subtype totals (out of %i Objects):|n\n%s" % (nobjs, totaltable)
|
||||
string += "\n|wObject typeclass distribution:|n\n%s" % typetable
|
||||
string += "\n|wLast %s Objects created:|n\n%s" % (min(nobjs, nlim), latesttable)
|
||||
caller.msg(string)
|
||||
|
||||
|
||||
|
|
@ -473,7 +472,7 @@ class CmdPlayers(COMMAND_DEFAULT_CLASS):
|
|||
help_category = "System"
|
||||
|
||||
def func(self):
|
||||
"List the players"
|
||||
"""List the players"""
|
||||
|
||||
caller = self.caller
|
||||
if self.args and self.args.isdigit():
|
||||
|
|
@ -485,17 +484,17 @@ class CmdPlayers(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
# typeclass table
|
||||
dbtotals = PlayerDB.objects.object_totals()
|
||||
typetable = EvTable("{wtypeclass{n", "{wcount{n", "{w%%{n", border="cells", align="l")
|
||||
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))
|
||||
# last N table
|
||||
plyrs = PlayerDB.objects.all().order_by("db_date_created")[max(0, nplayers - nlim):]
|
||||
latesttable = EvTable("{wcreated{n", "{wdbref{n", "{wname{n", "{wtypeclass{n", border="cells", align="l")
|
||||
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|wPlayer typeclass distribution:|n\n%s" % typetable
|
||||
string += "\n|wLast %s Players created:|n\n%s" % (min(nplayers, nlim), latesttable)
|
||||
caller.msg(string)
|
||||
|
||||
|
||||
|
|
@ -525,7 +524,7 @@ class CmdService(COMMAND_DEFAULT_CLASS):
|
|||
help_category = "System"
|
||||
|
||||
def func(self):
|
||||
"Implement command"
|
||||
"""Implement command"""
|
||||
|
||||
caller = self.caller
|
||||
switches = self.switches
|
||||
|
|
@ -540,9 +539,9 @@ class CmdService(COMMAND_DEFAULT_CLASS):
|
|||
if not switches or switches[0] == "list":
|
||||
# Just display the list of installed services and their
|
||||
# status, then exit.
|
||||
table = EvTable("{wService{n (use @services/start|stop|delete)", "{wstatus", align="l")
|
||||
table = EvTable("|wService|n (use @services/start|stop|delete)", "|wstatus", align="l")
|
||||
for service in service_collection.services:
|
||||
table.add_row(service.name, service.running and "{gRunning" or "{rNot Running")
|
||||
table.add_row(service.name, service.running and "|gRunning" or "|rNot Running")
|
||||
caller.msg(unicode(table))
|
||||
return
|
||||
|
||||
|
|
@ -584,7 +583,7 @@ class CmdService(COMMAND_DEFAULT_CLASS):
|
|||
return
|
||||
|
||||
if switches[0] == "start":
|
||||
#Starts a service.
|
||||
# Attempt to start a service.
|
||||
if service.running:
|
||||
caller.msg('That service is already running.')
|
||||
return
|
||||
|
|
@ -608,23 +607,23 @@ class CmdAbout(COMMAND_DEFAULT_CLASS):
|
|||
help_category = "System"
|
||||
|
||||
def func(self):
|
||||
"Show the version"
|
||||
"""Display information about server or target"""
|
||||
|
||||
string = """
|
||||
{cEvennia{n %s{n
|
||||
|cEvennia|n %s|n
|
||||
MUD/MUX/MU* development system
|
||||
|
||||
{wLicence{n BSD 3-Clause Licence
|
||||
{wWeb{n http://www.evennia.com
|
||||
{wIrc{n #evennia on FreeNode
|
||||
{wForum{n http://www.evennia.com/discussions
|
||||
{wMaintainer{n (2010-) Griatch (griatch AT gmail DOT com)
|
||||
{wMaintainer{n (2006-10) Greg Taylor
|
||||
|wLicence|n https://opensource.org/licenses/BSD-3-Clause
|
||||
|wWeb|n http://www.evennia.com
|
||||
|wIrc|n #evennia on FreeNode
|
||||
|wForum|n http://www.evennia.com/discussions
|
||||
|wMaintainer|n (2010-) Griatch (griatch AT gmail DOT com)
|
||||
|wMaintainer|n (2006-10) Greg Taylor
|
||||
|
||||
{wOS{n %s
|
||||
{wPython{n %s
|
||||
{wTwisted{n %s
|
||||
{wDjango{n %s
|
||||
|wOS|n %s
|
||||
|wPython|n %s
|
||||
|wTwisted|n %s
|
||||
|wDjango|n %s
|
||||
""" % (utils.get_evennia_version(),
|
||||
os.name,
|
||||
sys.version.split()[0],
|
||||
|
|
@ -649,8 +648,8 @@ class CmdTime(COMMAND_DEFAULT_CLASS):
|
|||
help_category = "System"
|
||||
|
||||
def func(self):
|
||||
"Show server time data in a table."
|
||||
table1 = EvTable("|wServer time","", align="l", width=78)
|
||||
"""Show server time data in a table."""
|
||||
table1 = EvTable("|wServer time", "", align="l", width=78)
|
||||
table1.add_row("Current uptime", utils.time_format(gametime.uptime(), 3))
|
||||
table1.add_row("Total runtime", utils.time_format(gametime.runtime(), 2))
|
||||
table1.add_row("First start", datetime.datetime.fromtimestamp(gametime.server_epoch()))
|
||||
|
|
@ -682,20 +681,20 @@ class CmdServerLoad(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
Some Important statistics in the table:
|
||||
|
||||
{wServer load{n is an average of processor usage. It's usually
|
||||
|wServer load|n is an average of processor usage. It's usually
|
||||
between 0 (no usage) and 1 (100% usage), but may also be
|
||||
temporarily higher if your computer has multiple CPU cores.
|
||||
|
||||
The {wResident/Virtual memory{n displays the total memory used by
|
||||
The |wResident/Virtual memory|n displays the total memory used by
|
||||
the server process.
|
||||
|
||||
Evennia {wcaches{n all retrieved database entities when they are
|
||||
Evennia |wcaches|n all retrieved database entities when they are
|
||||
loaded by use of the idmapper functionality. This allows Evennia
|
||||
to maintain the same instances of an entity and allowing
|
||||
non-persistent storage schemes. The total amount of cached objects
|
||||
are displayed plus a breakdown of database object types.
|
||||
|
||||
The {wflushmem{n switch allows to flush the object cache. Please
|
||||
The |wflushmem|n switch allows to flush the object cache. Please
|
||||
note that due to how Python's memory management works, releasing
|
||||
caches may not show you a lower Residual/Virtual memory footprint,
|
||||
the released memory will instead be re-used by the program.
|
||||
|
|
@ -707,7 +706,7 @@ class CmdServerLoad(COMMAND_DEFAULT_CLASS):
|
|||
help_category = "System"
|
||||
|
||||
def func(self):
|
||||
"Show list."
|
||||
"""Show list."""
|
||||
|
||||
global _IDMAPPER
|
||||
if not _IDMAPPER:
|
||||
|
|
@ -741,21 +740,21 @@ class CmdServerLoad(COMMAND_DEFAULT_CLASS):
|
|||
if has_psutil:
|
||||
loadavg = psutil.cpu_percent()
|
||||
_mem = psutil.virtual_memory()
|
||||
rmem = _mem.used / (1000.0 * 1000)
|
||||
rmem = _mem.used / (1000.0 * 1000)
|
||||
pmem = _mem.percent
|
||||
|
||||
if "mem" in self.switches:
|
||||
string = "Total computer memory usage: {w%g{n MB (%g%%)"
|
||||
string = "Total computer memory usage: |w%g|n MB (%g%%)"
|
||||
self.caller.msg(string % (rmem, pmem))
|
||||
return
|
||||
# Display table
|
||||
loadtable = EvTable("property", "statistic", align="l")
|
||||
loadtable.add_row("Total CPU load", "%g %%" % loadavg)
|
||||
loadtable.add_row("Total computer memory usage","%g MB (%g%%)" % (rmem, pmem))
|
||||
loadtable.add_row("Total computer memory usage", "%g MB (%g%%)" % (rmem, pmem))
|
||||
loadtable.add_row("Process ID", "%g" % pid),
|
||||
else:
|
||||
loadtable = "Not available on Windows without 'psutil' library " \
|
||||
"(install with {wpip install psutil{n)."
|
||||
"(install with |wpip install psutil|n)."
|
||||
|
||||
else:
|
||||
# Linux / BSD (OSX) - proper pid-based statistics
|
||||
|
|
@ -767,46 +766,49 @@ class CmdServerLoad(COMMAND_DEFAULT_CLASS):
|
|||
loadavg = os.getloadavg()[0]
|
||||
rmem = float(os.popen('ps -p %d -o %s | tail -1' % (pid, "rss")).read()) / 1000.0 # resident memory
|
||||
vmem = float(os.popen('ps -p %d -o %s | tail -1' % (pid, "vsz")).read()) / 1000.0 # virtual memory
|
||||
pmem = float(os.popen('ps -p %d -o %s | tail -1' % (pid, "%mem")).read()) # percent of resident memory to total
|
||||
pmem = float(os.popen('ps -p %d -o %s | tail -1' % (pid, "%mem")).read()) # % of resident memory to total
|
||||
rusage = _RESOURCE.getrusage(_RESOURCE.RUSAGE_SELF)
|
||||
|
||||
if "mem" in self.switches:
|
||||
string = "Memory usage: RMEM: {w%g{n MB (%g%%), " \
|
||||
" VMEM (res+swap+cache): {w%g{n MB."
|
||||
string = "Memory usage: RMEM: |w%g|n MB (%g%%), VMEM (res+swap+cache): |w%g|n MB."
|
||||
self.caller.msg(string % (rmem, pmem, vmem))
|
||||
return
|
||||
|
||||
loadtable = EvTable("property", "statistic", align="l")
|
||||
loadtable.add_row("Server load (1 min)", "%g" % loadavg)
|
||||
loadtable.add_row("Process ID", "%g" % pid),
|
||||
loadtable.add_row("Memory usage","%g MB (%g%%)" % (rmem, pmem))
|
||||
loadtable.add_row("Memory usage", "%g MB (%g%%)" % (rmem, pmem))
|
||||
loadtable.add_row("Virtual address space", "")
|
||||
loadtable.add_row("{x(resident+swap+caching){n", "%g MB" % vmem)
|
||||
loadtable.add_row("CPU time used (total)", "%s (%gs)" % (utils.time_format(rusage.ru_utime), rusage.ru_utime))
|
||||
loadtable.add_row("CPU time used (user)", "%s (%gs)" % (utils.time_format(rusage.ru_stime), rusage.ru_stime))
|
||||
loadtable.add_row("Page faults", "%g hard, %g soft, %g swapouts" % (rusage.ru_majflt, rusage.ru_minflt, rusage.ru_nswap))
|
||||
loadtable.add_row("|x(resident+swap+caching)|n", "%g MB" % vmem)
|
||||
loadtable.add_row("CPU time used (total)", "%s (%gs)"
|
||||
% (utils.time_format(rusage.ru_utime), rusage.ru_utime))
|
||||
loadtable.add_row("CPU time used (user)", "%s (%gs)"
|
||||
% (utils.time_format(rusage.ru_stime), rusage.ru_stime))
|
||||
loadtable.add_row("Page faults", "%g hard, %g soft, %g swapouts"
|
||||
% (rusage.ru_majflt, rusage.ru_minflt, rusage.ru_nswap))
|
||||
loadtable.add_row("Disk I/O", "%g reads, %g writes" % (rusage.ru_inblock, rusage.ru_oublock))
|
||||
loadtable.add_row("Network I/O", "%g in, %g out" % (rusage.ru_msgrcv, rusage.ru_msgsnd))
|
||||
loadtable.add_row("Context switching", "%g vol, %g forced, %g signals" % (rusage.ru_nvcsw, rusage.ru_nivcsw, rusage.ru_nsignals))
|
||||
|
||||
loadtable.add_row("Context switching", "%g vol, %g forced, %g signals"
|
||||
% (rusage.ru_nvcsw, rusage.ru_nivcsw, rusage.ru_nsignals))
|
||||
|
||||
# os-generic
|
||||
|
||||
string = "{wServer CPU and Memory load:{n\n%s" % loadtable
|
||||
string = "|wServer CPU and Memory load:|n\n%s" % loadtable
|
||||
|
||||
# object cache count (note that sys.getsiseof is not called so this works for pypy too.
|
||||
total_num, cachedict = _IDMAPPER.cache_size()
|
||||
sorted_cache = sorted([(key, num) for key, num in cachedict.items() if num > 0],
|
||||
key=lambda tup: tup[1], reverse=True)
|
||||
key=lambda tup: tup[1], reverse=True)
|
||||
memtable = EvTable("entity name", "number", "idmapper %", align="l")
|
||||
for tup in sorted_cache:
|
||||
memtable.add_row(tup[0], "%i" % tup[1], "%.2f" % (float(tup[1]) / total_num * 100))
|
||||
|
||||
string += "\n{w Entity idmapper cache:{n %i items\n%s" % (total_num, memtable)
|
||||
string += "\n|w Entity idmapper cache:|n %i items\n%s" % (total_num, memtable)
|
||||
|
||||
# return to caller
|
||||
self.caller.msg(string)
|
||||
|
||||
|
||||
class CmdTickers(COMMAND_DEFAULT_CLASS):
|
||||
"""
|
||||
View running tickers
|
||||
|
|
@ -832,13 +834,9 @@ class CmdTickers(COMMAND_DEFAULT_CLASS):
|
|||
table = EvTable("interval (s)", "object", "path/methodname", "idstring", "db")
|
||||
for sub in all_subs:
|
||||
table.add_row(sub[3],
|
||||
"%s%s" % (sub[0] or "[None]", sub[0] and " (#%s)" % (sub[0].id if hasattr(sub[0], "id") else "") or ""),
|
||||
"%s%s" % (sub[0] or "[None]",
|
||||
sub[0] and " (#%s)" % (sub[0].id if hasattr(sub[0], "id") else "") or ""),
|
||||
sub[1] if sub[1] else sub[2],
|
||||
sub[4] or "[Unset]",
|
||||
"*" if sub[5] else "-")
|
||||
self.caller.msg("|wActive tickers|n:\n" + unicode(table))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ class CommandTest(EvenniaTest):
|
|||
Tests a command
|
||||
"""
|
||||
|
||||
def call(self, cmdobj, args, msg=None, cmdset=None, noansi=True, caller=None, receiver=None, cmdstring=None):
|
||||
def call(self, cmdobj, args, msg=None, cmdset=None, noansi=True, caller=None, receiver=None, cmdstring=None, obj=None):
|
||||
"""
|
||||
Test a command by assigning all the needed
|
||||
properties to cmdobj and running
|
||||
|
|
@ -48,6 +48,10 @@ class CommandTest(EvenniaTest):
|
|||
cmdobj.at_post_cmd()
|
||||
The msgreturn value is compared to eventual
|
||||
output sent to caller.msg in the game
|
||||
|
||||
Returns:
|
||||
msg (str): The received message that was sent to the caller.
|
||||
|
||||
"""
|
||||
caller = caller if caller else self.char1
|
||||
receiver = receiver if receiver else caller
|
||||
|
|
@ -60,9 +64,10 @@ class CommandTest(EvenniaTest):
|
|||
cmdobj.session = SESSIONS.session_from_sessid(1)
|
||||
cmdobj.player = self.player
|
||||
cmdobj.raw_string = cmdobj.key + " " + args
|
||||
cmdobj.obj = caller if caller else self.char1
|
||||
cmdobj.obj = obj or (caller if caller else self.char1)
|
||||
# test
|
||||
old_msg = receiver.msg
|
||||
returned_msg = ""
|
||||
try:
|
||||
receiver.msg = Mock()
|
||||
cmdobj.at_pre_cmd()
|
||||
|
|
@ -74,18 +79,23 @@ class CommandTest(EvenniaTest):
|
|||
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
|
||||
stored_msg = [smsg[0] if isinstance(smsg, tuple) else smsg for smsg in stored_msg]
|
||||
returned_msg = "||".join(_RE.sub("", mess) for mess in stored_msg)
|
||||
returned_msg = ansi.parse_ansi(returned_msg, strip_ansi=noansi).strip()
|
||||
if msg is not None:
|
||||
returned_msg = "||".join(_RE.sub("", mess) for mess in stored_msg)
|
||||
returned_msg = ansi.parse_ansi(returned_msg, strip_ansi=noansi).strip()
|
||||
if msg == "" and returned_msg or not returned_msg.startswith(msg.strip()):
|
||||
sep1 = "\n" + "="*30 + "Wanted message" + "="*34 + "\n"
|
||||
sep2 = "\n" + "="*30 + "Returned message" + "="*32 + "\n"
|
||||
sep3 = "\n" + "="*78
|
||||
retval = sep1 + msg.strip() + sep2 + returned_msg + sep3
|
||||
raise AssertionError(retval)
|
||||
else:
|
||||
returned_msg = "\n".join(stored_msg)
|
||||
returned_msg = ansi.parse_ansi(returned_msg, strip_ansi=noansi).strip()
|
||||
finally:
|
||||
receiver.msg = old_msg
|
||||
|
||||
return returned_msg
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# Individual module Tests
|
||||
# ------------------------------------------------------------
|
||||
|
|
@ -119,6 +129,9 @@ class TestGeneral(CommandTest):
|
|||
def test_say(self):
|
||||
self.call(general.CmdSay(), "Testing", "You say, \"Testing\"")
|
||||
|
||||
def test_whisper(self):
|
||||
self.call(general.CmdWhisper(), "Obj = Testing", "You whisper to Obj, \"Testing\"")
|
||||
|
||||
def test_access(self):
|
||||
self.call(general.CmdAccess(), "", "Permission Hierarchy (climbing):")
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@ CONNECTION_SCREEN_MODULE = settings.CONNECTION_SCREEN_MODULE
|
|||
# would also block dummyrunner, so it's not added as default.
|
||||
|
||||
_LATEST_FAILED_LOGINS = defaultdict(list)
|
||||
|
||||
|
||||
def _throttle(session, maxlim=None, timeout=None, storage=_LATEST_FAILED_LOGINS):
|
||||
"""
|
||||
This will check the session's address against the
|
||||
|
|
@ -95,8 +97,8 @@ def create_guest_player(session):
|
|||
bans = ServerConfig.objects.conf("server_bans")
|
||||
if bans and any(tup[2].match(session.address) for tup in bans if tup[2]):
|
||||
# this is a banned IP!
|
||||
string = "{rYou have been banned and cannot continue from here." \
|
||||
"\nIf you feel this ban is in error, please email an admin.{x"
|
||||
string = "|rYou have been banned and cannot continue from here." \
|
||||
"\nIf you feel this ban is in error, please email an admin.|x"
|
||||
session.msg(string)
|
||||
session.sessionhandler.disconnect(session, "Good bye! Disconnecting.")
|
||||
return True, None
|
||||
|
|
@ -118,14 +120,11 @@ def create_guest_player(session):
|
|||
permissions = settings.PERMISSION_GUEST_DEFAULT
|
||||
typeclass = settings.BASE_CHARACTER_TYPECLASS
|
||||
ptypeclass = settings.BASE_GUEST_TYPECLASS
|
||||
new_player = _create_player(session, playername, password,
|
||||
permissions, ptypeclass)
|
||||
new_player = _create_player(session, playername, password, permissions, ptypeclass)
|
||||
if new_player:
|
||||
_create_character(session, new_player, typeclass,
|
||||
home, permissions)
|
||||
_create_character(session, new_player, typeclass, home, permissions)
|
||||
return True, new_player
|
||||
|
||||
|
||||
except Exception:
|
||||
# We are in the middle between logged in and -not, so we have
|
||||
# to handle tracebacks ourselves at this point. If we don't,
|
||||
|
|
@ -150,7 +149,7 @@ def create_normal_player(session, name, password):
|
|||
# check for too many login errors too quick.
|
||||
if _throttle(session, maxlim=5, timeout=5*60):
|
||||
# timeout is 5 minutes.
|
||||
session.msg("{RYou made too many connection attempts. Try again in a few minutes.{n")
|
||||
session.msg("|RYou made too many connection attempts. Try again in a few minutes.|n")
|
||||
return None
|
||||
|
||||
# Match account name and check password
|
||||
|
|
@ -167,15 +166,14 @@ def create_normal_player(session, name, password):
|
|||
player.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] == player.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!
|
||||
string = "{rYou have been banned and cannot continue from here." \
|
||||
"\nIf you feel this ban is in error, please email an admin.{x"
|
||||
string = "|rYou have been banned and cannot continue from here." \
|
||||
"\nIf you feel this ban is in error, please email an admin.|x"
|
||||
session.msg(string)
|
||||
session.sessionhandler.disconnect(session, "Good bye! Disconnecting.")
|
||||
return None
|
||||
|
|
@ -213,7 +211,7 @@ class CmdUnconnectedConnect(COMMAND_DEFAULT_CLASS):
|
|||
# check for too many login errors too quick.
|
||||
if _throttle(session, maxlim=5, timeout=5*60, storage=_LATEST_FAILED_LOGINS):
|
||||
# timeout is 5 minutes.
|
||||
session.msg("{RYou made too many connection attempts. Try again in a few minutes.{n")
|
||||
session.msg("|RYou made too many connection attempts. Try again in a few minutes.|n")
|
||||
return
|
||||
|
||||
args = self.args
|
||||
|
|
@ -237,12 +235,6 @@ class CmdUnconnectedConnect(COMMAND_DEFAULT_CLASS):
|
|||
name, password = parts
|
||||
player = create_normal_player(session, name, password)
|
||||
if player:
|
||||
# actually do the login. This will call all other hooks:
|
||||
# session.at_login()
|
||||
# player.at_init() # always called when object is loaded from disk
|
||||
# player.at_first_login() # only once, for player-centric setup
|
||||
# player.at_pre_login()
|
||||
# player.at_post_login(session=session)
|
||||
session.sessionhandler.login(session, player)
|
||||
|
||||
|
||||
|
|
@ -264,7 +256,7 @@ class CmdUnconnectedCreate(COMMAND_DEFAULT_CLASS):
|
|||
arg_regex = r"\s.*?|$"
|
||||
|
||||
def func(self):
|
||||
"Do checks and create account"
|
||||
"""Do checks and create account"""
|
||||
|
||||
session = self.caller
|
||||
args = self.args.strip()
|
||||
|
|
@ -309,12 +301,12 @@ 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] == playername.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!
|
||||
string = "{rYou have been banned and cannot continue from here." \
|
||||
"\nIf you feel this ban is in error, please email an admin.{x"
|
||||
string = "|rYou have been banned and cannot continue from here." \
|
||||
"\nIf you feel this ban is in error, please email an admin.|x"
|
||||
session.msg(string)
|
||||
session.sessionhandler.disconnect(session, "Good bye! Disconnecting.")
|
||||
return
|
||||
|
|
@ -327,8 +319,7 @@ class CmdUnconnectedCreate(COMMAND_DEFAULT_CLASS):
|
|||
if new_player:
|
||||
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_player, typeclass, default_home, permissions)
|
||||
# tell the caller everything went well.
|
||||
string = "A new account '%s' was created. Welcome!"
|
||||
if " " in playername:
|
||||
|
|
@ -361,7 +352,7 @@ class CmdUnconnectedQuit(COMMAND_DEFAULT_CLASS):
|
|||
locks = "cmd:all()"
|
||||
|
||||
def func(self):
|
||||
"Simply close the connection."
|
||||
"""Simply close the connection."""
|
||||
session = self.caller
|
||||
session.sessionhandler.disconnect(session, "Good bye! Disconnecting.")
|
||||
|
||||
|
|
@ -383,7 +374,7 @@ class CmdUnconnectedLook(COMMAND_DEFAULT_CLASS):
|
|||
locks = "cmd:all()"
|
||||
|
||||
def func(self):
|
||||
"Show the connect screen."
|
||||
"""Show the connect screen."""
|
||||
connection_screen = utils.random_string_from_module(CONNECTION_SCREEN_MODULE)
|
||||
if not connection_screen:
|
||||
connection_screen = "No connection screen found. Please contact an admin."
|
||||
|
|
@ -405,25 +396,25 @@ class CmdUnconnectedHelp(COMMAND_DEFAULT_CLASS):
|
|||
locks = "cmd:all()"
|
||||
|
||||
def func(self):
|
||||
"Shows help"
|
||||
"""Shows help"""
|
||||
|
||||
string = \
|
||||
"""
|
||||
You are not yet logged into the game. Commands available at this point:
|
||||
|
||||
{wcreate{n - create a new account
|
||||
{wconnect{n - connect with an existing account
|
||||
{wlook{n - re-show the connection screen
|
||||
{whelp{n - show this help
|
||||
{wencoding{n - change the text encoding to match your client
|
||||
{wscreenreader{n - make the server more suitable for use with screen readers
|
||||
{wquit{n - abort the connection
|
||||
|wcreate|n - create a new account
|
||||
|wconnect|n - connect with an existing account
|
||||
|wlook|n - re-show the connection screen
|
||||
|whelp|n - show this help
|
||||
|wencoding|n - change the text encoding to match your client
|
||||
|wscreenreader|n - make the server more suitable for use with screen readers
|
||||
|wquit|n - abort the connection
|
||||
|
||||
First create an account e.g. with {wcreate Anna c67jHL8p{n
|
||||
(If you have spaces in your name, use double quotes: {wcreate "Anna the Barbarian" c67jHL8p{n
|
||||
Next you can connect to the game: {wconnect Anna c67jHL8p{n
|
||||
First create an account e.g. with |wcreate Anna c67jHL8p|n
|
||||
(If you have spaces in your name, use double quotes: |wcreate "Anna the Barbarian" c67jHL8p|n
|
||||
Next you can connect to the game: |wconnect Anna c67jHL8p|n
|
||||
|
||||
You can use the {wlook{n command if you want to see the connect screen again.
|
||||
You can use the |wlook|n command if you want to see the connect screen again.
|
||||
|
||||
"""
|
||||
self.caller.msg(string)
|
||||
|
|
@ -479,10 +470,10 @@ class CmdUnconnectedEncoding(COMMAND_DEFAULT_CLASS):
|
|||
pencoding = self.session.protocol_flags.get("ENCODING", None)
|
||||
string = ""
|
||||
if pencoding:
|
||||
string += "Default encoding: {g%s{n (change with {w@encoding <encoding>{n)" % pencoding
|
||||
string += "Default encoding: |g%s|n (change with |w@encoding <encoding>|n)" % pencoding
|
||||
encodings = settings.ENCODINGS
|
||||
if encodings:
|
||||
string += "\nServer's alternative encodings (tested in this order):\n {g%s{n" % ", ".join(encodings)
|
||||
string += "\nServer's alternative encodings (tested in this order):\n |g%s|n" % ", ".join(encodings)
|
||||
if not string:
|
||||
string = "No encodings found."
|
||||
else:
|
||||
|
|
@ -492,7 +483,8 @@ class CmdUnconnectedEncoding(COMMAND_DEFAULT_CLASS):
|
|||
try:
|
||||
utils.to_str(utils.to_unicode("test-string"), encoding=encoding)
|
||||
except LookupError:
|
||||
string = "|rThe encoding '|w%s|r' is invalid. Keeping the previous encoding '|w%s|r'.|n" % (encoding, old_encoding)
|
||||
string = "|rThe encoding '|w%s|r' is invalid. Keeping the previous encoding '|w%s|r'.|n"\
|
||||
% (encoding, old_encoding)
|
||||
else:
|
||||
self.session.protocol_flags["ENCODING"] = encoding
|
||||
string = "Your custom text encoding was changed from '|w%s|n' to '|w%s|n'." % (old_encoding, encoding)
|
||||
|
|
@ -501,6 +493,7 @@ class CmdUnconnectedEncoding(COMMAND_DEFAULT_CLASS):
|
|||
self.session.sessionhandler.session_portal_sync(self.session)
|
||||
self.caller.msg(string.strip())
|
||||
|
||||
|
||||
class CmdUnconnectedScreenreader(COMMAND_DEFAULT_CLASS):
|
||||
"""
|
||||
Activate screenreader mode.
|
||||
|
|
@ -515,21 +508,20 @@ class CmdUnconnectedScreenreader(COMMAND_DEFAULT_CLASS):
|
|||
aliases = "@screenreader"
|
||||
|
||||
def func(self):
|
||||
"Flips screenreader setting."
|
||||
"""Flips screenreader setting."""
|
||||
new_setting = not self.session.protocol_flags.get("SCREENREADER", False)
|
||||
self.session.protocol_flags["SCREENREADER"] = new_setting
|
||||
string = "Screenreader mode turned {w%s{n." % ("on" if new_setting else "off")
|
||||
self.session.protocol_flags["SCREENREADER"] = new_setting
|
||||
string = "Screenreader mode turned |w%s|n." % ("on" if new_setting else "off")
|
||||
self.caller.msg(string)
|
||||
self.session.sessionhandler.session_portal_sync(self.session)
|
||||
|
||||
|
||||
def _create_player(session, playername, password, permissions, typeclass=None):
|
||||
def _create_player(session, playername, password, permissions, typeclass=None, email=None):
|
||||
"""
|
||||
Helper function, creates a player of the specified typeclass.
|
||||
"""
|
||||
try:
|
||||
new_player = create.create_player(playername, None, password,
|
||||
permissions=permissions, typeclass=typeclass)
|
||||
new_player = create.create_player(playername, 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)
|
||||
|
|
@ -543,7 +535,7 @@ def _create_player(session, playername, password, permissions, typeclass=None):
|
|||
|
||||
# join the new player to the public channel
|
||||
pchannel = ChannelDB.objects.get_channel(settings.DEFAULT_CHANNELS[0]["key"])
|
||||
if not pchannel.connect(new_player):
|
||||
if not pchannel or not pchannel.connect(new_player):
|
||||
string = "New player '%s' could not connect to public channel!" % new_player.key
|
||||
logger.log_err(string)
|
||||
return new_player
|
||||
|
|
@ -555,8 +547,7 @@ def _create_character(session, new_player, typeclass, home, permissions):
|
|||
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_player.key, home=home, permissions=permissions)
|
||||
# set playable character list
|
||||
new_player.db._playable_characters.append(new_character)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue