Format code with black. Add makefile to run fmt/tests
This commit is contained in:
parent
d00bce9288
commit
c2c7fa311a
299 changed files with 19037 additions and 11611 deletions
|
|
@ -30,9 +30,21 @@ _MAX_NR_CHARACTERS = settings.MAX_NR_CHARACTERS
|
|||
_MULTISESSION_MODE = settings.MULTISESSION_MODE
|
||||
|
||||
# limit symbol import for API
|
||||
__all__ = ("CmdOOCLook", "CmdIC", "CmdOOC", "CmdPassword", "CmdQuit",
|
||||
"CmdCharCreate", "CmdOption", "CmdSessions", "CmdWho",
|
||||
"CmdColorTest", "CmdQuell", "CmdCharDelete", "CmdStyle")
|
||||
__all__ = (
|
||||
"CmdOOCLook",
|
||||
"CmdIC",
|
||||
"CmdOOC",
|
||||
"CmdPassword",
|
||||
"CmdQuit",
|
||||
"CmdCharCreate",
|
||||
"CmdOption",
|
||||
"CmdSessions",
|
||||
"CmdWho",
|
||||
"CmdColorTest",
|
||||
"CmdQuell",
|
||||
"CmdCharDelete",
|
||||
"CmdStyle",
|
||||
)
|
||||
|
||||
|
||||
class MuxAccountLookCommand(COMMAND_DEFAULT_CLASS):
|
||||
|
|
@ -60,8 +72,9 @@ class MuxAccountLookCommand(COMMAND_DEFAULT_CLASS):
|
|||
self.account.db._playable_characters = playable
|
||||
# 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)
|
||||
self.playable = dict((utils.to_str(char.key.lower()), char) for char in playable).get(
|
||||
self.args.lower(), None
|
||||
)
|
||||
else:
|
||||
self.playable = playable
|
||||
|
||||
|
|
@ -119,6 +132,7 @@ class CmdCharCreate(COMMAND_DEFAULT_CLASS):
|
|||
always be able to access your character using lower-case letters
|
||||
if you want.
|
||||
"""
|
||||
|
||||
key = "charcreate"
|
||||
locks = "cmd:pperm(Player)"
|
||||
help_category = "General"
|
||||
|
|
@ -137,12 +151,13 @@ class CmdCharCreate(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
charmax = _MAX_NR_CHARACTERS
|
||||
|
||||
if not account.is_superuser and \
|
||||
(account.db._playable_characters and
|
||||
len(account.db._playable_characters) >= charmax):
|
||||
if not account.is_superuser and (
|
||||
account.db._playable_characters and len(account.db._playable_characters) >= charmax
|
||||
):
|
||||
self.msg("You may only create a maximum of %i characters." % charmax)
|
||||
return
|
||||
from evennia.objects.models import ObjectDB
|
||||
|
||||
typeclass = settings.BASE_CHARACTER_TYPECLASS
|
||||
|
||||
if ObjectDB.objects.filter(db_typeclass_path=typeclass, db_key__iexact=key):
|
||||
|
|
@ -156,21 +171,27 @@ class CmdCharCreate(COMMAND_DEFAULT_CLASS):
|
|||
start_location = ObjectDB.objects.get_id(settings.START_LOCATION)
|
||||
default_home = ObjectDB.objects.get_id(settings.DEFAULT_HOME)
|
||||
permissions = settings.PERMISSION_ACCOUNT_DEFAULT
|
||||
new_character = create.create_object(typeclass, key=key,
|
||||
location=start_location,
|
||||
home=default_home,
|
||||
permissions=permissions)
|
||||
new_character = create.create_object(
|
||||
typeclass, key=key, location=start_location, home=default_home, permissions=permissions
|
||||
)
|
||||
# only allow creator (and developers) to puppet this char
|
||||
new_character.locks.add("puppet:id(%i) or pid(%i) or perm(Developer) or pperm(Developer);delete:id(%i) or perm(Admin)" %
|
||||
(new_character.id, account.id, account.id))
|
||||
new_character.locks.add(
|
||||
"puppet:id(%i) or pid(%i) or perm(Developer) or pperm(Developer);delete:id(%i) or perm(Admin)"
|
||||
% (new_character.id, account.id, account.id)
|
||||
)
|
||||
account.db._playable_characters.append(new_character)
|
||||
if desc:
|
||||
new_character.db.desc = desc
|
||||
elif not new_character.db.desc:
|
||||
new_character.db.desc = "This is a character."
|
||||
self.msg("Created new character %s. Use |wic %s|n to enter the game as this character."
|
||||
% (new_character.key, new_character.key))
|
||||
logger.log_sec('Character Created: %s (Caller: %s, IP: %s).' % (new_character, account, self.session.address))
|
||||
self.msg(
|
||||
"Created new character %s. Use |wic %s|n to enter the game as this character."
|
||||
% (new_character.key, new_character.key)
|
||||
)
|
||||
logger.log_sec(
|
||||
"Character Created: %s (Caller: %s, IP: %s)."
|
||||
% (new_character, account, self.session.address)
|
||||
)
|
||||
|
||||
|
||||
class CmdCharDelete(COMMAND_DEFAULT_CLASS):
|
||||
|
|
@ -182,6 +203,7 @@ class CmdCharDelete(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
Permanently deletes one of your characters.
|
||||
"""
|
||||
|
||||
key = "chardelete"
|
||||
locks = "cmd:pperm(Player)"
|
||||
help_category = "General"
|
||||
|
|
@ -195,13 +217,18 @@ class CmdCharDelete(COMMAND_DEFAULT_CLASS):
|
|||
return
|
||||
|
||||
# use the playable_characters list to search
|
||||
match = [char for char in utils.make_iter(account.db._playable_characters)
|
||||
if char.key.lower() == self.args.lower()]
|
||||
match = [
|
||||
char
|
||||
for char in utils.make_iter(account.db._playable_characters)
|
||||
if char.key.lower() == self.args.lower()
|
||||
]
|
||||
if not match:
|
||||
self.msg("You have no such character to delete.")
|
||||
return
|
||||
elif len(match) > 1:
|
||||
self.msg("Aborting - there are two characters with the same name. Ask an admin to delete the right one.")
|
||||
self.msg(
|
||||
"Aborting - there are two characters with the same name. Ask an admin to delete the right one."
|
||||
)
|
||||
return
|
||||
else: # one match
|
||||
from evennia.utils.evmenu import get_input
|
||||
|
|
@ -211,10 +238,15 @@ class CmdCharDelete(COMMAND_DEFAULT_CLASS):
|
|||
# only take action
|
||||
delobj = caller.ndb._char_to_delete
|
||||
key = delobj.key
|
||||
caller.db._playable_characters = [pc for pc in caller.db._playable_characters if pc != 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)
|
||||
logger.log_sec('Character Deleted: %s (Caller: %s, IP: %s).' % (key, account, self.session.address))
|
||||
logger.log_sec(
|
||||
"Character Deleted: %s (Caller: %s, IP: %s)."
|
||||
% (key, account, self.session.address)
|
||||
)
|
||||
else:
|
||||
self.msg("Deletion was aborted.")
|
||||
del caller.ndb._char_to_delete
|
||||
|
|
@ -223,11 +255,13 @@ class CmdCharDelete(COMMAND_DEFAULT_CLASS):
|
|||
account.ndb._char_to_delete = match
|
||||
|
||||
# Return if caller has no permission to delete this
|
||||
if not match.access(account, 'delete'):
|
||||
if not match.access(account, "delete"):
|
||||
self.msg("You do not have permission to delete this character.")
|
||||
return
|
||||
|
||||
prompt = "|rThis will permanently destroy '%s'. This cannot be undone.|n Continue yes/[no]?"
|
||||
prompt = (
|
||||
"|rThis will permanently destroy '%s'. This cannot be undone.|n Continue yes/[no]?"
|
||||
)
|
||||
get_input(account, prompt % match.key, _callback)
|
||||
|
||||
|
||||
|
|
@ -273,23 +307,33 @@ class CmdIC(COMMAND_DEFAULT_CLASS):
|
|||
return
|
||||
if not new_character:
|
||||
# search for a matching character
|
||||
new_character = [char for char in search.object_search(self.args) if char.access(account, "puppet")]
|
||||
new_character = [
|
||||
char for char in search.object_search(self.args) if char.access(account, "puppet")
|
||||
]
|
||||
if not new_character:
|
||||
self.msg("That is not a valid character choice.")
|
||||
return
|
||||
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]
|
||||
try:
|
||||
account.puppet_object(session, new_character)
|
||||
account.db._last_puppet = new_character
|
||||
logger.log_sec('Puppet Success: (Caller: %s, Target: %s, IP: %s).' % (account, new_character, self.session.address))
|
||||
logger.log_sec(
|
||||
"Puppet Success: (Caller: %s, Target: %s, IP: %s)."
|
||||
% (account, new_character, self.session.address)
|
||||
)
|
||||
except RuntimeError as exc:
|
||||
self.msg("|rYou cannot become |C%s|n: %s" % (new_character.name, exc))
|
||||
logger.log_sec('Puppet Failed: %s (Caller: %s, Target: %s, IP: %s).' % (exc, account, new_character, self.session.address))
|
||||
logger.log_sec(
|
||||
"Puppet Failed: %s (Caller: %s, Target: %s, IP: %s)."
|
||||
% (exc, account, new_character, self.session.address)
|
||||
)
|
||||
|
||||
|
||||
# note that this is inheriting from MuxAccountLookCommand,
|
||||
|
|
@ -354,6 +398,7 @@ class CmdSessions(COMMAND_DEFAULT_CLASS):
|
|||
Lists the sessions currently connected to your account.
|
||||
|
||||
"""
|
||||
|
||||
key = "sessions"
|
||||
locks = "cmd:all()"
|
||||
help_category = "General"
|
||||
|
|
@ -365,17 +410,18 @@ class CmdSessions(COMMAND_DEFAULT_CLASS):
|
|||
"""Implement function"""
|
||||
account = self.account
|
||||
sessions = account.sessions.all()
|
||||
table = self.styled_table("|wsessid",
|
||||
"|wprotocol",
|
||||
"|whost",
|
||||
"|wpuppet/character",
|
||||
"|wlocation")
|
||||
table = self.styled_table(
|
||||
"|wsessid", "|wprotocol", "|whost", "|wpuppet/character", "|wlocation"
|
||||
)
|
||||
for sess in sorted(sessions, key=lambda x: x.sessid):
|
||||
char = account.get_puppet(sess)
|
||||
table.add_row(str(sess.sessid), str(sess.protocol_key),
|
||||
isinstance(sess.address, tuple) and sess.address[0] or sess.address,
|
||||
char and str(char) or "None",
|
||||
char and str(char.location) or "N/A")
|
||||
table.add_row(
|
||||
str(sess.sessid),
|
||||
str(sess.protocol_key),
|
||||
isinstance(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)
|
||||
|
||||
|
||||
|
|
@ -411,19 +457,23 @@ class CmdWho(COMMAND_DEFAULT_CLASS):
|
|||
if self.cmdstring == "doing":
|
||||
show_session_data = False
|
||||
else:
|
||||
show_session_data = account.check_permstring("Developer") or account.check_permstring("Admins")
|
||||
show_session_data = account.check_permstring("Developer") or account.check_permstring(
|
||||
"Admins"
|
||||
)
|
||||
|
||||
naccounts = SESSIONS.account_count()
|
||||
if show_session_data:
|
||||
# privileged info
|
||||
table = self.styled_table("|wAccount Name",
|
||||
"|wOn for",
|
||||
"|wIdle",
|
||||
"|wPuppeting",
|
||||
"|wRoom",
|
||||
"|wCmds",
|
||||
"|wProtocol",
|
||||
"|wHost")
|
||||
table = self.styled_table(
|
||||
"|wAccount Name",
|
||||
"|wOn for",
|
||||
"|wIdle",
|
||||
"|wPuppeting",
|
||||
"|wRoom",
|
||||
"|wCmds",
|
||||
"|wProtocol",
|
||||
"|wHost",
|
||||
)
|
||||
for session in session_list:
|
||||
if not session.logged_in:
|
||||
continue
|
||||
|
|
@ -432,14 +482,16 @@ class CmdWho(COMMAND_DEFAULT_CLASS):
|
|||
account = session.get_account()
|
||||
puppet = session.get_puppet()
|
||||
location = puppet.location.key if puppet and puppet.location else "None"
|
||||
table.add_row(utils.crop(account.get_display_name(account), width=25),
|
||||
utils.time_format(delta_conn, 0),
|
||||
utils.time_format(delta_cmd, 1),
|
||||
utils.crop(puppet.get_display_name(account) 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)
|
||||
table.add_row(
|
||||
utils.crop(account.get_display_name(account), width=25),
|
||||
utils.time_format(delta_conn, 0),
|
||||
utils.time_format(delta_cmd, 1),
|
||||
utils.crop(puppet.get_display_name(account) 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 = self.styled_table("|wAccount name", "|wOn for", "|wIdle")
|
||||
|
|
@ -449,12 +501,16 @@ class CmdWho(COMMAND_DEFAULT_CLASS):
|
|||
delta_cmd = time.time() - session.cmd_last_visible
|
||||
delta_conn = time.time() - session.conn_time
|
||||
account = session.get_account()
|
||||
table.add_row(utils.crop(account.get_display_name(account), width=25),
|
||||
utils.time_format(delta_conn, 0),
|
||||
utils.time_format(delta_cmd, 1))
|
||||
table.add_row(
|
||||
utils.crop(account.get_display_name(account), width=25),
|
||||
utils.time_format(delta_conn, 0),
|
||||
utils.time_format(delta_cmd, 1),
|
||||
)
|
||||
is_one = naccounts == 1
|
||||
self.msg("|wAccounts:|n\n%s\n%s unique account%s logged in."
|
||||
% (table, "One" if is_one else naccounts, "" if is_one else "s"))
|
||||
self.msg(
|
||||
"|wAccounts:|n\n%s\n%s unique account%s logged in."
|
||||
% (table, "One" if is_one else naccounts, "" if is_one else "s")
|
||||
)
|
||||
|
||||
|
||||
class CmdOption(COMMAND_DEFAULT_CLASS):
|
||||
|
|
@ -474,6 +530,7 @@ class CmdOption(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
|
||||
"""
|
||||
|
||||
key = "option"
|
||||
aliases = "options"
|
||||
switch_options = ("save", "clear")
|
||||
|
|
@ -511,14 +568,18 @@ class CmdOption(COMMAND_DEFAULT_CLASS):
|
|||
if len(options["SCREENWIDTH"]) == 1:
|
||||
options["SCREENWIDTH"] = options["SCREENWIDTH"][0]
|
||||
else:
|
||||
options["SCREENWIDTH"] = " \n".join("%s : %s" % (screenid, size)
|
||||
for screenid, size in options["SCREENWIDTH"].items())
|
||||
options["SCREENWIDTH"] = " \n".join(
|
||||
"%s : %s" % (screenid, size)
|
||||
for screenid, size in options["SCREENWIDTH"].items()
|
||||
)
|
||||
if "SCREENHEIGHT" in options:
|
||||
if len(options["SCREENHEIGHT"]) == 1:
|
||||
options["SCREENHEIGHT"] = options["SCREENHEIGHT"][0]
|
||||
else:
|
||||
options["SCREENHEIGHT"] = " \n".join("%s : %s" % (screenid, size)
|
||||
for screenid, size in options["SCREENHEIGHT"].items())
|
||||
options["SCREENHEIGHT"] = " \n".join(
|
||||
"%s : %s" % (screenid, size)
|
||||
for screenid, size in options["SCREENHEIGHT"].items()
|
||||
)
|
||||
options.pop("TTYPE", None)
|
||||
|
||||
header = ("Name", "Value", "Saved") if saved_options else ("Name", "Value")
|
||||
|
|
@ -527,7 +588,9 @@ class CmdOption(COMMAND_DEFAULT_CLASS):
|
|||
row = [key, options[key]]
|
||||
if saved_options:
|
||||
saved = " |YYes|n" if key in saved_options else ""
|
||||
changed = "|y*|n" if key in saved_options and flags[key] != saved_options[key] else ""
|
||||
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))
|
||||
|
|
@ -563,30 +626,35 @@ class CmdOption(COMMAND_DEFAULT_CLASS):
|
|||
self.msg("Option |w%s|n was kept as '|w%s|n'." % (new_name, old_val))
|
||||
else:
|
||||
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))
|
||||
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 as err:
|
||||
self.msg("|rCould not set option |w%s|r:|n %s" % (new_name, err))
|
||||
return False
|
||||
|
||||
validators = {"ANSI": validate_bool,
|
||||
"CLIENTNAME": utils.to_str,
|
||||
"ENCODING": validate_encoding,
|
||||
"MCCP": validate_bool,
|
||||
"NOGOAHEAD": validate_bool,
|
||||
"MXP": validate_bool,
|
||||
"NOCOLOR": validate_bool,
|
||||
"NOPKEEPALIVE": validate_bool,
|
||||
"OOB": validate_bool,
|
||||
"RAW": validate_bool,
|
||||
"SCREENHEIGHT": validate_size,
|
||||
"SCREENWIDTH": validate_size,
|
||||
"SCREENREADER": validate_bool,
|
||||
"TERM": utils.to_str,
|
||||
"UTF-8": validate_bool,
|
||||
"XTERM256": validate_bool,
|
||||
"INPUTDEBUG": validate_bool,
|
||||
"FORCEDENDLINE": validate_bool}
|
||||
validators = {
|
||||
"ANSI": validate_bool,
|
||||
"CLIENTNAME": utils.to_str,
|
||||
"ENCODING": validate_encoding,
|
||||
"MCCP": validate_bool,
|
||||
"NOGOAHEAD": validate_bool,
|
||||
"MXP": validate_bool,
|
||||
"NOCOLOR": validate_bool,
|
||||
"NOPKEEPALIVE": validate_bool,
|
||||
"OOB": validate_bool,
|
||||
"RAW": validate_bool,
|
||||
"SCREENHEIGHT": validate_size,
|
||||
"SCREENWIDTH": validate_size,
|
||||
"SCREENREADER": validate_bool,
|
||||
"TERM": utils.to_str,
|
||||
"UTF-8": validate_bool,
|
||||
"XTERM256": validate_bool,
|
||||
"INPUTDEBUG": validate_bool,
|
||||
"FORCEDENDLINE": validate_bool,
|
||||
}
|
||||
|
||||
name = self.lhs.upper()
|
||||
val = self.rhs.strip()
|
||||
|
|
@ -621,6 +689,7 @@ class CmdPassword(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
Changes your password. Make sure to pick a safe one.
|
||||
"""
|
||||
|
||||
key = "password"
|
||||
locks = "cmd:pperm(Player)"
|
||||
|
||||
|
|
@ -650,7 +719,10 @@ class CmdPassword(COMMAND_DEFAULT_CLASS):
|
|||
account.set_password(newpass)
|
||||
account.save()
|
||||
self.msg("Password changed.")
|
||||
logger.log_sec('Password Changed: %s (Caller: %s, IP: %s).' % (account, account, self.session.address))
|
||||
logger.log_sec(
|
||||
"Password Changed: %s (Caller: %s, IP: %s)."
|
||||
% (account, account, self.session.address)
|
||||
)
|
||||
|
||||
|
||||
class CmdQuit(COMMAND_DEFAULT_CLASS):
|
||||
|
|
@ -666,6 +738,7 @@ class CmdQuit(COMMAND_DEFAULT_CLASS):
|
|||
Gracefully disconnect your current session from the
|
||||
game. Use the /all switch to disconnect from all sessions.
|
||||
"""
|
||||
|
||||
key = "quit"
|
||||
switch_options = ("all",)
|
||||
locks = "cmd:all()"
|
||||
|
|
@ -677,8 +750,10 @@ class CmdQuit(COMMAND_DEFAULT_CLASS):
|
|||
"""hook function"""
|
||||
account = self.account
|
||||
|
||||
if 'all' in self.switches:
|
||||
account.msg("|RQuitting|n all sessions. Hope to see you soon again.", session=self.session)
|
||||
if "all" in self.switches:
|
||||
account.msg(
|
||||
"|RQuitting|n all sessions. Hope to see you soon again.", session=self.session
|
||||
)
|
||||
reason = "quit/all"
|
||||
for session in account.sessions.all():
|
||||
account.disconnect_session_from_account(session, reason)
|
||||
|
|
@ -688,7 +763,10 @@ class CmdQuit(COMMAND_DEFAULT_CLASS):
|
|||
if nsess == 2:
|
||||
account.msg("|RQuitting|n. One session is still connected.", session=self.session)
|
||||
elif nsess > 2:
|
||||
account.msg("|RQuitting|n. %i sessions are still connected." % (nsess - 1), session=self.session)
|
||||
account.msg(
|
||||
"|RQuitting|n. %i sessions are still connected." % (nsess - 1),
|
||||
session=self.session,
|
||||
)
|
||||
else:
|
||||
# we are quitting the last available session
|
||||
account.msg("|RQuitting|n. Hope to see you again, soon.", session=self.session)
|
||||
|
|
@ -708,6 +786,7 @@ class CmdColorTest(COMMAND_DEFAULT_CLASS):
|
|||
standard. No checking is done to determine your client supports
|
||||
color - if not you will see rubbish appear.
|
||||
"""
|
||||
|
||||
key = "color"
|
||||
locks = "cmd:all()"
|
||||
help_category = "General"
|
||||
|
|
@ -719,7 +798,7 @@ class CmdColorTest(COMMAND_DEFAULT_CLASS):
|
|||
# relevant color tags to display. Replace if using another schema.
|
||||
# This command can only show one set of markup.
|
||||
slice_bright_fg = slice(7, 15) # from ANSI_PARSER.ansi_map
|
||||
slice_dark_fg = slice(15, 23) # from ANSI_PARSER.ansi_map
|
||||
slice_dark_fg = slice(15, 23) # from ANSI_PARSER.ansi_map
|
||||
slice_dark_bg = slice(-8, None) # from ANSI_PARSER.ansi_map
|
||||
slice_bright_bg = slice(None, None) # from ANSI_PARSER.ansi_xterm256_bright_bg_map
|
||||
|
||||
|
|
@ -735,8 +814,12 @@ class CmdColorTest(COMMAND_DEFAULT_CLASS):
|
|||
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)])
|
||||
ftable.append(
|
||||
[
|
||||
str(col[irow]).ljust(max_widths[icol]) + " " * extra_space
|
||||
for icol, col in enumerate(table)
|
||||
]
|
||||
)
|
||||
return ftable
|
||||
|
||||
def func(self):
|
||||
|
|
@ -745,26 +828,37 @@ class CmdColorTest(COMMAND_DEFAULT_CLASS):
|
|||
if self.args.startswith("a"):
|
||||
# show ansi 16-color table
|
||||
from evennia.utils import ansi
|
||||
|
||||
ap = ansi.ANSI_PARSER
|
||||
# ansi colors
|
||||
# show all ansi color-related codes
|
||||
bright_fg = ["%s%s|n" % (code, code.replace("|", "||"))
|
||||
for code, _ in ap.ansi_map[self.slice_bright_fg]]
|
||||
dark_fg = ["%s%s|n" % (code, code.replace("|", "||"))
|
||||
for code, _ in ap.ansi_map[self.slice_dark_fg]]
|
||||
dark_bg = ["%s%s|n" % (code.replace("\\", ""), code.replace("|", "||").replace("\\", ""))
|
||||
for code, _ in ap.ansi_map[self.slice_dark_bg]]
|
||||
bright_bg = ["%s%s|n" % (code.replace("\\", ""), code.replace("|", "||").replace("\\", ""))
|
||||
for code, _ in ap.ansi_xterm256_bright_bg_map[self.slice_bright_bg]]
|
||||
bright_fg = [
|
||||
"%s%s|n" % (code, code.replace("|", "||"))
|
||||
for code, _ in ap.ansi_map[self.slice_bright_fg]
|
||||
]
|
||||
dark_fg = [
|
||||
"%s%s|n" % (code, code.replace("|", "||"))
|
||||
for code, _ in ap.ansi_map[self.slice_dark_fg]
|
||||
]
|
||||
dark_bg = [
|
||||
"%s%s|n" % (code.replace("\\", ""), code.replace("|", "||").replace("\\", ""))
|
||||
for code, _ in ap.ansi_map[self.slice_dark_bg]
|
||||
]
|
||||
bright_bg = [
|
||||
"%s%s|n" % (code.replace("\\", ""), code.replace("|", "||").replace("\\", ""))
|
||||
for code, _ in ap.ansi_xterm256_bright_bg_map[self.slice_bright_bg]
|
||||
]
|
||||
dark_fg.extend(["" for _ in range(len(bright_fg) - len(dark_fg))])
|
||||
table = utils.format_table([bright_fg, dark_fg, bright_bg, dark_bg])
|
||||
string = "ANSI colors:"
|
||||
for row in table:
|
||||
string += "\n " + " ".join(row)
|
||||
self.msg(string)
|
||||
self.msg("||X : black. ||/ : return, ||- : tab, ||_ : space, ||* : invert, ||u : underline\n"
|
||||
"To combine background and foreground, add background marker last, e.g. ||r||[B.\n"
|
||||
"Note: bright backgrounds like ||[r requires your client handling Xterm256 colors.")
|
||||
self.msg(
|
||||
"||X : black. ||/ : return, ||- : tab, ||_ : space, ||* : invert, ||u : underline\n"
|
||||
"To combine background and foreground, add background marker last, e.g. ||r||[B.\n"
|
||||
"Note: bright backgrounds like ||[r requires your client handling Xterm256 colors."
|
||||
)
|
||||
|
||||
elif self.args.startswith("x"):
|
||||
# show xterm256 table
|
||||
|
|
@ -775,8 +869,10 @@ 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)
|
||||
|
|
@ -845,24 +941,30 @@ class CmdQuell(COMMAND_DEFAULT_CLASS):
|
|||
def func(self):
|
||||
"""Perform the command"""
|
||||
account = self.account
|
||||
permstr = account.is_superuser and " (superuser)" or "(%s)" % (", ".join(account.permissions.all()))
|
||||
if self.cmdstring in ('unquell', 'unquell'):
|
||||
if not account.attributes.get('_quell'):
|
||||
permstr = (
|
||||
account.is_superuser
|
||||
and " (superuser)"
|
||||
or "(%s)" % (", ".join(account.permissions.all()))
|
||||
)
|
||||
if self.cmdstring in ("unquell", "unquell"):
|
||||
if not account.attributes.get("_quell"):
|
||||
self.msg("Already using normal Account permissions %s." % permstr)
|
||||
else:
|
||||
account.attributes.remove('_quell')
|
||||
account.attributes.remove("_quell")
|
||||
self.msg("Account permissions %s restored." % permstr)
|
||||
else:
|
||||
if account.attributes.get('_quell'):
|
||||
if account.attributes.get("_quell"):
|
||||
self.msg("Already quelling Account %s permissions." % permstr)
|
||||
return
|
||||
account.attributes.add('_quell', True)
|
||||
account.attributes.add("_quell", True)
|
||||
puppet = self.session.puppet
|
||||
if puppet:
|
||||
cpermstr = "(%s)" % ", ".join(puppet.permissions.all())
|
||||
cpermstr = "Quelling to current puppet's permissions %s." % cpermstr
|
||||
cpermstr += "\n(Note: If this is higher than Account permissions %s," \
|
||||
" the lowest of the two will be used.)" % permstr
|
||||
cpermstr += (
|
||||
"\n(Note: If this is higher than Account permissions %s,"
|
||||
" the lowest of the two will be used.)" % permstr
|
||||
)
|
||||
cpermstr += "\nUse unquell to return to normal permission usage."
|
||||
self.msg(cpermstr)
|
||||
else:
|
||||
|
|
@ -884,7 +986,7 @@ class CmdStyle(COMMAND_DEFAULT_CLASS):
|
|||
"""
|
||||
|
||||
key = "style"
|
||||
switch_options = ['clear']
|
||||
switch_options = ["clear"]
|
||||
|
||||
def func(self):
|
||||
if not self.args:
|
||||
|
|
@ -893,11 +995,12 @@ class CmdStyle(COMMAND_DEFAULT_CLASS):
|
|||
self.set()
|
||||
|
||||
def list_styles(self):
|
||||
table = self.styled_table('Option', 'Description', 'Type', 'Value', width=78)
|
||||
table = self.styled_table("Option", "Description", "Type", "Value", width=78)
|
||||
for op_key in self.account.options.options_dict.keys():
|
||||
op_found = self.account.options.get(op_key, return_obj=True)
|
||||
table.add_row(op_key, op_found.description,
|
||||
op_found.__class__.__name__, op_found.display())
|
||||
table.add_row(
|
||||
op_key, op_found.description, op_found.__class__.__name__, op_found.display()
|
||||
)
|
||||
self.msg(str(table))
|
||||
|
||||
def set(self):
|
||||
|
|
@ -906,4 +1009,4 @@ class CmdStyle(COMMAND_DEFAULT_CLASS):
|
|||
except ValueError as e:
|
||||
self.msg(str(e))
|
||||
return
|
||||
self.msg('Style %s set to %s' % (self.lhs, result))
|
||||
self.msg("Style %s set to %s" % (self.lhs, result))
|
||||
|
|
|
|||
|
|
@ -16,8 +16,16 @@ COMMAND_DEFAULT_CLASS = class_from_module(settings.COMMAND_DEFAULT_CLASS)
|
|||
PERMISSION_HIERARCHY = [p.lower() for p in settings.PERMISSION_HIERARCHY]
|
||||
|
||||
# limit members for API inclusion
|
||||
__all__ = ("CmdBoot", "CmdBan", "CmdUnban",
|
||||
"CmdEmit", "CmdNewPassword", "CmdPerm", "CmdWall", "CmdForce")
|
||||
__all__ = (
|
||||
"CmdBoot",
|
||||
"CmdBan",
|
||||
"CmdUnban",
|
||||
"CmdEmit",
|
||||
"CmdNewPassword",
|
||||
"CmdPerm",
|
||||
"CmdWall",
|
||||
"CmdForce",
|
||||
)
|
||||
|
||||
|
||||
class CmdBoot(COMMAND_DEFAULT_CLASS):
|
||||
|
|
@ -49,14 +57,14 @@ class CmdBoot(COMMAND_DEFAULT_CLASS):
|
|||
caller.msg("Usage: boot[/switches] <account> [:reason]")
|
||||
return
|
||||
|
||||
if ':' in args:
|
||||
args, reason = [a.strip() for a in args.split(':', 1)]
|
||||
if ":" in args:
|
||||
args, reason = [a.strip() for a in args.split(":", 1)]
|
||||
else:
|
||||
args, reason = args, ""
|
||||
|
||||
boot_list = []
|
||||
|
||||
if 'sid' in self.switches:
|
||||
if "sid" in self.switches:
|
||||
# Boot a particular session id.
|
||||
sessions = SESSIONS.get_sessions(True)
|
||||
for sess in sessions:
|
||||
|
|
@ -71,8 +79,8 @@ class CmdBoot(COMMAND_DEFAULT_CLASS):
|
|||
caller.msg("Account %s was not found." % args)
|
||||
return
|
||||
pobj = pobj[0]
|
||||
if not pobj.access(caller, 'boot'):
|
||||
string = "You don't have the permission to boot %s." % (pobj.key, )
|
||||
if not pobj.access(caller, "boot"):
|
||||
string = "You don't have the permission to boot %s." % (pobj.key,)
|
||||
caller.msg(string)
|
||||
return
|
||||
# we have a bootable object with a connected user
|
||||
|
|
@ -87,7 +95,7 @@ class CmdBoot(COMMAND_DEFAULT_CLASS):
|
|||
# Carry out the booting of the sessions in the boot list.
|
||||
|
||||
feedback = None
|
||||
if 'quiet' not 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
|
||||
|
|
@ -97,7 +105,10 @@ class CmdBoot(COMMAND_DEFAULT_CLASS):
|
|||
session.account.disconnect_session_from_account(session)
|
||||
|
||||
if pobj and boot_list:
|
||||
logger.log_sec('Booted: %s (Reason: %s, Caller: %s, IP: %s).' % (pobj, reason, caller, self.session.address))
|
||||
logger.log_sec(
|
||||
"Booted: %s (Reason: %s, Caller: %s, IP: %s)."
|
||||
% (pobj, reason, caller, self.session.address)
|
||||
)
|
||||
|
||||
|
||||
# regex matching IP addresses with wildcards, eg. 233.122.4.*
|
||||
|
|
@ -118,9 +129,7 @@ def list_bans(cmd, banlist):
|
|||
|
||||
table = cmd.styled_table("|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])
|
||||
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
|
||||
|
||||
|
||||
|
|
@ -157,6 +166,7 @@ class CmdBan(COMMAND_DEFAULT_CLASS):
|
|||
or region.
|
||||
|
||||
"""
|
||||
|
||||
key = "ban"
|
||||
aliases = ["bans"]
|
||||
locks = "cmd:perm(ban) or perm(Developer)"
|
||||
|
|
@ -175,20 +185,20 @@ class CmdBan(COMMAND_DEFAULT_CLASS):
|
|||
'reason' is any optional info given to the command. Unset
|
||||
values in each tuple is set to the empty string.
|
||||
"""
|
||||
banlist = ServerConfig.objects.conf('server_bans')
|
||||
banlist = ServerConfig.objects.conf("server_bans")
|
||||
if not banlist:
|
||||
banlist = []
|
||||
|
||||
if not self.args or (self.switches and
|
||||
not any(switch in ('ip', 'name')
|
||||
for switch in self.switches)):
|
||||
if not self.args or (
|
||||
self.switches and not any(switch in ("ip", "name") for switch in self.switches)
|
||||
):
|
||||
self.caller.msg(list_bans(self, banlist))
|
||||
return
|
||||
|
||||
now = time.ctime()
|
||||
reason = ""
|
||||
if ':' in self.args:
|
||||
ban, reason = self.args.rsplit(':', 1)
|
||||
if ":" in self.args:
|
||||
ban, reason = self.args.rsplit(":", 1)
|
||||
else:
|
||||
ban = self.args
|
||||
ban = ban.lower()
|
||||
|
|
@ -202,15 +212,18 @@ class CmdBan(COMMAND_DEFAULT_CLASS):
|
|||
typ = "IP"
|
||||
ban = ipban[0]
|
||||
# replace * with regex form and compile it
|
||||
ipregex = ban.replace('.', '\.')
|
||||
ipregex = ipregex.replace('*', '[0-9]{1,3}')
|
||||
ipregex = ban.replace(".", "\.")
|
||||
ipregex = ipregex.replace("*", "[0-9]{1,3}")
|
||||
ipregex = re.compile(r"%s" % ipregex)
|
||||
bantup = ("", ban, ipregex, now, reason)
|
||||
# save updated banlist
|
||||
banlist.append(bantup)
|
||||
ServerConfig.objects.conf('server_bans', banlist)
|
||||
ServerConfig.objects.conf("server_bans", banlist)
|
||||
self.caller.msg("%s-Ban |w%s|n was added." % (typ, ban))
|
||||
logger.log_sec('Banned %s: %s (Caller: %s, IP: %s).' % (typ, ban.strip(), self.caller, self.session.address))
|
||||
logger.log_sec(
|
||||
"Banned %s: %s (Caller: %s, IP: %s)."
|
||||
% (typ, ban.strip(), self.caller, self.session.address)
|
||||
)
|
||||
|
||||
|
||||
class CmdUnban(COMMAND_DEFAULT_CLASS):
|
||||
|
|
@ -226,6 +239,7 @@ class CmdUnban(COMMAND_DEFAULT_CLASS):
|
|||
unban.
|
||||
|
||||
"""
|
||||
|
||||
key = "unban"
|
||||
locks = "cmd:perm(unban) or perm(Developer)"
|
||||
help_category = "Admin"
|
||||
|
|
@ -233,7 +247,7 @@ class CmdUnban(COMMAND_DEFAULT_CLASS):
|
|||
def func(self):
|
||||
"""Implement unbanning"""
|
||||
|
||||
banlist = ServerConfig.objects.conf('server_bans')
|
||||
banlist = ServerConfig.objects.conf("server_bans")
|
||||
|
||||
if not self.args:
|
||||
self.caller.msg(list_bans(self, banlist))
|
||||
|
|
@ -253,11 +267,13 @@ class CmdUnban(COMMAND_DEFAULT_CLASS):
|
|||
# all is ok, clear ban
|
||||
ban = banlist[num - 1]
|
||||
del banlist[num - 1]
|
||||
ServerConfig.objects.conf('server_bans', banlist)
|
||||
ServerConfig.objects.conf("server_bans", banlist)
|
||||
value = " ".join([s for s in ban[:2]])
|
||||
self.caller.msg("Cleared ban %s: %s" %
|
||||
(num, value))
|
||||
logger.log_sec('Unbanned: %s (Caller: %s, IP: %s).' % (value.strip(), self.caller, self.session.address))
|
||||
self.caller.msg("Cleared ban %s: %s" % (num, value))
|
||||
logger.log_sec(
|
||||
"Unbanned: %s (Caller: %s, IP: %s)."
|
||||
% (value.strip(), self.caller, self.session.address)
|
||||
)
|
||||
|
||||
|
||||
class CmdEmit(COMMAND_DEFAULT_CLASS):
|
||||
|
|
@ -280,6 +296,7 @@ class CmdEmit(COMMAND_DEFAULT_CLASS):
|
|||
limited forms of emit, for sending to rooms and
|
||||
to accounts respectively.
|
||||
"""
|
||||
|
||||
key = "emit"
|
||||
aliases = ["pemit", "remit"]
|
||||
switch_options = ("room", "accounts", "contents")
|
||||
|
|
@ -300,15 +317,15 @@ class CmdEmit(COMMAND_DEFAULT_CLASS):
|
|||
caller.msg(string)
|
||||
return
|
||||
|
||||
rooms_only = 'rooms' in self.switches
|
||||
accounts_only = 'accounts' in self.switches
|
||||
send_to_contents = 'contents' in self.switches
|
||||
rooms_only = "rooms" in self.switches
|
||||
accounts_only = "accounts" in self.switches
|
||||
send_to_contents = "contents" in self.switches
|
||||
|
||||
# we check which command was used to force the switches
|
||||
if self.cmdstring == 'remit':
|
||||
if self.cmdstring == "remit":
|
||||
rooms_only = True
|
||||
send_to_contents = True
|
||||
elif self.cmdstring == 'pemit':
|
||||
elif self.cmdstring == "pemit":
|
||||
accounts_only = True
|
||||
|
||||
if not self.rhs:
|
||||
|
|
@ -329,7 +346,7 @@ class CmdEmit(COMMAND_DEFAULT_CLASS):
|
|||
if accounts_only and not obj.has_account:
|
||||
caller.msg("%s has no active account. Ignored." % objname)
|
||||
continue
|
||||
if obj.access(caller, 'tell'):
|
||||
if obj.access(caller, "tell"):
|
||||
obj.msg(message)
|
||||
if send_to_contents and hasattr(obj, "msg_contents"):
|
||||
obj.msg_contents(message)
|
||||
|
|
@ -382,9 +399,10 @@ class CmdNewPassword(COMMAND_DEFAULT_CLASS):
|
|||
account.save()
|
||||
self.msg("%s - new password set to '%s'." % (account.name, newpass))
|
||||
if account.character != caller:
|
||||
account.msg("%s has changed your password to '%s'." % (caller.name,
|
||||
newpass))
|
||||
logger.log_sec('Password Changed: %s (Caller: %s, IP: %s).' % (account, caller, self.session.address))
|
||||
account.msg("%s has changed your password to '%s'." % (caller.name, newpass))
|
||||
logger.log_sec(
|
||||
"Password Changed: %s (Caller: %s, IP: %s)." % (account, caller, self.session.address)
|
||||
)
|
||||
|
||||
|
||||
class CmdPerm(COMMAND_DEFAULT_CLASS):
|
||||
|
|
@ -402,6 +420,7 @@ class CmdPerm(COMMAND_DEFAULT_CLASS):
|
|||
This command sets/clears individual permission strings on an object
|
||||
or account. If no permission is given, list all permissions on <object>.
|
||||
"""
|
||||
|
||||
key = "perm"
|
||||
aliases = "setperm"
|
||||
switch_options = ("del", "account")
|
||||
|
|
@ -420,7 +439,7 @@ class CmdPerm(COMMAND_DEFAULT_CLASS):
|
|||
caller.msg(string)
|
||||
return
|
||||
|
||||
accountmode = 'account' in self.switches or lhs.startswith('*')
|
||||
accountmode = "account" in self.switches or lhs.startswith("*")
|
||||
lhs = lhs.lstrip("*")
|
||||
|
||||
if accountmode:
|
||||
|
|
@ -431,7 +450,7 @@ class CmdPerm(COMMAND_DEFAULT_CLASS):
|
|||
return
|
||||
|
||||
if not rhs:
|
||||
if not obj.access(caller, 'examine'):
|
||||
if not obj.access(caller, "examine"):
|
||||
caller.msg("You are not allowed to examine this object.")
|
||||
return
|
||||
|
||||
|
|
@ -440,9 +459,11 @@ class CmdPerm(COMMAND_DEFAULT_CLASS):
|
|||
string += "<None>"
|
||||
else:
|
||||
string += ", ".join(obj.permissions.all())
|
||||
if (hasattr(obj, 'account') and
|
||||
hasattr(obj.account, 'is_superuser') and
|
||||
obj.account.is_superuser):
|
||||
if (
|
||||
hasattr(obj, "account")
|
||||
and hasattr(obj.account, "is_superuser")
|
||||
and obj.account.is_superuser
|
||||
):
|
||||
string += "\n(... but this object is currently controlled by a SUPERUSER! "
|
||||
string += "All access checks are passed automatically.)"
|
||||
caller.msg(string)
|
||||
|
|
@ -451,22 +472,33 @@ class CmdPerm(COMMAND_DEFAULT_CLASS):
|
|||
# we supplied an argument on the form obj = perm
|
||||
locktype = "edit" if accountmode else "control"
|
||||
if not obj.access(caller, locktype):
|
||||
caller.msg("You are not allowed to edit this %s's permissions."
|
||||
% ("account" if accountmode else "object"))
|
||||
caller.msg(
|
||||
"You are not allowed to edit this %s's permissions."
|
||||
% ("account" if accountmode else "object")
|
||||
)
|
||||
return
|
||||
|
||||
caller_result = []
|
||||
target_result = []
|
||||
if 'del' in switches:
|
||||
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):
|
||||
caller_result.append("\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:
|
||||
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))
|
||||
logger.log_sec('Permissions Deleted: %s, %s (Caller: %s, IP: %s).' % (perm, obj, caller, self.session.address))
|
||||
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)
|
||||
)
|
||||
logger.log_sec(
|
||||
"Permissions Deleted: %s, %s (Caller: %s, IP: %s)."
|
||||
% (perm, obj, caller, self.session.address)
|
||||
)
|
||||
else:
|
||||
# add a new permission
|
||||
permissions = obj.permissions.all()
|
||||
|
|
@ -475,20 +507,32 @@ class CmdPerm(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
# don't allow to set a permission higher in the hierarchy than
|
||||
# the one the caller has (to prevent self-escalation)
|
||||
if (perm.lower() in PERMISSION_HIERARCHY and not
|
||||
obj.locks.check_lockstring(caller, "dummy:perm(%s)" % perm)):
|
||||
caller.msg("You cannot assign a permission higher than the one you have yourself.")
|
||||
if perm.lower() in PERMISSION_HIERARCHY and not obj.locks.check_lockstring(
|
||||
caller, "dummy:perm(%s)" % perm
|
||||
):
|
||||
caller.msg(
|
||||
"You cannot assign a permission higher than the one you have yourself."
|
||||
)
|
||||
return
|
||||
|
||||
if perm in permissions:
|
||||
caller_result.append("\nPermission '%s' is already defined on %s." % (perm, obj.name))
|
||||
caller_result.append(
|
||||
"\nPermission '%s' is already defined on %s." % (perm, obj.name)
|
||||
)
|
||||
else:
|
||||
obj.permissions.add(perm)
|
||||
plystring = "the Account" if accountmode else "the Object/Character"
|
||||
caller_result.append("\nPermission '%s' given to %s (%s)." % (perm, obj.name, plystring))
|
||||
target_result.append("\n%s gives you (%s, %s) the permission '%s'."
|
||||
% (caller.name, obj.name, plystring, perm))
|
||||
logger.log_sec('Permissions Added: %s, %s (Caller: %s, IP: %s).' % (obj, perm, caller, self.session.address))
|
||||
caller_result.append(
|
||||
"\nPermission '%s' given to %s (%s)." % (perm, obj.name, plystring)
|
||||
)
|
||||
target_result.append(
|
||||
"\n%s gives you (%s, %s) the permission '%s'."
|
||||
% (caller.name, obj.name, plystring, perm)
|
||||
)
|
||||
logger.log_sec(
|
||||
"Permissions Added: %s, %s (Caller: %s, IP: %s)."
|
||||
% (obj, perm, caller, self.session.address)
|
||||
)
|
||||
|
||||
caller.msg("".join(caller_result).strip())
|
||||
if target_result:
|
||||
|
|
@ -505,6 +549,7 @@ class CmdWall(COMMAND_DEFAULT_CLASS):
|
|||
Announces a message to all connected sessions
|
||||
including all currently unlogged in.
|
||||
"""
|
||||
|
||||
key = "wall"
|
||||
locks = "cmd:perm(wall) or perm(Admin)"
|
||||
help_category = "Admin"
|
||||
|
|
@ -514,7 +559,7 @@ class CmdWall(COMMAND_DEFAULT_CLASS):
|
|||
if not self.args:
|
||||
self.caller.msg("Usage: wall <message>")
|
||||
return
|
||||
message = "%s shouts \"%s\"" % (self.caller.name, self.args)
|
||||
message = '%s shouts "%s"' % (self.caller.name, self.args)
|
||||
self.msg("Announcing to all connected sessions ...")
|
||||
SESSIONS.announce_all(message)
|
||||
|
||||
|
|
@ -529,6 +574,7 @@ class CmdForce(COMMAND_DEFAULT_CLASS):
|
|||
Example:
|
||||
force bob=get stick
|
||||
"""
|
||||
|
||||
key = "force"
|
||||
locks = "cmd:perm(spawn) or perm(Builder)"
|
||||
help_category = "Building"
|
||||
|
|
|
|||
|
|
@ -84,6 +84,7 @@ print "leaving run ..."
|
|||
# Helper functions
|
||||
# -------------------------------------------------------------
|
||||
|
||||
|
||||
def format_header(caller, entry):
|
||||
"""
|
||||
Formats a header
|
||||
|
|
@ -100,7 +101,7 @@ def format_header(caller, entry):
|
|||
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')
|
||||
header = header.replace("\n", "\\n")
|
||||
|
||||
return header
|
||||
|
||||
|
|
@ -110,7 +111,7 @@ def format_code(entry):
|
|||
Formats the viewing of code and errors
|
||||
"""
|
||||
code = ""
|
||||
for line in entry.split('\n'):
|
||||
for line in entry.split("\n"):
|
||||
code += "\n|G>>>|n %s" % line
|
||||
return code.strip()
|
||||
|
||||
|
|
@ -141,8 +142,7 @@ def batch_code_exec(caller):
|
|||
code = stack[ptr]
|
||||
|
||||
caller.msg(format_header(caller, code))
|
||||
err = BATCHCODE.code_exec(code,
|
||||
extra_environ={"caller": caller}, debug=debug)
|
||||
err = BATCHCODE.code_exec(code, extra_environ={"caller": caller}, debug=debug)
|
||||
if err:
|
||||
caller.msg(format_code(err))
|
||||
return False
|
||||
|
|
@ -185,7 +185,7 @@ def show_curr(caller, showall=False):
|
|||
codeall = entry.strip()
|
||||
string += "|G(hh for help)"
|
||||
if showall:
|
||||
for line in codeall.split('\n'):
|
||||
for line in codeall.split("\n"):
|
||||
string += "\n|G||n %s" % line
|
||||
caller.msg(string)
|
||||
|
||||
|
|
@ -214,6 +214,7 @@ def purge_processor(caller):
|
|||
|
||||
caller.scripts.validate() # this will purge interactive mode
|
||||
|
||||
|
||||
# -------------------------------------------------------------
|
||||
# main access commands
|
||||
# -------------------------------------------------------------
|
||||
|
|
@ -234,6 +235,7 @@ class CmdBatchCommands(_COMMAND_DEFAULT_CLASS):
|
|||
Runs batches of commands from a batch-cmd text file (*.ev).
|
||||
|
||||
"""
|
||||
|
||||
key = "batchcommands"
|
||||
aliases = ["batchcommand", "batchcmd"]
|
||||
switch_options = ("interactive",)
|
||||
|
|
@ -263,8 +265,10 @@ class CmdBatchCommands(_COMMAND_DEFAULT_CLASS):
|
|||
err = "{}\n".format(str(err))
|
||||
else:
|
||||
err = ""
|
||||
string = "%s'%s' could not load. You have to supply python paths " \
|
||||
"from one of the defined batch-file directories\n (%s)."
|
||||
string = (
|
||||
"%s'%s' could not load. You have to supply python paths "
|
||||
"from one of the defined batch-file directories\n (%s)."
|
||||
)
|
||||
caller.msg(string % (err, python_path, ", ".join(settings.BASE_BATCHPROCESS_PATHS)))
|
||||
return
|
||||
if not commands:
|
||||
|
|
@ -282,7 +286,7 @@ class CmdBatchCommands(_COMMAND_DEFAULT_CLASS):
|
|||
caller.ndb.batch_cmdset_backup = list(caller.cmdset.cmdset_stack)
|
||||
caller.cmdset.add(BatchSafeCmdSet)
|
||||
|
||||
if 'inter' in switches or 'interactive' in switches:
|
||||
if "inter" in switches or "interactive" in switches:
|
||||
# Allow more control over how batch file is executed
|
||||
|
||||
# Set interactive state directly
|
||||
|
|
@ -291,9 +295,10 @@ 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():
|
||||
|
|
@ -312,11 +317,13 @@ class CmdBatchCommands(_COMMAND_DEFAULT_CLASS):
|
|||
caller.msg(" |RError from processor: '%s'" % e)
|
||||
purge_processor(caller)
|
||||
|
||||
utils.run_async(_PROCPOOL_BATCHCMD_SOURCE,
|
||||
commands=commands,
|
||||
caller=caller,
|
||||
at_return=callback,
|
||||
at_err=errback)
|
||||
utils.run_async(
|
||||
_PROCPOOL_BATCHCMD_SOURCE,
|
||||
commands=commands,
|
||||
caller=caller,
|
||||
at_return=callback,
|
||||
at_err=errback,
|
||||
)
|
||||
else:
|
||||
# run in-process (might block)
|
||||
for _ in range(len(commands)):
|
||||
|
|
@ -350,6 +357,7 @@ class CmdBatchCode(_COMMAND_DEFAULT_CLASS):
|
|||
Runs batches of commands from a batch-code text file (*.py).
|
||||
|
||||
"""
|
||||
|
||||
key = "batchcode"
|
||||
aliases = ["batchcodes"]
|
||||
switch_options = ("interactive", "debug")
|
||||
|
|
@ -366,7 +374,7 @@ class CmdBatchCode(_COMMAND_DEFAULT_CLASS):
|
|||
caller.msg("Usage: batchcode[/interactive/debug] <path.to.file>")
|
||||
return
|
||||
python_path = self.args
|
||||
debug = 'debug' in self.switches
|
||||
debug = "debug" in self.switches
|
||||
|
||||
# parse indata file
|
||||
try:
|
||||
|
|
@ -379,8 +387,10 @@ class CmdBatchCode(_COMMAND_DEFAULT_CLASS):
|
|||
err = "{}\n".format(str(err))
|
||||
else:
|
||||
err = ""
|
||||
string = "%s'%s' could not load. You have to supply python paths " \
|
||||
"from one of the defined batch-file directories\n (%s)."
|
||||
string = (
|
||||
"%s'%s' could not load. You have to supply python paths "
|
||||
"from one of the defined batch-file directories\n (%s)."
|
||||
)
|
||||
caller.msg(string % (err, python_path, ", ".join(settings.BASE_BATCHPROCESS_PATHS)))
|
||||
return
|
||||
if not codes:
|
||||
|
|
@ -399,7 +409,7 @@ class CmdBatchCode(_COMMAND_DEFAULT_CLASS):
|
|||
caller.ndb.batch_cmdset_backup = list(caller.cmdset.cmdset_stack)
|
||||
caller.cmdset.add(BatchSafeCmdSet)
|
||||
|
||||
if 'inter' in switches or 'interactive'in switches:
|
||||
if "inter" in switches or "interactive" in switches:
|
||||
# Allow more control over how batch file is executed
|
||||
|
||||
# Set interactive state directly
|
||||
|
|
@ -425,11 +435,14 @@ class CmdBatchCode(_COMMAND_DEFAULT_CLASS):
|
|||
def errback(e):
|
||||
caller.msg(" |RError from processor: '%s'" % e)
|
||||
purge_processor(caller)
|
||||
utils.run_async(_PROCPOOL_BATCHCODE_SOURCE,
|
||||
codes=codes,
|
||||
caller=caller,
|
||||
at_return=callback,
|
||||
at_err=errback)
|
||||
|
||||
utils.run_async(
|
||||
_PROCPOOL_BATCHCODE_SOURCE,
|
||||
codes=codes,
|
||||
caller=caller,
|
||||
at_return=callback,
|
||||
at_err=errback,
|
||||
)
|
||||
else:
|
||||
# un in-process (will block)
|
||||
for _ in range(len(codes)):
|
||||
|
|
@ -449,6 +462,7 @@ class CmdBatchCode(_COMMAND_DEFAULT_CLASS):
|
|||
# (these are the same for both processors)
|
||||
# -------------------------------------------------------------
|
||||
|
||||
|
||||
class CmdStateAbort(_COMMAND_DEFAULT_CLASS):
|
||||
"""
|
||||
abort
|
||||
|
|
@ -457,6 +471,7 @@ class CmdStateAbort(_COMMAND_DEFAULT_CLASS):
|
|||
the default cmdset, regardless of what current cmdset the processor might
|
||||
have put us in (e.g. when testing buggy scripts etc).
|
||||
"""
|
||||
|
||||
key = "abort"
|
||||
help_category = "BatchProcess"
|
||||
locks = "cmd:perm(batchcommands)"
|
||||
|
|
@ -474,6 +489,7 @@ class CmdStateLL(_COMMAND_DEFAULT_CLASS):
|
|||
Look at the full source for the current
|
||||
command definition.
|
||||
"""
|
||||
|
||||
key = "ll"
|
||||
help_category = "BatchProcess"
|
||||
locks = "cmd:perm(batchcommands)"
|
||||
|
|
@ -488,6 +504,7 @@ class CmdStatePP(_COMMAND_DEFAULT_CLASS):
|
|||
|
||||
Process the currently shown command definition.
|
||||
"""
|
||||
|
||||
key = "pp"
|
||||
help_category = "BatchProcess"
|
||||
locks = "cmd:perm(batchcommands)"
|
||||
|
|
@ -510,6 +527,7 @@ class CmdStateRR(_COMMAND_DEFAULT_CLASS):
|
|||
Reload the batch file, keeping the current
|
||||
position in it.
|
||||
"""
|
||||
|
||||
key = "rr"
|
||||
help_category = "BatchProcess"
|
||||
locks = "cmd:perm(batchcommands)"
|
||||
|
|
@ -532,6 +550,7 @@ class CmdStateRRR(_COMMAND_DEFAULT_CLASS):
|
|||
Reload the batch file, starting over
|
||||
from the beginning.
|
||||
"""
|
||||
|
||||
key = "rrr"
|
||||
help_category = "BatchProcess"
|
||||
locks = "cmd:perm(batchcommands)"
|
||||
|
|
@ -553,6 +572,7 @@ class CmdStateNN(_COMMAND_DEFAULT_CLASS):
|
|||
|
||||
Go to next command. No commands are executed.
|
||||
"""
|
||||
|
||||
key = "nn"
|
||||
help_category = "BatchProcess"
|
||||
locks = "cmd:perm(batchcommands)"
|
||||
|
|
@ -575,6 +595,7 @@ class CmdStateNL(_COMMAND_DEFAULT_CLASS):
|
|||
Go to next command, viewing its full source.
|
||||
No commands are executed.
|
||||
"""
|
||||
|
||||
key = "nl"
|
||||
help_category = "BatchProcess"
|
||||
locks = "cmd:perm(batchcommands)"
|
||||
|
|
@ -597,6 +618,7 @@ class CmdStateBB(_COMMAND_DEFAULT_CLASS):
|
|||
Backwards to previous command. No commands
|
||||
are executed.
|
||||
"""
|
||||
|
||||
key = "bb"
|
||||
help_category = "BatchProcess"
|
||||
locks = "cmd:perm(batchcommands)"
|
||||
|
|
@ -619,6 +641,7 @@ class CmdStateBL(_COMMAND_DEFAULT_CLASS):
|
|||
Backwards to previous command, viewing its full
|
||||
source. No commands are executed.
|
||||
"""
|
||||
|
||||
key = "bl"
|
||||
help_category = "BatchProcess"
|
||||
locks = "cmd:perm(batchcommands)"
|
||||
|
|
@ -642,6 +665,7 @@ class CmdStateSS(_COMMAND_DEFAULT_CLASS):
|
|||
one. If steps is given,
|
||||
process this many commands.
|
||||
"""
|
||||
|
||||
key = "ss"
|
||||
help_category = "BatchProcess"
|
||||
locks = "cmd:perm(batchcommands)"
|
||||
|
|
@ -671,6 +695,7 @@ class CmdStateSL(_COMMAND_DEFAULT_CLASS):
|
|||
one, viewing its full source. If steps is given,
|
||||
process this many commands.
|
||||
"""
|
||||
|
||||
key = "sl"
|
||||
help_category = "BatchProcess"
|
||||
locks = "cmd:perm(batchcommands)"
|
||||
|
|
@ -699,6 +724,7 @@ class CmdStateCC(_COMMAND_DEFAULT_CLASS):
|
|||
Continue to process all remaining
|
||||
commands.
|
||||
"""
|
||||
|
||||
key = "cc"
|
||||
help_category = "BatchProcess"
|
||||
locks = "cmd:perm(batchcommands)"
|
||||
|
|
@ -727,6 +753,7 @@ class CmdStateJJ(_COMMAND_DEFAULT_CLASS):
|
|||
|
||||
Jump to specific command number
|
||||
"""
|
||||
|
||||
key = "jj"
|
||||
help_category = "BatchProcess"
|
||||
locks = "cmd:perm(batchcommands)"
|
||||
|
|
@ -751,6 +778,7 @@ class CmdStateJL(_COMMAND_DEFAULT_CLASS):
|
|||
|
||||
Jump to specific command number and view its full source.
|
||||
"""
|
||||
|
||||
key = "jl"
|
||||
help_category = "BatchProcess"
|
||||
locks = "cmd:perm(batchcommands)"
|
||||
|
|
@ -775,6 +803,7 @@ class CmdStateQQ(_COMMAND_DEFAULT_CLASS):
|
|||
|
||||
Quit the batchprocessor.
|
||||
"""
|
||||
|
||||
key = "qq"
|
||||
help_category = "BatchProcess"
|
||||
locks = "cmd:perm(batchcommands)"
|
||||
|
|
@ -827,12 +856,14 @@ class CmdStateHH(_COMMAND_DEFAULT_CLASS):
|
|||
#
|
||||
# -------------------------------------------------------------
|
||||
|
||||
|
||||
class BatchSafeCmdSet(CmdSet):
|
||||
"""
|
||||
The base cmdset for the batch processor.
|
||||
This sets a 'safe' abort command that will
|
||||
always be available to get out of everything.
|
||||
"""
|
||||
|
||||
key = "Batch_default"
|
||||
priority = 150 # override other cmdsets.
|
||||
|
||||
|
|
@ -845,6 +876,7 @@ class BatchInteractiveCmdSet(CmdSet):
|
|||
"""
|
||||
The cmdset for the interactive batch processor mode.
|
||||
"""
|
||||
|
||||
key = "Batch_interactive"
|
||||
priority = 104
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -14,6 +14,7 @@ class CharacterCmdSet(CmdSet):
|
|||
"""
|
||||
Implements the default command set.
|
||||
"""
|
||||
|
||||
key = "DefaultCharacter"
|
||||
priority = 0
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ class SessionCmdSet(CmdSet):
|
|||
"""
|
||||
Sets up the unlogged cmdset.
|
||||
"""
|
||||
|
||||
key = "DefaultSession"
|
||||
priority = -20
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ class UnloggedinCmdSet(CmdSet):
|
|||
"""
|
||||
Sets up the unlogged cmdset.
|
||||
"""
|
||||
|
||||
key = "DefaultUnloggedin"
|
||||
priority = 0
|
||||
|
||||
|
|
|
|||
|
|
@ -23,10 +23,22 @@ CHANNEL_DEFAULT_TYPECLASS = class_from_module(settings.BASE_CHANNEL_TYPECLASS)
|
|||
|
||||
|
||||
# limit symbol import for API
|
||||
__all__ = ("CmdAddCom", "CmdDelCom", "CmdAllCom",
|
||||
"CmdChannels", "CmdCdestroy", "CmdCBoot", "CmdCemit",
|
||||
"CmdCWho", "CmdChannelCreate", "CmdClock", "CmdCdesc",
|
||||
"CmdPage", "CmdIRC2Chan", "CmdRSS2Chan")
|
||||
__all__ = (
|
||||
"CmdAddCom",
|
||||
"CmdDelCom",
|
||||
"CmdAllCom",
|
||||
"CmdChannels",
|
||||
"CmdCdestroy",
|
||||
"CmdCBoot",
|
||||
"CmdCemit",
|
||||
"CmdCWho",
|
||||
"CmdChannelCreate",
|
||||
"CmdClock",
|
||||
"CmdCdesc",
|
||||
"CmdPage",
|
||||
"CmdIRC2Chan",
|
||||
"CmdRSS2Chan",
|
||||
)
|
||||
_DEFAULT_WIDTH = settings.CLIENT_DEFAULT_WIDTH
|
||||
|
||||
|
||||
|
|
@ -38,8 +50,11 @@ def find_channel(caller, channelname, silent=False, noaliases=False):
|
|||
channels = CHANNEL_DEFAULT_TYPECLASS.objects.channel_search(channelname)
|
||||
if not channels:
|
||||
if not noaliases:
|
||||
channels = [chan for chan in CHANNEL_DEFAULT_TYPECLASS.objects.get_all_channels()
|
||||
if channelname in chan.aliases.all()]
|
||||
channels = [
|
||||
chan
|
||||
for chan in CHANNEL_DEFAULT_TYPECLASS.objects.get_all_channels()
|
||||
if channelname in chan.aliases.all()
|
||||
]
|
||||
if channels:
|
||||
return channels[0]
|
||||
if not silent:
|
||||
|
|
@ -99,7 +114,7 @@ class CmdAddCom(COMMAND_DEFAULT_CLASS):
|
|||
return
|
||||
|
||||
# check permissions
|
||||
if not channel.access(account, 'listen'):
|
||||
if not channel.access(account, "listen"):
|
||||
self.msg("%s: You are not allowed to listen to this channel." % channel.key)
|
||||
return
|
||||
|
||||
|
|
@ -171,8 +186,11 @@ class CmdDelCom(COMMAND_DEFAULT_CLASS):
|
|||
delnicks = "all" in self.switches
|
||||
# find all nicks linked to this channel and delete them
|
||||
if delnicks:
|
||||
for nick in [nick for nick in make_iter(caller.nicks.get(category="channel", return_obj=True))
|
||||
if nick and nick.pk and nick.value[3].lower() == chkey]:
|
||||
for nick in [
|
||||
nick
|
||||
for nick in make_iter(caller.nicks.get(category="channel", return_obj=True))
|
||||
if nick and nick.pk and nick.value[3].lower() == chkey
|
||||
]:
|
||||
nick.delete()
|
||||
disconnect = channel.disconnect(account)
|
||||
if disconnect:
|
||||
|
|
@ -227,8 +245,11 @@ class CmdAllCom(COMMAND_DEFAULT_CLASS):
|
|||
if args == "on":
|
||||
# get names of all channels available to listen to
|
||||
# and activate them all
|
||||
channels = [chan for chan in CHANNEL_DEFAULT_TYPECLASS.objects.get_all_channels()
|
||||
if chan.access(caller, 'listen')]
|
||||
channels = [
|
||||
chan
|
||||
for chan in CHANNEL_DEFAULT_TYPECLASS.objects.get_all_channels()
|
||||
if chan.access(caller, "listen")
|
||||
]
|
||||
for channel in channels:
|
||||
self.execute_cmd("addcom %s" % channel.key)
|
||||
elif args == "off":
|
||||
|
|
@ -238,15 +259,21 @@ class CmdAllCom(COMMAND_DEFAULT_CLASS):
|
|||
self.execute_cmd("delcom %s" % channel.key)
|
||||
elif args == "destroy":
|
||||
# destroy all channels you control
|
||||
channels = [chan for chan in CHANNEL_DEFAULT_TYPECLASS.objects.get_all_channels()
|
||||
if chan.access(caller, 'control')]
|
||||
channels = [
|
||||
chan
|
||||
for chan in CHANNEL_DEFAULT_TYPECLASS.objects.get_all_channels()
|
||||
if chan.access(caller, "control")
|
||||
]
|
||||
for channel in channels:
|
||||
self.execute_cmd("cdestroy %s" % channel.key)
|
||||
elif args == "who":
|
||||
# run a who, listing the subscribers on visible channels.
|
||||
string = "\n|CChannel subscriptions|n"
|
||||
channels = [chan for chan in CHANNEL_DEFAULT_TYPECLASS.objects.get_all_channels()
|
||||
if chan.access(caller, 'listen')]
|
||||
channels = [
|
||||
chan
|
||||
for chan in CHANNEL_DEFAULT_TYPECLASS.objects.get_all_channels()
|
||||
if chan.access(caller, "listen")
|
||||
]
|
||||
if not channels:
|
||||
string += "No channels."
|
||||
for channel in channels:
|
||||
|
|
@ -270,6 +297,7 @@ class CmdChannels(COMMAND_DEFAULT_CLASS):
|
|||
Use 'comlist' to only view your current channel subscriptions.
|
||||
Use addcom/delcom to join and leave channels
|
||||
"""
|
||||
|
||||
key = "channels"
|
||||
aliases = ["clist", "comlist", "chanlist", "channellist", "all channels"]
|
||||
help_category = "Comms"
|
||||
|
|
@ -284,8 +312,11 @@ class CmdChannels(COMMAND_DEFAULT_CLASS):
|
|||
caller = self.caller
|
||||
|
||||
# all channels we have available to listen to
|
||||
channels = [chan for chan in CHANNEL_DEFAULT_TYPECLASS.objects.get_all_channels()
|
||||
if chan.access(caller, 'listen')]
|
||||
channels = [
|
||||
chan
|
||||
for chan in CHANNEL_DEFAULT_TYPECLASS.objects.get_all_channels()
|
||||
if chan.access(caller, "listen")
|
||||
]
|
||||
if not channels:
|
||||
self.msg("No channels available.")
|
||||
return
|
||||
|
|
@ -294,22 +325,46 @@ class CmdChannels(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
if self.cmdstring == "comlist":
|
||||
# just display the subscribed channels with no extra info
|
||||
comtable = self.styled_table("|wchannel|n", "|wmy aliases|n",
|
||||
"|wdescription|n", align="l", maxwidth=_DEFAULT_WIDTH)
|
||||
comtable = self.styled_table(
|
||||
"|wchannel|n",
|
||||
"|wmy aliases|n",
|
||||
"|wdescription|n",
|
||||
align="l",
|
||||
maxwidth=_DEFAULT_WIDTH,
|
||||
)
|
||||
for chan in subs:
|
||||
clower = chan.key.lower()
|
||||
nicks = caller.nicks.get(category="channel", return_obj=True)
|
||||
comtable.add_row(*["%s%s" % (chan.key, chan.aliases.all() and
|
||||
"(%s)" % ",".join(chan.aliases.all()) or ""),
|
||||
"%s" % ",".join(nick.db_key for nick in make_iter(nicks)
|
||||
if nick and nick.value[3].lower() == clower),
|
||||
chan.db.desc])
|
||||
self.msg("\n|wChannel subscriptions|n (use |wchannels|n to list all,"
|
||||
" |waddcom|n/|wdelcom|n to sub/unsub):|n\n%s" % comtable)
|
||||
comtable.add_row(
|
||||
*[
|
||||
"%s%s"
|
||||
% (
|
||||
chan.key,
|
||||
chan.aliases.all() and "(%s)" % ",".join(chan.aliases.all()) or "",
|
||||
),
|
||||
"%s"
|
||||
% ",".join(
|
||||
nick.db_key
|
||||
for nick in make_iter(nicks)
|
||||
if nick and nick.value[3].lower() == clower
|
||||
),
|
||||
chan.db.desc,
|
||||
]
|
||||
)
|
||||
self.msg(
|
||||
"\n|wChannel subscriptions|n (use |wchannels|n to list all,"
|
||||
" |waddcom|n/|wdelcom|n to sub/unsub):|n\n%s" % comtable
|
||||
)
|
||||
else:
|
||||
# full listing (of channels caller is able to listen to)
|
||||
comtable = self.styled_table("|wsub|n", "|wchannel|n", "|wmy aliases|n",
|
||||
"|wlocks|n", "|wdescription|n", maxwidth=_DEFAULT_WIDTH)
|
||||
comtable = self.styled_table(
|
||||
"|wsub|n",
|
||||
"|wchannel|n",
|
||||
"|wmy aliases|n",
|
||||
"|wlocks|n",
|
||||
"|wdescription|n",
|
||||
maxwidth=_DEFAULT_WIDTH,
|
||||
)
|
||||
for chan in channels:
|
||||
clower = chan.key.lower()
|
||||
nicks = caller.nicks.get(category="channel", return_obj=True)
|
||||
|
|
@ -320,17 +375,30 @@ class CmdChannels(COMMAND_DEFAULT_CLASS):
|
|||
substatus = "|rMuted|n"
|
||||
else:
|
||||
substatus = "|gYes|n"
|
||||
comtable.add_row(*[substatus,
|
||||
"%s%s" % (chan.key, chan.aliases.all() and
|
||||
"(%s)" % ",".join(chan.aliases.all()) or ""),
|
||||
"%s" % ",".join(nick.db_key for nick in make_iter(nicks)
|
||||
if nick.value[3].lower() == clower),
|
||||
str(chan.locks),
|
||||
chan.db.desc])
|
||||
comtable.add_row(
|
||||
*[
|
||||
substatus,
|
||||
"%s%s"
|
||||
% (
|
||||
chan.key,
|
||||
chan.aliases.all() and "(%s)" % ",".join(chan.aliases.all()) or "",
|
||||
),
|
||||
"%s"
|
||||
% ",".join(
|
||||
nick.db_key
|
||||
for nick in make_iter(nicks)
|
||||
if nick.value[3].lower() == clower
|
||||
),
|
||||
str(chan.locks),
|
||||
chan.db.desc,
|
||||
]
|
||||
)
|
||||
comtable.reformat_column(0, width=9)
|
||||
comtable.reformat_column(3, width=14)
|
||||
self.msg("\n|wAvailable channels|n (use |wcomlist|n,|waddcom|n and |wdelcom|n"
|
||||
" to manage subscriptions):\n%s" % comtable)
|
||||
self.msg(
|
||||
"\n|wAvailable channels|n (use |wcomlist|n,|waddcom|n and |wdelcom|n"
|
||||
" to manage subscriptions):\n%s" % comtable
|
||||
)
|
||||
|
||||
|
||||
class CmdCdestroy(COMMAND_DEFAULT_CLASS):
|
||||
|
|
@ -361,7 +429,7 @@ class CmdCdestroy(COMMAND_DEFAULT_CLASS):
|
|||
if not channel:
|
||||
self.msg("Could not find channel %s." % self.args)
|
||||
return
|
||||
if not channel.access(caller, 'control'):
|
||||
if not channel.access(caller, "control"):
|
||||
self.msg("You are not allowed to do that.")
|
||||
return
|
||||
channel_key = channel.key
|
||||
|
|
@ -371,7 +439,10 @@ class CmdCdestroy(COMMAND_DEFAULT_CLASS):
|
|||
channel.delete()
|
||||
CHANNELHANDLER.update()
|
||||
self.msg("Channel '%s' was destroyed." % channel_key)
|
||||
logger.log_sec('Channel Deleted: %s (Caller: %s, IP: %s).' % (channel_key, caller, self.session.address))
|
||||
logger.log_sec(
|
||||
"Channel Deleted: %s (Caller: %s, IP: %s)."
|
||||
% (channel_key, caller, self.session.address)
|
||||
)
|
||||
|
||||
|
||||
class CmdCBoot(COMMAND_DEFAULT_CLASS):
|
||||
|
|
@ -410,9 +481,9 @@ class CmdCBoot(COMMAND_DEFAULT_CLASS):
|
|||
reason = ""
|
||||
if ":" in self.rhs:
|
||||
accountname, reason = self.rhs.rsplit(":", 1)
|
||||
searchstring = accountname.lstrip('*')
|
||||
searchstring = accountname.lstrip("*")
|
||||
else:
|
||||
searchstring = self.rhs.lstrip('*')
|
||||
searchstring = self.rhs.lstrip("*")
|
||||
account = self.caller.search(searchstring, account=True)
|
||||
if not account:
|
||||
return
|
||||
|
|
@ -430,15 +501,19 @@ class CmdCBoot(COMMAND_DEFAULT_CLASS):
|
|||
string = "%s boots %s from channel.%s" % (self.caller, account.key, reason)
|
||||
channel.msg(string)
|
||||
# find all account's nicks linked to this channel and delete them
|
||||
for nick in [nick for nick in
|
||||
account.character.nicks.get(category="channel") or []
|
||||
if nick.value[3].lower() == channel.key]:
|
||||
for nick in [
|
||||
nick
|
||||
for nick in account.character.nicks.get(category="channel") or []
|
||||
if nick.value[3].lower() == channel.key
|
||||
]:
|
||||
nick.delete()
|
||||
# disconnect account
|
||||
channel.disconnect(account)
|
||||
CHANNELHANDLER.update()
|
||||
logger.log_sec('Channel Boot: %s (Channel: %s, Reason: %s, Caller: %s, IP: %s).' % (
|
||||
account, channel, reason, self.caller, self.session.address))
|
||||
logger.log_sec(
|
||||
"Channel Boot: %s (Channel: %s, Reason: %s, Caller: %s, IP: %s)."
|
||||
% (account, channel, reason, self.caller, self.session.address)
|
||||
)
|
||||
|
||||
|
||||
class CmdCemit(COMMAND_DEFAULT_CLASS):
|
||||
|
|
@ -499,6 +574,7 @@ class CmdCWho(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
List who is connected to a given channel you have access to.
|
||||
"""
|
||||
|
||||
key = "cwho"
|
||||
locks = "cmd: not pperm(channel_banned)"
|
||||
help_category = "Comms"
|
||||
|
|
@ -560,19 +636,16 @@ class CmdChannelCreate(COMMAND_DEFAULT_CLASS):
|
|||
lhs = self.lhs
|
||||
channame = lhs
|
||||
aliases = None
|
||||
if ';' in lhs:
|
||||
channame, aliases = lhs.split(';', 1)
|
||||
aliases = [alias.strip().lower() for alias in aliases.split(';')]
|
||||
if ";" in lhs:
|
||||
channame, aliases = lhs.split(";", 1)
|
||||
aliases = [alias.strip().lower() for alias in aliases.split(";")]
|
||||
channel = CHANNEL_DEFAULT_TYPECLASS.objects.channel_search(channame)
|
||||
if channel:
|
||||
self.msg("A channel with that name already exists.")
|
||||
return
|
||||
# Create and set the channel up
|
||||
lockstring = "send:all();listen:all();control:id(%s)" % caller.id
|
||||
new_chan = create.create_channel(channame.strip(),
|
||||
aliases,
|
||||
description,
|
||||
locks=lockstring)
|
||||
new_chan = create.create_channel(channame.strip(), aliases, description, locks=lockstring)
|
||||
new_chan.connect(caller)
|
||||
CHANNELHANDLER.update()
|
||||
self.msg("Created channel %s and connected to it." % new_chan.key)
|
||||
|
|
@ -662,14 +735,13 @@ class CmdCdesc(COMMAND_DEFAULT_CLASS):
|
|||
self.msg("Channel '%s' not found." % self.lhs)
|
||||
return
|
||||
# check permissions
|
||||
if not channel.access(caller, 'control'):
|
||||
if not channel.access(caller, "control"):
|
||||
self.msg("You cannot admin this channel.")
|
||||
return
|
||||
# set the description
|
||||
channel.db.desc = self.rhs
|
||||
channel.save()
|
||||
self.msg("Description of channel '%s' set to '%s'." % (channel.key,
|
||||
self.rhs))
|
||||
self.msg("Description of channel '%s' set to '%s'." % (channel.key, self.rhs))
|
||||
|
||||
|
||||
class CmdPage(COMMAND_DEFAULT_CLASS):
|
||||
|
|
@ -690,7 +762,7 @@ class CmdPage(COMMAND_DEFAULT_CLASS):
|
|||
"""
|
||||
|
||||
key = "page"
|
||||
aliases = ['tell']
|
||||
aliases = ["tell"]
|
||||
switch_options = ("last", "list")
|
||||
locks = "cmd:not pperm(page_banned)"
|
||||
help_category = "Comms"
|
||||
|
|
@ -709,7 +781,7 @@ class CmdPage(COMMAND_DEFAULT_CLASS):
|
|||
# get last messages we've got
|
||||
pages_we_got = Msg.objects.get_messages_by_receiver(caller)
|
||||
|
||||
if 'last' in self.switches:
|
||||
if "last" in self.switches:
|
||||
if pages_we_sent:
|
||||
recv = ",".join(obj.key for obj in pages_we_sent[-1].receivers)
|
||||
self.msg("You last paged |c%s|n:%s" % (recv, pages_we_sent[-1].message))
|
||||
|
|
@ -735,11 +807,16 @@ class CmdPage(COMMAND_DEFAULT_CLASS):
|
|||
else:
|
||||
lastpages = pages
|
||||
template = "|w%s|n |c%s|n to |c%s|n: %s"
|
||||
lastpages = "\n ".join(template %
|
||||
(utils.datetime_format(page.date_created),
|
||||
",".join(obj.key for obj in page.senders),
|
||||
"|n,|c ".join([obj.name for obj in page.receivers]),
|
||||
page.message) for page in lastpages)
|
||||
lastpages = "\n ".join(
|
||||
template
|
||||
% (
|
||||
utils.datetime_format(page.date_created),
|
||||
",".join(obj.key for obj in page.senders),
|
||||
"|n,|c ".join([obj.name for obj in page.receivers]),
|
||||
page.message,
|
||||
)
|
||||
for page in lastpages
|
||||
)
|
||||
|
||||
if lastpages:
|
||||
string = "Your latest pages:\n %s" % lastpages
|
||||
|
|
@ -765,7 +842,7 @@ class CmdPage(COMMAND_DEFAULT_CLASS):
|
|||
for receiver in set(receivers):
|
||||
if isinstance(receiver, str):
|
||||
pobj = caller.search(receiver)
|
||||
elif hasattr(receiver, 'character'):
|
||||
elif hasattr(receiver, "character"):
|
||||
pobj = receiver
|
||||
else:
|
||||
self.msg("Who do you want to page?")
|
||||
|
|
@ -781,24 +858,25 @@ class CmdPage(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
# if message begins with a :, we assume it is a 'page-pose'
|
||||
if message.startswith(":"):
|
||||
message = "%s %s" % (caller.key, message.strip(':').strip())
|
||||
message = "%s %s" % (caller.key, message.strip(":").strip())
|
||||
|
||||
# create the persistent message object
|
||||
create.create_message(caller, message,
|
||||
receivers=recobjs)
|
||||
create.create_message(caller, message, receivers=recobjs)
|
||||
|
||||
# tell the accounts they got a message.
|
||||
received = []
|
||||
rstrings = []
|
||||
for pobj in recobjs:
|
||||
if not pobj.access(caller, 'msg'):
|
||||
if not pobj.access(caller, "msg"):
|
||||
rstrings.append("You are not allowed to page %s." % pobj)
|
||||
continue
|
||||
pobj.msg("%s %s" % (header, message))
|
||||
if hasattr(pobj, 'sessions') and not pobj.sessions.count():
|
||||
if hasattr(pobj, "sessions") and not pobj.sessions.count():
|
||||
received.append("|C%s|n" % pobj.name)
|
||||
rstrings.append("%s is offline. They will see your message if they list their pages later."
|
||||
% received[-1])
|
||||
rstrings.append(
|
||||
"%s is offline. They will see your message if they list their pages later."
|
||||
% received[-1]
|
||||
)
|
||||
else:
|
||||
received.append("|c%s|n" % pobj.name)
|
||||
if rstrings:
|
||||
|
|
@ -816,13 +894,31 @@ def _list_bots(cmd):
|
|||
bots (str): A table of bots or an error message.
|
||||
|
||||
"""
|
||||
ircbots = [bot for bot in AccountDB.objects.filter(db_is_bot=True, username__startswith="ircbot-")]
|
||||
ircbots = [
|
||||
bot for bot in AccountDB.objects.filter(db_is_bot=True, username__startswith="ircbot-")
|
||||
]
|
||||
if ircbots:
|
||||
table = cmd.styled_table("|w#dbref|n", "|wbotname|n", "|wev-channel|n",
|
||||
"|wirc-channel|n", "|wSSL|n", maxwidth=_DEFAULT_WIDTH)
|
||||
table = cmd.styled_table(
|
||||
"|w#dbref|n",
|
||||
"|wbotname|n",
|
||||
"|wev-channel|n",
|
||||
"|wirc-channel|n",
|
||||
"|wSSL|n",
|
||||
maxwidth=_DEFAULT_WIDTH,
|
||||
)
|
||||
for ircbot in ircbots:
|
||||
ircinfo = "%s (%s:%s)" % (ircbot.db.irc_channel, ircbot.db.irc_network, ircbot.db.irc_port)
|
||||
table.add_row("#%i" % ircbot.id, ircbot.db.irc_botname, ircbot.db.ev_channel, ircinfo, ircbot.db.irc_ssl)
|
||||
ircinfo = "%s (%s:%s)" % (
|
||||
ircbot.db.irc_channel,
|
||||
ircbot.db.irc_network,
|
||||
ircbot.db.irc_port,
|
||||
)
|
||||
table.add_row(
|
||||
"#%i" % ircbot.id,
|
||||
ircbot.db.irc_botname,
|
||||
ircbot.db.ev_channel,
|
||||
ircinfo,
|
||||
ircbot.db.irc_ssl,
|
||||
)
|
||||
return table
|
||||
else:
|
||||
return "No irc bots found."
|
||||
|
|
@ -872,12 +968,12 @@ class CmdIRC2Chan(COMMAND_DEFAULT_CLASS):
|
|||
self.msg(string)
|
||||
return
|
||||
|
||||
if 'list' in self.switches:
|
||||
if "list" in self.switches:
|
||||
# show all connections
|
||||
self.msg(_list_bots(self))
|
||||
return
|
||||
|
||||
if 'disconnect' in self.switches or 'remove' in self.switches or 'delete' in self.switches:
|
||||
if "disconnect" in self.switches or "remove" in self.switches or "delete" in self.switches:
|
||||
botname = "ircbot-%s" % self.lhs
|
||||
matches = AccountDB.objects.filter(db_is_bot=True, username=botname)
|
||||
dbref = utils.dbref(self.lhs)
|
||||
|
|
@ -892,16 +988,19 @@ class CmdIRC2Chan(COMMAND_DEFAULT_CLASS):
|
|||
return
|
||||
|
||||
if not self.args or not self.rhs:
|
||||
string = "Usage: irc2chan[/switches] <evennia_channel> =" \
|
||||
" <ircnetwork> <port> <#irchannel> <botname>[:typeclass]"
|
||||
string = (
|
||||
"Usage: irc2chan[/switches] <evennia_channel> ="
|
||||
" <ircnetwork> <port> <#irchannel> <botname>[:typeclass]"
|
||||
)
|
||||
self.msg(string)
|
||||
return
|
||||
|
||||
channel = self.lhs
|
||||
self.rhs = self.rhs.replace('#', ' ') # to avoid Python comment issues
|
||||
self.rhs = self.rhs.replace("#", " ") # to avoid Python comment issues
|
||||
try:
|
||||
irc_network, irc_port, irc_channel, irc_botname = \
|
||||
[part.strip() for part in self.rhs.split(None, 4)]
|
||||
irc_network, irc_port, irc_channel, irc_botname = [
|
||||
part.strip() for part in self.rhs.split(None, 4)
|
||||
]
|
||||
irc_channel = "#%s" % irc_channel
|
||||
except Exception:
|
||||
string = "IRC bot definition '%s' is not valid." % self.rhs
|
||||
|
|
@ -930,8 +1029,14 @@ class CmdIRC2Chan(COMMAND_DEFAULT_CLASS):
|
|||
except Exception as err:
|
||||
self.msg("|rError, could not create the bot:|n '%s'." % err)
|
||||
return
|
||||
bot.start(ev_channel=channel, irc_botname=irc_botname, irc_channel=irc_channel,
|
||||
irc_network=irc_network, irc_port=irc_port, irc_ssl=irc_ssl)
|
||||
bot.start(
|
||||
ev_channel=channel,
|
||||
irc_botname=irc_botname,
|
||||
irc_channel=irc_channel,
|
||||
irc_network=irc_network,
|
||||
irc_port=irc_port,
|
||||
irc_ssl=irc_ssl,
|
||||
)
|
||||
self.msg("Connection created. Starting IRC bot.")
|
||||
|
||||
|
||||
|
|
@ -953,6 +1058,7 @@ class CmdIRCStatus(COMMAND_DEFAULT_CLASS):
|
|||
messages sent to either channel will be lost.
|
||||
|
||||
"""
|
||||
|
||||
key = "ircstatus"
|
||||
locks = "cmd:serversetting(IRC_ENABLED) and perm(ircstatus) or perm(Builder))"
|
||||
help_category = "Comms"
|
||||
|
|
@ -976,13 +1082,20 @@ class CmdIRCStatus(COMMAND_DEFAULT_CLASS):
|
|||
if utils.dbref(botname):
|
||||
matches = AccountDB.objects.filter(db_is_bot=True, id=utils.dbref(botname))
|
||||
if not matches:
|
||||
self.msg("No matching IRC-bot found. Use ircstatus without arguments to list active bots.")
|
||||
self.msg(
|
||||
"No matching IRC-bot found. Use ircstatus without arguments to list active bots."
|
||||
)
|
||||
return
|
||||
ircbot = matches[0]
|
||||
channel = ircbot.db.irc_channel
|
||||
network = ircbot.db.irc_network
|
||||
port = ircbot.db.irc_port
|
||||
chtext = "IRC bot '%s' on channel %s (%s:%s)" % (ircbot.db.irc_botname, channel, network, port)
|
||||
chtext = "IRC bot '%s' on channel %s (%s:%s)" % (
|
||||
ircbot.db.irc_botname,
|
||||
channel,
|
||||
network,
|
||||
port,
|
||||
)
|
||||
if option == "ping":
|
||||
# check connection by sending outself a ping through the server.
|
||||
self.caller.msg("Pinging through %s." % chtext)
|
||||
|
|
@ -992,7 +1105,9 @@ class CmdIRCStatus(COMMAND_DEFAULT_CLASS):
|
|||
# an asynchronous call.
|
||||
self.caller.msg("Requesting nicklist from %s (%s:%s)." % (channel, network, port))
|
||||
ircbot.get_nicklist(self.caller)
|
||||
elif self.caller.locks.check_lockstring(self.caller, "dummy:perm(ircstatus) or perm(Developer)"):
|
||||
elif self.caller.locks.check_lockstring(
|
||||
self.caller, "dummy:perm(ircstatus) or perm(Developer)"
|
||||
):
|
||||
# reboot the client
|
||||
self.caller.msg("Forcing a disconnect + reconnect of %s." % chtext)
|
||||
ircbot.reconnect()
|
||||
|
|
@ -1041,27 +1156,41 @@ class CmdRSS2Chan(COMMAND_DEFAULT_CLASS):
|
|||
return
|
||||
try:
|
||||
import feedparser
|
||||
|
||||
assert feedparser # to avoid checker error of not being used
|
||||
except ImportError:
|
||||
string = "RSS requires python-feedparser (https://pypi.python.org/pypi/feedparser)." \
|
||||
" Install before continuing."
|
||||
string = (
|
||||
"RSS requires python-feedparser (https://pypi.python.org/pypi/feedparser)."
|
||||
" Install before continuing."
|
||||
)
|
||||
self.msg(string)
|
||||
return
|
||||
|
||||
if 'list' in self.switches:
|
||||
if "list" in self.switches:
|
||||
# show all connections
|
||||
rssbots = [bot for bot in AccountDB.objects.filter(db_is_bot=True, username__startswith="rssbot-")]
|
||||
rssbots = [
|
||||
bot
|
||||
for bot in AccountDB.objects.filter(db_is_bot=True, username__startswith="rssbot-")
|
||||
]
|
||||
if rssbots:
|
||||
table = self.styled_table("|wdbid|n", "|wupdate rate|n", "|wev-channel",
|
||||
"|wRSS feed URL|n", border="cells", maxwidth=_DEFAULT_WIDTH)
|
||||
table = self.styled_table(
|
||||
"|wdbid|n",
|
||||
"|wupdate rate|n",
|
||||
"|wev-channel",
|
||||
"|wRSS feed URL|n",
|
||||
border="cells",
|
||||
maxwidth=_DEFAULT_WIDTH,
|
||||
)
|
||||
for rssbot in rssbots:
|
||||
table.add_row(rssbot.id, rssbot.db.rss_rate, rssbot.db.ev_channel, rssbot.db.rss_url)
|
||||
table.add_row(
|
||||
rssbot.id, rssbot.db.rss_rate, rssbot.db.ev_channel, rssbot.db.rss_url
|
||||
)
|
||||
self.msg(table)
|
||||
else:
|
||||
self.msg("No rss bots found.")
|
||||
return
|
||||
|
||||
if 'disconnect' in self.switches or 'remove' in self.switches or 'delete' in self.switches:
|
||||
if "disconnect" in self.switches or "remove" in self.switches or "delete" in self.switches:
|
||||
botname = "rssbot-%s" % self.lhs
|
||||
matches = AccountDB.objects.filter(db_is_bot=True, db_key=botname)
|
||||
if not matches:
|
||||
|
|
@ -1133,12 +1262,20 @@ class CmdGrapevine2Chan(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
if "list" in self.switches:
|
||||
# show all connections
|
||||
gwbots = [bot for bot in
|
||||
AccountDB.objects.filter(db_is_bot=True,
|
||||
username__startswith="grapevinebot-")]
|
||||
gwbots = [
|
||||
bot
|
||||
for bot in AccountDB.objects.filter(
|
||||
db_is_bot=True, username__startswith="grapevinebot-"
|
||||
)
|
||||
]
|
||||
if gwbots:
|
||||
table = self.styled_table("|wdbid|n", "|wev-channel",
|
||||
"|wgw-channel|n", border="cells", maxwidth=_DEFAULT_WIDTH)
|
||||
table = self.styled_table(
|
||||
"|wdbid|n",
|
||||
"|wev-channel",
|
||||
"|wgw-channel|n",
|
||||
border="cells",
|
||||
maxwidth=_DEFAULT_WIDTH,
|
||||
)
|
||||
for gwbot in gwbots:
|
||||
table.add_row(gwbot.id, gwbot.db.ev_channel, gwbot.db.grapevine_channel)
|
||||
self.msg(table)
|
||||
|
|
@ -1146,7 +1283,7 @@ class CmdGrapevine2Chan(COMMAND_DEFAULT_CLASS):
|
|||
self.msg("No grapevine bots found.")
|
||||
return
|
||||
|
||||
if 'disconnect' in self.switches or 'remove' in self.switches or 'delete' in self.switches:
|
||||
if "disconnect" in self.switches or "remove" in self.switches or "delete" in self.switches:
|
||||
botname = "grapevinebot-%s" % self.lhs
|
||||
matches = AccountDB.objects.filter(db_is_bot=True, db_key=botname)
|
||||
|
||||
|
|
|
|||
|
|
@ -9,9 +9,20 @@ from evennia.typeclasses.attributes import NickTemplateInvalid
|
|||
COMMAND_DEFAULT_CLASS = utils.class_from_module(settings.COMMAND_DEFAULT_CLASS)
|
||||
|
||||
# limit symbol import for API
|
||||
__all__ = ("CmdHome", "CmdLook", "CmdNick",
|
||||
"CmdInventory", "CmdSetDesc", "CmdGet", "CmdDrop", "CmdGive",
|
||||
"CmdSay", "CmdWhisper", "CmdPose", "CmdAccess")
|
||||
__all__ = (
|
||||
"CmdHome",
|
||||
"CmdLook",
|
||||
"CmdNick",
|
||||
"CmdInventory",
|
||||
"CmdSetDesc",
|
||||
"CmdGet",
|
||||
"CmdDrop",
|
||||
"CmdGive",
|
||||
"CmdSay",
|
||||
"CmdWhisper",
|
||||
"CmdPose",
|
||||
"CmdAccess",
|
||||
)
|
||||
|
||||
|
||||
class CmdHome(COMMAND_DEFAULT_CLASS):
|
||||
|
|
@ -52,6 +63,7 @@ class CmdLook(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
Observes your location or objects in your vicinity.
|
||||
"""
|
||||
|
||||
key = "look"
|
||||
aliases = ["l", "ls"]
|
||||
locks = "cmd:all()"
|
||||
|
|
@ -71,7 +83,7 @@ class CmdLook(COMMAND_DEFAULT_CLASS):
|
|||
target = caller.search(self.args)
|
||||
if not target:
|
||||
return
|
||||
self.msg((caller.at_look(target), {'type': 'look'}), options=None)
|
||||
self.msg((caller.at_look(target), {"type": "look"}), options=None)
|
||||
|
||||
|
||||
class CmdNick(COMMAND_DEFAULT_CLASS):
|
||||
|
|
@ -116,6 +128,7 @@ class CmdNick(COMMAND_DEFAULT_CLASS):
|
|||
for everyone to use, you need build privileges and the alias command.
|
||||
|
||||
"""
|
||||
|
||||
key = "nick"
|
||||
switch_options = ("inputline", "object", "account", "list", "delete", "clearall")
|
||||
aliases = ["nickname", "nicks"]
|
||||
|
|
@ -148,11 +161,13 @@ class CmdNick(COMMAND_DEFAULT_CLASS):
|
|||
specified_nicktype = bool(nicktypes)
|
||||
nicktypes = nicktypes if specified_nicktype else ["inputline"]
|
||||
|
||||
nicklist = (utils.make_iter(caller.nicks.get(category="inputline", return_obj=True) or []) +
|
||||
utils.make_iter(caller.nicks.get(category="object", return_obj=True) or []) +
|
||||
utils.make_iter(caller.nicks.get(category="account", return_obj=True) or []))
|
||||
nicklist = (
|
||||
utils.make_iter(caller.nicks.get(category="inputline", return_obj=True) or [])
|
||||
+ utils.make_iter(caller.nicks.get(category="object", return_obj=True) or [])
|
||||
+ utils.make_iter(caller.nicks.get(category="account", return_obj=True) or [])
|
||||
)
|
||||
|
||||
if 'list' in switches or self.cmdstring in ("nicks",):
|
||||
if "list" in switches or self.cmdstring in ("nicks",):
|
||||
|
||||
if not nicklist:
|
||||
string = "|wNo nicks defined.|n"
|
||||
|
|
@ -160,18 +175,20 @@ class CmdNick(COMMAND_DEFAULT_CLASS):
|
|||
table = self.styled_table("#", "Type", "Nick match", "Replacement")
|
||||
for inum, nickobj in enumerate(nicklist):
|
||||
_, _, nickvalue, replacement = nickobj.value
|
||||
table.add_row(str(inum + 1), nickobj.db_category, _cy(nickvalue), _cy(replacement))
|
||||
table.add_row(
|
||||
str(inum + 1), nickobj.db_category, _cy(nickvalue), _cy(replacement)
|
||||
)
|
||||
string = "|wDefined Nicks:|n\n%s" % table
|
||||
caller.msg(string)
|
||||
return
|
||||
|
||||
if 'clearall' in switches:
|
||||
if "clearall" in switches:
|
||||
caller.nicks.clear()
|
||||
caller.account.nicks.clear()
|
||||
caller.msg("Cleared all nicks.")
|
||||
return
|
||||
|
||||
if 'delete' in switches or 'del' in switches:
|
||||
if "delete" in switches or "del" in switches:
|
||||
if not self.args or not self.lhs:
|
||||
caller.msg("usage nick/delete <nick> or <#num> ('nicks' for list)")
|
||||
return
|
||||
|
|
@ -199,8 +216,10 @@ class CmdNick(COMMAND_DEFAULT_CLASS):
|
|||
nicktypestr = "%s-nick" % nicktype.capitalize()
|
||||
_, _, old_nickstring, old_replstring = oldnick.value
|
||||
caller.nicks.remove(old_nickstring, category=nicktype)
|
||||
caller.msg("%s removed: '|w%s|n' -> |w%s|n." % (
|
||||
nicktypestr, old_nickstring, old_replstring))
|
||||
caller.msg(
|
||||
"%s removed: '|w%s|n' -> |w%s|n."
|
||||
% (nicktypestr, old_nickstring, old_replstring)
|
||||
)
|
||||
else:
|
||||
caller.msg("No matching nicks to remove.")
|
||||
return
|
||||
|
|
@ -211,14 +230,19 @@ class CmdNick(COMMAND_DEFAULT_CLASS):
|
|||
if not specified_nicktype:
|
||||
nicktypes = ("object", "account", "inputline")
|
||||
for nicktype in nicktypes:
|
||||
nicks = [nick for nick in
|
||||
utils.make_iter(caller.nicks.get(category=nicktype, return_obj=True))
|
||||
if nick]
|
||||
nicks = [
|
||||
nick
|
||||
for nick in utils.make_iter(
|
||||
caller.nicks.get(category=nicktype, return_obj=True)
|
||||
)
|
||||
if nick
|
||||
]
|
||||
for nick in nicks:
|
||||
_, _, nick, repl = nick.value
|
||||
if nick.startswith(self.lhs):
|
||||
strings.append("{}-nick: '{}' -> '{}'".format(
|
||||
nicktype.capitalize(), nick, repl))
|
||||
strings.append(
|
||||
"{}-nick: '{}' -> '{}'".format(nicktype.capitalize(), nick, repl)
|
||||
)
|
||||
if strings:
|
||||
caller.msg("\n".join(strings))
|
||||
else:
|
||||
|
|
@ -239,8 +263,9 @@ class CmdNick(COMMAND_DEFAULT_CLASS):
|
|||
for nick in nicks:
|
||||
_, _, nick, repl = nick.value
|
||||
if nick.startswith(self.lhs):
|
||||
strings.append("{}-nick: '{}' -> '{}'".format(
|
||||
nicktype.capitalize(), nick, repl))
|
||||
strings.append(
|
||||
"{}-nick: '{}' -> '{}'".format(nicktype.capitalize(), nick, repl)
|
||||
)
|
||||
if strings:
|
||||
caller.msg("\n".join(strings))
|
||||
else:
|
||||
|
|
@ -261,8 +286,9 @@ class CmdNick(COMMAND_DEFAULT_CLASS):
|
|||
for nick in nicks:
|
||||
_, _, nick, repl = nick.value
|
||||
if nick.startswith(self.lhs):
|
||||
strings.append("{}-nick: '{}' -> '{}'".format(
|
||||
nicktype.capitalize(), nick, repl))
|
||||
strings.append(
|
||||
"{}-nick: '{}' -> '{}'".format(nicktype.capitalize(), nick, repl)
|
||||
)
|
||||
if strings:
|
||||
caller.msg("\n".join(strings))
|
||||
else:
|
||||
|
|
@ -301,17 +327,30 @@ class CmdNick(COMMAND_DEFAULT_CLASS):
|
|||
string += "\nIdentical %s already set." % nicktypestr.lower()
|
||||
else:
|
||||
string += "\n%s '|w%s|n' updated to map to '|w%s|n'." % (
|
||||
nicktypestr, old_nickstring, replstring)
|
||||
nicktypestr,
|
||||
old_nickstring,
|
||||
replstring,
|
||||
)
|
||||
else:
|
||||
string += "\n%s '|w%s|n' mapped to '|w%s|n'." % (nicktypestr, nickstring, replstring)
|
||||
string += "\n%s '|w%s|n' mapped to '|w%s|n'." % (
|
||||
nicktypestr,
|
||||
nickstring,
|
||||
replstring,
|
||||
)
|
||||
try:
|
||||
caller.nicks.add(nickstring, replstring, category=nicktype)
|
||||
except NickTemplateInvalid:
|
||||
caller.msg("You must use the same $-markers both in the nick and in the replacement.")
|
||||
caller.msg(
|
||||
"You must use the same $-markers both in the nick and in the replacement."
|
||||
)
|
||||
return
|
||||
elif old_nickstring and old_replstring:
|
||||
# just looking at the nick
|
||||
string += "\n%s '|w%s|n' maps to '|w%s|n'." % (nicktypestr, old_nickstring, old_replstring)
|
||||
string += "\n%s '|w%s|n' maps to '|w%s|n'." % (
|
||||
nicktypestr,
|
||||
old_nickstring,
|
||||
old_replstring,
|
||||
)
|
||||
errstring = ""
|
||||
string = errstring if errstring else string
|
||||
caller.msg(_cy(string))
|
||||
|
|
@ -327,6 +366,7 @@ class CmdInventory(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
Shows your inventory.
|
||||
"""
|
||||
|
||||
key = "inventory"
|
||||
aliases = ["inv", "i"]
|
||||
locks = "cmd:all()"
|
||||
|
|
@ -355,6 +395,7 @@ class CmdGet(COMMAND_DEFAULT_CLASS):
|
|||
Picks up an object from your location and puts it in
|
||||
your inventory.
|
||||
"""
|
||||
|
||||
key = "get"
|
||||
aliases = "grab"
|
||||
locks = "cmd:all()"
|
||||
|
|
@ -374,7 +415,7 @@ class CmdGet(COMMAND_DEFAULT_CLASS):
|
|||
if caller == obj:
|
||||
caller.msg("You can't get yourself.")
|
||||
return
|
||||
if not obj.access(caller, 'get'):
|
||||
if not obj.access(caller, "get"):
|
||||
if obj.db.get_err_msg:
|
||||
caller.msg(obj.db.get_err_msg)
|
||||
else:
|
||||
|
|
@ -387,10 +428,7 @@ class CmdGet(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
obj.move_to(caller, quiet=True)
|
||||
caller.msg("You pick up %s." % obj.name)
|
||||
caller.location.msg_contents("%s picks up %s." %
|
||||
(caller.name,
|
||||
obj.name),
|
||||
exclude=caller)
|
||||
caller.location.msg_contents("%s picks up %s." % (caller.name, obj.name), exclude=caller)
|
||||
# calling at_get hook method
|
||||
obj.at_get(caller)
|
||||
|
||||
|
|
@ -420,9 +458,12 @@ class CmdDrop(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
# Because the DROP command by definition looks for items
|
||||
# in inventory, call the search function using location = caller
|
||||
obj = caller.search(self.args, location=caller,
|
||||
nofound_string="You aren't carrying %s." % self.args,
|
||||
multimatch_string="You carry more than one %s:" % self.args)
|
||||
obj = caller.search(
|
||||
self.args,
|
||||
location=caller,
|
||||
nofound_string="You aren't carrying %s." % self.args,
|
||||
multimatch_string="You carry more than one %s:" % self.args,
|
||||
)
|
||||
if not obj:
|
||||
return
|
||||
|
||||
|
|
@ -432,9 +473,7 @@ class CmdDrop(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
obj.move_to(caller.location, quiet=True)
|
||||
caller.msg("You drop %s." % (obj.name,))
|
||||
caller.location.msg_contents("%s drops %s." %
|
||||
(caller.name, obj.name),
|
||||
exclude=caller)
|
||||
caller.location.msg_contents("%s drops %s." % (caller.name, obj.name), exclude=caller)
|
||||
# Call the object script's at_drop() method.
|
||||
obj.at_drop(caller)
|
||||
|
||||
|
|
@ -449,6 +488,7 @@ class CmdGive(COMMAND_DEFAULT_CLASS):
|
|||
Gives an items from your inventory to another character,
|
||||
placing it in their inventory.
|
||||
"""
|
||||
|
||||
key = "give"
|
||||
rhs_split = ("=", " to ") # Prefer = delimiter, but allow " to " usage.
|
||||
locks = "cmd:all()"
|
||||
|
|
@ -461,9 +501,12 @@ class CmdGive(COMMAND_DEFAULT_CLASS):
|
|||
if not self.args or not self.rhs:
|
||||
caller.msg("Usage: give <inventory object> = <target>")
|
||||
return
|
||||
to_give = caller.search(self.lhs, location=caller,
|
||||
nofound_string="You aren't carrying %s." % self.lhs,
|
||||
multimatch_string="You carry more than one %s:" % self.lhs)
|
||||
to_give = caller.search(
|
||||
self.lhs,
|
||||
location=caller,
|
||||
nofound_string="You aren't carrying %s." % self.lhs,
|
||||
multimatch_string="You carry more than one %s:" % self.lhs,
|
||||
)
|
||||
target = caller.search(self.rhs)
|
||||
if not (to_give and target):
|
||||
return
|
||||
|
|
@ -497,6 +540,7 @@ class CmdSetDesc(COMMAND_DEFAULT_CLASS):
|
|||
will be visible to people when they
|
||||
look at you.
|
||||
"""
|
||||
|
||||
key = "setdesc"
|
||||
locks = "cmd:all()"
|
||||
arg_regex = r"\s|$"
|
||||
|
|
@ -606,6 +650,7 @@ class CmdPose(COMMAND_DEFAULT_CLASS):
|
|||
Describe an action being taken. The pose text will
|
||||
automatically begin with your name.
|
||||
"""
|
||||
|
||||
key = "pose"
|
||||
aliases = [":", "emote"]
|
||||
locks = "cmd:all()"
|
||||
|
|
@ -630,8 +675,7 @@ class CmdPose(COMMAND_DEFAULT_CLASS):
|
|||
self.caller.msg(msg)
|
||||
else:
|
||||
msg = "%s%s" % (self.caller.name, self.args)
|
||||
self.caller.location.msg_contents(text=(msg, {"type": "pose"}),
|
||||
from_obj=self.caller)
|
||||
self.caller.location.msg_contents(text=(msg, {"type": "pose"}), from_obj=self.caller)
|
||||
|
||||
|
||||
class CmdAccess(COMMAND_DEFAULT_CLASS):
|
||||
|
|
@ -644,6 +688,7 @@ class CmdAccess(COMMAND_DEFAULT_CLASS):
|
|||
This command shows you the permission hierarchy and
|
||||
which permission groups you are a member of.
|
||||
"""
|
||||
|
||||
key = "access"
|
||||
aliases = ["groups", "hierarchy"]
|
||||
locks = "cmd:all()"
|
||||
|
|
@ -665,6 +710,6 @@ class CmdAccess(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
string += "\n|wYour access|n:"
|
||||
string += "\nCharacter |c%s|n: %s" % (caller.key, cperms)
|
||||
if hasattr(caller, 'account'):
|
||||
if hasattr(caller, "account"):
|
||||
string += "\nAccount |c%s|n: %s" % (caller.account.key, pperms)
|
||||
caller.msg(string)
|
||||
|
|
|
|||
|
|
@ -37,8 +37,9 @@ class CmdHelp(Command):
|
|||
This will search for help on commands and other
|
||||
topics related to the game.
|
||||
"""
|
||||
|
||||
key = "help"
|
||||
aliases = ['?']
|
||||
aliases = ["?"]
|
||||
locks = "cmd:all()"
|
||||
arg_regex = r"\s|$"
|
||||
|
||||
|
|
@ -128,7 +129,11 @@ class CmdHelp(Command):
|
|||
string += "\n\n" + _SEP + "\n\r |COther help entries|n\n" + _SEP
|
||||
for category in sorted(hdict_db.keys()):
|
||||
string += "\n\r |w%s|n:\n" % (str(category).title())
|
||||
string += "|G" + fill(", ".join(sorted([str(topic) for topic in hdict_db[category]]))) + "|n"
|
||||
string += (
|
||||
"|G"
|
||||
+ fill(", ".join(sorted([str(topic) for topic in hdict_db[category]])))
|
||||
+ "|n"
|
||||
)
|
||||
return string
|
||||
|
||||
def check_show_help(self, cmd, caller):
|
||||
|
|
@ -198,9 +203,15 @@ class CmdHelp(Command):
|
|||
|
||||
# retrieve all available commands and database topics
|
||||
all_cmds = [cmd for cmd in cmdset if self.check_show_help(cmd, caller)]
|
||||
all_topics = [topic for topic in HelpEntry.objects.all() if topic.access(caller, 'view', default=True)]
|
||||
all_categories = list(set([cmd.help_category.lower() for cmd in all_cmds] + [topic.help_category.lower()
|
||||
for topic in all_topics]))
|
||||
all_topics = [
|
||||
topic for topic in HelpEntry.objects.all() if topic.access(caller, "view", default=True)
|
||||
]
|
||||
all_categories = list(
|
||||
set(
|
||||
[cmd.help_category.lower() for cmd in all_cmds]
|
||||
+ [topic.help_category.lower() for topic in all_topics]
|
||||
)
|
||||
)
|
||||
|
||||
if query in ("list", "all"):
|
||||
# we want to list all available help entries, grouped by category
|
||||
|
|
@ -222,13 +233,23 @@ class CmdHelp(Command):
|
|||
# build vocabulary of suggestions and rate them by string similarity.
|
||||
suggestions = None
|
||||
if suggestion_maxnum > 0:
|
||||
vocabulary = [cmd.key for cmd in all_cmds if cmd] + [topic.key for topic in all_topics] + all_categories
|
||||
vocabulary = (
|
||||
[cmd.key for cmd in all_cmds if cmd]
|
||||
+ [topic.key for topic in all_topics]
|
||||
+ all_categories
|
||||
)
|
||||
[vocabulary.extend(cmd.aliases) for cmd in all_cmds]
|
||||
suggestions = [sugg for sugg in string_suggestions(query, set(vocabulary), cutoff=suggestion_cutoff,
|
||||
maxnum=suggestion_maxnum)
|
||||
if sugg != query]
|
||||
suggestions = [
|
||||
sugg
|
||||
for sugg in string_suggestions(
|
||||
query, set(vocabulary), cutoff=suggestion_cutoff, maxnum=suggestion_maxnum
|
||||
)
|
||||
if sugg != query
|
||||
]
|
||||
if not suggestions:
|
||||
suggestions = [sugg for sugg in vocabulary if sugg != query and sugg.startswith(query)]
|
||||
suggestions = [
|
||||
sugg for sugg in vocabulary if sugg != query and sugg.startswith(query)
|
||||
]
|
||||
|
||||
# try an exact command auto-help match
|
||||
match = [cmd for cmd in all_cmds if cmd == query]
|
||||
|
|
@ -237,38 +258,52 @@ class CmdHelp(Command):
|
|||
# try an inexact match with prefixes stripped from query and cmds
|
||||
_query = query[1:] if query[0] in CMD_IGNORE_PREFIXES else query
|
||||
|
||||
match = [cmd for cmd in all_cmds
|
||||
for m in cmd._matchset if m == _query or
|
||||
m[0] in CMD_IGNORE_PREFIXES and m[1:] == _query]
|
||||
match = [
|
||||
cmd
|
||||
for cmd in all_cmds
|
||||
for m in cmd._matchset
|
||||
if m == _query or m[0] in CMD_IGNORE_PREFIXES and m[1:] == _query
|
||||
]
|
||||
|
||||
if len(match) == 1:
|
||||
formatted = self.format_help_entry(match[0].key,
|
||||
match[0].get_help(caller, cmdset),
|
||||
aliases=match[0].aliases,
|
||||
suggested=suggestions)
|
||||
formatted = self.format_help_entry(
|
||||
match[0].key,
|
||||
match[0].get_help(caller, cmdset),
|
||||
aliases=match[0].aliases,
|
||||
suggested=suggestions,
|
||||
)
|
||||
self.msg_help(formatted)
|
||||
return
|
||||
|
||||
# try an exact database help entry match
|
||||
match = list(HelpEntry.objects.find_topicmatch(query, exact=True))
|
||||
if len(match) == 1:
|
||||
formatted = self.format_help_entry(match[0].key,
|
||||
match[0].entrytext,
|
||||
aliases=match[0].aliases.all(),
|
||||
suggested=suggestions)
|
||||
formatted = self.format_help_entry(
|
||||
match[0].key,
|
||||
match[0].entrytext,
|
||||
aliases=match[0].aliases.all(),
|
||||
suggested=suggestions,
|
||||
)
|
||||
self.msg_help(formatted)
|
||||
return
|
||||
|
||||
# try to see if a category name was entered
|
||||
if query in all_categories:
|
||||
self.msg_help(self.format_help_list({query: [cmd.key for cmd in all_cmds if cmd.help_category == query]},
|
||||
{query: [topic.key for topic in all_topics
|
||||
if topic.help_category == query]}))
|
||||
self.msg_help(
|
||||
self.format_help_list(
|
||||
{query: [cmd.key for cmd in all_cmds if cmd.help_category == query]},
|
||||
{query: [topic.key for topic in all_topics if topic.help_category == query]},
|
||||
)
|
||||
)
|
||||
return
|
||||
|
||||
# no exact matches found. Just give suggestions.
|
||||
self.msg(self.format_help_entry("", f"No help entry found for '{query}'",
|
||||
None, suggested=suggestions), options={"type": "help"})
|
||||
self.msg(
|
||||
self.format_help_entry(
|
||||
"", f"No help entry found for '{query}'", None, suggested=suggestions
|
||||
),
|
||||
options={"type": "help"},
|
||||
)
|
||||
|
||||
|
||||
def _loadhelp(caller):
|
||||
|
|
@ -317,6 +352,7 @@ class CmdSetHelp(COMMAND_DEFAULT_CLASS):
|
|||
is to let everyone read the help file.
|
||||
|
||||
"""
|
||||
|
||||
key = "sethelp"
|
||||
switch_options = ("edit", "replace", "append", "extend", "delete")
|
||||
locks = "cmd:perm(Helper)"
|
||||
|
|
@ -329,7 +365,9 @@ class CmdSetHelp(COMMAND_DEFAULT_CLASS):
|
|||
lhslist = self.lhslist
|
||||
|
||||
if not self.args:
|
||||
self.msg("Usage: sethelp[/switches] <topic>[;alias;alias][,category[,locks,..] = <text>")
|
||||
self.msg(
|
||||
"Usage: sethelp[/switches] <topic>[;alias;alias][,category[,locks,..] = <text>"
|
||||
)
|
||||
return
|
||||
|
||||
nlist = len(lhslist)
|
||||
|
|
@ -357,7 +395,7 @@ class CmdSetHelp(COMMAND_DEFAULT_CLASS):
|
|||
lockstring = ",".join(lhslist[2:]) if nlist > 2 else "view:all()"
|
||||
category = category.lower()
|
||||
|
||||
if 'edit' in switches:
|
||||
if "edit" in switches:
|
||||
# open the line editor to edit the helptext. No = is needed.
|
||||
if old_entry:
|
||||
topicstr = old_entry.key
|
||||
|
|
@ -366,17 +404,22 @@ class CmdSetHelp(COMMAND_DEFAULT_CLASS):
|
|||
old_entry.entrytext += "\n%s" % self.rhs
|
||||
helpentry = old_entry
|
||||
else:
|
||||
helpentry = create.create_help_entry(topicstr,
|
||||
self.rhs, category=category,
|
||||
locks=lockstring, aliases=aliases)
|
||||
helpentry = create.create_help_entry(
|
||||
topicstr, self.rhs, category=category, locks=lockstring, aliases=aliases
|
||||
)
|
||||
self.caller.db._editing_help = helpentry
|
||||
|
||||
EvEditor(self.caller, loadfunc=_loadhelp, savefunc=_savehelp,
|
||||
quitfunc=_quithelp, key="topic {}".format(topicstr),
|
||||
persistent=True)
|
||||
EvEditor(
|
||||
self.caller,
|
||||
loadfunc=_loadhelp,
|
||||
savefunc=_savehelp,
|
||||
quitfunc=_quithelp,
|
||||
key="topic {}".format(topicstr),
|
||||
persistent=True,
|
||||
)
|
||||
return
|
||||
|
||||
if 'append' in switches or "merge" in switches or "extend" in switches:
|
||||
if "append" in switches or "merge" in switches or "extend" in switches:
|
||||
# merge/append operations
|
||||
if not old_entry:
|
||||
self.msg("Could not find topic '%s'. You must give an exact name." % topicstr)
|
||||
|
|
@ -384,14 +427,14 @@ class CmdSetHelp(COMMAND_DEFAULT_CLASS):
|
|||
if not self.rhs:
|
||||
self.msg("You must supply text to append/merge.")
|
||||
return
|
||||
if 'merge' in switches:
|
||||
if "merge" in switches:
|
||||
old_entry.entrytext += " " + self.rhs
|
||||
else:
|
||||
old_entry.entrytext += "\n%s" % self.rhs
|
||||
old_entry.aliases.add(aliases)
|
||||
self.msg("Entry updated:\n%s%s" % (old_entry.entrytext, aliastxt))
|
||||
return
|
||||
if 'delete' in switches or 'del' in switches:
|
||||
if "delete" in switches or "del" in switches:
|
||||
# delete the help entry
|
||||
if not old_entry:
|
||||
self.msg("Could not find topic '%s'%s." % (topicstr, aliastxt))
|
||||
|
|
@ -405,7 +448,7 @@ class CmdSetHelp(COMMAND_DEFAULT_CLASS):
|
|||
self.msg("You must supply a help text to add.")
|
||||
return
|
||||
if old_entry:
|
||||
if 'replace' in switches:
|
||||
if "replace" in switches:
|
||||
# overwrite old entry
|
||||
old_entry.key = topicstr
|
||||
old_entry.entrytext = self.rhs
|
||||
|
|
@ -416,22 +459,30 @@ class CmdSetHelp(COMMAND_DEFAULT_CLASS):
|
|||
old_entry.save()
|
||||
self.msg("Overwrote the old topic '%s'%s." % (topicstr, aliastxt))
|
||||
else:
|
||||
self.msg("Topic '%s'%s already exists. Use /replace to overwrite "
|
||||
"or /append or /merge to add text to it." % (topicstr, aliastxt))
|
||||
self.msg(
|
||||
"Topic '%s'%s already exists. Use /replace to overwrite "
|
||||
"or /append or /merge to add text to it." % (topicstr, aliastxt)
|
||||
)
|
||||
else:
|
||||
# no old entry. Create a new one.
|
||||
new_entry = create.create_help_entry(topicstr,
|
||||
self.rhs, category=category,
|
||||
locks=lockstring, aliases=aliases)
|
||||
new_entry = create.create_help_entry(
|
||||
topicstr, self.rhs, category=category, locks=lockstring, aliases=aliases
|
||||
)
|
||||
if new_entry:
|
||||
self.msg("Topic '%s'%s was successfully created." % (topicstr, aliastxt))
|
||||
if 'edit' in switches:
|
||||
if "edit" in switches:
|
||||
# open the line editor to edit the helptext
|
||||
self.caller.db._editing_help = new_entry
|
||||
EvEditor(self.caller, loadfunc=_loadhelp,
|
||||
savefunc=_savehelp, quitfunc=_quithelp,
|
||||
key="topic {}".format(new_entry.key),
|
||||
persistent=True)
|
||||
EvEditor(
|
||||
self.caller,
|
||||
loadfunc=_loadhelp,
|
||||
savefunc=_savehelp,
|
||||
quitfunc=_quithelp,
|
||||
key="topic {}".format(new_entry.key),
|
||||
persistent=True,
|
||||
)
|
||||
return
|
||||
else:
|
||||
self.msg("Error when creating topic '%s'%s! Contact an admin." % (topicstr, aliastxt))
|
||||
self.msg(
|
||||
"Error when creating topic '%s'%s! Contact an admin." % (topicstr, aliastxt)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -121,38 +121,46 @@ class MuxCommand(Command):
|
|||
switches = args[1:].split(None, 1)
|
||||
if len(switches) > 1:
|
||||
switches, args = switches
|
||||
switches = switches.split('/')
|
||||
switches = switches.split("/")
|
||||
else:
|
||||
args = ""
|
||||
switches = switches[0].split('/')
|
||||
switches = switches[0].split("/")
|
||||
# If user-provides switches, parse them with parser switch options.
|
||||
if switches and self.switch_options:
|
||||
valid_switches, unused_switches, extra_switches = [], [], []
|
||||
for element in switches:
|
||||
option_check = [opt for opt in self.switch_options if opt == element]
|
||||
if not option_check:
|
||||
option_check = [opt for opt in self.switch_options if opt.startswith(element)]
|
||||
option_check = [
|
||||
opt for opt in self.switch_options if opt.startswith(element)
|
||||
]
|
||||
match_count = len(option_check)
|
||||
if match_count > 1:
|
||||
extra_switches.extend(option_check) # Either the option provided is ambiguous,
|
||||
extra_switches.extend(
|
||||
option_check
|
||||
) # Either the option provided is ambiguous,
|
||||
elif match_count == 1:
|
||||
valid_switches.extend(option_check) # or it is a valid option abbreviation,
|
||||
elif match_count == 0:
|
||||
unused_switches.append(element) # or an extraneous option to be ignored.
|
||||
if extra_switches: # User provided switches
|
||||
self.msg('|g%s|n: |wAmbiguous switch supplied: Did you mean /|C%s|w?' %
|
||||
(self.cmdstring, ' |nor /|C'.join(extra_switches)))
|
||||
self.msg(
|
||||
"|g%s|n: |wAmbiguous switch supplied: Did you mean /|C%s|w?"
|
||||
% (self.cmdstring, " |nor /|C".join(extra_switches))
|
||||
)
|
||||
if unused_switches:
|
||||
plural = '' if len(unused_switches) == 1 else 'es'
|
||||
self.msg('|g%s|n: |wExtra switch%s "/|C%s|w" ignored.' %
|
||||
(self.cmdstring, plural, '|n, /|C'.join(unused_switches)))
|
||||
plural = "" if len(unused_switches) == 1 else "es"
|
||||
self.msg(
|
||||
'|g%s|n: |wExtra switch%s "/|C%s|w" ignored.'
|
||||
% (self.cmdstring, plural, "|n, /|C".join(unused_switches))
|
||||
)
|
||||
switches = valid_switches # Only include valid_switches in command function call
|
||||
arglist = [arg.strip() for arg in args.split()]
|
||||
|
||||
# check for arg1, arg2, ... = argA, argB, ... constructs
|
||||
lhs, rhs = args.strip(), None
|
||||
if lhs:
|
||||
if delimiters and hasattr(delimiters, '__iter__'): # If delimiter is iterable,
|
||||
if delimiters and hasattr(delimiters, "__iter__"): # If delimiter is iterable,
|
||||
best_split = delimiters[0] # (default to first delimiter)
|
||||
for this_split in delimiters: # try each delimiter
|
||||
if this_split in lhs: # to find first successful split
|
||||
|
|
@ -167,8 +175,8 @@ class MuxCommand(Command):
|
|||
rhs = rhs.strip() if rhs is not None else None
|
||||
lhs = lhs.strip()
|
||||
# Further split left/right sides by comma delimiter
|
||||
lhslist = [arg.strip() for arg in lhs.split(',')] if lhs is not None else ""
|
||||
rhslist = [arg.strip() for arg in rhs.split(',')] if rhs is not None else ""
|
||||
lhslist = [arg.strip() for arg in lhs.split(",")] if lhs is not None else ""
|
||||
rhslist = [arg.strip() for arg in rhs.split(",")] if rhs is not None else ""
|
||||
# save to object properties:
|
||||
self.raw = raw
|
||||
self.switches = switches
|
||||
|
|
@ -200,7 +208,9 @@ class MuxCommand(Command):
|
|||
by the cmdhandler right after self.parser() finishes, and so has access
|
||||
to all the variables defined therein.
|
||||
"""
|
||||
variables = '\n'.join(" |w{}|n ({}): {}".format(key, type(val), val) for key, val in self.__dict__.items())
|
||||
variables = "\n".join(
|
||||
" |w{}|n ({}): {}".format(key, type(val), val) for key, val in self.__dict__.items()
|
||||
)
|
||||
string = f"""
|
||||
Command {self} has no defined `func()` - showing on-command variables: No child func() defined for {self} - available variables:
|
||||
{variables}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ from evennia.commands.cmdhandler import CMD_CHANNEL
|
|||
from evennia.utils import utils
|
||||
|
||||
from django.conf import settings
|
||||
|
||||
COMMAND_DEFAULT_CLASS = utils.class_from_module(settings.COMMAND_DEFAULT_CLASS)
|
||||
|
||||
# Command called when there is no input at line
|
||||
|
|
@ -41,6 +42,7 @@ class SystemNoInput(COMMAND_DEFAULT_CLASS):
|
|||
"""
|
||||
This is called when there is no input given
|
||||
"""
|
||||
|
||||
key = CMD_NOINPUT
|
||||
locks = "cmd:all()"
|
||||
|
||||
|
|
@ -57,6 +59,7 @@ class SystemNoMatch(COMMAND_DEFAULT_CLASS):
|
|||
"""
|
||||
No command was found matching the given input.
|
||||
"""
|
||||
|
||||
key = CMD_NOMATCH
|
||||
locks = "cmd:all()"
|
||||
|
||||
|
|
@ -86,6 +89,7 @@ class SystemMultimatch(COMMAND_DEFAULT_CLASS):
|
|||
the `raw_cmdname` is the cmdname unmodified by eventual prefix-stripping.
|
||||
|
||||
"""
|
||||
|
||||
key = CMD_MULTIMATCH
|
||||
locks = "cmd:all()"
|
||||
|
||||
|
|
@ -99,8 +103,7 @@ class SystemMultimatch(COMMAND_DEFAULT_CLASS):
|
|||
# evennia.commands.cmdparse.create_match for more details.
|
||||
matches = self.matches
|
||||
# at_search_result will itself msg the multimatch options to the caller.
|
||||
at_search_result(
|
||||
[match[2] for match in matches], self.caller, query=matches[0][0])
|
||||
at_search_result([match[2] for match in matches], self.caller, query=matches[0][0])
|
||||
|
||||
|
||||
# Command called when the command given at the command line
|
||||
|
|
@ -108,6 +111,7 @@ class SystemMultimatch(COMMAND_DEFAULT_CLASS):
|
|||
# channel named 'ooc' and the user wrote
|
||||
# > ooc Hello!
|
||||
|
||||
|
||||
class SystemSendToChannel(COMMAND_DEFAULT_CLASS):
|
||||
"""
|
||||
This is a special command that the cmdhandler calls
|
||||
|
|
@ -119,7 +123,7 @@ class SystemSendToChannel(COMMAND_DEFAULT_CLASS):
|
|||
locks = "cmd:all()"
|
||||
|
||||
def parse(self):
|
||||
channelname, msg = self.args.split(':', 1)
|
||||
channelname, msg = self.args.split(":", 1)
|
||||
self.args = channelname.strip(), msg.strip()
|
||||
|
||||
def func(self):
|
||||
|
|
@ -140,7 +144,7 @@ class SystemSendToChannel(COMMAND_DEFAULT_CLASS):
|
|||
string = "You are not connected to channel '%s'."
|
||||
caller.msg(string % channelkey)
|
||||
return
|
||||
if not channel.access(caller, 'send'):
|
||||
if not channel.access(caller, "send"):
|
||||
string = "You are not permitted to send to channel '%s'."
|
||||
caller.msg(string % channelkey)
|
||||
return
|
||||
|
|
|
|||
|
|
@ -32,9 +32,18 @@ _RESOURCE = None
|
|||
_IDMAPPER = None
|
||||
|
||||
# limit symbol import for API
|
||||
__all__ = ("CmdReload", "CmdReset", "CmdShutdown", "CmdPy",
|
||||
"CmdScripts", "CmdObjects", "CmdService", "CmdAbout",
|
||||
"CmdTime", "CmdServerLoad")
|
||||
__all__ = (
|
||||
"CmdReload",
|
||||
"CmdReset",
|
||||
"CmdShutdown",
|
||||
"CmdPy",
|
||||
"CmdScripts",
|
||||
"CmdObjects",
|
||||
"CmdService",
|
||||
"CmdAbout",
|
||||
"CmdTime",
|
||||
"CmdServerLoad",
|
||||
)
|
||||
|
||||
|
||||
class CmdReload(COMMAND_DEFAULT_CLASS):
|
||||
|
|
@ -48,8 +57,9 @@ class CmdReload(COMMAND_DEFAULT_CLASS):
|
|||
affected. Non-persistent scripts will survive a reload (use
|
||||
reset to purge) and at_reload() hooks will be called.
|
||||
"""
|
||||
|
||||
key = "reload"
|
||||
aliases = ['restart']
|
||||
aliases = ["restart"]
|
||||
locks = "cmd:perm(reload) or perm(Developer)"
|
||||
help_category = "System"
|
||||
|
||||
|
|
@ -84,8 +94,9 @@ class CmdReset(COMMAND_DEFAULT_CLASS):
|
|||
cmdsets etc will be wiped.
|
||||
|
||||
"""
|
||||
|
||||
key = "reset"
|
||||
aliases = ['reboot']
|
||||
aliases = ["reboot"]
|
||||
locks = "cmd:perm(reload) or perm(Developer)"
|
||||
help_category = "System"
|
||||
|
||||
|
|
@ -107,6 +118,7 @@ class CmdShutdown(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
Gracefully shut down both Server and Portal.
|
||||
"""
|
||||
|
||||
key = "shutdown"
|
||||
locks = "cmd:perm(shutdown) or perm(Developer)"
|
||||
help_category = "System"
|
||||
|
|
@ -116,11 +128,11 @@ class CmdShutdown(COMMAND_DEFAULT_CLASS):
|
|||
# Only allow shutdown if caller has session
|
||||
if not self.caller.sessions.get():
|
||||
return
|
||||
self.msg('Shutting down server ...')
|
||||
self.msg("Shutting down server ...")
|
||||
announcement = "\nServer is being SHUT DOWN!\n"
|
||||
if self.args:
|
||||
announcement += "%s\n" % self.args
|
||||
logger.log_info('Server shutdown by %s.' % self.caller.name)
|
||||
logger.log_info("Server shutdown by %s." % self.caller.name)
|
||||
SESSIONS.announce_all(announcement)
|
||||
SESSIONS.portal_shutdown()
|
||||
|
||||
|
|
@ -135,13 +147,11 @@ def _py_code(caller, buf):
|
|||
"""
|
||||
measure_time = caller.db._py_measure_time
|
||||
client_raw = caller.db._py_clientraw
|
||||
string = "Executing code%s ..." % (
|
||||
" (measure timing)" if measure_time else "")
|
||||
string = "Executing code%s ..." % (" (measure timing)" if measure_time else "")
|
||||
caller.msg(string)
|
||||
_run_code_snippet(caller, buf, mode="exec",
|
||||
measure_time=measure_time,
|
||||
client_raw=client_raw,
|
||||
show_input=False)
|
||||
_run_code_snippet(
|
||||
caller, buf, mode="exec", measure_time=measure_time, client_raw=client_raw, show_input=False
|
||||
)
|
||||
return True
|
||||
|
||||
|
||||
|
|
@ -150,8 +160,9 @@ def _py_quit(caller):
|
|||
caller.msg("Exited the code editor.")
|
||||
|
||||
|
||||
def _run_code_snippet(caller, pycode, mode="eval", measure_time=False,
|
||||
client_raw=False, show_input=True):
|
||||
def _run_code_snippet(
|
||||
caller, pycode, mode="eval", measure_time=False, client_raw=False, show_input=True
|
||||
):
|
||||
"""
|
||||
Run code and try to display information to the caller.
|
||||
|
||||
|
|
@ -173,14 +184,10 @@ def _run_code_snippet(caller, pycode, mode="eval", measure_time=False,
|
|||
if show_input:
|
||||
for session in sessions:
|
||||
try:
|
||||
caller.msg(">>> %s" % pycode, session=session,
|
||||
options={"raw": True})
|
||||
caller.msg(">>> %s" % pycode, session=session, options={"raw": True})
|
||||
except TypeError:
|
||||
caller.msg(">>> %s" % pycode, options={"raw": True})
|
||||
|
||||
|
||||
|
||||
|
||||
try:
|
||||
# reroute standard output to game client console
|
||||
old_stdout = sys.stdout
|
||||
|
|
@ -214,7 +221,7 @@ def _run_code_snippet(caller, pycode, mode="eval", measure_time=False,
|
|||
ret = eval(pycode_compiled, {}, available_vars)
|
||||
|
||||
except Exception:
|
||||
errlist = traceback.format_exc().split('\n')
|
||||
errlist = traceback.format_exc().split("\n")
|
||||
if len(errlist) > 4:
|
||||
errlist = errlist[4:]
|
||||
ret = "\n".join("%s" % line for line in errlist if line)
|
||||
|
|
@ -228,26 +235,25 @@ def _run_code_snippet(caller, pycode, mode="eval", measure_time=False,
|
|||
|
||||
for session in sessions:
|
||||
try:
|
||||
caller.msg(ret, session=session, options={"raw": True,
|
||||
"client_raw": client_raw})
|
||||
caller.msg(ret, session=session, options={"raw": True, "client_raw": client_raw})
|
||||
except TypeError:
|
||||
caller.msg(ret, options={"raw": True,
|
||||
"client_raw": client_raw})
|
||||
caller.msg(ret, options={"raw": True, "client_raw": client_raw})
|
||||
|
||||
|
||||
def evennia_local_vars(caller):
|
||||
"""Return Evennia local variables usable in the py command as a dictionary."""
|
||||
import evennia
|
||||
|
||||
return {
|
||||
'self': caller,
|
||||
'me': caller,
|
||||
'here': getattr(caller, "location", None),
|
||||
'evennia': evennia,
|
||||
'ev': evennia,
|
||||
'inherits_from': utils.inherits_from,
|
||||
"self": caller,
|
||||
"me": caller,
|
||||
"here": getattr(caller, "location", None),
|
||||
"evennia": evennia,
|
||||
"ev": evennia,
|
||||
"inherits_from": utils.inherits_from,
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
class EvenniaPythonConsole(code.InteractiveConsole):
|
||||
|
||||
"""Evennia wrapper around a Python interactive console."""
|
||||
|
|
@ -330,6 +336,7 @@ class CmdPy(COMMAND_DEFAULT_CLASS):
|
|||
should only be accessible by trusted server admins/superusers.|n
|
||||
|
||||
"""
|
||||
|
||||
key = "py"
|
||||
aliases = ["!"]
|
||||
switch_options = ("time", "edit", "clientraw")
|
||||
|
|
@ -345,27 +352,40 @@ class CmdPy(COMMAND_DEFAULT_CLASS):
|
|||
if "edit" in self.switches:
|
||||
caller.db._py_measure_time = "time" in self.switches
|
||||
caller.db._py_clientraw = "clientraw" in self.switches
|
||||
EvEditor(self.caller, loadfunc=_py_load, savefunc=_py_code,
|
||||
quitfunc=_py_quit, key="Python exec: :w or :!", persistent=True,
|
||||
codefunc=_py_code)
|
||||
EvEditor(
|
||||
self.caller,
|
||||
loadfunc=_py_load,
|
||||
savefunc=_py_code,
|
||||
quitfunc=_py_quit,
|
||||
key="Python exec: :w or :!",
|
||||
persistent=True,
|
||||
codefunc=_py_code,
|
||||
)
|
||||
return
|
||||
|
||||
if not pycode:
|
||||
# Run in interactive mode
|
||||
console = EvenniaPythonConsole(self.caller)
|
||||
banner = (f"|gPython {sys.version} on {sys.platform}\n"
|
||||
"Evennia interactive console mode - type 'exit()' to leave.|n")
|
||||
banner = (
|
||||
f"|gPython {sys.version} on {sys.platform}\n"
|
||||
"Evennia interactive console mode - type 'exit()' to leave.|n"
|
||||
)
|
||||
self.msg(banner)
|
||||
line = ""
|
||||
prompt = ">>>"
|
||||
while line.lower() not in ("exit", "exit()"):
|
||||
line = yield(prompt)
|
||||
line = yield (prompt)
|
||||
prompt = "..." if console.push(line) else ">>>"
|
||||
self.msg("|gClosing the Python console.|n")
|
||||
return
|
||||
|
||||
_run_code_snippet(caller, self.args, measure_time="time" in self.switches,
|
||||
client_raw="clientraw" in self.switches)
|
||||
_run_code_snippet(
|
||||
caller,
|
||||
self.args,
|
||||
measure_time="time" in self.switches,
|
||||
client_raw="clientraw" in self.switches,
|
||||
)
|
||||
|
||||
|
||||
# helper function. Kept outside so it can be imported and run
|
||||
# by other commands.
|
||||
|
|
@ -376,9 +396,19 @@ def format_script_list(scripts):
|
|||
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",
|
||||
align='r', border="tablecols")
|
||||
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()
|
||||
if nextrep is None:
|
||||
|
|
@ -392,15 +422,17 @@ def format_script_list(scripts):
|
|||
else:
|
||||
rept = "-/-"
|
||||
|
||||
table.add_row(script.id,
|
||||
script.obj.key if (hasattr(script, 'obj') and script.obj) else "<Global>",
|
||||
script.key,
|
||||
script.interval if script.interval > 0 else "--",
|
||||
nextrep,
|
||||
rept,
|
||||
"*" if script.persistent else "-",
|
||||
script.typeclass_path.rsplit('.', 1)[-1],
|
||||
crop(script.desc, width=20))
|
||||
table.add_row(
|
||||
script.id,
|
||||
script.obj.key if (hasattr(script, "obj") and script.obj) else "<Global>",
|
||||
script.key,
|
||||
script.interval if script.interval > 0 else "--",
|
||||
nextrep,
|
||||
rept,
|
||||
"*" if script.persistent else "-",
|
||||
script.typeclass_path.rsplit(".", 1)[-1],
|
||||
crop(script.desc, width=20),
|
||||
)
|
||||
return "%s" % table
|
||||
|
||||
|
||||
|
|
@ -425,6 +457,7 @@ class CmdScripts(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
Use script for managing commands on objects.
|
||||
"""
|
||||
|
||||
key = "scripts"
|
||||
aliases = ["globalscript", "listscripts"]
|
||||
switch_options = ("start", "stop", "kill", "validate")
|
||||
|
|
@ -469,11 +502,11 @@ class CmdScripts(COMMAND_DEFAULT_CLASS):
|
|||
caller.msg(string)
|
||||
return
|
||||
|
||||
if self.switches and self.switches[0] in ('stop', 'del', 'delete', 'kill'):
|
||||
if self.switches and self.switches[0] in ("stop", "del", "delete", "kill"):
|
||||
# we want to delete something
|
||||
if len(scripts) == 1:
|
||||
# we have a unique match!
|
||||
if 'kill' in self.switches:
|
||||
if "kill" in self.switches:
|
||||
string = "Killing script '%s'" % scripts[0].key
|
||||
scripts[0].stop(kill=True)
|
||||
else:
|
||||
|
|
@ -508,8 +541,9 @@ class CmdObjects(COMMAND_DEFAULT_CLASS):
|
|||
a list of <nr> latest objects in database. If not
|
||||
given, <nr> defaults to 10.
|
||||
"""
|
||||
|
||||
key = "objects"
|
||||
aliases = ["listobjects", "listobjs", 'stats', 'db']
|
||||
aliases = ["listobjects", "listobjs", "stats", "db"]
|
||||
locks = "cmd:perm(listobjects) or perm(Builder)"
|
||||
help_category = "System"
|
||||
|
||||
|
|
@ -529,33 +563,49 @@ class CmdObjects(COMMAND_DEFAULT_CLASS):
|
|||
nobjs = nobjs or 1 # fix zero-div error with empty database
|
||||
|
||||
# total object sum table
|
||||
totaltable = self.styled_table("|wtype|n", "|wcomment|n", "|wcount|n", "|w%|n",
|
||||
border="table", align="l")
|
||||
totaltable.align = 'l'
|
||||
totaltable.add_row("Characters", "(BASE_CHARACTER_TYPECLASS + children)",
|
||||
nchars, "%.2f" % ((float(nchars) / nobjs) * 100))
|
||||
totaltable.add_row("Rooms", "(BASE_ROOM_TYPECLASS + children)",
|
||||
nrooms, "%.2f" % ((float(nrooms) / nobjs) * 100))
|
||||
totaltable.add_row("Exits", "(BASE_EXIT_TYPECLASS + children)",
|
||||
nexits, "%.2f" % ((float(nexits) / nobjs) * 100))
|
||||
totaltable = self.styled_table(
|
||||
"|wtype|n", "|wcomment|n", "|wcount|n", "|w%|n", border="table", align="l"
|
||||
)
|
||||
totaltable.align = "l"
|
||||
totaltable.add_row(
|
||||
"Characters",
|
||||
"(BASE_CHARACTER_TYPECLASS + children)",
|
||||
nchars,
|
||||
"%.2f" % ((float(nchars) / nobjs) * 100),
|
||||
)
|
||||
totaltable.add_row(
|
||||
"Rooms",
|
||||
"(BASE_ROOM_TYPECLASS + children)",
|
||||
nrooms,
|
||||
"%.2f" % ((float(nrooms) / nobjs) * 100),
|
||||
)
|
||||
totaltable.add_row(
|
||||
"Exits",
|
||||
"(BASE_EXIT_TYPECLASS + children)",
|
||||
nexits,
|
||||
"%.2f" % ((float(nexits) / nobjs) * 100),
|
||||
)
|
||||
totaltable.add_row("Other", "", nother, "%.2f" % ((float(nother) / nobjs) * 100))
|
||||
|
||||
# typeclass table
|
||||
typetable = self.styled_table("|wtypeclass|n", "|wcount|n", "|w%|n",
|
||||
border="table", align="l")
|
||||
typetable.align = 'l'
|
||||
typetable = self.styled_table(
|
||||
"|wtypeclass|n", "|wcount|n", "|w%|n", border="table", align="l"
|
||||
)
|
||||
typetable.align = "l"
|
||||
dbtotals = ObjectDB.objects.object_totals()
|
||||
for path, count in dbtotals.items():
|
||||
typetable.add_row(path, count, "%.2f" % ((float(count) / nobjs) * 100))
|
||||
|
||||
# last N table
|
||||
objs = ObjectDB.objects.all().order_by("db_date_created")[max(0, nobjs - nlim):]
|
||||
latesttable = self.styled_table("|wcreated|n", "|wdbref|n", "|wname|n",
|
||||
"|wtypeclass|n", align="l", border="table")
|
||||
latesttable.align = 'l'
|
||||
objs = ObjectDB.objects.all().order_by("db_date_created")[max(0, nobjs - nlim) :]
|
||||
latesttable = self.styled_table(
|
||||
"|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)
|
||||
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
|
||||
|
|
@ -578,9 +628,10 @@ class CmdAccounts(COMMAND_DEFAULT_CLASS):
|
|||
It will list the <nr> amount of latest registered accounts
|
||||
If not given, <nr> defaults to 10.
|
||||
"""
|
||||
|
||||
key = "accounts"
|
||||
aliases = ["account", "listaccounts"]
|
||||
switch_options = ("delete", )
|
||||
switch_options = ("delete",)
|
||||
locks = "cmd:perm(listaccounts) or perm(Admin)"
|
||||
help_category = "System"
|
||||
|
||||
|
|
@ -618,11 +669,13 @@ class CmdAccounts(COMMAND_DEFAULT_CLASS):
|
|||
return
|
||||
username = account.username
|
||||
# ask for confirmation
|
||||
confirm = ("It is often better to block access to an account rather than to delete it. "
|
||||
"|yAre you sure you want to permanently delete "
|
||||
"account '|n{}|y'|n yes/[no]?".format(username))
|
||||
answer = yield(confirm)
|
||||
if answer.lower() not in ('y', 'yes'):
|
||||
confirm = (
|
||||
"It is often better to block access to an account rather than to delete it. "
|
||||
"|yAre you sure you want to permanently delete "
|
||||
"account '|n{}|y'|n yes/[no]?".format(username)
|
||||
)
|
||||
answer = yield (confirm)
|
||||
if answer.lower() not in ("y", "yes"):
|
||||
caller.msg("Canceled deletion.")
|
||||
return
|
||||
|
||||
|
|
@ -632,7 +685,10 @@ class CmdAccounts(COMMAND_DEFAULT_CLASS):
|
|||
if reason:
|
||||
string += " Reason given:\n '%s'" % reason
|
||||
account.msg(string)
|
||||
logger.log_sec("Account Deleted: %s (Reason: %s, Caller: %s, IP: %s)." % (account, reason, caller, self.session.address))
|
||||
logger.log_sec(
|
||||
"Account Deleted: %s (Reason: %s, Caller: %s, IP: %s)."
|
||||
% (account, reason, caller, self.session.address)
|
||||
)
|
||||
account.delete()
|
||||
self.msg("Account %s was successfully deleted." % username)
|
||||
return
|
||||
|
|
@ -647,14 +703,20 @@ class CmdAccounts(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
# typeclass table
|
||||
dbtotals = AccountDB.objects.object_totals()
|
||||
typetable = self.styled_table("|wtypeclass|n", "|wcount|n", "|w%%|n", border="cells", align="l")
|
||||
typetable = self.styled_table(
|
||||
"|wtypeclass|n", "|wcount|n", "|w%%|n", border="cells", align="l"
|
||||
)
|
||||
for path, count in dbtotals.items():
|
||||
typetable.add_row(path, count, "%.2f" % ((float(count) / naccounts) * 100))
|
||||
# last N table
|
||||
plyrs = AccountDB.objects.all().order_by("db_date_created")[max(0, naccounts - nlim):]
|
||||
latesttable = self.styled_table("|wcreated|n", "|wdbref|n", "|wname|n", "|wtypeclass|n", border="cells", align="l")
|
||||
plyrs = AccountDB.objects.all().order_by("db_date_created")[max(0, naccounts - nlim) :]
|
||||
latesttable = self.styled_table(
|
||||
"|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)
|
||||
latesttable.add_row(
|
||||
utils.datetime_format(ply.date_created), ply.dbref, ply.key, ply.path
|
||||
)
|
||||
|
||||
string = "\n|wAccount typeclass distribution:|n\n%s" % typetable
|
||||
string += "\n|wLast %s Accounts created:|n\n%s" % (min(naccounts, nlim), latesttable)
|
||||
|
|
@ -703,7 +765,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 = self.styled_table("|wService|n (use services/start|stop|delete)", "|wstatus", align="l")
|
||||
table = self.styled_table(
|
||||
"|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")
|
||||
caller.msg(str(table))
|
||||
|
|
@ -714,8 +778,8 @@ class CmdService(COMMAND_DEFAULT_CLASS):
|
|||
try:
|
||||
service = service_collection.getServiceNamed(self.args)
|
||||
except Exception:
|
||||
string = 'Invalid service name. This command is case-sensitive. '
|
||||
string += 'See service/list for valid service name (enter the full name exactly).'
|
||||
string = "Invalid service name. This command is case-sensitive. "
|
||||
string += "See service/list for valid service name (enter the full name exactly)."
|
||||
caller.msg(string)
|
||||
return
|
||||
|
||||
|
|
@ -725,9 +789,9 @@ class CmdService(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
delmode = switches[0] == "delete"
|
||||
if not service.running:
|
||||
caller.msg('That service is not currently running.')
|
||||
caller.msg("That service is not currently running.")
|
||||
return
|
||||
if service.name[:7] == 'Evennia':
|
||||
if service.name[:7] == "Evennia":
|
||||
if delmode:
|
||||
caller.msg("You cannot remove a core Evennia service (named 'Evennia***').")
|
||||
return
|
||||
|
|
@ -749,7 +813,7 @@ class CmdService(COMMAND_DEFAULT_CLASS):
|
|||
if switches[0] == "start":
|
||||
# Attempt to start a service.
|
||||
if service.running:
|
||||
caller.msg('That service is already running.')
|
||||
caller.msg("That service is already running.")
|
||||
return
|
||||
caller.msg("Starting service '%s'." % self.args)
|
||||
service.startService()
|
||||
|
|
@ -789,11 +853,13 @@ class CmdAbout(COMMAND_DEFAULT_CLASS):
|
|||
|wMaintainer|n (2010-) Griatch (griatch AT gmail DOT com)
|
||||
|wMaintainer|n (2006-10) Greg Taylor
|
||||
|
||||
""".format(version=utils.get_evennia_version(),
|
||||
os=os.name,
|
||||
python=sys.version.split()[0],
|
||||
twisted=twisted.version.short(),
|
||||
django=django.get_version())
|
||||
""".format(
|
||||
version=utils.get_evennia_version(),
|
||||
os=os.name,
|
||||
python=sys.version.split()[0],
|
||||
twisted=twisted.version.short(),
|
||||
django=django.get_version(),
|
||||
)
|
||||
self.caller.msg(string)
|
||||
|
||||
|
||||
|
|
@ -807,6 +873,7 @@ class CmdTime(COMMAND_DEFAULT_CLASS):
|
|||
List Server time statistics such as uptime
|
||||
and the current time stamp.
|
||||
"""
|
||||
|
||||
key = "time"
|
||||
aliases = "uptime"
|
||||
locks = "cmd:perm(time) or perm(Player)"
|
||||
|
|
@ -821,11 +888,19 @@ class CmdTime(COMMAND_DEFAULT_CLASS):
|
|||
table1.add_row("First start", datetime.datetime.fromtimestamp(gametime.server_epoch()))
|
||||
table1.add_row("Current time", datetime.datetime.now())
|
||||
table1.reformat_column(0, width=30)
|
||||
table2 = self.styled_table("|wIn-Game time", "|wReal time x %g" % gametime.TIMEFACTOR, align="l", width=77, border_top=0)
|
||||
table2 = self.styled_table(
|
||||
"|wIn-Game time",
|
||||
"|wReal time x %g" % gametime.TIMEFACTOR,
|
||||
align="l",
|
||||
width=77,
|
||||
border_top=0,
|
||||
)
|
||||
epochtxt = "Epoch (%s)" % ("from settings" if settings.TIME_GAME_EPOCH else "server start")
|
||||
table2.add_row(epochtxt, datetime.datetime.fromtimestamp(gametime.game_epoch()))
|
||||
table2.add_row("Total time passed:", utils.time_format(gametime.gametime(), 2))
|
||||
table2.add_row("Current time ", datetime.datetime.fromtimestamp(gametime.gametime(absolute=True)))
|
||||
table2.add_row(
|
||||
"Current time ", datetime.datetime.fromtimestamp(gametime.gametime(absolute=True))
|
||||
)
|
||||
table2.reformat_column(0, width=30)
|
||||
self.caller.msg(str(table1) + "\n" + str(table2))
|
||||
|
||||
|
|
@ -866,6 +941,7 @@ class CmdServerLoad(COMMAND_DEFAULT_CLASS):
|
|||
the released memory will instead be re-used by the program.
|
||||
|
||||
"""
|
||||
|
||||
key = "server"
|
||||
aliases = ["serverload", "serverprocess"]
|
||||
switch_options = ("mem", "flushmem")
|
||||
|
|
@ -884,8 +960,10 @@ class CmdServerLoad(COMMAND_DEFAULT_CLASS):
|
|||
prev, _ = _IDMAPPER.cache_size()
|
||||
nflushed = _IDMAPPER.flush_cache()
|
||||
now, _ = _IDMAPPER.cache_size()
|
||||
string = "The Idmapper cache freed |w{idmapper}|n database objects.\n" \
|
||||
"The Python garbage collector freed |w{gc}|n Python instances total."
|
||||
string = (
|
||||
"The Idmapper cache freed |w{idmapper}|n database objects.\n"
|
||||
"The Python garbage collector freed |w{gc}|n Python instances total."
|
||||
)
|
||||
self.caller.msg(string.format(idmapper=(prev - now), gc=nflushed))
|
||||
return
|
||||
|
||||
|
|
@ -900,6 +978,7 @@ class CmdServerLoad(COMMAND_DEFAULT_CLASS):
|
|||
# unfortunately, since it's not specific to the process) /rant
|
||||
try:
|
||||
import psutil
|
||||
|
||||
has_psutil = True
|
||||
except ImportError:
|
||||
has_psutil = False
|
||||
|
|
@ -920,8 +999,10 @@ class CmdServerLoad(COMMAND_DEFAULT_CLASS):
|
|||
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)."
|
||||
loadtable = (
|
||||
"Not available on Windows without 'psutil' library "
|
||||
"(install with |wpip install psutil|n)."
|
||||
)
|
||||
|
||||
else:
|
||||
# Linux / BSD (OSX) - proper pid-based statistics
|
||||
|
|
@ -931,9 +1012,15 @@ class CmdServerLoad(COMMAND_DEFAULT_CLASS):
|
|||
import resource as _RESOURCE
|
||||
|
||||
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()) # % of resident memory to total
|
||||
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()
|
||||
) # % of resident memory to total
|
||||
rusage = _RESOURCE.getrusage(_RESOURCE.RUSAGE_SELF)
|
||||
|
||||
if "mem" in self.switches:
|
||||
|
|
@ -947,16 +1034,28 @@ class CmdServerLoad(COMMAND_DEFAULT_CLASS):
|
|||
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("Disk I/O", "%g reads, %g writes" % (rusage.ru_inblock, rusage.ru_oublock))
|
||||
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
|
||||
|
||||
|
|
@ -964,8 +1063,11 @@ class CmdServerLoad(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
# 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)
|
||||
sorted_cache = sorted(
|
||||
[(key, num) for key, num in cachedict.items() if num > 0],
|
||||
key=lambda tup: tup[1],
|
||||
reverse=True,
|
||||
)
|
||||
memtable = self.styled_table("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))
|
||||
|
|
@ -988,22 +1090,29 @@ class CmdTickers(COMMAND_DEFAULT_CLASS):
|
|||
inspecting the current status.
|
||||
|
||||
"""
|
||||
|
||||
key = "tickers"
|
||||
help_category = "System"
|
||||
locks = "cmd:perm(tickers) or perm(Builder)"
|
||||
|
||||
def func(self):
|
||||
from evennia import TICKER_HANDLER
|
||||
|
||||
all_subs = TICKER_HANDLER.all_display()
|
||||
if not all_subs:
|
||||
self.caller.msg("No tickers are currently active.")
|
||||
return
|
||||
table = self.styled_table("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 ""),
|
||||
sub[1] if sub[1] else sub[2],
|
||||
sub[4] or "[Unset]",
|
||||
"*" if sub[5] else "-")
|
||||
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 "",
|
||||
),
|
||||
sub[1] if sub[1] else sub[2],
|
||||
sub[4] or "[Unset]",
|
||||
"*" if sub[5] else "-",
|
||||
)
|
||||
self.caller.msg("|wActive tickers|n:\n" + str(table))
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -14,8 +14,13 @@ from evennia.commands.cmdhandler import CMD_LOGINSTART
|
|||
COMMAND_DEFAULT_CLASS = utils.class_from_module(settings.COMMAND_DEFAULT_CLASS)
|
||||
|
||||
# limit symbol import for API
|
||||
__all__ = ("CmdUnconnectedConnect", "CmdUnconnectedCreate",
|
||||
"CmdUnconnectedQuit", "CmdUnconnectedLook", "CmdUnconnectedHelp")
|
||||
__all__ = (
|
||||
"CmdUnconnectedConnect",
|
||||
"CmdUnconnectedCreate",
|
||||
"CmdUnconnectedQuit",
|
||||
"CmdUnconnectedLook",
|
||||
"CmdUnconnectedHelp",
|
||||
)
|
||||
|
||||
MULTISESSION_MODE = settings.MULTISESSION_MODE
|
||||
CONNECTION_SCREEN_MODULE = settings.CONNECTION_SCREEN_MODULE
|
||||
|
|
@ -45,7 +50,7 @@ def create_guest_account(session):
|
|||
if account:
|
||||
return enabled, account
|
||||
else:
|
||||
session.msg("|R%s|n" % '\n'.join(errors))
|
||||
session.msg("|R%s|n" % "\n".join(errors))
|
||||
return enabled, None
|
||||
|
||||
|
||||
|
|
@ -68,10 +73,12 @@ def create_normal_account(session, name, password):
|
|||
|
||||
# Match account name and check password
|
||||
# authenticate() handles all its own throttling
|
||||
account, errors = Account.authenticate(username=name, password=password, ip=address, session=session)
|
||||
account, errors = Account.authenticate(
|
||||
username=name, password=password, ip=address, session=session
|
||||
)
|
||||
if not account:
|
||||
# No accountname or password match
|
||||
session.msg("|R%s|n" % '\n'.join(errors))
|
||||
session.msg("|R%s|n" % "\n".join(errors))
|
||||
return None
|
||||
|
||||
return account
|
||||
|
|
@ -89,6 +96,7 @@ class CmdUnconnectedConnect(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
If you have spaces in your name, enclose it in double quotes.
|
||||
"""
|
||||
|
||||
key = "connect"
|
||||
aliases = ["conn", "con", "co"]
|
||||
locks = "cmd:all()" # not really needed
|
||||
|
|
@ -122,7 +130,7 @@ class CmdUnconnectedConnect(COMMAND_DEFAULT_CLASS):
|
|||
session.sessionhandler.login(session, account)
|
||||
return
|
||||
else:
|
||||
session.msg("|R%s|n" % '\n'.join(errors))
|
||||
session.msg("|R%s|n" % "\n".join(errors))
|
||||
return
|
||||
|
||||
if len(parts) != 2:
|
||||
|
|
@ -133,11 +141,13 @@ class CmdUnconnectedConnect(COMMAND_DEFAULT_CLASS):
|
|||
Account = class_from_module(settings.BASE_ACCOUNT_TYPECLASS)
|
||||
|
||||
name, password = parts
|
||||
account, errors = Account.authenticate(username=name, password=password, ip=address, session=session)
|
||||
account, errors = Account.authenticate(
|
||||
username=name, password=password, ip=address, session=session
|
||||
)
|
||||
if account:
|
||||
session.sessionhandler.login(session, account)
|
||||
else:
|
||||
session.msg("|R%s|n" % '\n'.join(errors))
|
||||
session.msg("|R%s|n" % "\n".join(errors))
|
||||
|
||||
|
||||
class CmdUnconnectedCreate(COMMAND_DEFAULT_CLASS):
|
||||
|
|
@ -152,6 +162,7 @@ class CmdUnconnectedCreate(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
If you have spaces in your name, enclose it in double quotes.
|
||||
"""
|
||||
|
||||
key = "create"
|
||||
aliases = ["cre", "cr"]
|
||||
locks = "cmd:all()"
|
||||
|
|
@ -174,25 +185,31 @@ class CmdUnconnectedCreate(COMMAND_DEFAULT_CLASS):
|
|||
# this was (hopefully) due to no quotes being found
|
||||
parts = parts[0].split(None, 1)
|
||||
if len(parts) != 2:
|
||||
string = "\n Usage (without <>): create <name> <password>" \
|
||||
"\nIf <name> or <password> contains spaces, enclose it in double quotes."
|
||||
string = (
|
||||
"\n Usage (without <>): create <name> <password>"
|
||||
"\nIf <name> or <password> contains spaces, enclose it in double quotes."
|
||||
)
|
||||
session.msg(string)
|
||||
return
|
||||
|
||||
username, password = parts
|
||||
|
||||
# everything's ok. Create the new account account.
|
||||
account, errors = Account.create(username=username, password=password, ip=address, session=session)
|
||||
account, errors = Account.create(
|
||||
username=username, password=password, ip=address, session=session
|
||||
)
|
||||
if account:
|
||||
# tell the caller everything went well.
|
||||
string = "A new account '%s' was created. Welcome!"
|
||||
if " " in username:
|
||||
string += "\n\nYou can now log in with the command 'connect \"%s\" <your password>'."
|
||||
string += (
|
||||
"\n\nYou can now log in with the command 'connect \"%s\" <your password>'."
|
||||
)
|
||||
else:
|
||||
string += "\n\nYou can now log with the command 'connect %s <your password>'."
|
||||
session.msg(string % (username, username))
|
||||
else:
|
||||
session.msg("|R%s|n" % '\n'.join(errors))
|
||||
session.msg("|R%s|n" % "\n".join(errors))
|
||||
|
||||
|
||||
class CmdUnconnectedQuit(COMMAND_DEFAULT_CLASS):
|
||||
|
|
@ -206,6 +223,7 @@ class CmdUnconnectedQuit(COMMAND_DEFAULT_CLASS):
|
|||
here for unconnected accounts for the sake of simplicity. The logged in
|
||||
version is a bit more complicated.
|
||||
"""
|
||||
|
||||
key = "quit"
|
||||
aliases = ["q", "qu"]
|
||||
locks = "cmd:all()"
|
||||
|
|
@ -228,6 +246,7 @@ class CmdUnconnectedLook(COMMAND_DEFAULT_CLASS):
|
|||
This is called by the server and kicks everything in gear.
|
||||
All it does is display the connect screen.
|
||||
"""
|
||||
|
||||
key = CMD_LOGINSTART
|
||||
aliases = ["look", "l"]
|
||||
locks = "cmd:all()"
|
||||
|
|
@ -237,7 +256,7 @@ class CmdUnconnectedLook(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
callables = utils.callables_from_module(CONNECTION_SCREEN_MODULE)
|
||||
if "connection_screen" in callables:
|
||||
connection_screen = callables['connection_screen']()
|
||||
connection_screen = callables["connection_screen"]()
|
||||
else:
|
||||
connection_screen = utils.random_string_from_module(CONNECTION_SCREEN_MODULE)
|
||||
if not connection_screen:
|
||||
|
|
@ -255,6 +274,7 @@ class CmdUnconnectedHelp(COMMAND_DEFAULT_CLASS):
|
|||
This is an unconnected version of the help command,
|
||||
for simplicity. It shows a pane of info.
|
||||
"""
|
||||
|
||||
key = "help"
|
||||
aliases = ["h", "?"]
|
||||
locks = "cmd:all()"
|
||||
|
|
@ -262,8 +282,7 @@ class CmdUnconnectedHelp(COMMAND_DEFAULT_CLASS):
|
|||
def func(self):
|
||||
"""Shows help"""
|
||||
|
||||
string = \
|
||||
"""
|
||||
string = """
|
||||
You are not yet logged into the game. Commands available at this point:
|
||||
|
||||
|wcreate|n - create a new account
|
||||
|
|
@ -283,7 +302,7 @@ You can use the |wlook|n command if you want to see the connect screen again.
|
|||
"""
|
||||
|
||||
if settings.STAFF_CONTACT_EMAIL:
|
||||
string += 'For support, please contact: %s' % settings.STAFF_CONTACT_EMAIL
|
||||
string += "For support, please contact: %s" % settings.STAFF_CONTACT_EMAIL
|
||||
self.caller.msg(string)
|
||||
|
||||
|
||||
|
|
@ -311,7 +330,7 @@ class CmdUnconnectedEncoding(COMMAND_DEFAULT_CLASS):
|
|||
"""
|
||||
|
||||
key = "encoding"
|
||||
aliases = ("encode")
|
||||
aliases = "encode"
|
||||
locks = "cmd:all()"
|
||||
|
||||
def func(self):
|
||||
|
|
@ -323,7 +342,7 @@ class CmdUnconnectedEncoding(COMMAND_DEFAULT_CLASS):
|
|||
return
|
||||
|
||||
sync = False
|
||||
if 'clear' in self.switches:
|
||||
if "clear" in self.switches:
|
||||
# remove customization
|
||||
old_encoding = self.session.protocol_flags.get("ENCODING", None)
|
||||
if old_encoding:
|
||||
|
|
@ -337,10 +356,15 @@ class CmdUnconnectedEncoding(COMMAND_DEFAULT_CLASS):
|
|||
pencoding = self.session.protocol_flags.get("ENCODING", None)
|
||||
string = ""
|
||||
if pencoding:
|
||||
string += "Default encoding: |g%s|n (change with |wencoding <encoding>|n)" % pencoding
|
||||
string += (
|
||||
"Default encoding: |g%s|n (change with |wencoding <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:
|
||||
|
|
@ -350,11 +374,16 @@ class CmdUnconnectedEncoding(COMMAND_DEFAULT_CLASS):
|
|||
try:
|
||||
codecs_lookup(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)
|
||||
string = "Your custom text encoding was changed from '|w%s|n' to '|w%s|n'." % (
|
||||
old_encoding,
|
||||
encoding,
|
||||
)
|
||||
sync = True
|
||||
if sync:
|
||||
self.session.sessionhandler.session_portal_sync(self.session)
|
||||
|
|
@ -371,6 +400,7 @@ class CmdUnconnectedScreenreader(COMMAND_DEFAULT_CLASS):
|
|||
Used to flip screenreader mode on and off before logging in (when
|
||||
logged in, use option screenreader on).
|
||||
"""
|
||||
|
||||
key = "screenreader"
|
||||
|
||||
def func(self):
|
||||
|
|
@ -390,14 +420,20 @@ class CmdUnconnectedInfo(COMMAND_DEFAULT_CLASS):
|
|||
was created by looking at the MUDINFO implementation in MUX2, TinyMUSH, Rhost,
|
||||
and PennMUSH.
|
||||
"""
|
||||
|
||||
key = "info"
|
||||
locks = "cmd:all()"
|
||||
|
||||
def func(self):
|
||||
self.caller.msg("## BEGIN INFO 1.1\nName: %s\nUptime: %s\nConnected: %d\nVersion: Evennia %s\n## END INFO" % (
|
||||
settings.SERVERNAME,
|
||||
datetime.datetime.fromtimestamp(gametime.SERVER_START_TIME).ctime(),
|
||||
SESSIONS.account_count(), utils.get_evennia_version()))
|
||||
self.caller.msg(
|
||||
"## BEGIN INFO 1.1\nName: %s\nUptime: %s\nConnected: %d\nVersion: Evennia %s\n## END INFO"
|
||||
% (
|
||||
settings.SERVERNAME,
|
||||
datetime.datetime.fromtimestamp(gametime.SERVER_START_TIME).ctime(),
|
||||
SESSIONS.account_count(),
|
||||
utils.get_evennia_version(),
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def _create_account(session, accountname, password, permissions, typeclass=None, email=None):
|
||||
|
|
@ -405,10 +441,15 @@ def _create_account(session, accountname, password, permissions, typeclass=None,
|
|||
Helper function, creates an account of the specified typeclass.
|
||||
"""
|
||||
try:
|
||||
new_account = create.create_account(accountname, email, password, permissions=permissions, typeclass=typeclass)
|
||||
new_account = create.create_account(
|
||||
accountname, email, password, permissions=permissions, typeclass=typeclass
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
session.msg("There was an error creating the Account:\n%s\n If this problem persists, contact an admin." % e)
|
||||
session.msg(
|
||||
"There was an error creating the Account:\n%s\n If this problem persists, contact an admin."
|
||||
% e
|
||||
)
|
||||
logger.log_trace()
|
||||
return False
|
||||
|
||||
|
|
@ -431,13 +472,17 @@ def _create_character(session, new_account, typeclass, home, permissions):
|
|||
This is meant for Guest and MULTISESSION_MODE < 2 situations.
|
||||
"""
|
||||
try:
|
||||
new_character = create.create_object(typeclass, key=new_account.key, home=home, permissions=permissions)
|
||||
new_character = create.create_object(
|
||||
typeclass, key=new_account.key, home=home, permissions=permissions
|
||||
)
|
||||
# set playable character list
|
||||
new_account.db._playable_characters.append(new_character)
|
||||
|
||||
# allow only the character itself and the account to puppet this character (and Developers).
|
||||
new_character.locks.add("puppet:id(%i) or pid(%i) or perm(Developer) or pperm(Developer)" %
|
||||
(new_character.id, new_account.id))
|
||||
new_character.locks.add(
|
||||
"puppet:id(%i) or pid(%i) or perm(Developer) or pperm(Developer)"
|
||||
% (new_character.id, new_account.id)
|
||||
)
|
||||
|
||||
# If no description is set, set a default description
|
||||
if not new_character.db.desc:
|
||||
|
|
@ -445,5 +490,8 @@ def _create_character(session, new_account, typeclass, home, permissions):
|
|||
# We need to set this to have ic auto-connect to this character
|
||||
new_account.db._last_puppet = new_character
|
||||
except Exception as e:
|
||||
session.msg("There was an error creating the Character:\n%s\n If this problem persists, contact an admin." % e)
|
||||
session.msg(
|
||||
"There was an error creating the Character:\n%s\n If this problem persists, contact an admin."
|
||||
% e
|
||||
)
|
||||
logger.log_trace()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue