Ran black on branc
This commit is contained in:
parent
6effb6f456
commit
4ea6209123
230 changed files with 7108 additions and 2395 deletions
|
|
@ -39,25 +39,25 @@ SERVERNAME = "testing_mygame"
|
||||||
# Testing database types
|
# Testing database types
|
||||||
|
|
||||||
DATABASES = {
|
DATABASES = {
|
||||||
'default': {
|
"default": {
|
||||||
'ENGINE': 'django.db.backends.mysql',
|
"ENGINE": "django.db.backends.mysql",
|
||||||
'NAME': 'evennia',
|
"NAME": "evennia",
|
||||||
'USER': 'evennia',
|
"USER": "evennia",
|
||||||
'PASSWORD': 'password',
|
"PASSWORD": "password",
|
||||||
'HOST': 'localhost',
|
"HOST": "localhost",
|
||||||
'PORT': '', # use default port
|
"PORT": "", # use default port
|
||||||
'OPTIONS': {
|
"OPTIONS": {
|
||||||
'charset': 'utf8mb4',
|
"charset": "utf8mb4",
|
||||||
'init_command': 'set collation_connection=utf8mb4_unicode_ci'
|
"init_command": "set collation_connection=utf8mb4_unicode_ci",
|
||||||
},
|
},
|
||||||
'TEST': {
|
"TEST": {
|
||||||
'NAME': 'default',
|
"NAME": "default",
|
||||||
'OPTIONS': {
|
"OPTIONS": {
|
||||||
'charset': 'utf8mb4',
|
"charset": "utf8mb4",
|
||||||
# 'init_command': 'set collation_connection=utf8mb4_unicode_ci'
|
# 'init_command': 'set collation_connection=utf8mb4_unicode_ci'
|
||||||
'init_command': "SET NAMES 'utf8mb4'"
|
"init_command": "SET NAMES 'utf8mb4'",
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,16 +39,14 @@ SERVERNAME = "testing_mygame"
|
||||||
# Testing database types
|
# Testing database types
|
||||||
|
|
||||||
DATABASES = {
|
DATABASES = {
|
||||||
'default': {
|
"default": {
|
||||||
'ENGINE': 'django.db.backends.postgresql_psycopg2',
|
"ENGINE": "django.db.backends.postgresql_psycopg2",
|
||||||
'NAME': 'evennia',
|
"NAME": "evennia",
|
||||||
'USER': 'evennia',
|
"USER": "evennia",
|
||||||
'PASSWORD': 'password',
|
"PASSWORD": "password",
|
||||||
'HOST': 'localhost',
|
"HOST": "localhost",
|
||||||
'PORT': '', # use default
|
"PORT": "", # use default
|
||||||
'TEST': {
|
"TEST": {"NAME": "default"},
|
||||||
'NAME': 'default'
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ USE_COLOR = True
|
||||||
FAKE_MODE = False
|
FAKE_MODE = False
|
||||||
|
|
||||||
# if these words are longer than output word, retain given case
|
# if these words are longer than output word, retain given case
|
||||||
CASE_WORD_EXCEPTIONS = ('an', )
|
CASE_WORD_EXCEPTIONS = ("an",)
|
||||||
|
|
||||||
_HELP_TEXT = """This program interactively renames words in all files of your project. It's
|
_HELP_TEXT = """This program interactively renames words in all files of your project. It's
|
||||||
currently renaming {sources} to {targets}.
|
currently renaming {sources} to {targets}.
|
||||||
|
|
@ -80,6 +80,7 @@ def _case_sensitive_replace(string, old, new):
|
||||||
`old` has been replaced with `new`, retaining case.
|
`old` has been replaced with `new`, retaining case.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def repl(match):
|
def repl(match):
|
||||||
current = match.group()
|
current = match.group()
|
||||||
# treat multi-word sentences word-by-word
|
# treat multi-word sentences word-by-word
|
||||||
|
|
@ -99,15 +100,21 @@ def _case_sensitive_replace(string, old, new):
|
||||||
all_upper = False
|
all_upper = False
|
||||||
# special cases - keep remaing case)
|
# special cases - keep remaing case)
|
||||||
if new_word.lower() in CASE_WORD_EXCEPTIONS:
|
if new_word.lower() in CASE_WORD_EXCEPTIONS:
|
||||||
result.append(new_word[ind + 1:])
|
result.append(new_word[ind + 1 :])
|
||||||
# append any remaining characters from new
|
# append any remaining characters from new
|
||||||
elif all_upper:
|
elif all_upper:
|
||||||
result.append(new_word[ind + 1:].upper())
|
result.append(new_word[ind + 1 :].upper())
|
||||||
else:
|
else:
|
||||||
result.append(new_word[ind + 1:].lower())
|
result.append(new_word[ind + 1 :].lower())
|
||||||
out.append("".join(result))
|
out.append("".join(result))
|
||||||
# if we have more new words than old ones, just add them verbatim
|
# if we have more new words than old ones, just add them verbatim
|
||||||
out.extend([new_word for ind, new_word in enumerate(new_words) if ind >= len(old_words)])
|
out.extend(
|
||||||
|
[
|
||||||
|
new_word
|
||||||
|
for ind, new_word in enumerate(new_words)
|
||||||
|
if ind >= len(old_words)
|
||||||
|
]
|
||||||
|
)
|
||||||
return " ".join(out)
|
return " ".join(out)
|
||||||
|
|
||||||
regex = re.compile(re.escape(old), re.I)
|
regex = re.compile(re.escape(old), re.I)
|
||||||
|
|
@ -147,7 +154,9 @@ def rename_in_tree(path, in_list, out_list, excl_list, fileend_list, is_interact
|
||||||
print("%s skipped (excluded)." % full_path)
|
print("%s skipped (excluded)." % full_path)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if not fileend_list or any(file.endswith(ending) for ending in fileend_list):
|
if not fileend_list or any(
|
||||||
|
file.endswith(ending) for ending in fileend_list
|
||||||
|
):
|
||||||
rename_in_file(full_path, in_list, out_list, is_interactive)
|
rename_in_file(full_path, in_list, out_list, is_interactive)
|
||||||
|
|
||||||
# rename file - always ask
|
# rename file - always ask
|
||||||
|
|
@ -155,8 +164,10 @@ def rename_in_tree(path, in_list, out_list, excl_list, fileend_list, is_interact
|
||||||
for src, dst in repl_mapping:
|
for src, dst in repl_mapping:
|
||||||
new_file = _case_sensitive_replace(new_file, src, dst)
|
new_file = _case_sensitive_replace(new_file, src, dst)
|
||||||
if new_file != file:
|
if new_file != file:
|
||||||
inp = input(_green("Rename %s\n -> %s\n Y/[N]? > " % (file, new_file)))
|
inp = input(
|
||||||
if inp.upper() == 'Y':
|
_green("Rename %s\n -> %s\n Y/[N]? > " % (file, new_file))
|
||||||
|
)
|
||||||
|
if inp.upper() == "Y":
|
||||||
new_full_path = os.path.join(root, new_file)
|
new_full_path = os.path.join(root, new_file)
|
||||||
try:
|
try:
|
||||||
os.rename(full_path, new_full_path)
|
os.rename(full_path, new_full_path)
|
||||||
|
|
@ -171,8 +182,10 @@ def rename_in_tree(path, in_list, out_list, excl_list, fileend_list, is_interact
|
||||||
for src, dst in repl_mapping:
|
for src, dst in repl_mapping:
|
||||||
new_root = _case_sensitive_replace(new_root, src, dst)
|
new_root = _case_sensitive_replace(new_root, src, dst)
|
||||||
if new_root != root:
|
if new_root != root:
|
||||||
inp = input(_green("Dir Rename %s\n -> %s\n Y/[N]? > " % (root, new_root)))
|
inp = input(
|
||||||
if inp.upper() == 'Y':
|
_green("Dir Rename %s\n -> %s\n Y/[N]? > " % (root, new_root))
|
||||||
|
)
|
||||||
|
if inp.upper() == "Y":
|
||||||
try:
|
try:
|
||||||
os.rename(root, new_root)
|
os.rename(root, new_root)
|
||||||
except OSError as err:
|
except OSError as err:
|
||||||
|
|
@ -201,7 +214,7 @@ def rename_in_file(path, in_list, out_list, is_interactive):
|
||||||
print("%s is a directory. You should use the --recursive option." % path)
|
print("%s is a directory. You should use the --recursive option." % path)
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
||||||
with open(path, 'r') as fil:
|
with open(path, "r") as fil:
|
||||||
org_text = fil.read()
|
org_text = fil.read()
|
||||||
|
|
||||||
repl_mapping = list(zip(in_list, out_list))
|
repl_mapping = list(zip(in_list, out_list))
|
||||||
|
|
@ -215,7 +228,7 @@ def rename_in_file(path, in_list, out_list, is_interactive):
|
||||||
if FAKE_MODE:
|
if FAKE_MODE:
|
||||||
print(" ... Saved changes to %s. (faked)" % path)
|
print(" ... Saved changes to %s. (faked)" % path)
|
||||||
else:
|
else:
|
||||||
with open(path, 'w') as fil:
|
with open(path, "w") as fil:
|
||||||
fil.write(new_text)
|
fil.write(new_text)
|
||||||
print(" ... Saved changes to %s." % path)
|
print(" ... Saved changes to %s." % path)
|
||||||
else:
|
else:
|
||||||
|
|
@ -239,18 +252,24 @@ def rename_in_file(path, in_list, out_list, is_interactive):
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
|
|
||||||
for iline, renamed_line in sorted(list(renamed.items()), key=lambda tup: tup[0]):
|
for iline, renamed_line in sorted(
|
||||||
|
list(renamed.items()), key=lambda tup: tup[0]
|
||||||
|
):
|
||||||
print("%3i orig: %s" % (iline + 1, org_lines[iline]))
|
print("%3i orig: %s" % (iline + 1, org_lines[iline]))
|
||||||
print(" new : %s" % (_yellow(renamed_line)))
|
print(" new : %s" % (_yellow(renamed_line)))
|
||||||
print(_green("%s (%i lines changed)" % (path, len(renamed))))
|
print(_green("%s (%i lines changed)" % (path, len(renamed))))
|
||||||
|
|
||||||
ret = input(_green("Choose: "
|
ret = input(
|
||||||
|
_green(
|
||||||
|
"Choose: "
|
||||||
"[q]uit, "
|
"[q]uit, "
|
||||||
"[h]elp, "
|
"[h]elp, "
|
||||||
"[s]kip file, "
|
"[s]kip file, "
|
||||||
"[i]gnore lines, "
|
"[i]gnore lines, "
|
||||||
"[c]lear ignores, "
|
"[c]lear ignores, "
|
||||||
"[a]ccept/save file: ".lower()))
|
"[a]ccept/save file: ".lower()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
if ret == "s":
|
if ret == "s":
|
||||||
# skip file entirely
|
# skip file entirely
|
||||||
|
|
@ -267,7 +286,7 @@ def rename_in_file(path, in_list, out_list, is_interactive):
|
||||||
if FAKE_MODE:
|
if FAKE_MODE:
|
||||||
print(" ... Saved file %s (faked)" % path)
|
print(" ... Saved file %s (faked)" % path)
|
||||||
return
|
return
|
||||||
with open(path, 'w') as fil:
|
with open(path, "w") as fil:
|
||||||
fil.writelines("\n".join(org_lines))
|
fil.writelines("\n".join(org_lines))
|
||||||
print(" ... Saved file %s" % path)
|
print(" ... Saved file %s" % path)
|
||||||
return
|
return
|
||||||
|
|
@ -278,7 +297,11 @@ def rename_in_file(path, in_list, out_list, is_interactive):
|
||||||
input(_HELP_TEXT.format(sources=in_list, targets=out_list))
|
input(_HELP_TEXT.format(sources=in_list, targets=out_list))
|
||||||
elif ret.startswith("i"):
|
elif ret.startswith("i"):
|
||||||
# ignore one or more lines
|
# ignore one or more lines
|
||||||
ignores = [int(ind) - 1 for ind in ret[1:].split(',') if ind.strip().isdigit()]
|
ignores = [
|
||||||
|
int(ind) - 1
|
||||||
|
for ind in ret[1:].split(",")
|
||||||
|
if ind.strip().isdigit()
|
||||||
|
]
|
||||||
if not ignores:
|
if not ignores:
|
||||||
input("Ignore example: i 2,7,34,133\n (return to continue)")
|
input("Ignore example: i 2,7,34,133\n (return to continue)")
|
||||||
continue
|
continue
|
||||||
|
|
@ -291,36 +314,57 @@ if __name__ == "__main__":
|
||||||
import argparse
|
import argparse
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
description="Rename text in a source tree, or a single file")
|
description="Rename text in a source tree, or a single file"
|
||||||
|
)
|
||||||
|
|
||||||
parser.add_argument('-i', '--input', action='append',
|
parser.add_argument(
|
||||||
help="Source word to rename (quote around multiple words)")
|
"-i",
|
||||||
parser.add_argument('-o', '--output', action='append',
|
"--input",
|
||||||
help="Word to rename a matching src-word to")
|
action="append",
|
||||||
parser.add_argument('-x', '--exc', action='append',
|
help="Source word to rename (quote around multiple words)",
|
||||||
help="File path patterns to exclude")
|
)
|
||||||
parser.add_argument('-a', '--auto', action='store_true',
|
parser.add_argument(
|
||||||
help="Automatic mode, don't ask to rename")
|
"-o", "--output", action="append", help="Word to rename a matching src-word to"
|
||||||
parser.add_argument('-r', '--recursive', action='store_true',
|
)
|
||||||
help="Recurse subdirs")
|
parser.add_argument(
|
||||||
parser.add_argument('-f', '--fileending', action='append',
|
"-x", "--exc", action="append", help="File path patterns to exclude"
|
||||||
help="Change which file endings to allow (default .py and .html)")
|
)
|
||||||
parser.add_argument('--nocolor', action='store_true',
|
parser.add_argument(
|
||||||
help="Turn off in-program color")
|
"-a", "--auto", action="store_true", help="Automatic mode, don't ask to rename"
|
||||||
parser.add_argument('--fake', action='store_true',
|
)
|
||||||
help="Simulate run but don't actually save")
|
parser.add_argument(
|
||||||
parser.add_argument('path',
|
"-r", "--recursive", action="store_true", help="Recurse subdirs"
|
||||||
help="File or directory in which to rename text")
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"-f",
|
||||||
|
"--fileending",
|
||||||
|
action="append",
|
||||||
|
help="Change which file endings to allow (default .py and .html)",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--nocolor", action="store_true", help="Turn off in-program color"
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--fake", action="store_true", help="Simulate run but don't actually save"
|
||||||
|
)
|
||||||
|
parser.add_argument("path", help="File or directory in which to rename text")
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
in_list, out_list, exc_list, fileend_list = args.input, args.output, args.exc, args.fileending
|
in_list, out_list, exc_list, fileend_list = (
|
||||||
|
args.input,
|
||||||
|
args.output,
|
||||||
|
args.exc,
|
||||||
|
args.fileending,
|
||||||
|
)
|
||||||
|
|
||||||
if not (in_list and out_list):
|
if not (in_list and out_list):
|
||||||
print('At least one source- and destination word must be given.')
|
print("At least one source- and destination word must be given.")
|
||||||
sys.exit()
|
sys.exit()
|
||||||
if len(in_list) != len(out_list):
|
if len(in_list) != len(out_list):
|
||||||
print('Number of sources must be identical to the number of destination arguments.')
|
print(
|
||||||
|
"Number of sources must be identical to the number of destination arguments."
|
||||||
|
)
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
||||||
exc_list = exc_list or []
|
exc_list = exc_list or []
|
||||||
|
|
@ -332,6 +376,8 @@ if __name__ == "__main__":
|
||||||
FAKE_MODE = args.fake
|
FAKE_MODE = args.fake
|
||||||
|
|
||||||
if is_recursive:
|
if is_recursive:
|
||||||
rename_in_tree(args.path, in_list, out_list, exc_list, fileend_list, is_interactive)
|
rename_in_tree(
|
||||||
|
args.path, in_list, out_list, exc_list, fileend_list, is_interactive
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
rename_in_file(args.path, in_list, out_list, is_interactive)
|
rename_in_file(args.path, in_list, out_list, is_interactive)
|
||||||
|
|
|
||||||
|
|
@ -14,4 +14,5 @@ sys.path.insert(0, os.path.abspath(os.getcwd()))
|
||||||
sys.path.insert(0, os.path.join(sys.prefix, "Lib", "site-packages"))
|
sys.path.insert(0, os.path.join(sys.prefix, "Lib", "site-packages"))
|
||||||
|
|
||||||
from evennia.server.evennia_launcher import main
|
from evennia.server.evennia_launcher import main
|
||||||
|
|
||||||
main()
|
main()
|
||||||
|
|
|
||||||
|
|
@ -142,7 +142,9 @@ def _create_version():
|
||||||
print(err)
|
print(err)
|
||||||
try:
|
try:
|
||||||
rev = (
|
rev = (
|
||||||
check_output("git rev-parse --short HEAD", shell=True, cwd=root, stderr=STDOUT)
|
check_output(
|
||||||
|
"git rev-parse --short HEAD", shell=True, cwd=root, stderr=STDOUT
|
||||||
|
)
|
||||||
.strip()
|
.strip()
|
||||||
.decode()
|
.decode()
|
||||||
)
|
)
|
||||||
|
|
@ -261,7 +263,9 @@ def _init():
|
||||||
|
|
||||||
def _help(self):
|
def _help(self):
|
||||||
"Returns list of contents"
|
"Returns list of contents"
|
||||||
names = [name for name in self.__class__.__dict__ if not name.startswith("_")]
|
names = [
|
||||||
|
name for name in self.__class__.__dict__ if not name.startswith("_")
|
||||||
|
]
|
||||||
names += [name for name in self.__dict__ if not name.startswith("_")]
|
names += [name for name in self.__dict__ if not name.startswith("_")]
|
||||||
print(self.__doc__ + "-" * 60 + "\n" + ", ".join(names))
|
print(self.__doc__ + "-" * 60 + "\n" + ", ".join(names))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,13 @@ from evennia.commands import cmdhandler
|
||||||
from evennia.server.models import ServerConfig
|
from evennia.server.models import ServerConfig
|
||||||
from evennia.server.throttle import Throttle
|
from evennia.server.throttle import Throttle
|
||||||
from evennia.utils import class_from_module, create, logger
|
from evennia.utils import class_from_module, create, logger
|
||||||
from evennia.utils.utils import lazy_property, to_str, make_iter, is_iter, variable_from_module
|
from evennia.utils.utils import (
|
||||||
|
lazy_property,
|
||||||
|
to_str,
|
||||||
|
make_iter,
|
||||||
|
is_iter,
|
||||||
|
variable_from_module,
|
||||||
|
)
|
||||||
from evennia.server.signals import (
|
from evennia.server.signals import (
|
||||||
SIGNAL_ACCOUNT_POST_CREATE,
|
SIGNAL_ACCOUNT_POST_CREATE,
|
||||||
SIGNAL_OBJECT_POST_PUPPET,
|
SIGNAL_OBJECT_POST_PUPPET,
|
||||||
|
|
@ -289,7 +295,9 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase):
|
||||||
self.msg(txt1, session=session)
|
self.msg(txt1, session=session)
|
||||||
self.msg(txt2, session=obj.sessions.all())
|
self.msg(txt2, session=obj.sessions.all())
|
||||||
else:
|
else:
|
||||||
txt1 = f"Taking over |c{obj.name}|n from another of your sessions."
|
txt1 = (
|
||||||
|
f"Taking over |c{obj.name}|n from another of your sessions."
|
||||||
|
)
|
||||||
txt2 = f"|c{obj.name}|n|R is now acted from another of your sessions.|n"
|
txt2 = f"|c{obj.name}|n|R is now acted from another of your sessions.|n"
|
||||||
self.msg(txt1, session=session)
|
self.msg(txt1, session=session)
|
||||||
self.msg(txt2, session=obj.sessions.all())
|
self.msg(txt2, session=obj.sessions.all())
|
||||||
|
|
@ -344,7 +352,9 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase):
|
||||||
if not obj.sessions.count():
|
if not obj.sessions.count():
|
||||||
del obj.account
|
del obj.account
|
||||||
obj.at_post_unpuppet(self, session=session)
|
obj.at_post_unpuppet(self, session=session)
|
||||||
SIGNAL_OBJECT_POST_UNPUPPET.send(sender=obj, session=session, account=self)
|
SIGNAL_OBJECT_POST_UNPUPPET.send(
|
||||||
|
sender=obj, session=session, account=self
|
||||||
|
)
|
||||||
# Just to be sure we're always clear.
|
# Just to be sure we're always clear.
|
||||||
session.puppet = None
|
session.puppet = None
|
||||||
session.puid = None
|
session.puid = None
|
||||||
|
|
@ -380,7 +390,9 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase):
|
||||||
by this Account.
|
by this Account.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return list(set(session.puppet for session in self.sessions.all() if session.puppet))
|
return list(
|
||||||
|
set(session.puppet for session in self.sessions.all() if session.puppet)
|
||||||
|
)
|
||||||
|
|
||||||
def __get_single_puppet(self):
|
def __get_single_puppet(self):
|
||||||
"""
|
"""
|
||||||
|
|
@ -723,7 +735,11 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase):
|
||||||
try:
|
try:
|
||||||
try:
|
try:
|
||||||
account = create.create_account(
|
account = create.create_account(
|
||||||
username, email, password, permissions=permissions, typeclass=typeclass
|
username,
|
||||||
|
email,
|
||||||
|
password,
|
||||||
|
permissions=permissions,
|
||||||
|
typeclass=typeclass,
|
||||||
)
|
)
|
||||||
logger.log_sec(f"Account Created: {account} (IP: {ip}).")
|
logger.log_sec(f"Account Created: {account} (IP: {ip}).")
|
||||||
|
|
||||||
|
|
@ -744,9 +760,13 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase):
|
||||||
account.db.creator_ip = ip
|
account.db.creator_ip = ip
|
||||||
|
|
||||||
# join the new account to the public channel
|
# join the new account to the public channel
|
||||||
pchannel = ChannelDB.objects.get_channel(settings.DEFAULT_CHANNELS[0]["key"])
|
pchannel = ChannelDB.objects.get_channel(
|
||||||
|
settings.DEFAULT_CHANNELS[0]["key"]
|
||||||
|
)
|
||||||
if not pchannel or not pchannel.connect(account):
|
if not pchannel or not pchannel.connect(account):
|
||||||
string = f"New account '{account.key}' could not connect to public channel!"
|
string = (
|
||||||
|
f"New account '{account.key}' could not connect to public channel!"
|
||||||
|
)
|
||||||
errors.append(string)
|
errors.append(string)
|
||||||
logger.log_err(string)
|
logger.log_err(string)
|
||||||
|
|
||||||
|
|
@ -781,7 +801,9 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase):
|
||||||
# We are in the middle between logged in and -not, so we have
|
# We are in the middle between logged in and -not, so we have
|
||||||
# to handle tracebacks ourselves at this point. If we don't,
|
# to handle tracebacks ourselves at this point. If we don't,
|
||||||
# we won't see any errors at all.
|
# we won't see any errors at all.
|
||||||
errors.append("An error occurred. Please e-mail an admin if the problem persists.")
|
errors.append(
|
||||||
|
"An error occurred. Please e-mail an admin if the problem persists."
|
||||||
|
)
|
||||||
logger.log_trace()
|
logger.log_trace()
|
||||||
|
|
||||||
# Update the throttle to indicate a new account was created from this IP
|
# Update the throttle to indicate a new account was created from this IP
|
||||||
|
|
@ -808,7 +830,9 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase):
|
||||||
except RuntimeError:
|
except RuntimeError:
|
||||||
# no puppet to disconnect from
|
# no puppet to disconnect from
|
||||||
pass
|
pass
|
||||||
session.sessionhandler.disconnect(session, reason=_("Account being deleted."))
|
session.sessionhandler.disconnect(
|
||||||
|
session, reason=_("Account being deleted.")
|
||||||
|
)
|
||||||
self.scripts.stop()
|
self.scripts.stop()
|
||||||
self.attributes.clear()
|
self.attributes.clear()
|
||||||
self.nicks.clear()
|
self.nicks.clear()
|
||||||
|
|
@ -968,7 +992,12 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase):
|
||||||
return matches
|
return matches
|
||||||
|
|
||||||
def access(
|
def access(
|
||||||
self, accessing_obj, access_type="read", default=False, no_superuser_bypass=False, **kwargs
|
self,
|
||||||
|
accessing_obj,
|
||||||
|
access_type="read",
|
||||||
|
default=False,
|
||||||
|
no_superuser_bypass=False,
|
||||||
|
**kwargs,
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
Determines if another object has permission to access this
|
Determines if another object has permission to access this
|
||||||
|
|
@ -1048,7 +1077,9 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
# set an (empty) attribute holding the characters this account has
|
# set an (empty) attribute holding the characters this account has
|
||||||
lockstring = "attrread:perm(Admins);attredit:perm(Admins);" "attrcreate:perm(Admins);"
|
lockstring = (
|
||||||
|
"attrread:perm(Admins);attredit:perm(Admins);" "attrcreate:perm(Admins);"
|
||||||
|
)
|
||||||
self.attributes.add("_playable_characters", [], lockstring=lockstring)
|
self.attributes.add("_playable_characters", [], lockstring=lockstring)
|
||||||
self.attributes.add("_saved_protocol_flags", {}, lockstring=lockstring)
|
self.attributes.add("_saved_protocol_flags", {}, lockstring=lockstring)
|
||||||
|
|
||||||
|
|
@ -1203,13 +1234,19 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase):
|
||||||
global _MUDINFO_CHANNEL
|
global _MUDINFO_CHANNEL
|
||||||
if not _MUDINFO_CHANNEL:
|
if not _MUDINFO_CHANNEL:
|
||||||
try:
|
try:
|
||||||
_MUDINFO_CHANNEL = ChannelDB.objects.filter(db_key=settings.CHANNEL_MUDINFO["key"])[
|
_MUDINFO_CHANNEL = ChannelDB.objects.filter(
|
||||||
0
|
db_key=settings.CHANNEL_MUDINFO["key"]
|
||||||
]
|
)[0]
|
||||||
except Exception:
|
except Exception:
|
||||||
logger.log_trace()
|
logger.log_trace()
|
||||||
now = timezone.now()
|
now = timezone.now()
|
||||||
now = "%02i-%02i-%02i(%02i:%02i)" % (now.year, now.month, now.day, now.hour, now.minute)
|
now = "%02i-%02i-%02i(%02i:%02i)" % (
|
||||||
|
now.year,
|
||||||
|
now.month,
|
||||||
|
now.day,
|
||||||
|
now.hour,
|
||||||
|
now.minute,
|
||||||
|
)
|
||||||
if _MUDINFO_CHANNEL:
|
if _MUDINFO_CHANNEL:
|
||||||
_MUDINFO_CHANNEL.tempmsg(f"[{_MUDINFO_CHANNEL.key}, {now}]: {message}")
|
_MUDINFO_CHANNEL.tempmsg(f"[{_MUDINFO_CHANNEL.key}, {now}]: {message}")
|
||||||
else:
|
else:
|
||||||
|
|
@ -1261,9 +1298,12 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase):
|
||||||
# screen. We execute look on the account.
|
# screen. We execute look on the account.
|
||||||
# we make sure to clean up the _playable_characters list in case
|
# we make sure to clean up the _playable_characters list in case
|
||||||
# any was deleted in the interim.
|
# any was deleted in the interim.
|
||||||
self.db._playable_characters = [char for char in self.db._playable_characters if char]
|
self.db._playable_characters = [
|
||||||
|
char for char in self.db._playable_characters if char
|
||||||
|
]
|
||||||
self.msg(
|
self.msg(
|
||||||
self.at_look(target=self.db._playable_characters, session=session), session=session
|
self.at_look(target=self.db._playable_characters, session=session),
|
||||||
|
session=session,
|
||||||
)
|
)
|
||||||
|
|
||||||
def at_failed_login(self, session, **kwargs):
|
def at_failed_login(self, session, **kwargs):
|
||||||
|
|
@ -1421,7 +1461,9 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase):
|
||||||
csessid = sess.sessid
|
csessid = sess.sessid
|
||||||
addr = "%s (%s)" % (
|
addr = "%s (%s)" % (
|
||||||
sess.protocol_key,
|
sess.protocol_key,
|
||||||
isinstance(sess.address, tuple) and str(sess.address[0]) or str(sess.address),
|
isinstance(sess.address, tuple)
|
||||||
|
and str(sess.address[0])
|
||||||
|
or str(sess.address),
|
||||||
)
|
)
|
||||||
result.append(
|
result.append(
|
||||||
"\n %s %s"
|
"\n %s %s"
|
||||||
|
|
@ -1444,14 +1486,18 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase):
|
||||||
"\n\n You don't have any characters yet. See |whelp @charcreate|n for creating one."
|
"\n\n You don't have any characters yet. See |whelp @charcreate|n for creating one."
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
result.append("\n |w@charcreate <name> [=description]|n - create new character")
|
result.append(
|
||||||
|
"\n |w@charcreate <name> [=description]|n - create new character"
|
||||||
|
)
|
||||||
result.append(
|
result.append(
|
||||||
"\n |w@chardelete <name>|n - delete a character (cannot be undone!)"
|
"\n |w@chardelete <name>|n - delete a character (cannot be undone!)"
|
||||||
)
|
)
|
||||||
|
|
||||||
if characters:
|
if characters:
|
||||||
string_s_ending = len(characters) > 1 and "s" or ""
|
string_s_ending = len(characters) > 1 and "s" or ""
|
||||||
result.append("\n |w@ic <character>|n - enter the game (|w@ooc|n to get back here)")
|
result.append(
|
||||||
|
"\n |w@ic <character>|n - enter the game (|w@ooc|n to get back here)"
|
||||||
|
)
|
||||||
if is_su:
|
if is_su:
|
||||||
result.append(
|
result.append(
|
||||||
f"\n\nAvailable character{string_s_ending} ({len(characters)}/unlimited):"
|
f"\n\nAvailable character{string_s_ending} ({len(characters)}/unlimited):"
|
||||||
|
|
@ -1461,7 +1507,9 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase):
|
||||||
"\n\nAvailable character%s%s:"
|
"\n\nAvailable character%s%s:"
|
||||||
% (
|
% (
|
||||||
string_s_ending,
|
string_s_ending,
|
||||||
charmax > 1 and " (%i/%i)" % (len(characters), charmax) or "",
|
charmax > 1
|
||||||
|
and " (%i/%i)" % (len(characters), charmax)
|
||||||
|
or "",
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -1481,7 +1529,9 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase):
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
# character is "free to puppet"
|
# character is "free to puppet"
|
||||||
result.append(f"\n - {char.key} [{', '.join(char.permissions.all())}]")
|
result.append(
|
||||||
|
f"\n - {char.key} [{', '.join(char.permissions.all())}]"
|
||||||
|
)
|
||||||
look_string = ("-" * 68) + "\n" + "".join(result) + "\n" + ("-" * 68)
|
look_string = ("-" * 68) + "\n" + "".join(result) + "\n" + ("-" * 68)
|
||||||
return look_string
|
return look_string
|
||||||
|
|
||||||
|
|
@ -1559,7 +1609,9 @@ class DefaultGuest(DefaultAccount):
|
||||||
# We are in the middle between logged in and -not, so we have
|
# We are in the middle between logged in and -not, so we have
|
||||||
# to handle tracebacks ourselves at this point. If we don't,
|
# to handle tracebacks ourselves at this point. If we don't,
|
||||||
# we won't see any errors at all.
|
# we won't see any errors at all.
|
||||||
errors.append("An error occurred. Please e-mail an admin if the problem persists.")
|
errors.append(
|
||||||
|
"An error occurred. Please e-mail an admin if the problem persists."
|
||||||
|
)
|
||||||
logger.log_trace()
|
logger.log_trace()
|
||||||
return None, errors
|
return None, errors
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,8 @@ class AccountDBChangeForm(UserChangeForm):
|
||||||
"invalid": "This value may contain only letters, spaces, numbers "
|
"invalid": "This value may contain only letters, spaces, numbers "
|
||||||
"and @/./+/-/_ characters."
|
"and @/./+/-/_ characters."
|
||||||
},
|
},
|
||||||
help_text="30 characters or fewer. Letters, spaces, digits and " "@/./+/-/_ only.",
|
help_text="30 characters or fewer. Letters, spaces, digits and "
|
||||||
|
"@/./+/-/_ only.",
|
||||||
)
|
)
|
||||||
|
|
||||||
def clean_username(self):
|
def clean_username(self):
|
||||||
|
|
@ -66,7 +67,8 @@ class AccountDBCreationForm(UserCreationForm):
|
||||||
"invalid": "This value may contain only letters, spaces, numbers "
|
"invalid": "This value may contain only letters, spaces, numbers "
|
||||||
"and @/./+/-/_ characters."
|
"and @/./+/-/_ characters."
|
||||||
},
|
},
|
||||||
help_text="30 characters or fewer. Letters, spaces, digits and " "@/./+/-/_ only.",
|
help_text="30 characters or fewer. Letters, spaces, digits and "
|
||||||
|
"@/./+/-/_ only.",
|
||||||
)
|
)
|
||||||
|
|
||||||
def clean_username(self):
|
def clean_username(self):
|
||||||
|
|
@ -228,7 +230,13 @@ class AccountDBAdmin(BaseUserAdmin):
|
||||||
(
|
(
|
||||||
"Website Permissions",
|
"Website Permissions",
|
||||||
{
|
{
|
||||||
"fields": ("is_active", "is_staff", "is_superuser", "user_permissions", "groups"),
|
"fields": (
|
||||||
|
"is_active",
|
||||||
|
"is_staff",
|
||||||
|
"is_superuser",
|
||||||
|
"user_permissions",
|
||||||
|
"groups",
|
||||||
|
),
|
||||||
"description": "<i>These are permissions/permission groups for "
|
"description": "<i>These are permissions/permission groups for "
|
||||||
"accessing the admin site. They are unrelated to "
|
"accessing the admin site. They are unrelated to "
|
||||||
"in-game access rights.</i>",
|
"in-game access rights.</i>",
|
||||||
|
|
@ -238,7 +246,8 @@ class AccountDBAdmin(BaseUserAdmin):
|
||||||
"Game Options",
|
"Game Options",
|
||||||
{
|
{
|
||||||
"fields": ("db_typeclass_path", "db_cmdset_storage", "db_lock_storage"),
|
"fields": ("db_typeclass_path", "db_cmdset_storage", "db_lock_storage"),
|
||||||
"description": "<i>These are attributes that are more relevant " "to gameplay.</i>",
|
"description": "<i>These are attributes that are more relevant "
|
||||||
|
"to gameplay.</i>",
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
@ -281,7 +290,9 @@ class AccountDBAdmin(BaseUserAdmin):
|
||||||
from django.http import HttpResponseRedirect
|
from django.http import HttpResponseRedirect
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
|
|
||||||
return HttpResponseRedirect(reverse("admin:accounts_accountdb_change", args=[obj.id]))
|
return HttpResponseRedirect(
|
||||||
|
reverse("admin:accounts_accountdb_change", args=[obj.id])
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
admin.site.register(AccountDB, AccountDBAdmin)
|
admin.site.register(AccountDB, AccountDBAdmin)
|
||||||
|
|
|
||||||
|
|
@ -124,7 +124,9 @@ class Bot(DefaultAccount):
|
||||||
Evennia -> outgoing protocol
|
Evennia -> outgoing protocol
|
||||||
|
|
||||||
"""
|
"""
|
||||||
super().msg(text=text, from_obj=from_obj, session=session, options=options, **kwargs)
|
super().msg(
|
||||||
|
text=text, from_obj=from_obj, session=session, options=options, **kwargs
|
||||||
|
)
|
||||||
|
|
||||||
def execute_cmd(self, raw_string, session=None):
|
def execute_cmd(self, raw_string, session=None):
|
||||||
"""
|
"""
|
||||||
|
|
@ -325,8 +327,12 @@ class IRCBot(Bot):
|
||||||
if kwargs["type"] == "nicklist":
|
if kwargs["type"] == "nicklist":
|
||||||
# the return of a nicklist request
|
# the return of a nicklist request
|
||||||
if hasattr(self, "_nicklist_callers") and self._nicklist_callers:
|
if hasattr(self, "_nicklist_callers") and self._nicklist_callers:
|
||||||
chstr = f"{self.db.irc_channel} ({self.db.irc_network}:{self.db.irc_port})"
|
chstr = (
|
||||||
nicklist = ", ".join(sorted(kwargs["nicklist"], key=lambda n: n.lower()))
|
f"{self.db.irc_channel} ({self.db.irc_network}:{self.db.irc_port})"
|
||||||
|
)
|
||||||
|
nicklist = ", ".join(
|
||||||
|
sorted(kwargs["nicklist"], key=lambda n: n.lower())
|
||||||
|
)
|
||||||
for obj in self._nicklist_callers:
|
for obj in self._nicklist_callers:
|
||||||
obj.msg(f"Nicks at {chstr}:\n {nicklist}")
|
obj.msg(f"Nicks at {chstr}:\n {nicklist}")
|
||||||
self._nicklist_callers = []
|
self._nicklist_callers = []
|
||||||
|
|
@ -335,7 +341,9 @@ class IRCBot(Bot):
|
||||||
elif kwargs["type"] == "ping":
|
elif kwargs["type"] == "ping":
|
||||||
# the return of a ping
|
# the return of a ping
|
||||||
if hasattr(self, "_ping_callers") and self._ping_callers:
|
if hasattr(self, "_ping_callers") and self._ping_callers:
|
||||||
chstr = f"{self.db.irc_channel} ({self.db.irc_network}:{self.db.irc_port})"
|
chstr = (
|
||||||
|
f"{self.db.irc_channel} ({self.db.irc_network}:{self.db.irc_port})"
|
||||||
|
)
|
||||||
for obj in self._ping_callers:
|
for obj in self._ping_callers:
|
||||||
obj.msg(f"IRC ping return from {chstr} took {kwargs['timing']}s.")
|
obj.msg(f"IRC ping return from {chstr} took {kwargs['timing']}s.")
|
||||||
self._ping_callers = []
|
self._ping_callers = []
|
||||||
|
|
@ -434,8 +442,14 @@ class RSSBot(Bot):
|
||||||
self.db.rss_rate = rss_rate
|
self.db.rss_rate = rss_rate
|
||||||
# instruct the server and portal to create a new session with
|
# instruct the server and portal to create a new session with
|
||||||
# the stored configuration
|
# the stored configuration
|
||||||
configdict = {"uid": self.dbid, "url": self.db.rss_url, "rate": self.db.rss_rate}
|
configdict = {
|
||||||
_SESSIONS.start_bot_session("evennia.server.portal.rss.RSSBotFactory", configdict)
|
"uid": self.dbid,
|
||||||
|
"url": self.db.rss_url,
|
||||||
|
"rate": self.db.rss_rate,
|
||||||
|
}
|
||||||
|
_SESSIONS.start_bot_session(
|
||||||
|
"evennia.server.portal.rss.RSSBotFactory", configdict
|
||||||
|
)
|
||||||
|
|
||||||
def execute_cmd(self, txt=None, session=None, **kwargs):
|
def execute_cmd(self, txt=None, session=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -92,7 +92,9 @@ class AccountDBManager(TypedObjectManager, UserManager):
|
||||||
end_date = timezone.now()
|
end_date = timezone.now()
|
||||||
tdelta = datetime.timedelta(days)
|
tdelta = datetime.timedelta(days)
|
||||||
start_date = end_date - tdelta
|
start_date = end_date - tdelta
|
||||||
return self.filter(last_login__range=(start_date, end_date)).order_by("-last_login")
|
return self.filter(last_login__range=(start_date, end_date)).order_by(
|
||||||
|
"-last_login"
|
||||||
|
)
|
||||||
|
|
||||||
def get_account_from_email(self, uemail):
|
def get_account_from_email(self, uemail):
|
||||||
"""
|
"""
|
||||||
|
|
@ -177,7 +179,11 @@ class AccountDBManager(TypedObjectManager, UserManager):
|
||||||
# try alias match
|
# try alias match
|
||||||
matches = self.filter(
|
matches = self.filter(
|
||||||
db_tags__db_tagtype__iexact="alias",
|
db_tags__db_tagtype__iexact="alias",
|
||||||
**{"db_tags__db_key__iexact" if exact else "db_tags__db_key__icontains": ostring},
|
**{
|
||||||
|
"db_tags__db_key__iexact"
|
||||||
|
if exact
|
||||||
|
else "db_tags__db_key__icontains": ostring
|
||||||
|
},
|
||||||
)
|
)
|
||||||
return matches
|
return matches
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,10 @@ class Migration(migrations.Migration):
|
||||||
(
|
(
|
||||||
"id",
|
"id",
|
||||||
models.AutoField(
|
models.AutoField(
|
||||||
verbose_name="ID", serialize=False, auto_created=True, primary_key=True
|
verbose_name="ID",
|
||||||
|
serialize=False,
|
||||||
|
auto_created=True,
|
||||||
|
primary_key=True,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
("password", models.CharField(max_length=128, verbose_name="password")),
|
("password", models.CharField(max_length=128, verbose_name="password")),
|
||||||
|
|
@ -51,15 +54,21 @@ class Migration(migrations.Migration):
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"first_name",
|
"first_name",
|
||||||
models.CharField(max_length=30, verbose_name="first name", blank=True),
|
models.CharField(
|
||||||
|
max_length=30, verbose_name="first name", blank=True
|
||||||
|
),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"last_name",
|
"last_name",
|
||||||
models.CharField(max_length=30, verbose_name="last name", blank=True),
|
models.CharField(
|
||||||
|
max_length=30, verbose_name="last name", blank=True
|
||||||
|
),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"email",
|
"email",
|
||||||
models.EmailField(max_length=75, verbose_name="email address", blank=True),
|
models.EmailField(
|
||||||
|
max_length=75, verbose_name="email address", blank=True
|
||||||
|
),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"is_staff",
|
"is_staff",
|
||||||
|
|
@ -83,7 +92,10 @@ class Migration(migrations.Migration):
|
||||||
default=django.utils.timezone.now, verbose_name="date joined"
|
default=django.utils.timezone.now, verbose_name="date joined"
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
("db_key", models.CharField(max_length=255, verbose_name="key", db_index=True)),
|
(
|
||||||
|
"db_key",
|
||||||
|
models.CharField(max_length=255, verbose_name="key", db_index=True),
|
||||||
|
),
|
||||||
(
|
(
|
||||||
"db_typeclass_path",
|
"db_typeclass_path",
|
||||||
models.CharField(
|
models.CharField(
|
||||||
|
|
@ -95,7 +107,9 @@ class Migration(migrations.Migration):
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"db_date_created",
|
"db_date_created",
|
||||||
models.DateTimeField(auto_now_add=True, verbose_name="creation date"),
|
models.DateTimeField(
|
||||||
|
auto_now_add=True, verbose_name="creation date"
|
||||||
|
),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"db_lock_storage",
|
"db_lock_storage",
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,9 @@ from django.db import models, migrations
|
||||||
|
|
||||||
def convert_defaults(apps, schema_editor):
|
def convert_defaults(apps, schema_editor):
|
||||||
AccountDB = apps.get_model("accounts", "AccountDB")
|
AccountDB = apps.get_model("accounts", "AccountDB")
|
||||||
for account in AccountDB.objects.filter(db_typeclass_path="src.accounts.account.Account"):
|
for account in AccountDB.objects.filter(
|
||||||
|
db_typeclass_path="src.accounts.account.Account"
|
||||||
|
):
|
||||||
account.db_typeclass_path = "typeclasses.accounts.Account"
|
account.db_typeclass_path = "typeclasses.accounts.Account"
|
||||||
account.save()
|
account.save()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,10 @@ class Migration(migrations.Migration):
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name="DefaultAccount", fields=[], options={"proxy": True}, bases=("accounts.accountdb",)
|
name="DefaultAccount",
|
||||||
|
fields=[],
|
||||||
|
options={"proxy": True},
|
||||||
|
bases=("accounts.accountdb",),
|
||||||
),
|
),
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name="DefaultGuest",
|
name="DefaultGuest",
|
||||||
|
|
@ -18,5 +21,7 @@ class Migration(migrations.Migration):
|
||||||
options={"proxy": True},
|
options={"proxy": True},
|
||||||
bases=("accounts.defaultaccount",),
|
bases=("accounts.defaultaccount",),
|
||||||
),
|
),
|
||||||
migrations.AlterModelOptions(name="accountdb", options={"verbose_name": "Account"}),
|
migrations.AlterModelOptions(
|
||||||
|
name="accountdb", options={"verbose_name": "Account"}
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -14,12 +14,15 @@ class Migration(migrations.Migration):
|
||||||
migrations.DeleteModel(name="DefaultGuest"),
|
migrations.DeleteModel(name="DefaultGuest"),
|
||||||
migrations.DeleteModel(name="DefaultAccount"),
|
migrations.DeleteModel(name="DefaultAccount"),
|
||||||
migrations.AlterModelManagers(
|
migrations.AlterModelManagers(
|
||||||
name="accountdb", managers=[("objects", evennia.accounts.manager.AccountDBManager())]
|
name="accountdb",
|
||||||
|
managers=[("objects", evennia.accounts.manager.AccountDBManager())],
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name="accountdb",
|
model_name="accountdb",
|
||||||
name="email",
|
name="email",
|
||||||
field=models.EmailField(max_length=254, verbose_name="email address", blank=True),
|
field=models.EmailField(
|
||||||
|
max_length=254, verbose_name="email address", blank=True
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name="accountdb",
|
model_name="accountdb",
|
||||||
|
|
@ -36,7 +39,9 @@ class Migration(migrations.Migration):
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name="accountdb",
|
model_name="accountdb",
|
||||||
name="last_login",
|
name="last_login",
|
||||||
field=models.DateTimeField(null=True, verbose_name="last login", blank=True),
|
field=models.DateTimeField(
|
||||||
|
null=True, verbose_name="last login", blank=True
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name="accountdb",
|
model_name="accountdb",
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,8 @@ class Migration(migrations.Migration):
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterModelManagers(
|
migrations.AlterModelManagers(
|
||||||
name="accountdb", managers=[("objects", evennia.accounts.manager.AccountDBManager())]
|
name="accountdb",
|
||||||
|
managers=[("objects", evennia.accounts.manager.AccountDBManager())],
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name="accountdb",
|
model_name="accountdb",
|
||||||
|
|
@ -41,7 +42,9 @@ class Migration(migrations.Migration):
|
||||||
model_name="accountdb",
|
model_name="accountdb",
|
||||||
name="db_is_bot",
|
name="db_is_bot",
|
||||||
field=models.BooleanField(
|
field=models.BooleanField(
|
||||||
default=False, help_text="Used to identify irc/rss bots", verbose_name="is_bot"
|
default=False,
|
||||||
|
help_text="Used to identify irc/rss bots",
|
||||||
|
verbose_name="is_bot",
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
|
|
|
||||||
|
|
@ -5,19 +5,25 @@ from django.db import migrations, models
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("accounts", "0008_auto_20190128_1820")]
|
||||||
('accounts', '0008_auto_20190128_1820'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='accountdb',
|
model_name="accountdb",
|
||||||
name='db_typeclass_path',
|
name="db_typeclass_path",
|
||||||
field=models.CharField(db_index=True, help_text="this defines what 'type' of entity this is. This variable holds a Python path to a module with a valid Evennia Typeclass.", max_length=255, null=True, verbose_name='typeclass'),
|
field=models.CharField(
|
||||||
|
db_index=True,
|
||||||
|
help_text="this defines what 'type' of entity this is. This variable holds a Python path to a module with a valid Evennia Typeclass.",
|
||||||
|
max_length=255,
|
||||||
|
null=True,
|
||||||
|
verbose_name="typeclass",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='accountdb',
|
model_name="accountdb",
|
||||||
name='last_name',
|
name="last_name",
|
||||||
field=models.CharField(blank=True, max_length=150, verbose_name='last name'),
|
field=models.CharField(
|
||||||
|
blank=True, max_length=150, verbose_name="last name"
|
||||||
|
),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -129,7 +129,11 @@ class AccountDB(TypedObject, AbstractUser):
|
||||||
Setter. Allows for self.name = value. Stores as a comma-separated
|
Setter. Allows for self.name = value. Stores as a comma-separated
|
||||||
string.
|
string.
|
||||||
"""
|
"""
|
||||||
_SA(self, "db_cmdset_storage", ",".join(str(val).strip() for val in make_iter(value)))
|
_SA(
|
||||||
|
self,
|
||||||
|
"db_cmdset_storage",
|
||||||
|
",".join(str(val).strip() for val in make_iter(value)),
|
||||||
|
)
|
||||||
_GA(self, "save")()
|
_GA(self, "save")()
|
||||||
|
|
||||||
# @cmdset_storage.deleter
|
# @cmdset_storage.deleter
|
||||||
|
|
@ -138,7 +142,9 @@ class AccountDB(TypedObject, AbstractUser):
|
||||||
_SA(self, "db_cmdset_storage", None)
|
_SA(self, "db_cmdset_storage", None)
|
||||||
_GA(self, "save")()
|
_GA(self, "save")()
|
||||||
|
|
||||||
cmdset_storage = property(__cmdset_storage_get, __cmdset_storage_set, __cmdset_storage_del)
|
cmdset_storage = property(
|
||||||
|
__cmdset_storage_get, __cmdset_storage_set, __cmdset_storage_del
|
||||||
|
)
|
||||||
|
|
||||||
#
|
#
|
||||||
# property/field access
|
# property/field access
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,9 @@ class TestAccountSessionHandler(TestCase):
|
||||||
evennia.server.sessionhandler.SESSIONS[s3.uid] = s3
|
evennia.server.sessionhandler.SESSIONS[s3.uid] = s3
|
||||||
|
|
||||||
self.assertEqual([s.uid for s in self.handler.get()], [s1.uid])
|
self.assertEqual([s.uid for s in self.handler.get()], [s1.uid])
|
||||||
self.assertEqual([s.uid for s in [self.handler.get(self.account.uid)]], [s1.uid])
|
self.assertEqual(
|
||||||
|
[s.uid for s in [self.handler.get(self.account.uid)]], [s1.uid]
|
||||||
|
)
|
||||||
self.assertEqual([s.uid for s in self.handler.get(self.account.uid + 1)], [])
|
self.assertEqual([s.uid for s in self.handler.get(self.account.uid + 1)], [])
|
||||||
|
|
||||||
def test_all(self):
|
def test_all(self):
|
||||||
|
|
@ -86,7 +88,8 @@ class TestDefaultGuest(EvenniaTest):
|
||||||
# Create a second guest account
|
# Create a second guest account
|
||||||
account, errors = DefaultGuest.authenticate(ip=self.ip)
|
account, errors = DefaultGuest.authenticate(ip=self.ip)
|
||||||
self.assertFalse(
|
self.assertFalse(
|
||||||
account, "Two guest accounts were created with a single entry on the guest list!"
|
account,
|
||||||
|
"Two guest accounts were created with a single entry on the guest list!",
|
||||||
)
|
)
|
||||||
|
|
||||||
@patch("evennia.accounts.accounts.ChannelDB.objects.get_channel")
|
@patch("evennia.accounts.accounts.ChannelDB.objects.get_channel")
|
||||||
|
|
@ -147,13 +150,17 @@ class TestDefaultAccountAuth(EvenniaTest):
|
||||||
|
|
||||||
# Try creating a duplicate account
|
# Try creating a duplicate account
|
||||||
account2, errors = DefaultAccount.create(username="Ziggy", password="starman11")
|
account2, errors = DefaultAccount.create(username="Ziggy", password="starman11")
|
||||||
self.assertFalse(account2, "Duplicate account name should not have been allowed.")
|
self.assertFalse(
|
||||||
|
account2, "Duplicate account name should not have been allowed."
|
||||||
|
)
|
||||||
account.delete()
|
account.delete()
|
||||||
|
|
||||||
def test_throttle(self):
|
def test_throttle(self):
|
||||||
"Confirm throttle activates on too many failures."
|
"Confirm throttle activates on too many failures."
|
||||||
for x in range(20):
|
for x in range(20):
|
||||||
obj, errors = DefaultAccount.authenticate(self.account.name, "xyzzy", ip="12.24.36.48")
|
obj, errors = DefaultAccount.authenticate(
|
||||||
|
self.account.name, "xyzzy", ip="12.24.36.48"
|
||||||
|
)
|
||||||
self.assertFalse(
|
self.assertFalse(
|
||||||
obj,
|
obj,
|
||||||
"Authentication was provided a bogus password; this should NOT have returned an account!",
|
"Authentication was provided a bogus password; this should NOT have returned an account!",
|
||||||
|
|
@ -176,7 +183,9 @@ class TestDefaultAccountAuth(EvenniaTest):
|
||||||
|
|
||||||
# Should not allow duplicate username
|
# Should not allow duplicate username
|
||||||
result, error = DefaultAccount.validate_username(self.account.name)
|
result, error = DefaultAccount.validate_username(self.account.name)
|
||||||
self.assertFalse(result, "Duplicate username should not have passed validation.")
|
self.assertFalse(
|
||||||
|
result, "Duplicate username should not have passed validation."
|
||||||
|
)
|
||||||
|
|
||||||
# Should not allow username too short
|
# Should not allow username too short
|
||||||
result, error = DefaultAccount.validate_username("xx")
|
result, error = DefaultAccount.validate_username("xx")
|
||||||
|
|
@ -292,7 +301,9 @@ class TestDefaultAccount(TestCase):
|
||||||
account.puppet_object(self.s1, obj)
|
account.puppet_object(self.s1, obj)
|
||||||
|
|
||||||
self.assertTrue(
|
self.assertTrue(
|
||||||
self.s1.data_out.call_args[1]["text"].startswith("You don't have permission to puppet")
|
self.s1.data_out.call_args[1]["text"].startswith(
|
||||||
|
"You don't have permission to puppet"
|
||||||
|
)
|
||||||
)
|
)
|
||||||
self.assertIsNone(obj.at_post_puppet.call_args)
|
self.assertIsNone(obj.at_post_puppet.call_args)
|
||||||
|
|
||||||
|
|
@ -323,7 +334,9 @@ class TestDefaultAccount(TestCase):
|
||||||
account.puppet_object(self.s1, obj)
|
account.puppet_object(self.s1, obj)
|
||||||
# works because django.conf.settings.MULTISESSION_MODE is not in (1, 3)
|
# works because django.conf.settings.MULTISESSION_MODE is not in (1, 3)
|
||||||
self.assertTrue(
|
self.assertTrue(
|
||||||
self.s1.data_out.call_args[1]["text"].endswith("from another of your sessions.|n")
|
self.s1.data_out.call_args[1]["text"].endswith(
|
||||||
|
"from another of your sessions.|n"
|
||||||
|
)
|
||||||
)
|
)
|
||||||
self.assertTrue(obj.at_post_puppet.call_args[1] == {})
|
self.assertTrue(obj.at_post_puppet.call_args[1] == {})
|
||||||
|
|
||||||
|
|
@ -365,12 +378,15 @@ class TestAccountPuppetDeletion(EvenniaTest):
|
||||||
def test_puppet_deletion(self):
|
def test_puppet_deletion(self):
|
||||||
# Check for existing chars
|
# Check for existing chars
|
||||||
self.assertFalse(
|
self.assertFalse(
|
||||||
self.account.db._playable_characters, "Account should not have any chars by default."
|
self.account.db._playable_characters,
|
||||||
|
"Account should not have any chars by default.",
|
||||||
)
|
)
|
||||||
|
|
||||||
# Add char1 to account's playable characters
|
# Add char1 to account's playable characters
|
||||||
self.account.db._playable_characters.append(self.char1)
|
self.account.db._playable_characters.append(self.char1)
|
||||||
self.assertTrue(self.account.db._playable_characters, "Char was not added to account.")
|
self.assertTrue(
|
||||||
|
self.account.db._playable_characters, "Char was not added to account."
|
||||||
|
)
|
||||||
|
|
||||||
# See what happens when we delete char1.
|
# See what happens when we delete char1.
|
||||||
self.char1.delete()
|
self.char1.delete()
|
||||||
|
|
@ -398,7 +414,9 @@ class TestDefaultAccountEv(EvenniaTest):
|
||||||
self.account.msg = MagicMock()
|
self.account.msg = MagicMock()
|
||||||
with patch("evennia.accounts.accounts._MULTISESSION_MODE", 2):
|
with patch("evennia.accounts.accounts._MULTISESSION_MODE", 2):
|
||||||
self.account.puppet_object(self.session, self.char1)
|
self.account.puppet_object(self.session, self.char1)
|
||||||
self.account.msg.assert_called_with("You are already puppeting this object.")
|
self.account.msg.assert_called_with(
|
||||||
|
"You are already puppeting this object."
|
||||||
|
)
|
||||||
|
|
||||||
@patch("evennia.accounts.accounts.time.time", return_value=10000)
|
@patch("evennia.accounts.accounts.time.time", return_value=10000)
|
||||||
def test_idle_time(self, mock_time):
|
def test_idle_time(self, mock_time):
|
||||||
|
|
@ -432,8 +450,15 @@ class TestDefaultAccountEv(EvenniaTest):
|
||||||
"test@test.com",
|
"test@test.com",
|
||||||
"testpassword123",
|
"testpassword123",
|
||||||
locks="test:all()",
|
locks="test:all()",
|
||||||
tags=[("tag1", "category1"), ("tag2", "category2", "data1"), ("tag3", None)],
|
tags=[
|
||||||
attributes=[("key1", "value1", "category1", "edit:false()", True), ("key2", "value2")],
|
("tag1", "category1"),
|
||||||
|
("tag2", "category2", "data1"),
|
||||||
|
("tag3", None),
|
||||||
|
],
|
||||||
|
attributes=[
|
||||||
|
("key1", "value1", "category1", "edit:false()", True),
|
||||||
|
("key2", "value2"),
|
||||||
|
],
|
||||||
)
|
)
|
||||||
acct.save()
|
acct.save()
|
||||||
self.assertTrue(acct.pk)
|
self.assertTrue(acct.pk)
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,9 @@ CMD_CHANNEL = "__send_to_channel_command"
|
||||||
CMD_LOGINSTART = "__unloggedin_look_command"
|
CMD_LOGINSTART = "__unloggedin_look_command"
|
||||||
|
|
||||||
# Function for handling multiple command matches.
|
# Function for handling multiple command matches.
|
||||||
_SEARCH_AT_RESULT = utils.variable_from_module(*settings.SEARCH_AT_RESULT.rsplit(".", 1))
|
_SEARCH_AT_RESULT = utils.variable_from_module(
|
||||||
|
*settings.SEARCH_AT_RESULT.rsplit(".", 1)
|
||||||
|
)
|
||||||
|
|
||||||
# Output strings. The first is the IN_GAME_ERRORS return, the second
|
# Output strings. The first is the IN_GAME_ERRORS return, the second
|
||||||
# is the normal "production message to echo to the account.
|
# is the normal "production message to echo to the account.
|
||||||
|
|
@ -132,7 +134,8 @@ likely file a bug report with the Evennia project.
|
||||||
)
|
)
|
||||||
|
|
||||||
_ERROR_RECURSION_LIMIT = (
|
_ERROR_RECURSION_LIMIT = (
|
||||||
"Command recursion limit ({recursion_limit}) " "reached for '{raw_cmdname}' ({cmdclass})."
|
"Command recursion limit ({recursion_limit}) "
|
||||||
|
"reached for '{raw_cmdname}' ({cmdclass})."
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -161,7 +164,9 @@ def _msg_err(receiver, stringtuple):
|
||||||
if _IN_GAME_ERRORS:
|
if _IN_GAME_ERRORS:
|
||||||
receiver.msg(
|
receiver.msg(
|
||||||
string.format(
|
string.format(
|
||||||
traceback=tracestring, errmsg=stringtuple[0].strip(), timestamp=timestamp
|
traceback=tracestring,
|
||||||
|
errmsg=stringtuple[0].strip(),
|
||||||
|
timestamp=timestamp,
|
||||||
).strip()
|
).strip()
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
|
|
@ -213,7 +218,9 @@ def _progressive_cmd_run(cmd, generator, response=None):
|
||||||
elif isinstance(value, str):
|
elif isinstance(value, str):
|
||||||
_GET_INPUT(cmd.caller, value, _process_input, cmd=cmd, generator=generator)
|
_GET_INPUT(cmd.caller, value, _process_input, cmd=cmd, generator=generator)
|
||||||
else:
|
else:
|
||||||
raise ValueError("unknown type for a yielded value in command: {}".format(type(value)))
|
raise ValueError(
|
||||||
|
"unknown type for a yielded value in command: {}".format(type(value))
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def _process_input(caller, prompt, result, cmd, generator):
|
def _process_input(caller, prompt, result, cmd, generator):
|
||||||
|
|
@ -324,7 +331,9 @@ def get_and_merge_cmdsets(caller, session, account, obj, callertype, raw_string)
|
||||||
# Gather all cmdsets stored on objects in the room and
|
# Gather all cmdsets stored on objects in the room and
|
||||||
# also in the caller's inventory and the location itself
|
# also in the caller's inventory and the location itself
|
||||||
local_objlist = yield (
|
local_objlist = yield (
|
||||||
location.contents_get(exclude=obj) + obj.contents_get() + [location]
|
location.contents_get(exclude=obj)
|
||||||
|
+ obj.contents_get()
|
||||||
|
+ [location]
|
||||||
)
|
)
|
||||||
local_objlist = [o for o in local_objlist if not o._is_deleted]
|
local_objlist = [o for o in local_objlist if not o._is_deleted]
|
||||||
for lobj in local_objlist:
|
for lobj in local_objlist:
|
||||||
|
|
@ -354,7 +363,9 @@ def get_and_merge_cmdsets(caller, session, account, obj, callertype, raw_string)
|
||||||
# only keep the setting if duplicates were set to False/True
|
# only keep the setting if duplicates were set to False/True
|
||||||
# explicitly.
|
# explicitly.
|
||||||
cset.old_duplicates = cset.duplicates
|
cset.old_duplicates = cset.duplicates
|
||||||
cset.duplicates = True if cset.duplicates is None else cset.duplicates
|
cset.duplicates = (
|
||||||
|
True if cset.duplicates is None else cset.duplicates
|
||||||
|
)
|
||||||
returnValue(local_obj_cmdsets)
|
returnValue(local_obj_cmdsets)
|
||||||
except Exception:
|
except Exception:
|
||||||
_msg_err(caller, _ERROR_CMDSETS)
|
_msg_err(caller, _ERROR_CMDSETS)
|
||||||
|
|
@ -394,7 +405,9 @@ def get_and_merge_cmdsets(caller, session, account, obj, callertype, raw_string)
|
||||||
if current.no_exits:
|
if current.no_exits:
|
||||||
# filter out all exits
|
# filter out all exits
|
||||||
local_obj_cmdsets = [
|
local_obj_cmdsets = [
|
||||||
cmdset for cmdset in local_obj_cmdsets if cmdset.key != "ExitCmdSet"
|
cmdset
|
||||||
|
for cmdset in local_obj_cmdsets
|
||||||
|
if cmdset.key != "ExitCmdSet"
|
||||||
]
|
]
|
||||||
cmdsets += local_obj_cmdsets
|
cmdsets += local_obj_cmdsets
|
||||||
if not current.no_channels:
|
if not current.no_channels:
|
||||||
|
|
@ -418,7 +431,9 @@ def get_and_merge_cmdsets(caller, session, account, obj, callertype, raw_string)
|
||||||
if current.no_exits:
|
if current.no_exits:
|
||||||
# filter out all exits
|
# filter out all exits
|
||||||
local_obj_cmdsets = [
|
local_obj_cmdsets = [
|
||||||
cmdset for cmdset in local_obj_cmdsets if cmdset.key != "ExitCmdSet"
|
cmdset
|
||||||
|
for cmdset in local_obj_cmdsets
|
||||||
|
if cmdset.key != "ExitCmdSet"
|
||||||
]
|
]
|
||||||
cmdsets += local_obj_cmdsets
|
cmdsets += local_obj_cmdsets
|
||||||
if not current.no_channels:
|
if not current.no_channels:
|
||||||
|
|
@ -436,20 +451,28 @@ def get_and_merge_cmdsets(caller, session, account, obj, callertype, raw_string)
|
||||||
if current.no_exits:
|
if current.no_exits:
|
||||||
# filter out all exits
|
# filter out all exits
|
||||||
local_obj_cmdsets = [
|
local_obj_cmdsets = [
|
||||||
cmdset for cmdset in local_obj_cmdsets if cmdset.key != "ExitCmdSet"
|
cmdset
|
||||||
|
for cmdset in local_obj_cmdsets
|
||||||
|
if cmdset.key != "ExitCmdSet"
|
||||||
]
|
]
|
||||||
cmdsets += yield local_obj_cmdsets
|
cmdsets += yield local_obj_cmdsets
|
||||||
if not current.no_channels:
|
if not current.no_channels:
|
||||||
# also objs may have channels
|
# also objs may have channels
|
||||||
cmdsets += yield _get_channel_cmdset(obj)
|
cmdsets += yield _get_channel_cmdset(obj)
|
||||||
else:
|
else:
|
||||||
raise Exception("get_and_merge_cmdsets: callertype %s is not valid." % callertype)
|
raise Exception(
|
||||||
|
"get_and_merge_cmdsets: callertype %s is not valid." % callertype
|
||||||
|
)
|
||||||
|
|
||||||
# weed out all non-found sets
|
# weed out all non-found sets
|
||||||
cmdsets = yield [cmdset for cmdset in cmdsets if cmdset and cmdset.key != "_EMPTY_CMDSET"]
|
cmdsets = yield [
|
||||||
|
cmdset for cmdset in cmdsets if cmdset and cmdset.key != "_EMPTY_CMDSET"
|
||||||
|
]
|
||||||
# report cmdset errors to user (these should already have been logged)
|
# report cmdset errors to user (these should already have been logged)
|
||||||
yield [
|
yield [
|
||||||
report_to.msg(cmdset.errmessage) for cmdset in cmdsets if cmdset.key == "_CMDSET_ERROR"
|
report_to.msg(cmdset.errmessage)
|
||||||
|
for cmdset in cmdsets
|
||||||
|
if cmdset.key == "_CMDSET_ERROR"
|
||||||
]
|
]
|
||||||
|
|
||||||
if cmdsets:
|
if cmdsets:
|
||||||
|
|
@ -472,7 +495,9 @@ def get_and_merge_cmdsets(caller, session, account, obj, callertype, raw_string)
|
||||||
tempmergers[prio] = cmdset
|
tempmergers[prio] = cmdset
|
||||||
|
|
||||||
# sort cmdsets after reverse priority (highest prio are merged in last)
|
# sort cmdsets after reverse priority (highest prio are merged in last)
|
||||||
cmdsets = yield sorted(list(tempmergers.values()), key=lambda x: x.priority)
|
cmdsets = yield sorted(
|
||||||
|
list(tempmergers.values()), key=lambda x: x.priority
|
||||||
|
)
|
||||||
|
|
||||||
# Merge all command sets into one, beginning with the lowest-prio one
|
# Merge all command sets into one, beginning with the lowest-prio one
|
||||||
cmdset = cmdsets[0]
|
cmdset = cmdsets[0]
|
||||||
|
|
@ -733,7 +758,12 @@ def cmdhandler(
|
||||||
if len(matches) == 1:
|
if len(matches) == 1:
|
||||||
# We have a unique command match. But it may still be invalid.
|
# We have a unique command match. But it may still be invalid.
|
||||||
match = matches[0]
|
match = matches[0]
|
||||||
cmdname, args, cmd, raw_cmdname = match[0], match[1], match[2], match[5]
|
cmdname, args, cmd, raw_cmdname = (
|
||||||
|
match[0],
|
||||||
|
match[1],
|
||||||
|
match[2],
|
||||||
|
match[5],
|
||||||
|
)
|
||||||
|
|
||||||
if not matches:
|
if not matches:
|
||||||
# No commands match our entered command
|
# No commands match our entered command
|
||||||
|
|
@ -771,7 +801,9 @@ def cmdhandler(
|
||||||
raise ExecSystemCommand(cmd, sysarg)
|
raise ExecSystemCommand(cmd, sysarg)
|
||||||
|
|
||||||
# A normal command.
|
# A normal command.
|
||||||
ret = yield _run_command(cmd, cmdname, args, raw_cmdname, cmdset, session, account)
|
ret = yield _run_command(
|
||||||
|
cmd, cmdname, args, raw_cmdname, cmdset, session, account
|
||||||
|
)
|
||||||
returnValue(ret)
|
returnValue(ret)
|
||||||
|
|
||||||
except ErrorReported as exc:
|
except ErrorReported as exc:
|
||||||
|
|
@ -787,7 +819,13 @@ def cmdhandler(
|
||||||
|
|
||||||
if syscmd:
|
if syscmd:
|
||||||
ret = yield _run_command(
|
ret = yield _run_command(
|
||||||
syscmd, syscmd.key, sysarg, unformatted_raw_string, cmdset, session, account
|
syscmd,
|
||||||
|
syscmd.key,
|
||||||
|
sysarg,
|
||||||
|
unformatted_raw_string,
|
||||||
|
cmdset,
|
||||||
|
session,
|
||||||
|
account,
|
||||||
)
|
)
|
||||||
returnValue(ret)
|
returnValue(ret)
|
||||||
elif sysarg:
|
elif sysarg:
|
||||||
|
|
|
||||||
|
|
@ -71,13 +71,18 @@ def build_matches(raw_string, cmdset, include_prefixes=False):
|
||||||
for cmdname in [cmd.key] + cmd.aliases
|
for cmdname in [cmd.key] + cmd.aliases
|
||||||
if cmdname
|
if cmdname
|
||||||
and l_raw_string.startswith(cmdname.lower())
|
and l_raw_string.startswith(cmdname.lower())
|
||||||
and (not cmd.arg_regex or cmd.arg_regex.match(l_raw_string[len(cmdname) :]))
|
and (
|
||||||
|
not cmd.arg_regex
|
||||||
|
or cmd.arg_regex.match(l_raw_string[len(cmdname) :])
|
||||||
|
)
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
# strip prefixes set in settings
|
# strip prefixes set in settings
|
||||||
raw_string = (
|
raw_string = (
|
||||||
raw_string.lstrip(_CMD_IGNORE_PREFIXES) if len(raw_string) > 1 else raw_string
|
raw_string.lstrip(_CMD_IGNORE_PREFIXES)
|
||||||
|
if len(raw_string) > 1
|
||||||
|
else raw_string
|
||||||
)
|
)
|
||||||
l_raw_string = raw_string.lower()
|
l_raw_string = raw_string.lower()
|
||||||
for cmd in cmdset:
|
for cmd in cmdset:
|
||||||
|
|
@ -90,9 +95,14 @@ def build_matches(raw_string, cmdset, include_prefixes=False):
|
||||||
if (
|
if (
|
||||||
cmdname
|
cmdname
|
||||||
and l_raw_string.startswith(cmdname.lower())
|
and l_raw_string.startswith(cmdname.lower())
|
||||||
and (not cmd.arg_regex or cmd.arg_regex.match(l_raw_string[len(cmdname) :]))
|
and (
|
||||||
|
not cmd.arg_regex
|
||||||
|
or cmd.arg_regex.match(l_raw_string[len(cmdname) :])
|
||||||
|
)
|
||||||
):
|
):
|
||||||
matches.append(create_match(cmdname, raw_string, cmd, raw_cmdname))
|
matches.append(
|
||||||
|
create_match(cmdname, raw_string, cmd, raw_cmdname)
|
||||||
|
)
|
||||||
except Exception:
|
except Exception:
|
||||||
log_trace("cmdhandler error. raw_input:%s" % raw_string)
|
log_trace("cmdhandler error. raw_input:%s" % raw_string)
|
||||||
return matches
|
return matches
|
||||||
|
|
@ -125,7 +135,10 @@ def try_num_prefixes(raw_string):
|
||||||
# the user might be trying to identify the command
|
# the user might be trying to identify the command
|
||||||
# with a #num-command style syntax. We expect the regex to
|
# with a #num-command style syntax. We expect the regex to
|
||||||
# contain the groups "number" and "name".
|
# contain the groups "number" and "name".
|
||||||
mindex, new_raw_string = num_ref_match.group("number"), num_ref_match.group("name")
|
mindex, new_raw_string = (
|
||||||
|
num_ref_match.group("number"),
|
||||||
|
num_ref_match.group("name"),
|
||||||
|
)
|
||||||
return mindex, new_raw_string
|
return mindex, new_raw_string
|
||||||
else:
|
else:
|
||||||
return None, None
|
return None, None
|
||||||
|
|
@ -180,7 +193,9 @@ def cmdparser(raw_string, cmdset, caller, match_index=None):
|
||||||
if _CMD_IGNORE_PREFIXES:
|
if _CMD_IGNORE_PREFIXES:
|
||||||
# still no match. Try to strip prefixes
|
# still no match. Try to strip prefixes
|
||||||
raw_string = (
|
raw_string = (
|
||||||
raw_string.lstrip(_CMD_IGNORE_PREFIXES) if len(raw_string) > 1 else raw_string
|
raw_string.lstrip(_CMD_IGNORE_PREFIXES)
|
||||||
|
if len(raw_string) > 1
|
||||||
|
else raw_string
|
||||||
)
|
)
|
||||||
matches = build_matches(raw_string, cmdset, include_prefixes=False)
|
matches = build_matches(raw_string, cmdset, include_prefixes=False)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -334,7 +334,9 @@ class CmdSet(object, metaclass=_CmdSetMeta):
|
||||||
commands (str): Representation of commands in Cmdset.
|
commands (str): Representation of commands in Cmdset.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return ", ".join([str(cmd) for cmd in sorted(self.commands, key=lambda o: o.key)])
|
return ", ".join(
|
||||||
|
[str(cmd) for cmd in sorted(self.commands, key=lambda o: o.key)]
|
||||||
|
)
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
"""
|
"""
|
||||||
|
|
@ -403,10 +405,16 @@ class CmdSet(object, metaclass=_CmdSetMeta):
|
||||||
# set changes the setting (i.e. has a non-None value). We don't pass through
|
# set changes the setting (i.e. has a non-None value). We don't pass through
|
||||||
# the duplicates setting; that is per-merge
|
# the duplicates setting; that is per-merge
|
||||||
cmdset_c.no_channels = (
|
cmdset_c.no_channels = (
|
||||||
self.no_channels if cmdset_a.no_channels is None else cmdset_a.no_channels
|
self.no_channels
|
||||||
|
if cmdset_a.no_channels is None
|
||||||
|
else cmdset_a.no_channels
|
||||||
|
)
|
||||||
|
cmdset_c.no_exits = (
|
||||||
|
self.no_exits if cmdset_a.no_exits is None else cmdset_a.no_exits
|
||||||
|
)
|
||||||
|
cmdset_c.no_objs = (
|
||||||
|
self.no_objs if cmdset_a.no_objs is None else cmdset_a.no_objs
|
||||||
)
|
)
|
||||||
cmdset_c.no_exits = self.no_exits if cmdset_a.no_exits is None else cmdset_a.no_exits
|
|
||||||
cmdset_c.no_objs = self.no_objs if cmdset_a.no_objs is None else cmdset_a.no_objs
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# B higher priority than A
|
# B higher priority than A
|
||||||
|
|
@ -432,8 +440,12 @@ class CmdSet(object, metaclass=_CmdSetMeta):
|
||||||
cmdset_c.no_channels = (
|
cmdset_c.no_channels = (
|
||||||
cmdset_a.no_channels if self.no_channels is None else self.no_channels
|
cmdset_a.no_channels if self.no_channels is None else self.no_channels
|
||||||
)
|
)
|
||||||
cmdset_c.no_exits = cmdset_a.no_exits if self.no_exits is None else self.no_exits
|
cmdset_c.no_exits = (
|
||||||
cmdset_c.no_objs = cmdset_a.no_objs if self.no_objs is None else self.no_objs
|
cmdset_a.no_exits if self.no_exits is None else self.no_exits
|
||||||
|
)
|
||||||
|
cmdset_c.no_objs = (
|
||||||
|
cmdset_a.no_objs if self.no_objs is None else self.no_objs
|
||||||
|
)
|
||||||
|
|
||||||
# we store actual_mergetype since key_mergetypes
|
# we store actual_mergetype since key_mergetypes
|
||||||
# might be different from the main mergetype.
|
# might be different from the main mergetype.
|
||||||
|
|
@ -617,7 +629,11 @@ class CmdSet(object, metaclass=_CmdSetMeta):
|
||||||
"""
|
"""
|
||||||
names = []
|
names = []
|
||||||
if caller:
|
if caller:
|
||||||
[names.extend(cmd._keyaliases) for cmd in self.commands if cmd.access(caller)]
|
[
|
||||||
|
names.extend(cmd._keyaliases)
|
||||||
|
for cmd in self.commands
|
||||||
|
if cmd.access(caller)
|
||||||
|
]
|
||||||
else:
|
else:
|
||||||
[names.extend(cmd._keyaliases) for cmd in self.commands]
|
[names.extend(cmd._keyaliases) for cmd in self.commands]
|
||||||
return names
|
return names
|
||||||
|
|
|
||||||
|
|
@ -114,7 +114,9 @@ Replacing with fallback '{fallback_path}'.
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
|
||||||
_ERROR_CMDSET_NO_FALLBACK = _("""Fallback path '{fallback_path}' failed to generate a cmdset.""")
|
_ERROR_CMDSET_NO_FALLBACK = _(
|
||||||
|
"""Fallback path '{fallback_path}' failed to generate a cmdset."""
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class _ErrorCmdSet(CmdSet):
|
class _ErrorCmdSet(CmdSet):
|
||||||
|
|
@ -160,7 +162,9 @@ def import_cmdset(path, cmdsetobj, emit_to_obj=None, no_logging=False):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
python_paths = [path] + [
|
python_paths = [path] + [
|
||||||
"%s.%s" % (prefix, path) for prefix in _CMDSET_PATHS if not path.startswith(prefix)
|
"%s.%s" % (prefix, path)
|
||||||
|
for prefix in _CMDSET_PATHS
|
||||||
|
if not path.startswith(prefix)
|
||||||
]
|
]
|
||||||
errstring = ""
|
errstring = ""
|
||||||
for python_path in python_paths:
|
for python_path in python_paths:
|
||||||
|
|
@ -168,7 +172,9 @@ def import_cmdset(path, cmdsetobj, emit_to_obj=None, no_logging=False):
|
||||||
if "." in path:
|
if "." in path:
|
||||||
modpath, classname = python_path.rsplit(".", 1)
|
modpath, classname = python_path.rsplit(".", 1)
|
||||||
else:
|
else:
|
||||||
raise ImportError("The path '%s' is not on the form modulepath.ClassName" % path)
|
raise ImportError(
|
||||||
|
"The path '%s' is not on the form modulepath.ClassName" % path
|
||||||
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# first try to get from cache
|
# first try to get from cache
|
||||||
|
|
@ -207,7 +213,9 @@ def import_cmdset(path, cmdsetobj, emit_to_obj=None, no_logging=False):
|
||||||
errstring += _ERROR_CMDSET_IMPORT
|
errstring += _ERROR_CMDSET_IMPORT
|
||||||
if _IN_GAME_ERRORS:
|
if _IN_GAME_ERRORS:
|
||||||
errstring = errstring.format(
|
errstring = errstring.format(
|
||||||
path=python_path, traceback=format_exc(), timestamp=logger.timeformat()
|
path=python_path,
|
||||||
|
traceback=format_exc(),
|
||||||
|
timestamp=logger.timeformat(),
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
errstring = errstring.format(
|
errstring = errstring.format(
|
||||||
|
|
@ -226,7 +234,9 @@ def import_cmdset(path, cmdsetobj, emit_to_obj=None, no_logging=False):
|
||||||
errstring += _ERROR_CMDSET_SYNTAXERROR
|
errstring += _ERROR_CMDSET_SYNTAXERROR
|
||||||
if _IN_GAME_ERRORS:
|
if _IN_GAME_ERRORS:
|
||||||
errstring = errstring.format(
|
errstring = errstring.format(
|
||||||
path=python_path, traceback=format_exc(), timestamp=logger.timeformat()
|
path=python_path,
|
||||||
|
traceback=format_exc(),
|
||||||
|
timestamp=logger.timeformat(),
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
errstring = errstring.format(
|
errstring = errstring.format(
|
||||||
|
|
@ -238,7 +248,9 @@ def import_cmdset(path, cmdsetobj, emit_to_obj=None, no_logging=False):
|
||||||
errstring += _ERROR_CMDSET_EXCEPTION
|
errstring += _ERROR_CMDSET_EXCEPTION
|
||||||
if _IN_GAME_ERRORS:
|
if _IN_GAME_ERRORS:
|
||||||
errstring = errstring.format(
|
errstring = errstring.format(
|
||||||
path=python_path, traceback=format_exc(), timestamp=logger.timeformat()
|
path=python_path,
|
||||||
|
traceback=format_exc(),
|
||||||
|
timestamp=logger.timeformat(),
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
errstring = errstring.format(
|
errstring = errstring.format(
|
||||||
|
|
@ -347,13 +359,17 @@ class CmdSetHandler(object):
|
||||||
permstring = "non-perm"
|
permstring = "non-perm"
|
||||||
if self.current.permanent:
|
if self.current.permanent:
|
||||||
permstring = "perm"
|
permstring = "perm"
|
||||||
tmpstring = _(" <{key} ({mergetype}, prio {prio}, {permstring})>:\n {keylist}")
|
tmpstring = _(
|
||||||
|
" <{key} ({mergetype}, prio {prio}, {permstring})>:\n {keylist}"
|
||||||
|
)
|
||||||
string += tmpstring.format(
|
string += tmpstring.format(
|
||||||
key=self.current.key,
|
key=self.current.key,
|
||||||
mergetype=mergetype,
|
mergetype=mergetype,
|
||||||
prio=self.current.priority,
|
prio=self.current.priority,
|
||||||
permstring=permstring,
|
permstring=permstring,
|
||||||
keylist=", ".join(cmd.key for cmd in sorted(self.current, key=lambda o: o.key)),
|
keylist=", ".join(
|
||||||
|
cmd.key for cmd in sorted(self.current, key=lambda o: o.key)
|
||||||
|
),
|
||||||
)
|
)
|
||||||
return string.strip()
|
return string.strip()
|
||||||
|
|
||||||
|
|
@ -491,7 +507,9 @@ class CmdSetHandler(object):
|
||||||
permanent (bool, optional): The new Cmdset should survive a server reboot.
|
permanent (bool, optional): The new Cmdset should survive a server reboot.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
self.add(cmdset, emit_to_obj=emit_to_obj, permanent=permanent, default_cmdset=True)
|
self.add(
|
||||||
|
cmdset, emit_to_obj=emit_to_obj, permanent=permanent, default_cmdset=True
|
||||||
|
)
|
||||||
|
|
||||||
def remove(self, cmdset=None, default_cmdset=False):
|
def remove(self, cmdset=None, default_cmdset=False):
|
||||||
"""
|
"""
|
||||||
|
|
@ -535,7 +553,9 @@ class CmdSetHandler(object):
|
||||||
else:
|
else:
|
||||||
# try it as a callable
|
# try it as a callable
|
||||||
if callable(cmdset) and hasattr(cmdset, "path"):
|
if callable(cmdset) and hasattr(cmdset, "path"):
|
||||||
delcmdsets = [cset for cset in self.cmdset_stack[1:] if cset.path == cmdset.path]
|
delcmdsets = [
|
||||||
|
cset for cset in self.cmdset_stack[1:] if cset.path == cmdset.path
|
||||||
|
]
|
||||||
else:
|
else:
|
||||||
# try it as a path or key
|
# try it as a path or key
|
||||||
delcmdsets = [
|
delcmdsets = [
|
||||||
|
|
@ -627,12 +647,15 @@ class CmdSetHandler(object):
|
||||||
if must_be_default:
|
if must_be_default:
|
||||||
return self.cmdset_stack and (self.cmdset_stack[0].path == cmdset.path)
|
return self.cmdset_stack and (self.cmdset_stack[0].path == cmdset.path)
|
||||||
else:
|
else:
|
||||||
return any([cset for cset in self.cmdset_stack if cset.path == cmdset.path])
|
return any(
|
||||||
|
[cset for cset in self.cmdset_stack if cset.path == cmdset.path]
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
# try it as a path or key
|
# try it as a path or key
|
||||||
if must_be_default:
|
if must_be_default:
|
||||||
return self.cmdset_stack and (
|
return self.cmdset_stack and (
|
||||||
self.cmdset_stack[0].key == cmdset or self.cmdset_stack[0].path == cmdset
|
self.cmdset_stack[0].key == cmdset
|
||||||
|
or self.cmdset_stack[0].path == cmdset
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
return any(
|
return any(
|
||||||
|
|
|
||||||
|
|
@ -37,10 +37,14 @@ def _init_command(cls, **kwargs):
|
||||||
cls.key = cls.key.lower()
|
cls.key = cls.key.lower()
|
||||||
if cls.aliases and not is_iter(cls.aliases):
|
if cls.aliases and not is_iter(cls.aliases):
|
||||||
try:
|
try:
|
||||||
cls.aliases = [str(alias).strip().lower() for alias in cls.aliases.split(",")]
|
cls.aliases = [
|
||||||
|
str(alias).strip().lower() for alias in cls.aliases.split(",")
|
||||||
|
]
|
||||||
except Exception:
|
except Exception:
|
||||||
cls.aliases = []
|
cls.aliases = []
|
||||||
cls.aliases = list(set(alias for alias in cls.aliases if alias and alias != cls.key))
|
cls.aliases = list(
|
||||||
|
set(alias for alias in cls.aliases if alias and alias != cls.key)
|
||||||
|
)
|
||||||
|
|
||||||
# optimization - a set is much faster to match against than a list
|
# optimization - a set is much faster to match against than a list
|
||||||
cls._matchset = set([cls.key] + cls.aliases)
|
cls._matchset = set([cls.key] + cls.aliases)
|
||||||
|
|
@ -410,7 +414,8 @@ class Command(object, metaclass=CommandMeta):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
variables = "\n".join(
|
variables = "\n".join(
|
||||||
" |w{}|n ({}): {}".format(key, type(val), val) for key, val in self.__dict__.items()
|
" |w{}|n ({}): {}".format(key, type(val), val)
|
||||||
|
for key, val in self.__dict__.items()
|
||||||
)
|
)
|
||||||
string = f"""
|
string = f"""
|
||||||
Command {self} has no defined `func()` - showing on-command variables:
|
Command {self} has no defined `func()` - showing on-command variables:
|
||||||
|
|
@ -426,7 +431,10 @@ Command {self} has no defined `func()` - showing on-command variables:
|
||||||
string += "\nname of cmd (self.key): |w%s|n\n" % self.key
|
string += "\nname of cmd (self.key): |w%s|n\n" % self.key
|
||||||
string += "cmd aliases (self.aliases): |w%s|n\n" % self.aliases
|
string += "cmd aliases (self.aliases): |w%s|n\n" % self.aliases
|
||||||
string += "cmd locks (self.locks): |w%s|n\n" % self.locks
|
string += "cmd locks (self.locks): |w%s|n\n" % self.locks
|
||||||
string += "help category (self.help_category): |w%s|n\n" % self.help_category.capitalize()
|
string += (
|
||||||
|
"help category (self.help_category): |w%s|n\n"
|
||||||
|
% self.help_category.capitalize()
|
||||||
|
)
|
||||||
string += "object calling (self.caller): |w%s|n\n" % self.caller
|
string += "object calling (self.caller): |w%s|n\n" % self.caller
|
||||||
string += "object storing cmdset (self.obj): |w%s|n\n" % self.obj
|
string += "object storing cmdset (self.obj): |w%s|n\n" % self.obj
|
||||||
string += "command string given (self.cmdstring): |w%s|n\n" % self.cmdstring
|
string += "command string given (self.cmdstring): |w%s|n\n" % self.cmdstring
|
||||||
|
|
@ -577,15 +585,21 @@ Command {self} has no defined `func()` - showing on-command variables:
|
||||||
if header_text:
|
if header_text:
|
||||||
if color_header:
|
if color_header:
|
||||||
header_text = ANSIString(header_text).clean()
|
header_text = ANSIString(header_text).clean()
|
||||||
header_text = ANSIString("|n|%s%s|n" % (colors["headertext"], header_text))
|
header_text = ANSIString(
|
||||||
|
"|n|%s%s|n" % (colors["headertext"], header_text)
|
||||||
|
)
|
||||||
if mode == "header":
|
if mode == "header":
|
||||||
begin_center = ANSIString(
|
begin_center = ANSIString(
|
||||||
"|n|%s<|%s* |n" % (colors["border"], colors["headerstar"])
|
"|n|%s<|%s* |n" % (colors["border"], colors["headerstar"])
|
||||||
)
|
)
|
||||||
end_center = ANSIString("|n |%s*|%s>|n" % (colors["headerstar"], colors["border"]))
|
end_center = ANSIString(
|
||||||
|
"|n |%s*|%s>|n" % (colors["headerstar"], colors["border"])
|
||||||
|
)
|
||||||
center_string = ANSIString(begin_center + header_text + end_center)
|
center_string = ANSIString(begin_center + header_text + end_center)
|
||||||
else:
|
else:
|
||||||
center_string = ANSIString("|n |%s%s |n" % (colors["headertext"], header_text))
|
center_string = ANSIString(
|
||||||
|
"|n |%s%s |n" % (colors["headertext"], header_text)
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
center_string = ""
|
center_string = ""
|
||||||
|
|
||||||
|
|
@ -599,14 +613,22 @@ Command {self} has no defined `func()` - showing on-command variables:
|
||||||
right_width = math.floor(remain_fill / 2)
|
right_width = math.floor(remain_fill / 2)
|
||||||
left_width = math.ceil(remain_fill / 2)
|
left_width = math.ceil(remain_fill / 2)
|
||||||
|
|
||||||
right_fill = ANSIString("|n|%s%s|n" % (colors["border"], fill_character * int(right_width)))
|
right_fill = ANSIString(
|
||||||
left_fill = ANSIString("|n|%s%s|n" % (colors["border"], fill_character * int(left_width)))
|
"|n|%s%s|n" % (colors["border"], fill_character * int(right_width))
|
||||||
|
)
|
||||||
|
left_fill = ANSIString(
|
||||||
|
"|n|%s%s|n" % (colors["border"], fill_character * int(left_width))
|
||||||
|
)
|
||||||
|
|
||||||
if edge_character:
|
if edge_character:
|
||||||
edge_fill = ANSIString("|n|%s%s|n" % (colors["border"], edge_character))
|
edge_fill = ANSIString("|n|%s%s|n" % (colors["border"], edge_character))
|
||||||
main_string = ANSIString(center_string)
|
main_string = ANSIString(center_string)
|
||||||
final_send = (
|
final_send = (
|
||||||
ANSIString(edge_fill) + left_fill + main_string + right_fill + ANSIString(edge_fill)
|
ANSIString(edge_fill)
|
||||||
|
+ left_fill
|
||||||
|
+ main_string
|
||||||
|
+ right_fill
|
||||||
|
+ ANSIString(edge_fill)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
final_send = left_fill + ANSIString(center_string) + right_fill
|
final_send = left_fill + ANSIString(center_string) + right_fill
|
||||||
|
|
|
||||||
|
|
@ -72,9 +72,9 @@ class MuxAccountLookCommand(COMMAND_DEFAULT_CLASS):
|
||||||
self.account.db._playable_characters = playable
|
self.account.db._playable_characters = playable
|
||||||
# store playable property
|
# store playable property
|
||||||
if self.args:
|
if self.args:
|
||||||
self.playable = dict((utils.to_str(char.key.lower()), char) for char in playable).get(
|
self.playable = dict(
|
||||||
self.args.lower(), None
|
(utils.to_str(char.key.lower()), char) for char in playable
|
||||||
)
|
).get(self.args.lower(), None)
|
||||||
else:
|
else:
|
||||||
self.playable = playable
|
self.playable = playable
|
||||||
|
|
||||||
|
|
@ -113,7 +113,9 @@ class CmdOOCLook(MuxAccountLookCommand):
|
||||||
|
|
||||||
if _MULTISESSION_MODE < 2:
|
if _MULTISESSION_MODE < 2:
|
||||||
# only one character allowed
|
# only one character allowed
|
||||||
self.msg("You are out-of-character (OOC).\nUse |wic|n to get back into the game.")
|
self.msg(
|
||||||
|
"You are out-of-character (OOC).\nUse |wic|n to get back into the game."
|
||||||
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
# call on-account look helper method
|
# call on-account look helper method
|
||||||
|
|
@ -152,7 +154,8 @@ class CmdCharCreate(COMMAND_DEFAULT_CLASS):
|
||||||
charmax = _MAX_NR_CHARACTERS
|
charmax = _MAX_NR_CHARACTERS
|
||||||
|
|
||||||
if not account.is_superuser and (
|
if not account.is_superuser and (
|
||||||
account.db._playable_characters and len(account.db._playable_characters) >= charmax
|
account.db._playable_characters
|
||||||
|
and len(account.db._playable_characters) >= charmax
|
||||||
):
|
):
|
||||||
self.msg("You may only create a maximum of %i characters." % charmax)
|
self.msg("You may only create a maximum of %i characters." % charmax)
|
||||||
return
|
return
|
||||||
|
|
@ -172,7 +175,11 @@ class CmdCharCreate(COMMAND_DEFAULT_CLASS):
|
||||||
default_home = ObjectDB.objects.get_id(settings.DEFAULT_HOME)
|
default_home = ObjectDB.objects.get_id(settings.DEFAULT_HOME)
|
||||||
permissions = settings.PERMISSION_ACCOUNT_DEFAULT
|
permissions = settings.PERMISSION_ACCOUNT_DEFAULT
|
||||||
new_character = create.create_object(
|
new_character = create.create_object(
|
||||||
typeclass, key=key, location=start_location, home=default_home, permissions=permissions
|
typeclass,
|
||||||
|
key=key,
|
||||||
|
location=start_location,
|
||||||
|
home=default_home,
|
||||||
|
permissions=permissions,
|
||||||
)
|
)
|
||||||
# only allow creator (and developers) to puppet this char
|
# only allow creator (and developers) to puppet this char
|
||||||
new_character.locks.add(
|
new_character.locks.add(
|
||||||
|
|
@ -259,9 +266,7 @@ class CmdCharDelete(COMMAND_DEFAULT_CLASS):
|
||||||
self.msg("You do not have permission to delete this character.")
|
self.msg("You do not have permission to delete this character.")
|
||||||
return
|
return
|
||||||
|
|
||||||
prompt = (
|
prompt = "|rThis will permanently destroy '%s'. This cannot be undone.|n Continue yes/[no]?"
|
||||||
"|rThis will permanently destroy '%s'. This cannot be undone.|n Continue yes/[no]?"
|
|
||||||
)
|
|
||||||
get_input(account, prompt % match.key, _callback)
|
get_input(account, prompt % match.key, _callback)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -308,7 +313,9 @@ class CmdIC(COMMAND_DEFAULT_CLASS):
|
||||||
if not new_character:
|
if not new_character:
|
||||||
# search for a matching character
|
# search for a matching character
|
||||||
new_character = [
|
new_character = [
|
||||||
char for char in search.object_search(self.args) if char.access(account, "puppet")
|
char
|
||||||
|
for char in search.object_search(self.args)
|
||||||
|
if char.access(account, "puppet")
|
||||||
]
|
]
|
||||||
if not new_character:
|
if not new_character:
|
||||||
self.msg("That is not a valid character choice.")
|
self.msg("That is not a valid character choice.")
|
||||||
|
|
@ -379,7 +386,9 @@ class CmdOOC(MuxAccountLookCommand):
|
||||||
|
|
||||||
if _MULTISESSION_MODE < 2:
|
if _MULTISESSION_MODE < 2:
|
||||||
# only one character allowed
|
# only one character allowed
|
||||||
self.msg("You are out-of-character (OOC).\nUse |wic|n to get back into the game.")
|
self.msg(
|
||||||
|
"You are out-of-character (OOC).\nUse |wic|n to get back into the game."
|
||||||
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
self.msg(account.at_look(target=self.playable, session=session))
|
self.msg(account.at_look(target=self.playable, session=session))
|
||||||
|
|
@ -457,9 +466,9 @@ class CmdWho(COMMAND_DEFAULT_CLASS):
|
||||||
if self.cmdstring == "doing":
|
if self.cmdstring == "doing":
|
||||||
show_session_data = False
|
show_session_data = False
|
||||||
else:
|
else:
|
||||||
show_session_data = account.check_permstring("Developer") or account.check_permstring(
|
show_session_data = account.check_permstring(
|
||||||
"Admins"
|
"Developer"
|
||||||
)
|
) or account.check_permstring("Admins")
|
||||||
|
|
||||||
naccounts = SESSIONS.account_count()
|
naccounts = SESSIONS.account_count()
|
||||||
if show_session_data:
|
if show_session_data:
|
||||||
|
|
@ -486,11 +495,15 @@ class CmdWho(COMMAND_DEFAULT_CLASS):
|
||||||
utils.crop(account.get_display_name(account), width=25),
|
utils.crop(account.get_display_name(account), width=25),
|
||||||
utils.time_format(delta_conn, 0),
|
utils.time_format(delta_conn, 0),
|
||||||
utils.time_format(delta_cmd, 1),
|
utils.time_format(delta_cmd, 1),
|
||||||
utils.crop(puppet.get_display_name(account) if puppet else "None", width=25),
|
utils.crop(
|
||||||
|
puppet.get_display_name(account) if puppet else "None", width=25
|
||||||
|
),
|
||||||
utils.crop(location, width=25),
|
utils.crop(location, width=25),
|
||||||
session.cmd_total,
|
session.cmd_total,
|
||||||
session.protocol_key,
|
session.protocol_key,
|
||||||
isinstance(session.address, tuple) and session.address[0] or session.address,
|
isinstance(session.address, tuple)
|
||||||
|
and session.address[0]
|
||||||
|
or session.address,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
# unprivileged
|
# unprivileged
|
||||||
|
|
@ -562,7 +575,9 @@ class CmdOption(COMMAND_DEFAULT_CLASS):
|
||||||
self.msg("|gCleared all saved options.")
|
self.msg("|gCleared all saved options.")
|
||||||
|
|
||||||
options = dict(flags) # make a copy of the flag dict
|
options = dict(flags) # make a copy of the flag dict
|
||||||
saved_options = dict(self.caller.attributes.get("_saved_protocol_flags", default={}))
|
saved_options = dict(
|
||||||
|
self.caller.attributes.get("_saved_protocol_flags", default={})
|
||||||
|
)
|
||||||
|
|
||||||
if "SCREENWIDTH" in options:
|
if "SCREENWIDTH" in options:
|
||||||
if len(options["SCREENWIDTH"]) == 1:
|
if len(options["SCREENWIDTH"]) == 1:
|
||||||
|
|
@ -589,11 +604,15 @@ class CmdOption(COMMAND_DEFAULT_CLASS):
|
||||||
if saved_options:
|
if saved_options:
|
||||||
saved = " |YYes|n" if key in saved_options else ""
|
saved = " |YYes|n" if key in saved_options else ""
|
||||||
changed = (
|
changed = (
|
||||||
"|y*|n" if key in saved_options and flags[key] != saved_options[key] else ""
|
"|y*|n"
|
||||||
|
if key in saved_options and flags[key] != saved_options[key]
|
||||||
|
else ""
|
||||||
)
|
)
|
||||||
row.append("%s%s" % (saved, changed))
|
row.append("%s%s" % (saved, changed))
|
||||||
table.add_row(*row)
|
table.add_row(*row)
|
||||||
self.msg("|wClient settings (%s):|n\n%s|n" % (self.session.protocol_key, table))
|
self.msg(
|
||||||
|
"|wClient settings (%s):|n\n%s|n" % (self.session.protocol_key, table)
|
||||||
|
)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
@ -623,7 +642,9 @@ class CmdOption(COMMAND_DEFAULT_CLASS):
|
||||||
old_val = flags.get(new_name, False)
|
old_val = flags.get(new_name, False)
|
||||||
new_val = validator(new_val)
|
new_val = validator(new_val)
|
||||||
if old_val == new_val:
|
if old_val == new_val:
|
||||||
self.msg("Option |w%s|n was kept as '|w%s|n'." % (new_name, old_val))
|
self.msg(
|
||||||
|
"Option |w%s|n was kept as '|w%s|n'." % (new_name, old_val)
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
flags[new_name] = new_val
|
flags[new_name] = new_val
|
||||||
self.msg(
|
self.msg(
|
||||||
|
|
@ -667,7 +688,9 @@ class CmdOption(COMMAND_DEFAULT_CLASS):
|
||||||
# a valid setting
|
# a valid setting
|
||||||
if "save" in self.switches:
|
if "save" in self.switches:
|
||||||
# save this option only
|
# save this option only
|
||||||
saved_options = self.account.attributes.get("_saved_protocol_flags", default={})
|
saved_options = self.account.attributes.get(
|
||||||
|
"_saved_protocol_flags", default={}
|
||||||
|
)
|
||||||
saved_options.update(optiondict)
|
saved_options.update(optiondict)
|
||||||
self.account.attributes.add("_saved_protocol_flags", saved_options)
|
self.account.attributes.add("_saved_protocol_flags", saved_options)
|
||||||
for key in optiondict:
|
for key in optiondict:
|
||||||
|
|
@ -675,7 +698,9 @@ class CmdOption(COMMAND_DEFAULT_CLASS):
|
||||||
if "clear" in self.switches:
|
if "clear" in self.switches:
|
||||||
# clear this save
|
# clear this save
|
||||||
for key in optiondict:
|
for key in optiondict:
|
||||||
self.account.attributes.get("_saved_protocol_flags", {}).pop(key, None)
|
self.account.attributes.get("_saved_protocol_flags", {}).pop(
|
||||||
|
key, None
|
||||||
|
)
|
||||||
self.msg("|gCleared saved %s." % key)
|
self.msg("|gCleared saved %s." % key)
|
||||||
self.session.update_flags(**optiondict)
|
self.session.update_flags(**optiondict)
|
||||||
|
|
||||||
|
|
@ -752,7 +777,8 @@ class CmdQuit(COMMAND_DEFAULT_CLASS):
|
||||||
|
|
||||||
if "all" in self.switches:
|
if "all" in self.switches:
|
||||||
account.msg(
|
account.msg(
|
||||||
"|RQuitting|n all sessions. Hope to see you soon again.", session=self.session
|
"|RQuitting|n all sessions. Hope to see you soon again.",
|
||||||
|
session=self.session,
|
||||||
)
|
)
|
||||||
reason = "quit/all"
|
reason = "quit/all"
|
||||||
for session in account.sessions.all():
|
for session in account.sessions.all():
|
||||||
|
|
@ -761,7 +787,10 @@ class CmdQuit(COMMAND_DEFAULT_CLASS):
|
||||||
nsess = len(account.sessions.all())
|
nsess = len(account.sessions.all())
|
||||||
reason = "quit"
|
reason = "quit"
|
||||||
if nsess == 2:
|
if nsess == 2:
|
||||||
account.msg("|RQuitting|n. One session is still connected.", session=self.session)
|
account.msg(
|
||||||
|
"|RQuitting|n. One session is still connected.",
|
||||||
|
session=self.session,
|
||||||
|
)
|
||||||
elif nsess > 2:
|
elif nsess > 2:
|
||||||
account.msg(
|
account.msg(
|
||||||
"|RQuitting|n. %i sessions are still connected." % (nsess - 1),
|
"|RQuitting|n. %i sessions are still connected." % (nsess - 1),
|
||||||
|
|
@ -769,7 +798,9 @@ class CmdQuit(COMMAND_DEFAULT_CLASS):
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
# we are quitting the last available session
|
# we are quitting the last available session
|
||||||
account.msg("|RQuitting|n. Hope to see you again, soon.", session=self.session)
|
account.msg(
|
||||||
|
"|RQuitting|n. Hope to see you again, soon.", session=self.session
|
||||||
|
)
|
||||||
account.disconnect_session_from_account(self.session, reason)
|
account.disconnect_session_from_account(self.session, reason)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -841,11 +872,13 @@ class CmdColorTest(COMMAND_DEFAULT_CLASS):
|
||||||
for code, _ in ap.ansi_map[self.slice_dark_fg]
|
for code, _ in ap.ansi_map[self.slice_dark_fg]
|
||||||
]
|
]
|
||||||
dark_bg = [
|
dark_bg = [
|
||||||
"%s%s|n" % (code.replace("\\", ""), code.replace("|", "||").replace("\\", ""))
|
"%s%s|n"
|
||||||
|
% (code.replace("\\", ""), code.replace("|", "||").replace("\\", ""))
|
||||||
for code, _ in ap.ansi_map[self.slice_dark_bg]
|
for code, _ in ap.ansi_map[self.slice_dark_bg]
|
||||||
]
|
]
|
||||||
bright_bg = [
|
bright_bg = [
|
||||||
"%s%s|n" % (code.replace("\\", ""), code.replace("|", "||").replace("\\", ""))
|
"%s%s|n"
|
||||||
|
% (code.replace("\\", ""), code.replace("|", "||").replace("\\", ""))
|
||||||
for code, _ in ap.ansi_xterm256_bright_bg_map[self.slice_bright_bg]
|
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))])
|
dark_fg.extend(["" for _ in range(len(bright_fg) - len(dark_fg))])
|
||||||
|
|
@ -867,11 +900,21 @@ class CmdColorTest(COMMAND_DEFAULT_CLASS):
|
||||||
for ig in range(6):
|
for ig in range(6):
|
||||||
for ib in range(6):
|
for ib in range(6):
|
||||||
# foreground table
|
# foreground table
|
||||||
table[ir].append("|%i%i%i%s|n" % (ir, ig, ib, "||%i%i%i" % (ir, ig, ib)))
|
table[ir].append(
|
||||||
|
"|%i%i%i%s|n" % (ir, ig, ib, "||%i%i%i" % (ir, ig, ib))
|
||||||
|
)
|
||||||
# background table
|
# background table
|
||||||
table[6 + ir].append(
|
table[6 + ir].append(
|
||||||
"|%i%i%i|[%i%i%i%s|n"
|
"|%i%i%i|[%i%i%i%s|n"
|
||||||
% (5 - ir, 5 - ig, 5 - ib, ir, ig, ib, "||[%i%i%i" % (ir, ig, ib))
|
% (
|
||||||
|
5 - ir,
|
||||||
|
5 - ig,
|
||||||
|
5 - ib,
|
||||||
|
ir,
|
||||||
|
ig,
|
||||||
|
ib,
|
||||||
|
"||[%i%i%i" % (ir, ig, ib),
|
||||||
|
)
|
||||||
)
|
)
|
||||||
table = self.table_format(table)
|
table = self.table_format(table)
|
||||||
string = "Xterm256 colors (if not all hues show, your client might not report that it can handle xterm256):"
|
string = "Xterm256 colors (if not all hues show, your client might not report that it can handle xterm256):"
|
||||||
|
|
@ -882,7 +925,9 @@ class CmdColorTest(COMMAND_DEFAULT_CLASS):
|
||||||
letter = chr(97 + (ibatch * 6 + igray))
|
letter = chr(97 + (ibatch * 6 + igray))
|
||||||
inverse = chr(122 - (ibatch * 6 + igray))
|
inverse = chr(122 - (ibatch * 6 + igray))
|
||||||
table[0 + igray].append("|=%s%s |n" % (letter, "||=%s" % letter))
|
table[0 + igray].append("|=%s%s |n" % (letter, "||=%s" % letter))
|
||||||
table[6 + igray].append("|=%s|[=%s%s |n" % (inverse, letter, "||[=%s" % letter))
|
table[6 + igray].append(
|
||||||
|
"|=%s|[=%s%s |n" % (inverse, letter, "||[=%s" % letter)
|
||||||
|
)
|
||||||
for igray in range(6):
|
for igray in range(6):
|
||||||
# the last row (y, z) has empty columns
|
# the last row (y, z) has empty columns
|
||||||
if igray < 2:
|
if igray < 2:
|
||||||
|
|
@ -968,7 +1013,10 @@ class CmdQuell(COMMAND_DEFAULT_CLASS):
|
||||||
cpermstr += "\nUse unquell to return to normal permission usage."
|
cpermstr += "\nUse unquell to return to normal permission usage."
|
||||||
self.msg(cpermstr)
|
self.msg(cpermstr)
|
||||||
else:
|
else:
|
||||||
self.msg("Quelling Account permissions%s. Use unquell to get them back." % permstr)
|
self.msg(
|
||||||
|
"Quelling Account permissions%s. Use unquell to get them back."
|
||||||
|
% permstr
|
||||||
|
)
|
||||||
self._recache_locks(account)
|
self._recache_locks(account)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -999,7 +1047,10 @@ class CmdStyle(COMMAND_DEFAULT_CLASS):
|
||||||
for op_key in self.account.options.options_dict.keys():
|
for op_key in self.account.options.options_dict.keys():
|
||||||
op_found = self.account.options.get(op_key, return_obj=True)
|
op_found = self.account.options.get(op_key, return_obj=True)
|
||||||
table.add_row(
|
table.add_row(
|
||||||
op_key, op_found.description, op_found.__class__.__name__, op_found.display()
|
op_key,
|
||||||
|
op_found.description,
|
||||||
|
op_found.__class__.__name__,
|
||||||
|
op_found.display(),
|
||||||
)
|
)
|
||||||
self.msg(str(table))
|
self.msg(str(table))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,9 @@ class CmdBoot(COMMAND_DEFAULT_CLASS):
|
||||||
boot_list.append(match)
|
boot_list.append(match)
|
||||||
|
|
||||||
if not boot_list:
|
if not boot_list:
|
||||||
caller.msg("No matching sessions found. The Account does not seem to be online.")
|
caller.msg(
|
||||||
|
"No matching sessions found. The Account does not seem to be online."
|
||||||
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
# Carry out the booting of the sessions in the boot list.
|
# Carry out the booting of the sessions in the boot list.
|
||||||
|
|
@ -190,7 +192,8 @@ class CmdBan(COMMAND_DEFAULT_CLASS):
|
||||||
banlist = []
|
banlist = []
|
||||||
|
|
||||||
if not self.args or (
|
if not self.args or (
|
||||||
self.switches and not any(switch in ("ip", "name") for switch in self.switches)
|
self.switches
|
||||||
|
and not any(switch in ("ip", "name") for switch in self.switches)
|
||||||
):
|
):
|
||||||
self.caller.msg(list_bans(self, banlist))
|
self.caller.msg(list_bans(self, banlist))
|
||||||
return
|
return
|
||||||
|
|
@ -399,9 +402,12 @@ class CmdNewPassword(COMMAND_DEFAULT_CLASS):
|
||||||
account.save()
|
account.save()
|
||||||
self.msg("%s - new password set to '%s'." % (account.name, newpass))
|
self.msg("%s - new password set to '%s'." % (account.name, newpass))
|
||||||
if account.character != caller:
|
if account.character != caller:
|
||||||
account.msg("%s has changed your password to '%s'." % (caller.name, newpass))
|
account.msg(
|
||||||
|
"%s has changed your password to '%s'." % (caller.name, newpass)
|
||||||
|
)
|
||||||
logger.log_sec(
|
logger.log_sec(
|
||||||
"Password Changed: %s (Caller: %s, IP: %s)." % (account, caller, self.session.address)
|
"Password Changed: %s (Caller: %s, IP: %s)."
|
||||||
|
% (account, caller, self.session.address)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -486,14 +492,17 @@ class CmdPerm(COMMAND_DEFAULT_CLASS):
|
||||||
obj.permissions.remove(perm)
|
obj.permissions.remove(perm)
|
||||||
if obj.permissions.get(perm):
|
if obj.permissions.get(perm):
|
||||||
caller_result.append(
|
caller_result.append(
|
||||||
"\nPermissions %s could not be removed from %s." % (perm, obj.name)
|
"\nPermissions %s could not be removed from %s."
|
||||||
|
% (perm, obj.name)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
caller_result.append(
|
caller_result.append(
|
||||||
"\nPermission %s removed from %s (if they existed)." % (perm, obj.name)
|
"\nPermission %s removed from %s (if they existed)."
|
||||||
|
% (perm, obj.name)
|
||||||
)
|
)
|
||||||
target_result.append(
|
target_result.append(
|
||||||
"\n%s revokes the permission(s) %s from you." % (caller.name, perm)
|
"\n%s revokes the permission(s) %s from you."
|
||||||
|
% (caller.name, perm)
|
||||||
)
|
)
|
||||||
logger.log_sec(
|
logger.log_sec(
|
||||||
"Permissions Deleted: %s, %s (Caller: %s, IP: %s)."
|
"Permissions Deleted: %s, %s (Caller: %s, IP: %s)."
|
||||||
|
|
@ -523,7 +532,8 @@ class CmdPerm(COMMAND_DEFAULT_CLASS):
|
||||||
obj.permissions.add(perm)
|
obj.permissions.add(perm)
|
||||||
plystring = "the Account" if accountmode else "the Object/Character"
|
plystring = "the Account" if accountmode else "the Object/Character"
|
||||||
caller_result.append(
|
caller_result.append(
|
||||||
"\nPermission '%s' given to %s (%s)." % (perm, obj.name, plystring)
|
"\nPermission '%s' given to %s (%s)."
|
||||||
|
% (perm, obj.name, plystring)
|
||||||
)
|
)
|
||||||
target_result.append(
|
target_result.append(
|
||||||
"\n%s gives you (%s, %s) the permission '%s'."
|
"\n%s gives you (%s, %s) the permission '%s'."
|
||||||
|
|
@ -583,13 +593,17 @@ class CmdForce(COMMAND_DEFAULT_CLASS):
|
||||||
def func(self):
|
def func(self):
|
||||||
"""Implements the force command"""
|
"""Implements the force command"""
|
||||||
if not self.lhs or not self.rhs:
|
if not self.lhs or not self.rhs:
|
||||||
self.caller.msg("You must provide a target and a command string to execute.")
|
self.caller.msg(
|
||||||
|
"You must provide a target and a command string to execute."
|
||||||
|
)
|
||||||
return
|
return
|
||||||
targ = self.caller.search(self.lhs)
|
targ = self.caller.search(self.lhs)
|
||||||
if not targ:
|
if not targ:
|
||||||
return
|
return
|
||||||
if not targ.access(self.caller, self.perm_used):
|
if not targ.access(self.caller, self.perm_used):
|
||||||
self.caller.msg("You don't have permission to force them to execute commands.")
|
self.caller.msg(
|
||||||
|
"You don't have permission to force them to execute commands."
|
||||||
|
)
|
||||||
return
|
return
|
||||||
targ.execute_cmd(self.rhs)
|
targ.execute_cmd(self.rhs)
|
||||||
self.caller.msg("You have forced %s to: %s" % (targ, self.rhs))
|
self.caller.msg("You have forced %s to: %s" % (targ, self.rhs))
|
||||||
|
|
|
||||||
|
|
@ -269,7 +269,9 @@ class CmdBatchCommands(_COMMAND_DEFAULT_CLASS):
|
||||||
"%s'%s' could not load. You have to supply python paths "
|
"%s'%s' could not load. You have to supply python paths "
|
||||||
"from one of the defined batch-file directories\n (%s)."
|
"from one of the defined batch-file directories\n (%s)."
|
||||||
)
|
)
|
||||||
caller.msg(string % (err, python_path, ", ".join(settings.BASE_BATCHPROCESS_PATHS)))
|
caller.msg(
|
||||||
|
string % (err, python_path, ", ".join(settings.BASE_BATCHPROCESS_PATHS))
|
||||||
|
)
|
||||||
return
|
return
|
||||||
if not commands:
|
if not commands:
|
||||||
caller.msg("File %s seems empty of valid commands." % python_path)
|
caller.msg("File %s seems empty of valid commands." % python_path)
|
||||||
|
|
@ -292,7 +294,9 @@ class CmdBatchCommands(_COMMAND_DEFAULT_CLASS):
|
||||||
# Set interactive state directly
|
# Set interactive state directly
|
||||||
caller.cmdset.add(BatchInteractiveCmdSet)
|
caller.cmdset.add(BatchInteractiveCmdSet)
|
||||||
|
|
||||||
caller.msg("\nBatch-command processor - Interactive mode for %s ..." % python_path)
|
caller.msg(
|
||||||
|
"\nBatch-command processor - Interactive mode for %s ..." % python_path
|
||||||
|
)
|
||||||
show_curr(caller)
|
show_curr(caller)
|
||||||
else:
|
else:
|
||||||
caller.msg(
|
caller.msg(
|
||||||
|
|
@ -391,7 +395,9 @@ class CmdBatchCode(_COMMAND_DEFAULT_CLASS):
|
||||||
"%s'%s' could not load. You have to supply python paths "
|
"%s'%s' could not load. You have to supply python paths "
|
||||||
"from one of the defined batch-file directories\n (%s)."
|
"from one of the defined batch-file directories\n (%s)."
|
||||||
)
|
)
|
||||||
caller.msg(string % (err, python_path, ", ".join(settings.BASE_BATCHPROCESS_PATHS)))
|
caller.msg(
|
||||||
|
string % (err, python_path, ", ".join(settings.BASE_BATCHPROCESS_PATHS))
|
||||||
|
)
|
||||||
return
|
return
|
||||||
if not codes:
|
if not codes:
|
||||||
caller.msg("File %s seems empty of functional code." % python_path)
|
caller.msg("File %s seems empty of functional code." % python_path)
|
||||||
|
|
@ -415,10 +421,14 @@ class CmdBatchCode(_COMMAND_DEFAULT_CLASS):
|
||||||
# Set interactive state directly
|
# Set interactive state directly
|
||||||
caller.cmdset.add(BatchInteractiveCmdSet)
|
caller.cmdset.add(BatchInteractiveCmdSet)
|
||||||
|
|
||||||
caller.msg("\nBatch-code processor - Interactive mode for %s ..." % python_path)
|
caller.msg(
|
||||||
|
"\nBatch-code processor - Interactive mode for %s ..." % python_path
|
||||||
|
)
|
||||||
show_curr(caller)
|
show_curr(caller)
|
||||||
else:
|
else:
|
||||||
caller.msg("Running Batch-code processor - Automatic mode for %s ..." % python_path)
|
caller.msg(
|
||||||
|
"Running Batch-code processor - Automatic mode for %s ..." % python_path
|
||||||
|
)
|
||||||
|
|
||||||
procpool = False
|
procpool = False
|
||||||
if "PythonProcPool" in utils.server_services():
|
if "PythonProcPool" in utils.server_services():
|
||||||
|
|
@ -479,7 +489,9 @@ class CmdStateAbort(_COMMAND_DEFAULT_CLASS):
|
||||||
def func(self):
|
def func(self):
|
||||||
"""Exit back to default."""
|
"""Exit back to default."""
|
||||||
purge_processor(self.caller)
|
purge_processor(self.caller)
|
||||||
self.caller.msg("Exited processor and reset out active cmdset back to the default one.")
|
self.caller.msg(
|
||||||
|
"Exited processor and reset out active cmdset back to the default one."
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class CmdStateLL(_COMMAND_DEFAULT_CLASS):
|
class CmdStateLL(_COMMAND_DEFAULT_CLASS):
|
||||||
|
|
|
||||||
|
|
@ -108,12 +108,20 @@ class ObjManipCommand(COMMAND_DEFAULT_CLASS):
|
||||||
objdef, option = [part.strip() for part in objdef.rsplit(":", 1)]
|
objdef, option = [part.strip() for part in objdef.rsplit(":", 1)]
|
||||||
if ";" in objdef:
|
if ";" in objdef:
|
||||||
objdef, aliases = [part.strip() for part in objdef.split(";", 1)]
|
objdef, aliases = [part.strip() for part in objdef.split(";", 1)]
|
||||||
aliases = [alias.strip() for alias in aliases.split(";") if alias.strip()]
|
aliases = [
|
||||||
|
alias.strip() for alias in aliases.split(";") if alias.strip()
|
||||||
|
]
|
||||||
if "/" in objdef:
|
if "/" in objdef:
|
||||||
objdef, attrs = [part.strip() for part in objdef.split("/", 1)]
|
objdef, attrs = [part.strip() for part in objdef.split("/", 1)]
|
||||||
attrs = [part.strip().lower() for part in attrs.split("/") if part.strip()]
|
attrs = [
|
||||||
|
part.strip().lower()
|
||||||
|
for part in attrs.split("/")
|
||||||
|
if part.strip()
|
||||||
|
]
|
||||||
# store data
|
# store data
|
||||||
obj_defs[iside].append({"name": objdef, "option": option, "aliases": aliases})
|
obj_defs[iside].append(
|
||||||
|
{"name": objdef, "option": option, "aliases": aliases}
|
||||||
|
)
|
||||||
obj_attrs[iside].append({"name": objdef, "attrs": attrs})
|
obj_attrs[iside].append({"name": objdef, "attrs": attrs})
|
||||||
|
|
||||||
# store for future access
|
# store for future access
|
||||||
|
|
@ -177,7 +185,12 @@ class CmdSetObjAlias(COMMAND_DEFAULT_CLASS):
|
||||||
obj.get_display_name(caller),
|
obj.get_display_name(caller),
|
||||||
", ".join(
|
", ".join(
|
||||||
"'%s'%s"
|
"'%s'%s"
|
||||||
% (alias, "" if category is None else "[category:'%s']" % category)
|
% (
|
||||||
|
alias,
|
||||||
|
""
|
||||||
|
if category is None
|
||||||
|
else "[category:'%s']" % category,
|
||||||
|
)
|
||||||
for (alias, category) in aliases
|
for (alias, category) in aliases
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
@ -218,7 +231,9 @@ class CmdSetObjAlias(COMMAND_DEFAULT_CLASS):
|
||||||
|
|
||||||
# merge the old and new aliases (if any)
|
# merge the old and new aliases (if any)
|
||||||
old_aliases = obj.aliases.get(category=category, return_list=True)
|
old_aliases = obj.aliases.get(category=category, return_list=True)
|
||||||
new_aliases = [alias.strip().lower() for alias in rhs.split(",") if alias.strip()]
|
new_aliases = [
|
||||||
|
alias.strip().lower() for alias in rhs.split(",") if alias.strip()
|
||||||
|
]
|
||||||
|
|
||||||
# make the aliases only appear once
|
# make the aliases only appear once
|
||||||
old_aliases.extend(new_aliases)
|
old_aliases.extend(new_aliases)
|
||||||
|
|
@ -324,7 +339,10 @@ class CmdCopy(ObjManipCommand):
|
||||||
to_obj_aliases,
|
to_obj_aliases,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
string = "There was an error copying %s to '%s'." % (from_obj_name, to_obj_name)
|
string = "There was an error copying %s to '%s'." % (
|
||||||
|
from_obj_name,
|
||||||
|
to_obj_name,
|
||||||
|
)
|
||||||
# we are done, echo to user
|
# we are done, echo to user
|
||||||
caller.msg(string)
|
caller.msg(string)
|
||||||
|
|
||||||
|
|
@ -547,7 +565,9 @@ class CmdCreate(ObjManipCommand):
|
||||||
|
|
||||||
# lockstring of newly created objects, for easy overloading.
|
# lockstring of newly created objects, for easy overloading.
|
||||||
# Will be formatted with the {id} of the creating object.
|
# Will be formatted with the {id} of the creating object.
|
||||||
new_obj_lockstring = "control:id({id}) or perm(Admin);delete:id({id}) or perm(Admin)"
|
new_obj_lockstring = (
|
||||||
|
"control:id({id}) or perm(Admin);delete:id({id}) or perm(Admin)"
|
||||||
|
)
|
||||||
|
|
||||||
def func(self):
|
def func(self):
|
||||||
"""
|
"""
|
||||||
|
|
@ -640,7 +660,9 @@ class CmdDesc(COMMAND_DEFAULT_CLASS):
|
||||||
|
|
||||||
def edit_handler(self):
|
def edit_handler(self):
|
||||||
if self.rhs:
|
if self.rhs:
|
||||||
self.msg("|rYou may specify a value, or use the edit switch, " "but not both.|n")
|
self.msg(
|
||||||
|
"|rYou may specify a value, or use the edit switch, " "but not both.|n"
|
||||||
|
)
|
||||||
return
|
return
|
||||||
if self.args:
|
if self.args:
|
||||||
obj = self.caller.search(self.args)
|
obj = self.caller.search(self.args)
|
||||||
|
|
@ -650,7 +672,9 @@ class CmdDesc(COMMAND_DEFAULT_CLASS):
|
||||||
return
|
return
|
||||||
|
|
||||||
if not (obj.access(self.caller, "control") or obj.access(self.caller, "edit")):
|
if not (obj.access(self.caller, "control") or obj.access(self.caller, "edit")):
|
||||||
self.caller.msg("You don't have permission to edit the description of %s." % obj.key)
|
self.caller.msg(
|
||||||
|
"You don't have permission to edit the description of %s." % obj.key
|
||||||
|
)
|
||||||
|
|
||||||
self.caller.db.evmenu_target = obj
|
self.caller.db.evmenu_target = obj
|
||||||
# launch the editor
|
# launch the editor
|
||||||
|
|
@ -691,7 +715,9 @@ class CmdDesc(COMMAND_DEFAULT_CLASS):
|
||||||
obj.db.desc = desc
|
obj.db.desc = desc
|
||||||
caller.msg("The description was set on %s." % obj.get_display_name(caller))
|
caller.msg("The description was set on %s." % obj.get_display_name(caller))
|
||||||
else:
|
else:
|
||||||
caller.msg("You don't have permission to edit the description of %s." % obj.key)
|
caller.msg(
|
||||||
|
"You don't have permission to edit the description of %s." % obj.key
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class CmdDestroy(COMMAND_DEFAULT_CLASS):
|
class CmdDestroy(COMMAND_DEFAULT_CLASS):
|
||||||
|
|
@ -772,9 +798,13 @@ class CmdDestroy(COMMAND_DEFAULT_CLASS):
|
||||||
else:
|
else:
|
||||||
string += "\n%s was destroyed." % objname
|
string += "\n%s was destroyed." % objname
|
||||||
if had_exits:
|
if had_exits:
|
||||||
string += " Exits to and from %s were destroyed as well." % objname
|
string += (
|
||||||
|
" Exits to and from %s were destroyed as well." % objname
|
||||||
|
)
|
||||||
if had_objs:
|
if had_objs:
|
||||||
string += " Objects inside %s were moved to their homes." % objname
|
string += (
|
||||||
|
" Objects inside %s were moved to their homes." % objname
|
||||||
|
)
|
||||||
return string
|
return string
|
||||||
|
|
||||||
objs = []
|
objs = []
|
||||||
|
|
@ -784,7 +814,9 @@ class CmdDestroy(COMMAND_DEFAULT_CLASS):
|
||||||
|
|
||||||
if "-" in objname:
|
if "-" in objname:
|
||||||
# might be a range of dbrefs
|
# might be a range of dbrefs
|
||||||
dmin, dmax = [utils.dbref(part, reqhash=False) for part in objname.split("-", 1)]
|
dmin, dmax = [
|
||||||
|
utils.dbref(part, reqhash=False) for part in objname.split("-", 1)
|
||||||
|
]
|
||||||
if dmin and dmax:
|
if dmin and dmax:
|
||||||
for dbref in range(int(dmin), int(dmax + 1)):
|
for dbref in range(int(dmin), int(dmax + 1)):
|
||||||
obj = caller.search("#" + str(dbref))
|
obj = caller.search("#" + str(dbref))
|
||||||
|
|
@ -877,7 +909,10 @@ class CmdDig(ObjManipCommand):
|
||||||
caller = self.caller
|
caller = self.caller
|
||||||
|
|
||||||
if not self.lhs:
|
if not self.lhs:
|
||||||
string = "Usage: dig[/teleport] <roomname>[;alias;alias...]" "[:parent] [= <exit_there>"
|
string = (
|
||||||
|
"Usage: dig[/teleport] <roomname>[;alias;alias...]"
|
||||||
|
"[:parent] [= <exit_there>"
|
||||||
|
)
|
||||||
string += "[;alias;alias..][:parent]] "
|
string += "[;alias;alias..][:parent]] "
|
||||||
string += "[, <exit_back_here>[;alias;alias..][:parent]]"
|
string += "[, <exit_back_here>[;alias;alias..][:parent]]"
|
||||||
caller.msg(string)
|
caller.msg(string)
|
||||||
|
|
@ -957,7 +992,9 @@ class CmdDig(ObjManipCommand):
|
||||||
if not back_exit["name"]:
|
if not back_exit["name"]:
|
||||||
exit_back_string = "\nNo back exit created."
|
exit_back_string = "\nNo back exit created."
|
||||||
elif not location:
|
elif not location:
|
||||||
exit_back_string = "\nYou cannot create an exit back to a None-location."
|
exit_back_string = (
|
||||||
|
"\nYou cannot create an exit back to a None-location."
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
typeclass = back_exit["option"]
|
typeclass = back_exit["option"]
|
||||||
if not typeclass:
|
if not typeclass:
|
||||||
|
|
@ -1051,8 +1088,9 @@ class CmdTunnel(COMMAND_DEFAULT_CLASS):
|
||||||
exitshort = self.lhs.split(":")[0]
|
exitshort = self.lhs.split(":")[0]
|
||||||
|
|
||||||
if exitshort not in self.directions:
|
if exitshort not in self.directions:
|
||||||
string = "tunnel can only understand the following directions: %s." % ",".join(
|
string = (
|
||||||
sorted(self.directions.keys())
|
"tunnel can only understand the following directions: %s."
|
||||||
|
% ",".join(sorted(self.directions.keys()))
|
||||||
)
|
)
|
||||||
string += "\n(use dig for more freedom)"
|
string += "\n(use dig for more freedom)"
|
||||||
self.caller.msg(string)
|
self.caller.msg(string)
|
||||||
|
|
@ -1083,7 +1121,13 @@ class CmdTunnel(COMMAND_DEFAULT_CLASS):
|
||||||
backstring = ", %s;%s" % (backname, backshort)
|
backstring = ", %s;%s" % (backname, backshort)
|
||||||
|
|
||||||
# build the string we will use to call dig
|
# build the string we will use to call dig
|
||||||
digstring = "dig%s %s = %s;%s%s" % (telswitch, roomname, exitname, exitshort, backstring)
|
digstring = "dig%s %s = %s;%s%s" % (
|
||||||
|
telswitch,
|
||||||
|
roomname,
|
||||||
|
exitname,
|
||||||
|
exitshort,
|
||||||
|
backstring,
|
||||||
|
)
|
||||||
self.execute_cmd(digstring)
|
self.execute_cmd(digstring)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1124,8 +1168,12 @@ class CmdLink(COMMAND_DEFAULT_CLASS):
|
||||||
|
|
||||||
# try to search locally first
|
# try to search locally first
|
||||||
results = caller.search(object_name, quiet=True)
|
results = caller.search(object_name, quiet=True)
|
||||||
if len(results) > 1: # local results was a multimatch. Inform them to be more specific
|
if (
|
||||||
_AT_SEARCH_RESULT = variable_from_module(*settings.SEARCH_AT_RESULT.rsplit(".", 1))
|
len(results) > 1
|
||||||
|
): # local results was a multimatch. Inform them to be more specific
|
||||||
|
_AT_SEARCH_RESULT = variable_from_module(
|
||||||
|
*settings.SEARCH_AT_RESULT.rsplit(".", 1)
|
||||||
|
)
|
||||||
return _AT_SEARCH_RESULT(results, caller, query=object_name)
|
return _AT_SEARCH_RESULT(results, caller, query=object_name)
|
||||||
elif len(results) == 1: # A unique local match
|
elif len(results) == 1: # A unique local match
|
||||||
obj = results[0]
|
obj = results[0]
|
||||||
|
|
@ -1150,9 +1198,9 @@ class CmdLink(COMMAND_DEFAULT_CLASS):
|
||||||
string = note % (obj.name, obj.dbref)
|
string = note % (obj.name, obj.dbref)
|
||||||
if "twoway" in self.switches:
|
if "twoway" in self.switches:
|
||||||
if not (target.location and obj.location):
|
if not (target.location and obj.location):
|
||||||
string = "To create a two-way link, %s and %s must both have a location" % (
|
string = (
|
||||||
obj,
|
"To create a two-way link, %s and %s must both have a location"
|
||||||
target,
|
% (obj, target)
|
||||||
)
|
)
|
||||||
string += " (i.e. they cannot be rooms, but should be exits)."
|
string += " (i.e. they cannot be rooms, but should be exits)."
|
||||||
self.caller.msg(string)
|
self.caller.msg(string)
|
||||||
|
|
@ -1179,7 +1227,10 @@ class CmdLink(COMMAND_DEFAULT_CLASS):
|
||||||
if dest:
|
if dest:
|
||||||
string = "%s is an exit to %s." % (obj.name, dest.name)
|
string = "%s is an exit to %s." % (obj.name, dest.name)
|
||||||
else:
|
else:
|
||||||
string = "%s is not an exit. Its home location is %s." % (obj.name, obj.home)
|
string = "%s is not an exit. Its home location is %s." % (
|
||||||
|
obj.name,
|
||||||
|
obj.home,
|
||||||
|
)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# We gave the command link 'obj = ' which means we want to
|
# We gave the command link 'obj = ' which means we want to
|
||||||
|
|
@ -1282,7 +1333,11 @@ class CmdSetHome(CmdLink):
|
||||||
new_home.dbref,
|
new_home.dbref,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
string = "Home location of %s was set to %s(%s)." % (obj, new_home, new_home.dbref)
|
string = "Home location of %s was set to %s(%s)." % (
|
||||||
|
obj,
|
||||||
|
new_home,
|
||||||
|
new_home.dbref,
|
||||||
|
)
|
||||||
self.caller.msg(string)
|
self.caller.msg(string)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1355,8 +1410,12 @@ class CmdName(ObjManipCommand):
|
||||||
if not newname:
|
if not newname:
|
||||||
caller.msg("No name defined!")
|
caller.msg("No name defined!")
|
||||||
return
|
return
|
||||||
if not (obj.access(caller, "control") or obj.access(caller, "edit")):
|
if not (
|
||||||
caller.msg("You don't have right to edit this account %s." % obj)
|
obj.access(caller, "control") or obj.access(caller, "edit")
|
||||||
|
):
|
||||||
|
caller.msg(
|
||||||
|
"You don't have right to edit this account %s." % obj
|
||||||
|
)
|
||||||
return
|
return
|
||||||
obj.username = newname
|
obj.username = newname
|
||||||
obj.save()
|
obj.save()
|
||||||
|
|
@ -1411,7 +1470,9 @@ class CmdOpen(ObjManipCommand):
|
||||||
help_category = "Building"
|
help_category = "Building"
|
||||||
|
|
||||||
# a custom member method to chug out exits and do checks
|
# a custom member method to chug out exits and do checks
|
||||||
def create_exit(self, exit_name, location, destination, exit_aliases=None, typeclass=None):
|
def create_exit(
|
||||||
|
self, exit_name, location, destination, exit_aliases=None, typeclass=None
|
||||||
|
):
|
||||||
"""
|
"""
|
||||||
Helper function to avoid code duplication.
|
Helper function to avoid code duplication.
|
||||||
At this point we know destination is a valid location
|
At this point we know destination is a valid location
|
||||||
|
|
@ -1432,9 +1493,7 @@ class CmdOpen(ObjManipCommand):
|
||||||
if not exit_obj.destination:
|
if not exit_obj.destination:
|
||||||
# we are trying to link a non-exit
|
# we are trying to link a non-exit
|
||||||
string = "'%s' already exists and is not an exit!\nIf you want to convert it "
|
string = "'%s' already exists and is not an exit!\nIf you want to convert it "
|
||||||
string += (
|
string += "to an exit, you must assign an object to the 'destination' property first."
|
||||||
"to an exit, you must assign an object to the 'destination' property first."
|
|
||||||
)
|
|
||||||
caller.msg(string % exit_name)
|
caller.msg(string % exit_name)
|
||||||
return None
|
return None
|
||||||
# we are re-linking an old exit.
|
# we are re-linking an old exit.
|
||||||
|
|
@ -1446,9 +1505,9 @@ class CmdOpen(ObjManipCommand):
|
||||||
exit_obj.destination = destination
|
exit_obj.destination = destination
|
||||||
if exit_aliases:
|
if exit_aliases:
|
||||||
[exit_obj.aliases.add(alias) for alias in exit_aliases]
|
[exit_obj.aliases.add(alias) for alias in exit_aliases]
|
||||||
string += " Rerouted its old destination '%s' to '%s' and changed aliases." % (
|
string += (
|
||||||
old_destination.name,
|
" Rerouted its old destination '%s' to '%s' and changed aliases."
|
||||||
destination.name,
|
% (old_destination.name, destination.name)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
string += " It already points to the correct place."
|
string += " It already points to the correct place."
|
||||||
|
|
@ -1458,7 +1517,11 @@ class CmdOpen(ObjManipCommand):
|
||||||
if not typeclass:
|
if not typeclass:
|
||||||
typeclass = settings.BASE_EXIT_TYPECLASS
|
typeclass = settings.BASE_EXIT_TYPECLASS
|
||||||
exit_obj = create.create_object(
|
exit_obj = create.create_object(
|
||||||
typeclass, key=exit_name, location=location, aliases=exit_aliases, report_to=caller
|
typeclass,
|
||||||
|
key=exit_name,
|
||||||
|
location=location,
|
||||||
|
aliases=exit_aliases,
|
||||||
|
report_to=caller,
|
||||||
)
|
)
|
||||||
if exit_obj:
|
if exit_obj:
|
||||||
# storing a destination is what makes it an exit!
|
# storing a destination is what makes it an exit!
|
||||||
|
|
@ -1513,7 +1576,9 @@ class CmdOpen(ObjManipCommand):
|
||||||
return
|
return
|
||||||
|
|
||||||
# Create exit
|
# Create exit
|
||||||
ok = self.create_exit(exit_name, location, destination, exit_aliases, exit_typeclass)
|
ok = self.create_exit(
|
||||||
|
exit_name, location, destination, exit_aliases, exit_typeclass
|
||||||
|
)
|
||||||
if not ok:
|
if not ok:
|
||||||
# an error; the exit was not created, so we quit.
|
# an error; the exit was not created, so we quit.
|
||||||
return
|
return
|
||||||
|
|
@ -1523,7 +1588,11 @@ class CmdOpen(ObjManipCommand):
|
||||||
back_exit_aliases = self.lhs_objs[1]["aliases"]
|
back_exit_aliases = self.lhs_objs[1]["aliases"]
|
||||||
back_exit_typeclass = self.lhs_objs[1]["option"]
|
back_exit_typeclass = self.lhs_objs[1]["option"]
|
||||||
self.create_exit(
|
self.create_exit(
|
||||||
back_exit_name, destination, location, back_exit_aliases, back_exit_typeclass
|
back_exit_name,
|
||||||
|
destination,
|
||||||
|
location,
|
||||||
|
back_exit_aliases,
|
||||||
|
back_exit_typeclass,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1718,11 +1787,18 @@ class CmdSetAttribute(ObjManipCommand):
|
||||||
del deep[del_key]
|
del deep[del_key]
|
||||||
except (IndexError, KeyError, TypeError):
|
except (IndexError, KeyError, TypeError):
|
||||||
continue
|
continue
|
||||||
return "\nDeleted attribute '%s' (= nested) from %s." % (attr, obj.name)
|
return "\nDeleted attribute '%s' (= nested) from %s." % (
|
||||||
|
attr,
|
||||||
|
obj.name,
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
exists = obj.attributes.has(key)
|
exists = obj.attributes.has(key)
|
||||||
obj.attributes.remove(attr)
|
obj.attributes.remove(attr)
|
||||||
return "\nDeleted attribute '%s' (= %s) from %s." % (attr, exists, obj.name)
|
return "\nDeleted attribute '%s' (= %s) from %s." % (
|
||||||
|
attr,
|
||||||
|
exists,
|
||||||
|
obj.name,
|
||||||
|
)
|
||||||
error = "\n%s has no attribute '%s'." % (obj.name, attr)
|
error = "\n%s has no attribute '%s'." % (obj.name, attr)
|
||||||
if nested:
|
if nested:
|
||||||
error += " (Nested lookups attempted)"
|
error += " (Nested lookups attempted)"
|
||||||
|
|
@ -1816,7 +1892,9 @@ class CmdSetAttribute(ObjManipCommand):
|
||||||
"""
|
"""
|
||||||
from evennia.utils.utils import variable_from_module
|
from evennia.utils.utils import variable_from_module
|
||||||
|
|
||||||
_AT_SEARCH_RESULT = variable_from_module(*settings.SEARCH_AT_RESULT.rsplit(".", 1))
|
_AT_SEARCH_RESULT = variable_from_module(
|
||||||
|
*settings.SEARCH_AT_RESULT.rsplit(".", 1)
|
||||||
|
)
|
||||||
caller = self.caller
|
caller = self.caller
|
||||||
if objname.startswith("*") or "account" in self.switches:
|
if objname.startswith("*") or "account" in self.switches:
|
||||||
found_obj = caller.search_account(objname.lstrip("*"))
|
found_obj = caller.search_account(objname.lstrip("*"))
|
||||||
|
|
@ -1835,7 +1913,9 @@ class CmdSetAttribute(ObjManipCommand):
|
||||||
else:
|
else:
|
||||||
global_search = False
|
global_search = False
|
||||||
typeclass = None
|
typeclass = None
|
||||||
found_obj = caller.search(objname, global_search=global_search, typeclass=typeclass)
|
found_obj = caller.search(
|
||||||
|
objname, global_search=global_search, typeclass=typeclass
|
||||||
|
)
|
||||||
return found_obj
|
return found_obj
|
||||||
|
|
||||||
def func(self):
|
def func(self):
|
||||||
|
|
@ -1861,12 +1941,16 @@ class CmdSetAttribute(ObjManipCommand):
|
||||||
result = []
|
result = []
|
||||||
if "edit" in self.switches:
|
if "edit" in self.switches:
|
||||||
# edit in the line editor
|
# edit in the line editor
|
||||||
if not (obj.access(self.caller, "control") or obj.access(self.caller, "edit")):
|
if not (
|
||||||
|
obj.access(self.caller, "control") or obj.access(self.caller, "edit")
|
||||||
|
):
|
||||||
caller.msg("You don't have permission to edit %s." % obj.key)
|
caller.msg("You don't have permission to edit %s." % obj.key)
|
||||||
return
|
return
|
||||||
|
|
||||||
if len(attrs) > 1:
|
if len(attrs) > 1:
|
||||||
caller.msg("The Line editor can only be applied " "to one attribute at a time.")
|
caller.msg(
|
||||||
|
"The Line editor can only be applied " "to one attribute at a time."
|
||||||
|
)
|
||||||
return
|
return
|
||||||
self.edit_handler(obj, attrs[0])
|
self.edit_handler(obj, attrs[0])
|
||||||
return
|
return
|
||||||
|
|
@ -1884,7 +1968,10 @@ class CmdSetAttribute(ObjManipCommand):
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
# deleting the attribute(s)
|
# deleting the attribute(s)
|
||||||
if not (obj.access(self.caller, "control") or obj.access(self.caller, "edit")):
|
if not (
|
||||||
|
obj.access(self.caller, "control")
|
||||||
|
or obj.access(self.caller, "edit")
|
||||||
|
):
|
||||||
caller.msg("You don't have permission to edit %s." % obj.key)
|
caller.msg("You don't have permission to edit %s." % obj.key)
|
||||||
return
|
return
|
||||||
for attr in attrs:
|
for attr in attrs:
|
||||||
|
|
@ -1893,7 +1980,9 @@ class CmdSetAttribute(ObjManipCommand):
|
||||||
result.append(self.rm_attr(obj, attr))
|
result.append(self.rm_attr(obj, attr))
|
||||||
else:
|
else:
|
||||||
# setting attribute(s). Make sure to convert to real Python type before saving.
|
# setting attribute(s). Make sure to convert to real Python type before saving.
|
||||||
if not (obj.access(self.caller, "control") or obj.access(self.caller, "edit")):
|
if not (
|
||||||
|
obj.access(self.caller, "control") or obj.access(self.caller, "edit")
|
||||||
|
):
|
||||||
caller.msg("You don't have permission to edit %s." % obj.key)
|
caller.msg("You don't have permission to edit %s." % obj.key)
|
||||||
return
|
return
|
||||||
for attr in attrs:
|
for attr in attrs:
|
||||||
|
|
@ -1964,15 +2053,17 @@ class CmdTypeclass(COMMAND_DEFAULT_CLASS):
|
||||||
|
|
||||||
if "list" in self.switches:
|
if "list" in self.switches:
|
||||||
tclasses = get_all_typeclasses()
|
tclasses = get_all_typeclasses()
|
||||||
contribs = [key for key in sorted(tclasses) if key.startswith("evennia.contrib")] or [
|
contribs = [
|
||||||
"<None loaded>"
|
key for key in sorted(tclasses) if key.startswith("evennia.contrib")
|
||||||
]
|
] or ["<None loaded>"]
|
||||||
core = [
|
core = [
|
||||||
key for key in sorted(tclasses) if key.startswith("evennia") and key not in contribs
|
key
|
||||||
|
for key in sorted(tclasses)
|
||||||
|
if key.startswith("evennia") and key not in contribs
|
||||||
|
] or ["<None loaded>"]
|
||||||
|
game = [
|
||||||
|
key for key in sorted(tclasses) if not key.startswith("evennia")
|
||||||
] or ["<None loaded>"]
|
] or ["<None loaded>"]
|
||||||
game = [key for key in sorted(tclasses) if not key.startswith("evennia")] or [
|
|
||||||
"<None loaded>"
|
|
||||||
]
|
|
||||||
string = (
|
string = (
|
||||||
"|wCore typeclasses|n\n"
|
"|wCore typeclasses|n\n"
|
||||||
" {core}\n"
|
" {core}\n"
|
||||||
|
|
@ -1981,7 +2072,9 @@ class CmdTypeclass(COMMAND_DEFAULT_CLASS):
|
||||||
"|wGame-dir typeclasses|n\n"
|
"|wGame-dir typeclasses|n\n"
|
||||||
" {game}"
|
" {game}"
|
||||||
).format(
|
).format(
|
||||||
core="\n ".join(core), contrib="\n ".join(contribs), game="\n ".join(game)
|
core="\n ".join(core),
|
||||||
|
contrib="\n ".join(contribs),
|
||||||
|
game="\n ".join(game),
|
||||||
)
|
)
|
||||||
EvMore(caller, string, exit_on_lastpage=True)
|
EvMore(caller, string, exit_on_lastpage=True)
|
||||||
return
|
return
|
||||||
|
|
@ -1997,7 +2090,9 @@ class CmdTypeclass(COMMAND_DEFAULT_CLASS):
|
||||||
# no object found to examine, see if it's a typeclass-path instead
|
# no object found to examine, see if it's a typeclass-path instead
|
||||||
tclasses = get_all_typeclasses()
|
tclasses = get_all_typeclasses()
|
||||||
matches = [
|
matches = [
|
||||||
(key, tclass) for key, tclass in tclasses.items() if key.endswith(oquery)
|
(key, tclass)
|
||||||
|
for key, tclass in tclasses.items()
|
||||||
|
if key.endswith(oquery)
|
||||||
]
|
]
|
||||||
nmatches = len(matches)
|
nmatches = len(matches)
|
||||||
if nmatches > 1:
|
if nmatches > 1:
|
||||||
|
|
@ -2007,11 +2102,15 @@ class CmdTypeclass(COMMAND_DEFAULT_CLASS):
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
elif not matches:
|
elif not matches:
|
||||||
caller.msg("No object or typeclass path found to match '{}'".format(oquery))
|
caller.msg(
|
||||||
|
"No object or typeclass path found to match '{}'".format(oquery)
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
# one match found
|
# one match found
|
||||||
caller.msg(
|
caller.msg(
|
||||||
"Docstring for typeclass '{}':\n{}".format(oquery, matches[0][1].__doc__)
|
"Docstring for typeclass '{}':\n{}".format(
|
||||||
|
oquery, matches[0][1].__doc__
|
||||||
|
)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
# do the search again to get the error handling in case of multi-match
|
# do the search again to get the error handling in case of multi-match
|
||||||
|
|
@ -2071,11 +2170,17 @@ class CmdTypeclass(COMMAND_DEFAULT_CLASS):
|
||||||
|
|
||||||
# we let this raise exception if needed
|
# we let this raise exception if needed
|
||||||
obj.swap_typeclass(
|
obj.swap_typeclass(
|
||||||
new_typeclass, clean_attributes=reset, clean_cmdsets=reset, run_start_hooks=hooks
|
new_typeclass,
|
||||||
|
clean_attributes=reset,
|
||||||
|
clean_cmdsets=reset,
|
||||||
|
run_start_hooks=hooks,
|
||||||
)
|
)
|
||||||
|
|
||||||
if is_same:
|
if is_same:
|
||||||
string = "%s updated its existing typeclass (%s).\n" % (obj.name, obj.path)
|
string = "%s updated its existing typeclass (%s).\n" % (
|
||||||
|
obj.name,
|
||||||
|
obj.path,
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
string = "%s changed typeclass from %s to %s.\n" % (
|
string = "%s changed typeclass from %s to %s.\n" % (
|
||||||
obj.name,
|
obj.name,
|
||||||
|
|
@ -2189,7 +2294,8 @@ class CmdLock(ObjManipCommand):
|
||||||
caller = self.caller
|
caller = self.caller
|
||||||
if not self.args:
|
if not self.args:
|
||||||
string = (
|
string = (
|
||||||
"Usage: lock <object>[ = <lockstring>] or lock[/switch] " "<object>/<access_type>"
|
"Usage: lock <object>[ = <lockstring>] or lock[/switch] "
|
||||||
|
"<object>/<access_type>"
|
||||||
)
|
)
|
||||||
caller.msg(string)
|
caller.msg(string)
|
||||||
return
|
return
|
||||||
|
|
@ -2335,7 +2441,10 @@ class CmdExamine(ObjManipCommand):
|
||||||
except Exception:
|
except Exception:
|
||||||
ndb_attr = None
|
ndb_attr = None
|
||||||
else:
|
else:
|
||||||
db_attr = [(attr.key, attr.value, attr.category) for attr in obj.db_attributes.all()]
|
db_attr = [
|
||||||
|
(attr.key, attr.value, attr.category)
|
||||||
|
for attr in obj.db_attributes.all()
|
||||||
|
]
|
||||||
try:
|
try:
|
||||||
ndb_attr = obj.nattributes.all(return_tuples=True)
|
ndb_attr = obj.nattributes.all(return_tuples=True)
|
||||||
except Exception:
|
except Exception:
|
||||||
|
|
@ -2359,7 +2468,9 @@ class CmdExamine(ObjManipCommand):
|
||||||
"""
|
"""
|
||||||
string = "\n|wName/key|n: |c%s|n (%s)" % (obj.name, obj.dbref)
|
string = "\n|wName/key|n: |c%s|n (%s)" % (obj.name, obj.dbref)
|
||||||
if hasattr(obj, "aliases") and obj.aliases.all():
|
if hasattr(obj, "aliases") and obj.aliases.all():
|
||||||
string += "\n|wAliases|n: %s" % (", ".join(utils.make_iter(str(obj.aliases))))
|
string += "\n|wAliases|n: %s" % (
|
||||||
|
", ".join(utils.make_iter(str(obj.aliases)))
|
||||||
|
)
|
||||||
if hasattr(obj, "sessions") and obj.sessions.all():
|
if hasattr(obj, "sessions") and obj.sessions.all():
|
||||||
string += "\n|wSession id(s)|n: %s" % (
|
string += "\n|wSession id(s)|n: %s" % (
|
||||||
", ".join("#%i" % sess.sessid for sess in obj.sessions.all())
|
", ".join("#%i" % sess.sessid for sess in obj.sessions.all())
|
||||||
|
|
@ -2401,14 +2512,20 @@ class CmdExamine(ObjManipCommand):
|
||||||
|
|
||||||
locks = str(obj.locks)
|
locks = str(obj.locks)
|
||||||
if locks:
|
if locks:
|
||||||
locks_string = utils.fill("; ".join([lock for lock in locks.split(";")]), indent=6)
|
locks_string = utils.fill(
|
||||||
|
"; ".join([lock for lock in locks.split(";")]), indent=6
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
locks_string = " Default"
|
locks_string = " Default"
|
||||||
string += "\n|wLocks|n:%s" % locks_string
|
string += "\n|wLocks|n:%s" % locks_string
|
||||||
|
|
||||||
if not (len(obj.cmdset.all()) == 1 and obj.cmdset.current.key == "_EMPTY_CMDSET"):
|
if not (
|
||||||
|
len(obj.cmdset.all()) == 1 and obj.cmdset.current.key == "_EMPTY_CMDSET"
|
||||||
|
):
|
||||||
# all() returns a 'stack', so make a copy to sort.
|
# all() returns a 'stack', so make a copy to sort.
|
||||||
stored_cmdsets = sorted(obj.cmdset.all(), key=lambda x: x.priority, reverse=True)
|
stored_cmdsets = sorted(
|
||||||
|
obj.cmdset.all(), key=lambda x: x.priority, reverse=True
|
||||||
|
)
|
||||||
string += "\n|wStored Cmdset(s)|n:\n %s" % (
|
string += "\n|wStored Cmdset(s)|n:\n %s" % (
|
||||||
"\n ".join(
|
"\n ".join(
|
||||||
"%s [%s] (%s, prio %s)"
|
"%s [%s] (%s, prio %s)"
|
||||||
|
|
@ -2423,7 +2540,9 @@ class CmdExamine(ObjManipCommand):
|
||||||
# we always at least try to add account- and session sets since these are ignored
|
# we always at least try to add account- and session sets since these are ignored
|
||||||
# if we merge on the object level.
|
# if we merge on the object level.
|
||||||
if hasattr(obj, "account") and obj.account:
|
if hasattr(obj, "account") and obj.account:
|
||||||
all_cmdsets.extend([(cmdset.key, cmdset) for cmdset in obj.account.cmdset.all()])
|
all_cmdsets.extend(
|
||||||
|
[(cmdset.key, cmdset) for cmdset in obj.account.cmdset.all()]
|
||||||
|
)
|
||||||
if obj.sessions.count():
|
if obj.sessions.count():
|
||||||
# if there are more sessions than one on objects it's because of multisession mode 3.
|
# if there are more sessions than one on objects it's because of multisession mode 3.
|
||||||
# we only show the first session's cmdset here (it is -in principle- possible that
|
# we only show the first session's cmdset here (it is -in principle- possible that
|
||||||
|
|
@ -2441,7 +2560,9 @@ class CmdExamine(ObjManipCommand):
|
||||||
all_cmdsets.extend(
|
all_cmdsets.extend(
|
||||||
[
|
[
|
||||||
(cmdset.key, cmdset)
|
(cmdset.key, cmdset)
|
||||||
for cmdset in obj.get_session(obj.sessions.get()).cmdset.all()
|
for cmdset in obj.get_session(
|
||||||
|
obj.sessions.get()
|
||||||
|
).cmdset.all()
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
except (TypeError, AttributeError):
|
except (TypeError, AttributeError):
|
||||||
|
|
@ -2458,15 +2579,21 @@ class CmdExamine(ObjManipCommand):
|
||||||
)
|
)
|
||||||
|
|
||||||
# list the commands available to this object
|
# list the commands available to this object
|
||||||
avail_cmdset = sorted([cmd.key for cmd in avail_cmdset if cmd.access(obj, "cmd")])
|
avail_cmdset = sorted(
|
||||||
|
[cmd.key for cmd in avail_cmdset if cmd.access(obj, "cmd")]
|
||||||
cmdsetstr = utils.fill(", ".join(avail_cmdset), indent=2)
|
|
||||||
string += "\n|wCommands available to %s (result of Merged CmdSets)|n:\n %s" % (
|
|
||||||
obj.key,
|
|
||||||
cmdsetstr,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if hasattr(obj, "scripts") and hasattr(obj.scripts, "all") and obj.scripts.all():
|
cmdsetstr = utils.fill(", ".join(avail_cmdset), indent=2)
|
||||||
|
string += (
|
||||||
|
"\n|wCommands available to %s (result of Merged CmdSets)|n:\n %s"
|
||||||
|
% (obj.key, cmdsetstr)
|
||||||
|
)
|
||||||
|
|
||||||
|
if (
|
||||||
|
hasattr(obj, "scripts")
|
||||||
|
and hasattr(obj.scripts, "all")
|
||||||
|
and obj.scripts.all()
|
||||||
|
):
|
||||||
string += "\n|wScripts|n:\n %s" % obj.scripts
|
string += "\n|wScripts|n:\n %s" % obj.scripts
|
||||||
# add the attributes
|
# add the attributes
|
||||||
string += self.format_attributes(obj)
|
string += self.format_attributes(obj)
|
||||||
|
|
@ -2645,7 +2772,9 @@ class CmdFind(COMMAND_DEFAULT_CLASS):
|
||||||
caller.msg("Usage: find <string> [= low [-high]]")
|
caller.msg("Usage: find <string> [= low [-high]]")
|
||||||
return
|
return
|
||||||
|
|
||||||
if "locate" in self.cmdstring: # Use option /loc as a default for locate command alias
|
if (
|
||||||
|
"locate" in self.cmdstring
|
||||||
|
): # Use option /loc as a default for locate command alias
|
||||||
switches.append("loc")
|
switches.append("loc")
|
||||||
|
|
||||||
searchstring = self.lhs
|
searchstring = self.lhs
|
||||||
|
|
@ -2693,10 +2822,16 @@ class CmdFind(COMMAND_DEFAULT_CLASS):
|
||||||
if not result:
|
if not result:
|
||||||
string += "\n |RNo match found.|n"
|
string += "\n |RNo match found.|n"
|
||||||
elif not low <= int(result[0].id) <= high:
|
elif not low <= int(result[0].id) <= high:
|
||||||
string += "\n |RNo match found for '%s' in #dbref interval.|n" % searchstring
|
string += (
|
||||||
|
"\n |RNo match found for '%s' in #dbref interval.|n"
|
||||||
|
% searchstring
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
result = result[0]
|
result = result[0]
|
||||||
string += "\n|g %s - %s|n" % (result.get_display_name(caller), result.path)
|
string += "\n|g %s - %s|n" % (
|
||||||
|
result.get_display_name(caller),
|
||||||
|
result.path,
|
||||||
|
)
|
||||||
if "loc" in self.switches and not is_account and result.location:
|
if "loc" in self.switches and not is_account and result.location:
|
||||||
string += " (|wlocation|n: |g{}|n)".format(
|
string += " (|wlocation|n: |g{}|n)".format(
|
||||||
result.location.get_display_name(caller)
|
result.location.get_display_name(caller)
|
||||||
|
|
@ -2713,7 +2848,9 @@ class CmdFind(COMMAND_DEFAULT_CLASS):
|
||||||
id__lte=high,
|
id__lte=high,
|
||||||
)
|
)
|
||||||
elif "startswith" in switches:
|
elif "startswith" in switches:
|
||||||
keyquery = Q(db_key__istartswith=searchstring, id__gte=low, id__lte=high)
|
keyquery = Q(
|
||||||
|
db_key__istartswith=searchstring, id__gte=low, id__lte=high
|
||||||
|
)
|
||||||
aliasquery = Q(
|
aliasquery = Q(
|
||||||
db_tags__db_key__istartswith=searchstring,
|
db_tags__db_key__istartswith=searchstring,
|
||||||
db_tags__db_tagtype__iexact="alias",
|
db_tags__db_tagtype__iexact="alias",
|
||||||
|
|
@ -2736,19 +2873,33 @@ class CmdFind(COMMAND_DEFAULT_CLASS):
|
||||||
# convert result to typeclasses.
|
# convert result to typeclasses.
|
||||||
results = [result for result in results]
|
results = [result for result in results]
|
||||||
if "room" in switches:
|
if "room" in switches:
|
||||||
results = [obj for obj in results if inherits_from(obj, ROOM_TYPECLASS)]
|
results = [
|
||||||
|
obj for obj in results if inherits_from(obj, ROOM_TYPECLASS)
|
||||||
|
]
|
||||||
if "exit" in switches:
|
if "exit" in switches:
|
||||||
results = [obj for obj in results if inherits_from(obj, EXIT_TYPECLASS)]
|
results = [
|
||||||
|
obj for obj in results if inherits_from(obj, EXIT_TYPECLASS)
|
||||||
|
]
|
||||||
if "char" in switches:
|
if "char" in switches:
|
||||||
results = [obj for obj in results if inherits_from(obj, CHAR_TYPECLASS)]
|
results = [
|
||||||
|
obj for obj in results if inherits_from(obj, CHAR_TYPECLASS)
|
||||||
|
]
|
||||||
nresults = len(results)
|
nresults = len(results)
|
||||||
|
|
||||||
# still results after type filtering?
|
# still results after type filtering?
|
||||||
if nresults:
|
if nresults:
|
||||||
if nresults > 1:
|
if nresults > 1:
|
||||||
string = "|w%i Matches|n(#%i-#%i%s):" % (nresults, low, high, restrictions)
|
string = "|w%i Matches|n(#%i-#%i%s):" % (
|
||||||
|
nresults,
|
||||||
|
low,
|
||||||
|
high,
|
||||||
|
restrictions,
|
||||||
|
)
|
||||||
for res in results:
|
for res in results:
|
||||||
string += "\n |g%s - %s|n" % (res.get_display_name(caller), res.path)
|
string += "\n |g%s - %s|n" % (
|
||||||
|
res.get_display_name(caller),
|
||||||
|
res.path,
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
string = "|wOne Match|n(#%i-#%i%s):" % (low, high, restrictions)
|
string = "|wOne Match|n(#%i-#%i%s):" % (low, high, restrictions)
|
||||||
string += "\n |g%s - %s|n" % (
|
string += "\n |g%s - %s|n" % (
|
||||||
|
|
@ -2834,7 +2985,8 @@ class CmdTeleport(COMMAND_DEFAULT_CLASS):
|
||||||
caller.msg("Teleported %s -> None-location." % obj_to_teleport)
|
caller.msg("Teleported %s -> None-location." % obj_to_teleport)
|
||||||
if obj_to_teleport.location and not tel_quietly:
|
if obj_to_teleport.location and not tel_quietly:
|
||||||
obj_to_teleport.location.msg_contents(
|
obj_to_teleport.location.msg_contents(
|
||||||
"%s teleported %s into nothingness." % (caller, obj_to_teleport), exclude=caller
|
"%s teleported %s into nothingness." % (caller, obj_to_teleport),
|
||||||
|
exclude=caller,
|
||||||
)
|
)
|
||||||
obj_to_teleport.location = None
|
obj_to_teleport.location = None
|
||||||
return
|
return
|
||||||
|
|
@ -2877,7 +3029,10 @@ class CmdTeleport(COMMAND_DEFAULT_CLASS):
|
||||||
|
|
||||||
# try the teleport
|
# try the teleport
|
||||||
if obj_to_teleport.move_to(
|
if obj_to_teleport.move_to(
|
||||||
destination, quiet=tel_quietly, emit_to_obj=caller, use_destination=use_destination
|
destination,
|
||||||
|
quiet=tel_quietly,
|
||||||
|
emit_to_obj=caller,
|
||||||
|
use_destination=use_destination,
|
||||||
):
|
):
|
||||||
if obj_to_teleport == caller:
|
if obj_to_teleport == caller:
|
||||||
caller.msg("Teleported to %s." % destination)
|
caller.msg("Teleported to %s." % destination)
|
||||||
|
|
@ -2922,7 +3077,9 @@ class CmdScript(COMMAND_DEFAULT_CLASS):
|
||||||
return
|
return
|
||||||
|
|
||||||
if not self.lhs:
|
if not self.lhs:
|
||||||
caller.msg("To create a global script you need |wscripts/add <typeclass>|n.")
|
caller.msg(
|
||||||
|
"To create a global script you need |wscripts/add <typeclass>|n."
|
||||||
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
obj = caller.search(self.lhs)
|
obj = caller.search(self.lhs)
|
||||||
|
|
@ -2934,7 +3091,9 @@ class CmdScript(COMMAND_DEFAULT_CLASS):
|
||||||
# no rhs means we want to operate on all scripts
|
# no rhs means we want to operate on all scripts
|
||||||
scripts = obj.scripts.all()
|
scripts = obj.scripts.all()
|
||||||
if not scripts:
|
if not scripts:
|
||||||
result.append("No scripts defined on %s." % obj.get_display_name(caller))
|
result.append(
|
||||||
|
"No scripts defined on %s." % obj.get_display_name(caller)
|
||||||
|
)
|
||||||
elif not self.switches:
|
elif not self.switches:
|
||||||
# view all scripts
|
# view all scripts
|
||||||
from evennia.commands.default.system import format_script_list
|
from evennia.commands.default.system import format_script_list
|
||||||
|
|
@ -2942,12 +3101,17 @@ class CmdScript(COMMAND_DEFAULT_CLASS):
|
||||||
result.append(format_script_list(scripts))
|
result.append(format_script_list(scripts))
|
||||||
elif "start" in self.switches:
|
elif "start" in self.switches:
|
||||||
num = sum([obj.scripts.start(script.key) for script in scripts])
|
num = sum([obj.scripts.start(script.key) for script in scripts])
|
||||||
result.append("%s scripts started on %s." % (num, obj.get_display_name(caller)))
|
result.append(
|
||||||
|
"%s scripts started on %s." % (num, obj.get_display_name(caller))
|
||||||
|
)
|
||||||
elif "stop" in self.switches:
|
elif "stop" in self.switches:
|
||||||
for script in scripts:
|
for script in scripts:
|
||||||
result.append(
|
result.append(
|
||||||
"Stopping script %s on %s."
|
"Stopping script %s on %s."
|
||||||
% (script.get_display_name(caller), obj.get_display_name(caller))
|
% (
|
||||||
|
script.get_display_name(caller),
|
||||||
|
obj.get_display_name(caller),
|
||||||
|
)
|
||||||
)
|
)
|
||||||
script.stop()
|
script.stop()
|
||||||
obj.scripts.validate()
|
obj.scripts.validate()
|
||||||
|
|
@ -2975,7 +3139,10 @@ class CmdScript(COMMAND_DEFAULT_CLASS):
|
||||||
for path in paths:
|
for path in paths:
|
||||||
ok = obj.scripts.stop(path)
|
ok = obj.scripts.stop(path)
|
||||||
if not ok:
|
if not ok:
|
||||||
result.append("\nScript %s could not be stopped. Does it exist?" % path)
|
result.append(
|
||||||
|
"\nScript %s could not be stopped. Does it exist?"
|
||||||
|
% path
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
result = ["Script stopped and removed from object."]
|
result = ["Script stopped and removed from object."]
|
||||||
break
|
break
|
||||||
|
|
@ -2984,7 +3151,9 @@ class CmdScript(COMMAND_DEFAULT_CLASS):
|
||||||
for path in paths:
|
for path in paths:
|
||||||
ok = obj.scripts.start(path)
|
ok = obj.scripts.start(path)
|
||||||
if not ok:
|
if not ok:
|
||||||
result.append("\nScript %s could not be (re)started." % path)
|
result.append(
|
||||||
|
"\nScript %s could not be (re)started." % path
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
result = ["Script started successfully."]
|
result = ["Script started successfully."]
|
||||||
break
|
break
|
||||||
|
|
@ -3088,7 +3257,10 @@ class CmdTag(COMMAND_DEFAULT_CLASS):
|
||||||
]
|
]
|
||||||
if old_tags:
|
if old_tags:
|
||||||
obj.tags.clear()
|
obj.tags.clear()
|
||||||
string = "Cleared all tags from %s: %s" % (obj, ", ".join(sorted(old_tags)))
|
string = "Cleared all tags from %s: %s" % (
|
||||||
|
obj,
|
||||||
|
", ".join(sorted(old_tags)),
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
string = "No Tags to clear on %s." % obj
|
string = "No Tags to clear on %s." % obj
|
||||||
self.caller.msg(string)
|
self.caller.msg(string)
|
||||||
|
|
@ -3119,12 +3291,18 @@ class CmdTag(COMMAND_DEFAULT_CLASS):
|
||||||
tagtuples = obj.tags.all(return_key_and_category=True)
|
tagtuples = obj.tags.all(return_key_and_category=True)
|
||||||
ntags = len(tagtuples)
|
ntags = len(tagtuples)
|
||||||
tags = [tup[0] for tup in tagtuples]
|
tags = [tup[0] for tup in tagtuples]
|
||||||
categories = [" (category: %s)" % tup[1] if tup[1] else "" for tup in tagtuples]
|
categories = [
|
||||||
|
" (category: %s)" % tup[1] if tup[1] else "" for tup in tagtuples
|
||||||
|
]
|
||||||
if ntags:
|
if ntags:
|
||||||
string = "Tag%s on %s: %s" % (
|
string = "Tag%s on %s: %s" % (
|
||||||
"s" if ntags > 1 else "",
|
"s" if ntags > 1 else "",
|
||||||
obj,
|
obj,
|
||||||
", ".join(sorted("'%s'%s" % (tags[i], categories[i]) for i in range(ntags))),
|
", ".join(
|
||||||
|
sorted(
|
||||||
|
"'%s'%s" % (tags[i], categories[i]) for i in range(ntags)
|
||||||
|
)
|
||||||
|
),
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
string = "No tags attached to %s." % obj
|
string = "No tags attached to %s." % obj
|
||||||
|
|
@ -3239,9 +3417,12 @@ class CmdSpawn(COMMAND_DEFAULT_CLASS):
|
||||||
return None
|
return None
|
||||||
if expect == dict:
|
if expect == dict:
|
||||||
# an actual prototype. We need to make sure it's safe. Don't allow exec
|
# an actual prototype. We need to make sure it's safe. Don't allow exec
|
||||||
if "exec" in prototype and not self.caller.check_permstring("Developer"):
|
if "exec" in prototype and not self.caller.check_permstring(
|
||||||
|
"Developer"
|
||||||
|
):
|
||||||
self.caller.msg(
|
self.caller.msg(
|
||||||
"Spawn aborted: You are not allowed to " "use the 'exec' prototype key."
|
"Spawn aborted: You are not allowed to "
|
||||||
|
"use the 'exec' prototype key."
|
||||||
)
|
)
|
||||||
return None
|
return None
|
||||||
try:
|
try:
|
||||||
|
|
@ -3277,7 +3458,10 @@ class CmdSpawn(COMMAND_DEFAULT_CLASS):
|
||||||
if len(prototype) > 1:
|
if len(prototype) > 1:
|
||||||
caller.msg(
|
caller.msg(
|
||||||
"More than one match for {}:\n{}".format(
|
"More than one match for {}:\n{}".format(
|
||||||
key, "\n".join(proto.get("prototype_key", "") for proto in prototype)
|
key,
|
||||||
|
"\n".join(
|
||||||
|
proto.get("prototype_key", "") for proto in prototype
|
||||||
|
),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
@ -3298,7 +3482,9 @@ class CmdSpawn(COMMAND_DEFAULT_CLASS):
|
||||||
else:
|
else:
|
||||||
key, tags = self.args.strip(), None
|
key, tags = self.args.strip(), None
|
||||||
if ";" in self.args:
|
if ";" in self.args:
|
||||||
key, tags = (part.strip().lower() for part in self.args.split(";", 1))
|
key, tags = (
|
||||||
|
part.strip().lower() for part in self.args.split(";", 1)
|
||||||
|
)
|
||||||
tags = [tag.strip() for tag in tags.split(",")] if tags else None
|
tags = [tag.strip() for tag in tags.split(",")] if tags else None
|
||||||
EvMore(
|
EvMore(
|
||||||
caller,
|
caller,
|
||||||
|
|
@ -3351,14 +3537,18 @@ class CmdSpawn(COMMAND_DEFAULT_CLASS):
|
||||||
|
|
||||||
prototype_key = prototype.get("prototype_key")
|
prototype_key = prototype.get("prototype_key")
|
||||||
if not prototype_key:
|
if not prototype_key:
|
||||||
caller.msg("\n|yTo save a prototype it must have the 'prototype_key' set.")
|
caller.msg(
|
||||||
|
"\n|yTo save a prototype it must have the 'prototype_key' set."
|
||||||
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
# check for existing prototype,
|
# check for existing prototype,
|
||||||
old_matchstring = _search_show_prototype(prototype_key)
|
old_matchstring = _search_show_prototype(prototype_key)
|
||||||
|
|
||||||
if old_matchstring:
|
if old_matchstring:
|
||||||
string += "\n|yExisting saved prototype found:|n\n{}".format(old_matchstring)
|
string += "\n|yExisting saved prototype found:|n\n{}".format(
|
||||||
|
old_matchstring
|
||||||
|
)
|
||||||
question = "\n|yDo you want to replace the existing prototype?|n [Y]/N"
|
question = "\n|yDo you want to replace the existing prototype?|n [Y]/N"
|
||||||
|
|
||||||
answer = yield (string + question)
|
answer = yield (string + question)
|
||||||
|
|
@ -3396,7 +3586,9 @@ class CmdSpawn(COMMAND_DEFAULT_CLASS):
|
||||||
"Use spawn/update <key> to apply later as needed.|n"
|
"Use spawn/update <key> to apply later as needed.|n"
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
n_updated = spawner.batch_update_objects_with_prototype(existing_objects, key)
|
n_updated = spawner.batch_update_objects_with_prototype(
|
||||||
|
existing_objects, key
|
||||||
|
)
|
||||||
caller.msg("{} objects were updated.".format(n_updated))
|
caller.msg("{} objects were updated.".format(n_updated))
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
@ -3424,7 +3616,9 @@ class CmdSpawn(COMMAND_DEFAULT_CLASS):
|
||||||
caller.msg("|rError deleting:|R {}|n".format(err))
|
caller.msg("|rError deleting:|R {}|n".format(err))
|
||||||
caller.msg(
|
caller.msg(
|
||||||
"Deletion {}.".format(
|
"Deletion {}.".format(
|
||||||
"successful" if success else "failed (does the prototype exist?)"
|
"successful"
|
||||||
|
if success
|
||||||
|
else "failed (does the prototype exist?)"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
@ -3448,7 +3642,9 @@ class CmdSpawn(COMMAND_DEFAULT_CLASS):
|
||||||
if answer.lower() in ["n", "no"]:
|
if answer.lower() in ["n", "no"]:
|
||||||
caller.msg("|rUpdate cancelled.")
|
caller.msg("|rUpdate cancelled.")
|
||||||
return
|
return
|
||||||
n_updated = spawner.batch_update_objects_with_prototype(existing_objects, key)
|
n_updated = spawner.batch_update_objects_with_prototype(
|
||||||
|
existing_objects, key
|
||||||
|
)
|
||||||
caller.msg("{} objects were updated.".format(n_updated))
|
caller.msg("{} objects were updated.".format(n_updated))
|
||||||
|
|
||||||
# A direct creation of an object from a given prototype
|
# A direct creation of an object from a given prototype
|
||||||
|
|
@ -3474,14 +3670,19 @@ class CmdSpawn(COMMAND_DEFAULT_CLASS):
|
||||||
"Found {} prototypes matching '{}':\n {}".format(
|
"Found {} prototypes matching '{}':\n {}".format(
|
||||||
nprots,
|
nprots,
|
||||||
prototype,
|
prototype,
|
||||||
", ".join(proto.get("prototype_key", "") for proto in prototypes),
|
", ".join(
|
||||||
|
proto.get("prototype_key", "") for proto in prototypes
|
||||||
|
),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
# we have a prototype, check access
|
# we have a prototype, check access
|
||||||
prototype = prototypes[0]
|
prototype = prototypes[0]
|
||||||
if not caller.locks.check_lockstring(
|
if not caller.locks.check_lockstring(
|
||||||
caller, prototype.get("prototype_locks", ""), access_type="spawn", default=True
|
caller,
|
||||||
|
prototype.get("prototype_locks", ""),
|
||||||
|
access_type="spawn",
|
||||||
|
default=True,
|
||||||
):
|
):
|
||||||
caller.msg("You don't have access to use this prototype.")
|
caller.msg("You don't have access to use this prototype.")
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -188,14 +188,18 @@ class CmdDelCom(COMMAND_DEFAULT_CLASS):
|
||||||
if delnicks:
|
if delnicks:
|
||||||
for nick in [
|
for nick in [
|
||||||
nick
|
nick
|
||||||
for nick in make_iter(caller.nicks.get(category="channel", return_obj=True))
|
for nick in make_iter(
|
||||||
|
caller.nicks.get(category="channel", return_obj=True)
|
||||||
|
)
|
||||||
if nick and nick.pk and nick.value[3].lower() == chkey
|
if nick and nick.pk and nick.value[3].lower() == chkey
|
||||||
]:
|
]:
|
||||||
nick.delete()
|
nick.delete()
|
||||||
disconnect = channel.disconnect(account)
|
disconnect = channel.disconnect(account)
|
||||||
if disconnect:
|
if disconnect:
|
||||||
wipednicks = " Eventual aliases were removed." if delnicks else ""
|
wipednicks = " Eventual aliases were removed." if delnicks else ""
|
||||||
self.msg("You stop listening to channel '%s'.%s" % (channel.key, wipednicks))
|
self.msg(
|
||||||
|
"You stop listening to channel '%s'.%s" % (channel.key, wipednicks)
|
||||||
|
)
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
# we are removing a channel nick
|
# we are removing a channel nick
|
||||||
|
|
@ -206,7 +210,10 @@ class CmdDelCom(COMMAND_DEFAULT_CLASS):
|
||||||
else:
|
else:
|
||||||
if caller.nicks.get(ostring, category="channel"):
|
if caller.nicks.get(ostring, category="channel"):
|
||||||
caller.nicks.remove(ostring, category="channel")
|
caller.nicks.remove(ostring, category="channel")
|
||||||
self.msg("Your alias '%s' for channel %s was cleared." % (ostring, channel.key))
|
self.msg(
|
||||||
|
"Your alias '%s' for channel %s was cleared."
|
||||||
|
% (ostring, channel.key)
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
self.msg("You had no such alias defined for this channel.")
|
self.msg("You had no such alias defined for this channel.")
|
||||||
|
|
||||||
|
|
@ -340,7 +347,9 @@ class CmdChannels(COMMAND_DEFAULT_CLASS):
|
||||||
"%s%s"
|
"%s%s"
|
||||||
% (
|
% (
|
||||||
chan.key,
|
chan.key,
|
||||||
chan.aliases.all() and "(%s)" % ",".join(chan.aliases.all()) or "",
|
chan.aliases.all()
|
||||||
|
and "(%s)" % ",".join(chan.aliases.all())
|
||||||
|
or "",
|
||||||
),
|
),
|
||||||
"%s"
|
"%s"
|
||||||
% ",".join(
|
% ",".join(
|
||||||
|
|
@ -381,7 +390,9 @@ class CmdChannels(COMMAND_DEFAULT_CLASS):
|
||||||
"%s%s"
|
"%s%s"
|
||||||
% (
|
% (
|
||||||
chan.key,
|
chan.key,
|
||||||
chan.aliases.all() and "(%s)" % ",".join(chan.aliases.all()) or "",
|
chan.aliases.all()
|
||||||
|
and "(%s)" % ",".join(chan.aliases.all())
|
||||||
|
or "",
|
||||||
),
|
),
|
||||||
"%s"
|
"%s"
|
||||||
% ",".join(
|
% ",".join(
|
||||||
|
|
@ -433,7 +444,9 @@ class CmdCdestroy(COMMAND_DEFAULT_CLASS):
|
||||||
self.msg("You are not allowed to do that.")
|
self.msg("You are not allowed to do that.")
|
||||||
return
|
return
|
||||||
channel_key = channel.key
|
channel_key = channel.key
|
||||||
message = "%s is being destroyed. Make sure to change your aliases." % channel_key
|
message = (
|
||||||
|
"%s is being destroyed. Make sure to change your aliases." % channel_key
|
||||||
|
)
|
||||||
msgobj = create.create_message(caller, message, channel)
|
msgobj = create.create_message(caller, message, channel)
|
||||||
channel.msg(msgobj)
|
channel.msg(msgobj)
|
||||||
channel.delete()
|
channel.delete()
|
||||||
|
|
@ -494,7 +507,10 @@ class CmdCBoot(COMMAND_DEFAULT_CLASS):
|
||||||
self.msg(string)
|
self.msg(string)
|
||||||
return
|
return
|
||||||
if not channel.subscriptions.has(account):
|
if not channel.subscriptions.has(account):
|
||||||
string = "Account %s is not connected to channel %s." % (account.key, channel.key)
|
string = "Account %s is not connected to channel %s." % (
|
||||||
|
account.key,
|
||||||
|
channel.key,
|
||||||
|
)
|
||||||
self.msg(string)
|
self.msg(string)
|
||||||
return
|
return
|
||||||
if "quiet" not in self.switches:
|
if "quiet" not in self.switches:
|
||||||
|
|
@ -645,7 +661,9 @@ class CmdChannelCreate(COMMAND_DEFAULT_CLASS):
|
||||||
return
|
return
|
||||||
# Create and set the channel up
|
# Create and set the channel up
|
||||||
lockstring = "send:all();listen:all();control:id(%s)" % caller.id
|
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)
|
new_chan.connect(caller)
|
||||||
CHANNELHANDLER.update()
|
CHANNELHANDLER.update()
|
||||||
self.msg("Created channel %s and connected to it." % new_chan.key)
|
self.msg("Created channel %s and connected to it." % new_chan.key)
|
||||||
|
|
@ -777,7 +795,9 @@ class CmdPage(COMMAND_DEFAULT_CLASS):
|
||||||
caller = self.caller
|
caller = self.caller
|
||||||
|
|
||||||
# get the messages we've sent (not to channels)
|
# get the messages we've sent (not to channels)
|
||||||
pages_we_sent = Msg.objects.get_messages_by_sender(caller, exclude_channel_messages=True)
|
pages_we_sent = Msg.objects.get_messages_by_sender(
|
||||||
|
caller, exclude_channel_messages=True
|
||||||
|
)
|
||||||
# get last messages we've got
|
# get last messages we've got
|
||||||
pages_we_got = Msg.objects.get_messages_by_receiver(caller)
|
pages_we_got = Msg.objects.get_messages_by_receiver(caller)
|
||||||
|
|
||||||
|
|
@ -895,7 +915,10 @@ def _list_bots(cmd):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
ircbots = [
|
ircbots = [
|
||||||
bot for bot in AccountDB.objects.filter(db_is_bot=True, username__startswith="ircbot-")
|
bot
|
||||||
|
for bot in AccountDB.objects.filter(
|
||||||
|
db_is_bot=True, username__startswith="ircbot-"
|
||||||
|
)
|
||||||
]
|
]
|
||||||
if ircbots:
|
if ircbots:
|
||||||
table = cmd.styled_table(
|
table = cmd.styled_table(
|
||||||
|
|
@ -964,7 +987,9 @@ class CmdIRC2Chan(COMMAND_DEFAULT_CLASS):
|
||||||
"""Setup the irc-channel mapping"""
|
"""Setup the irc-channel mapping"""
|
||||||
|
|
||||||
if not settings.IRC_ENABLED:
|
if not settings.IRC_ENABLED:
|
||||||
string = """IRC is not enabled. You need to activate it in game/settings.py."""
|
string = (
|
||||||
|
"""IRC is not enabled. You need to activate it in game/settings.py."""
|
||||||
|
)
|
||||||
self.msg(string)
|
self.msg(string)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
@ -973,7 +998,11 @@ class CmdIRC2Chan(COMMAND_DEFAULT_CLASS):
|
||||||
self.msg(_list_bots(self))
|
self.msg(_list_bots(self))
|
||||||
return
|
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
|
botname = "ircbot-%s" % self.lhs
|
||||||
matches = AccountDB.objects.filter(db_is_bot=True, username=botname)
|
matches = AccountDB.objects.filter(db_is_bot=True, username=botname)
|
||||||
dbref = utils.dbref(self.lhs)
|
dbref = utils.dbref(self.lhs)
|
||||||
|
|
@ -1103,7 +1132,9 @@ class CmdIRCStatus(COMMAND_DEFAULT_CLASS):
|
||||||
elif option in ("users", "nicklist", "who"):
|
elif option in ("users", "nicklist", "who"):
|
||||||
# retrieve user list. The bot must handles the echo since it's
|
# retrieve user list. The bot must handles the echo since it's
|
||||||
# an asynchronous call.
|
# an asynchronous call.
|
||||||
self.caller.msg("Requesting nicklist from %s (%s:%s)." % (channel, network, port))
|
self.caller.msg(
|
||||||
|
"Requesting nicklist from %s (%s:%s)." % (channel, network, port)
|
||||||
|
)
|
||||||
ircbot.get_nicklist(self.caller)
|
ircbot.get_nicklist(self.caller)
|
||||||
elif self.caller.locks.check_lockstring(
|
elif self.caller.locks.check_lockstring(
|
||||||
self.caller, "dummy:perm(ircstatus) or perm(Developer)"
|
self.caller, "dummy:perm(ircstatus) or perm(Developer)"
|
||||||
|
|
@ -1151,7 +1182,9 @@ class CmdRSS2Chan(COMMAND_DEFAULT_CLASS):
|
||||||
|
|
||||||
# checking we have all we need
|
# checking we have all we need
|
||||||
if not settings.RSS_ENABLED:
|
if not settings.RSS_ENABLED:
|
||||||
string = """RSS is not enabled. You need to activate it in game/settings.py."""
|
string = (
|
||||||
|
"""RSS is not enabled. You need to activate it in game/settings.py."""
|
||||||
|
)
|
||||||
self.msg(string)
|
self.msg(string)
|
||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
|
|
@ -1170,7 +1203,9 @@ class CmdRSS2Chan(COMMAND_DEFAULT_CLASS):
|
||||||
# show all connections
|
# show all connections
|
||||||
rssbots = [
|
rssbots = [
|
||||||
bot
|
bot
|
||||||
for bot in AccountDB.objects.filter(db_is_bot=True, username__startswith="rssbot-")
|
for bot in AccountDB.objects.filter(
|
||||||
|
db_is_bot=True, username__startswith="rssbot-"
|
||||||
|
)
|
||||||
]
|
]
|
||||||
if rssbots:
|
if rssbots:
|
||||||
table = self.styled_table(
|
table = self.styled_table(
|
||||||
|
|
@ -1183,19 +1218,28 @@ class CmdRSS2Chan(COMMAND_DEFAULT_CLASS):
|
||||||
)
|
)
|
||||||
for rssbot in rssbots:
|
for rssbot in rssbots:
|
||||||
table.add_row(
|
table.add_row(
|
||||||
rssbot.id, rssbot.db.rss_rate, rssbot.db.ev_channel, rssbot.db.rss_url
|
rssbot.id,
|
||||||
|
rssbot.db.rss_rate,
|
||||||
|
rssbot.db.ev_channel,
|
||||||
|
rssbot.db.rss_url,
|
||||||
)
|
)
|
||||||
self.msg(table)
|
self.msg(table)
|
||||||
else:
|
else:
|
||||||
self.msg("No rss bots found.")
|
self.msg("No rss bots found.")
|
||||||
return
|
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
|
botname = "rssbot-%s" % self.lhs
|
||||||
matches = AccountDB.objects.filter(db_is_bot=True, db_key=botname)
|
matches = AccountDB.objects.filter(db_is_bot=True, db_key=botname)
|
||||||
if not matches:
|
if not matches:
|
||||||
# try dbref match
|
# try dbref match
|
||||||
matches = AccountDB.objects.filter(db_is_bot=True, id=self.args.lstrip("#"))
|
matches = AccountDB.objects.filter(
|
||||||
|
db_is_bot=True, id=self.args.lstrip("#")
|
||||||
|
)
|
||||||
if matches:
|
if matches:
|
||||||
matches[0].delete()
|
matches[0].delete()
|
||||||
self.msg("RSS connection destroyed.")
|
self.msg("RSS connection destroyed.")
|
||||||
|
|
@ -1277,24 +1321,34 @@ class CmdGrapevine2Chan(COMMAND_DEFAULT_CLASS):
|
||||||
maxwidth=_DEFAULT_WIDTH,
|
maxwidth=_DEFAULT_WIDTH,
|
||||||
)
|
)
|
||||||
for gwbot in gwbots:
|
for gwbot in gwbots:
|
||||||
table.add_row(gwbot.id, gwbot.db.ev_channel, gwbot.db.grapevine_channel)
|
table.add_row(
|
||||||
|
gwbot.id, gwbot.db.ev_channel, gwbot.db.grapevine_channel
|
||||||
|
)
|
||||||
self.msg(table)
|
self.msg(table)
|
||||||
else:
|
else:
|
||||||
self.msg("No grapevine bots found.")
|
self.msg("No grapevine bots found.")
|
||||||
return
|
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
|
botname = "grapevinebot-%s" % self.lhs
|
||||||
matches = AccountDB.objects.filter(db_is_bot=True, db_key=botname)
|
matches = AccountDB.objects.filter(db_is_bot=True, db_key=botname)
|
||||||
|
|
||||||
if not matches:
|
if not matches:
|
||||||
# try dbref match
|
# try dbref match
|
||||||
matches = AccountDB.objects.filter(db_is_bot=True, id=self.args.lstrip("#"))
|
matches = AccountDB.objects.filter(
|
||||||
|
db_is_bot=True, id=self.args.lstrip("#")
|
||||||
|
)
|
||||||
if matches:
|
if matches:
|
||||||
matches[0].delete()
|
matches[0].delete()
|
||||||
self.msg("Grapevine connection destroyed.")
|
self.msg("Grapevine connection destroyed.")
|
||||||
else:
|
else:
|
||||||
self.msg("Grapevine connection/bot could not be removed, does it exist?")
|
self.msg(
|
||||||
|
"Grapevine connection/bot could not be removed, does it exist?"
|
||||||
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
if not self.args or not self.rhs:
|
if not self.args or not self.rhs:
|
||||||
|
|
@ -1317,7 +1371,9 @@ class CmdGrapevine2Chan(COMMAND_DEFAULT_CLASS):
|
||||||
self.msg("Reusing bot '%s' (%s)" % (botname, bot.dbref))
|
self.msg("Reusing bot '%s' (%s)" % (botname, bot.dbref))
|
||||||
else:
|
else:
|
||||||
# create a new bot
|
# create a new bot
|
||||||
bot = create.create_account(botname, None, None, typeclass=bots.GrapevineBot)
|
bot = create.create_account(
|
||||||
|
botname, None, None, typeclass=bots.GrapevineBot
|
||||||
|
)
|
||||||
|
|
||||||
bot.start(ev_channel=channel, grapevine_channel=grapevine_channel)
|
bot.start(ev_channel=channel, grapevine_channel=grapevine_channel)
|
||||||
self.msg(f"Grapevine connection created {channel} <-> {grapevine_channel}.")
|
self.msg(f"Grapevine connection created {channel} <-> {grapevine_channel}.")
|
||||||
|
|
|
||||||
|
|
@ -157,14 +157,24 @@ class CmdNick(COMMAND_DEFAULT_CLASS):
|
||||||
|
|
||||||
caller = self.caller
|
caller = self.caller
|
||||||
switches = self.switches
|
switches = self.switches
|
||||||
nicktypes = [switch for switch in switches if switch in ("object", "account", "inputline")]
|
nicktypes = [
|
||||||
|
switch
|
||||||
|
for switch in switches
|
||||||
|
if switch in ("object", "account", "inputline")
|
||||||
|
]
|
||||||
specified_nicktype = bool(nicktypes)
|
specified_nicktype = bool(nicktypes)
|
||||||
nicktypes = nicktypes if specified_nicktype else ["inputline"]
|
nicktypes = nicktypes if specified_nicktype else ["inputline"]
|
||||||
|
|
||||||
nicklist = (
|
nicklist = (
|
||||||
utils.make_iter(caller.nicks.get(category="inputline", return_obj=True) or [])
|
utils.make_iter(
|
||||||
+ utils.make_iter(caller.nicks.get(category="object", return_obj=True) or [])
|
caller.nicks.get(category="inputline", return_obj=True) or []
|
||||||
+ utils.make_iter(caller.nicks.get(category="account", 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",):
|
||||||
|
|
@ -176,7 +186,10 @@ class CmdNick(COMMAND_DEFAULT_CLASS):
|
||||||
for inum, nickobj in enumerate(nicklist):
|
for inum, nickobj in enumerate(nicklist):
|
||||||
_, _, nickvalue, replacement = nickobj.value
|
_, _, nickvalue, replacement = nickobj.value
|
||||||
table.add_row(
|
table.add_row(
|
||||||
str(inum + 1), nickobj.db_category, _cy(nickvalue), _cy(replacement)
|
str(inum + 1),
|
||||||
|
nickobj.db_category,
|
||||||
|
_cy(nickvalue),
|
||||||
|
_cy(replacement),
|
||||||
)
|
)
|
||||||
string = "|wDefined Nicks:|n\n%s" % table
|
string = "|wDefined Nicks:|n\n%s" % table
|
||||||
caller.msg(string)
|
caller.msg(string)
|
||||||
|
|
@ -207,7 +220,9 @@ class CmdNick(COMMAND_DEFAULT_CLASS):
|
||||||
if not specified_nicktype:
|
if not specified_nicktype:
|
||||||
nicktypes = ("object", "account", "inputline")
|
nicktypes = ("object", "account", "inputline")
|
||||||
for nicktype in nicktypes:
|
for nicktype in nicktypes:
|
||||||
oldnicks.append(caller.nicks.get(arg, category=nicktype, return_obj=True))
|
oldnicks.append(
|
||||||
|
caller.nicks.get(arg, category=nicktype, return_obj=True)
|
||||||
|
)
|
||||||
|
|
||||||
oldnicks = [oldnick for oldnick in oldnicks if oldnick]
|
oldnicks = [oldnick for oldnick in oldnicks if oldnick]
|
||||||
if oldnicks:
|
if oldnicks:
|
||||||
|
|
@ -241,7 +256,9 @@ class CmdNick(COMMAND_DEFAULT_CLASS):
|
||||||
_, _, nick, repl = nick.value
|
_, _, nick, repl = nick.value
|
||||||
if nick.startswith(self.lhs):
|
if nick.startswith(self.lhs):
|
||||||
strings.append(
|
strings.append(
|
||||||
"{}-nick: '{}' -> '{}'".format(nicktype.capitalize(), nick, repl)
|
"{}-nick: '{}' -> '{}'".format(
|
||||||
|
nicktype.capitalize(), nick, repl
|
||||||
|
)
|
||||||
)
|
)
|
||||||
if strings:
|
if strings:
|
||||||
caller.msg("\n".join(strings))
|
caller.msg("\n".join(strings))
|
||||||
|
|
@ -259,12 +276,16 @@ class CmdNick(COMMAND_DEFAULT_CLASS):
|
||||||
obj = account
|
obj = account
|
||||||
else:
|
else:
|
||||||
obj = caller
|
obj = caller
|
||||||
nicks = utils.make_iter(obj.nicks.get(category=nicktype, return_obj=True))
|
nicks = utils.make_iter(
|
||||||
|
obj.nicks.get(category=nicktype, return_obj=True)
|
||||||
|
)
|
||||||
for nick in nicks:
|
for nick in nicks:
|
||||||
_, _, nick, repl = nick.value
|
_, _, nick, repl = nick.value
|
||||||
if nick.startswith(self.lhs):
|
if nick.startswith(self.lhs):
|
||||||
strings.append(
|
strings.append(
|
||||||
"{}-nick: '{}' -> '{}'".format(nicktype.capitalize(), nick, repl)
|
"{}-nick: '{}' -> '{}'".format(
|
||||||
|
nicktype.capitalize(), nick, repl
|
||||||
|
)
|
||||||
)
|
)
|
||||||
if strings:
|
if strings:
|
||||||
caller.msg("\n".join(strings))
|
caller.msg("\n".join(strings))
|
||||||
|
|
@ -282,12 +303,16 @@ class CmdNick(COMMAND_DEFAULT_CLASS):
|
||||||
obj = account
|
obj = account
|
||||||
else:
|
else:
|
||||||
obj = caller
|
obj = caller
|
||||||
nicks = utils.make_iter(obj.nicks.get(category=nicktype, return_obj=True))
|
nicks = utils.make_iter(
|
||||||
|
obj.nicks.get(category=nicktype, return_obj=True)
|
||||||
|
)
|
||||||
for nick in nicks:
|
for nick in nicks:
|
||||||
_, _, nick, repl = nick.value
|
_, _, nick, repl = nick.value
|
||||||
if nick.startswith(self.lhs):
|
if nick.startswith(self.lhs):
|
||||||
strings.append(
|
strings.append(
|
||||||
"{}-nick: '{}' -> '{}'".format(nicktype.capitalize(), nick, repl)
|
"{}-nick: '{}' -> '{}'".format(
|
||||||
|
nicktype.capitalize(), nick, repl
|
||||||
|
)
|
||||||
)
|
)
|
||||||
if strings:
|
if strings:
|
||||||
caller.msg("\n".join(strings))
|
caller.msg("\n".join(strings))
|
||||||
|
|
@ -316,7 +341,9 @@ class CmdNick(COMMAND_DEFAULT_CLASS):
|
||||||
old_nickstring = None
|
old_nickstring = None
|
||||||
old_replstring = None
|
old_replstring = None
|
||||||
|
|
||||||
oldnick = caller.nicks.get(key=nickstring, category=nicktype, return_obj=True)
|
oldnick = caller.nicks.get(
|
||||||
|
key=nickstring, category=nicktype, return_obj=True
|
||||||
|
)
|
||||||
if oldnick:
|
if oldnick:
|
||||||
_, _, old_nickstring, old_replstring = oldnick.value
|
_, _, old_nickstring, old_replstring = oldnick.value
|
||||||
if replstring:
|
if replstring:
|
||||||
|
|
@ -428,7 +455,9 @@ class CmdGet(COMMAND_DEFAULT_CLASS):
|
||||||
|
|
||||||
obj.move_to(caller, quiet=True)
|
obj.move_to(caller, quiet=True)
|
||||||
caller.msg("You pick up %s." % obj.name)
|
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
|
# calling at_get hook method
|
||||||
obj.at_get(caller)
|
obj.at_get(caller)
|
||||||
|
|
||||||
|
|
@ -473,7 +502,9 @@ class CmdDrop(COMMAND_DEFAULT_CLASS):
|
||||||
|
|
||||||
obj.move_to(caller.location, quiet=True)
|
obj.move_to(caller.location, quiet=True)
|
||||||
caller.msg("You drop %s." % (obj.name,))
|
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.
|
# Call the object script's at_drop() method.
|
||||||
obj.at_drop(caller)
|
obj.at_drop(caller)
|
||||||
|
|
||||||
|
|
@ -675,7 +706,9 @@ class CmdPose(COMMAND_DEFAULT_CLASS):
|
||||||
self.caller.msg(msg)
|
self.caller.msg(msg)
|
||||||
else:
|
else:
|
||||||
msg = "%s%s" % (self.caller.name, self.args)
|
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):
|
class CmdAccess(COMMAND_DEFAULT_CLASS):
|
||||||
|
|
@ -699,7 +732,9 @@ class CmdAccess(COMMAND_DEFAULT_CLASS):
|
||||||
|
|
||||||
caller = self.caller
|
caller = self.caller
|
||||||
hierarchy_full = settings.PERMISSION_HIERARCHY
|
hierarchy_full = settings.PERMISSION_HIERARCHY
|
||||||
string = "\n|wPermission Hierarchy|n (climbing):\n %s" % ", ".join(hierarchy_full)
|
string = "\n|wPermission Hierarchy|n (climbing):\n %s" % ", ".join(
|
||||||
|
hierarchy_full
|
||||||
|
)
|
||||||
|
|
||||||
if self.caller.account.is_superuser:
|
if self.caller.account.is_superuser:
|
||||||
cperms = "<Superuser>"
|
cperms = "<Superuser>"
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,10 @@ class CmdHelp(Command):
|
||||||
if type(self).help_more:
|
if type(self).help_more:
|
||||||
usemore = True
|
usemore = True
|
||||||
|
|
||||||
if self.session and self.session.protocol_key in ("websocket", "ajax/comet"):
|
if self.session and self.session.protocol_key in (
|
||||||
|
"websocket",
|
||||||
|
"ajax/comet",
|
||||||
|
):
|
||||||
try:
|
try:
|
||||||
options = self.account.db._saved_webclient_options
|
options = self.account.db._saved_webclient_options
|
||||||
if options and options["helppopup"]:
|
if options and options["helppopup"]:
|
||||||
|
|
@ -101,7 +104,9 @@ class CmdHelp(Command):
|
||||||
if title:
|
if title:
|
||||||
string += "|CHelp for |w%s|n" % title
|
string += "|CHelp for |w%s|n" % title
|
||||||
if aliases:
|
if aliases:
|
||||||
string += " |C(aliases: %s|C)|n" % ("|C,|n ".join("|w%s|n" % ali for ali in aliases))
|
string += " |C(aliases: %s|C)|n" % (
|
||||||
|
"|C,|n ".join("|w%s|n" % ali for ali in aliases)
|
||||||
|
)
|
||||||
if help_text:
|
if help_text:
|
||||||
string += "\n%s" % dedent(help_text.rstrip())
|
string += "\n%s" % dedent(help_text.rstrip())
|
||||||
if suggested:
|
if suggested:
|
||||||
|
|
@ -124,14 +129,18 @@ class CmdHelp(Command):
|
||||||
string += "\n" + _SEP + "\n |CCommand help entries|n\n" + _SEP
|
string += "\n" + _SEP + "\n |CCommand help entries|n\n" + _SEP
|
||||||
for category in sorted(hdict_cmds.keys()):
|
for category in sorted(hdict_cmds.keys()):
|
||||||
string += "\n |w%s|n:\n" % (str(category).title())
|
string += "\n |w%s|n:\n" % (str(category).title())
|
||||||
string += "|G" + fill("|C, |G".join(sorted(hdict_cmds[category]))) + "|n"
|
string += (
|
||||||
|
"|G" + fill("|C, |G".join(sorted(hdict_cmds[category]))) + "|n"
|
||||||
|
)
|
||||||
if hdict_db and any(hdict_db.values()):
|
if hdict_db and any(hdict_db.values()):
|
||||||
string += "\n\n" + _SEP + "\n\r |COther help entries|n\n" + _SEP
|
string += "\n\n" + _SEP + "\n\r |COther help entries|n\n" + _SEP
|
||||||
for category in sorted(hdict_db.keys()):
|
for category in sorted(hdict_db.keys()):
|
||||||
string += "\n\r |w%s|n:\n" % (str(category).title())
|
string += "\n\r |w%s|n:\n" % (str(category).title())
|
||||||
string += (
|
string += (
|
||||||
"|G"
|
"|G"
|
||||||
+ fill(", ".join(sorted([str(topic) for topic in hdict_db[category]])))
|
+ fill(
|
||||||
|
", ".join(sorted([str(topic) for topic in hdict_db[category]]))
|
||||||
|
)
|
||||||
+ "|n"
|
+ "|n"
|
||||||
)
|
)
|
||||||
return string
|
return string
|
||||||
|
|
@ -204,7 +213,9 @@ class CmdHelp(Command):
|
||||||
# retrieve all available commands and database topics
|
# retrieve all available commands and database topics
|
||||||
all_cmds = [cmd for cmd in cmdset if self.check_show_help(cmd, caller)]
|
all_cmds = [cmd for cmd in cmdset if self.check_show_help(cmd, caller)]
|
||||||
all_topics = [
|
all_topics = [
|
||||||
topic for topic in HelpEntry.objects.all() if topic.access(caller, "view", default=True)
|
topic
|
||||||
|
for topic in HelpEntry.objects.all()
|
||||||
|
if topic.access(caller, "view", default=True)
|
||||||
]
|
]
|
||||||
all_categories = list(
|
all_categories = list(
|
||||||
set(
|
set(
|
||||||
|
|
@ -242,13 +253,18 @@ class CmdHelp(Command):
|
||||||
suggestions = [
|
suggestions = [
|
||||||
sugg
|
sugg
|
||||||
for sugg in string_suggestions(
|
for sugg in string_suggestions(
|
||||||
query, set(vocabulary), cutoff=suggestion_cutoff, maxnum=suggestion_maxnum
|
query,
|
||||||
|
set(vocabulary),
|
||||||
|
cutoff=suggestion_cutoff,
|
||||||
|
maxnum=suggestion_maxnum,
|
||||||
)
|
)
|
||||||
if sugg != query
|
if sugg != query
|
||||||
]
|
]
|
||||||
if not suggestions:
|
if not suggestions:
|
||||||
suggestions = [
|
suggestions = [
|
||||||
sugg for sugg in vocabulary if sugg != query and sugg.startswith(query)
|
sugg
|
||||||
|
for sugg in vocabulary
|
||||||
|
if sugg != query and sugg.startswith(query)
|
||||||
]
|
]
|
||||||
|
|
||||||
# try an exact command auto-help match
|
# try an exact command auto-help match
|
||||||
|
|
@ -291,8 +307,18 @@ class CmdHelp(Command):
|
||||||
if query in all_categories:
|
if query in all_categories:
|
||||||
self.msg_help(
|
self.msg_help(
|
||||||
self.format_help_list(
|
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]},
|
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
|
return
|
||||||
|
|
@ -376,14 +402,19 @@ class CmdSetHelp(COMMAND_DEFAULT_CLASS):
|
||||||
self.msg("You have to define a topic!")
|
self.msg("You have to define a topic!")
|
||||||
return
|
return
|
||||||
topicstrlist = topicstr.split(";")
|
topicstrlist = topicstr.split(";")
|
||||||
topicstr, aliases = topicstrlist[0], topicstrlist[1:] if len(topicstr) > 1 else []
|
topicstr, aliases = (
|
||||||
|
topicstrlist[0],
|
||||||
|
topicstrlist[1:] if len(topicstr) > 1 else [],
|
||||||
|
)
|
||||||
aliastxt = ("(aliases: %s)" % ", ".join(aliases)) if aliases else ""
|
aliastxt = ("(aliases: %s)" % ", ".join(aliases)) if aliases else ""
|
||||||
old_entry = None
|
old_entry = None
|
||||||
|
|
||||||
# check if we have an old entry with the same name
|
# check if we have an old entry with the same name
|
||||||
try:
|
try:
|
||||||
for querystr in topicstrlist:
|
for querystr in topicstrlist:
|
||||||
old_entry = HelpEntry.objects.find_topicmatch(querystr) # also search by alias
|
old_entry = HelpEntry.objects.find_topicmatch(
|
||||||
|
querystr
|
||||||
|
) # also search by alias
|
||||||
if old_entry:
|
if old_entry:
|
||||||
old_entry = list(old_entry)[0]
|
old_entry = list(old_entry)[0]
|
||||||
break
|
break
|
||||||
|
|
@ -405,7 +436,11 @@ class CmdSetHelp(COMMAND_DEFAULT_CLASS):
|
||||||
helpentry = old_entry
|
helpentry = old_entry
|
||||||
else:
|
else:
|
||||||
helpentry = create.create_help_entry(
|
helpentry = create.create_help_entry(
|
||||||
topicstr, self.rhs, category=category, locks=lockstring, aliases=aliases
|
topicstr,
|
||||||
|
self.rhs,
|
||||||
|
category=category,
|
||||||
|
locks=lockstring,
|
||||||
|
aliases=aliases,
|
||||||
)
|
)
|
||||||
self.caller.db._editing_help = helpentry
|
self.caller.db._editing_help = helpentry
|
||||||
|
|
||||||
|
|
@ -422,7 +457,9 @@ class CmdSetHelp(COMMAND_DEFAULT_CLASS):
|
||||||
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
|
# merge/append operations
|
||||||
if not old_entry:
|
if not old_entry:
|
||||||
self.msg("Could not find topic '%s'. You must give an exact name." % topicstr)
|
self.msg(
|
||||||
|
"Could not find topic '%s'. You must give an exact name." % topicstr
|
||||||
|
)
|
||||||
return
|
return
|
||||||
if not self.rhs:
|
if not self.rhs:
|
||||||
self.msg("You must supply text to append/merge.")
|
self.msg("You must supply text to append/merge.")
|
||||||
|
|
@ -469,7 +506,9 @@ class CmdSetHelp(COMMAND_DEFAULT_CLASS):
|
||||||
topicstr, self.rhs, category=category, locks=lockstring, aliases=aliases
|
topicstr, self.rhs, category=category, locks=lockstring, aliases=aliases
|
||||||
)
|
)
|
||||||
if new_entry:
|
if new_entry:
|
||||||
self.msg("Topic '%s'%s was successfully created." % (topicstr, aliastxt))
|
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
|
# open the line editor to edit the helptext
|
||||||
self.caller.db._editing_help = new_entry
|
self.caller.db._editing_help = new_entry
|
||||||
|
|
@ -484,5 +523,6 @@ class CmdSetHelp(COMMAND_DEFAULT_CLASS):
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
self.msg(
|
self.msg(
|
||||||
"Error when creating topic '%s'%s! Contact an admin." % (topicstr, aliastxt)
|
"Error when creating topic '%s'%s! Contact an admin."
|
||||||
|
% (topicstr, aliastxt)
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -129,10 +129,14 @@ class MuxCommand(Command):
|
||||||
if switches and self.switch_options:
|
if switches and self.switch_options:
|
||||||
valid_switches, unused_switches, extra_switches = [], [], []
|
valid_switches, unused_switches, extra_switches = [], [], []
|
||||||
for element in switches:
|
for element in switches:
|
||||||
option_check = [opt for opt in self.switch_options if opt == element]
|
option_check = [
|
||||||
|
opt for opt in self.switch_options if opt == element
|
||||||
|
]
|
||||||
if not option_check:
|
if not option_check:
|
||||||
option_check = [
|
option_check = [
|
||||||
opt for opt in self.switch_options if opt.startswith(element)
|
opt
|
||||||
|
for opt in self.switch_options
|
||||||
|
if opt.startswith(element)
|
||||||
]
|
]
|
||||||
match_count = len(option_check)
|
match_count = len(option_check)
|
||||||
if match_count > 1:
|
if match_count > 1:
|
||||||
|
|
@ -140,9 +144,13 @@ class MuxCommand(Command):
|
||||||
option_check
|
option_check
|
||||||
) # Either the option provided is ambiguous,
|
) # Either the option provided is ambiguous,
|
||||||
elif match_count == 1:
|
elif match_count == 1:
|
||||||
valid_switches.extend(option_check) # or it is a valid option abbreviation,
|
valid_switches.extend(
|
||||||
|
option_check
|
||||||
|
) # or it is a valid option abbreviation,
|
||||||
elif match_count == 0:
|
elif match_count == 0:
|
||||||
unused_switches.append(element) # or an extraneous option to be ignored.
|
unused_switches.append(
|
||||||
|
element
|
||||||
|
) # or an extraneous option to be ignored.
|
||||||
if extra_switches: # User provided switches
|
if extra_switches: # User provided switches
|
||||||
self.msg(
|
self.msg(
|
||||||
"|g%s|n: |wAmbiguous switch supplied: Did you mean /|C%s|w?"
|
"|g%s|n: |wAmbiguous switch supplied: Did you mean /|C%s|w?"
|
||||||
|
|
@ -154,13 +162,17 @@ class MuxCommand(Command):
|
||||||
'|g%s|n: |wExtra switch%s "/|C%s|w" ignored.'
|
'|g%s|n: |wExtra switch%s "/|C%s|w" ignored.'
|
||||||
% (self.cmdstring, plural, "|n, /|C".join(unused_switches))
|
% (self.cmdstring, plural, "|n, /|C".join(unused_switches))
|
||||||
)
|
)
|
||||||
switches = valid_switches # Only include valid_switches in command function call
|
switches = (
|
||||||
|
valid_switches
|
||||||
|
) # Only include valid_switches in command function call
|
||||||
arglist = [arg.strip() for arg in args.split()]
|
arglist = [arg.strip() for arg in args.split()]
|
||||||
|
|
||||||
# check for arg1, arg2, ... = argA, argB, ... constructs
|
# check for arg1, arg2, ... = argA, argB, ... constructs
|
||||||
lhs, rhs = args.strip(), None
|
lhs, rhs = args.strip(), None
|
||||||
if lhs:
|
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)
|
best_split = delimiters[0] # (default to first delimiter)
|
||||||
for this_split in delimiters: # try each delimiter
|
for this_split in delimiters: # try each delimiter
|
||||||
if this_split in lhs: # to find first successful split
|
if this_split in lhs: # to find first successful split
|
||||||
|
|
@ -192,11 +204,15 @@ class MuxCommand(Command):
|
||||||
# a special property "character" for the puppeted object, if any. This
|
# a special property "character" for the puppeted object, if any. This
|
||||||
# is convenient for commands defined on the Account only.
|
# is convenient for commands defined on the Account only.
|
||||||
if self.account_caller:
|
if self.account_caller:
|
||||||
if utils.inherits_from(self.caller, "evennia.objects.objects.DefaultObject"):
|
if utils.inherits_from(
|
||||||
|
self.caller, "evennia.objects.objects.DefaultObject"
|
||||||
|
):
|
||||||
# caller is an Object/Character
|
# caller is an Object/Character
|
||||||
self.character = self.caller
|
self.character = self.caller
|
||||||
self.caller = self.caller.account
|
self.caller = self.caller.account
|
||||||
elif utils.inherits_from(self.caller, "evennia.accounts.accounts.DefaultAccount"):
|
elif utils.inherits_from(
|
||||||
|
self.caller, "evennia.accounts.accounts.DefaultAccount"
|
||||||
|
):
|
||||||
# caller was already an Account
|
# caller was already an Account
|
||||||
self.character = self.caller.get_puppet(self.session)
|
self.character = self.caller.get_puppet(self.session)
|
||||||
else:
|
else:
|
||||||
|
|
@ -209,7 +225,8 @@ class MuxCommand(Command):
|
||||||
to all the variables defined therein.
|
to all the variables defined therein.
|
||||||
"""
|
"""
|
||||||
variables = "\n".join(
|
variables = "\n".join(
|
||||||
" |w{}|n ({}): {}".format(key, type(val), val) for key, val in self.__dict__.items()
|
" |w{}|n ({}): {}".format(key, type(val), val)
|
||||||
|
for key, val in self.__dict__.items()
|
||||||
)
|
)
|
||||||
string = f"""
|
string = f"""
|
||||||
Command {self} has no defined `func()` - showing on-command variables: No child func() defined for {self} - available variables:
|
Command {self} has no defined `func()` - showing on-command variables: No child func() defined for {self} - available variables:
|
||||||
|
|
@ -236,7 +253,9 @@ Command {self} has no defined `func()` - showing on-command variables: No child
|
||||||
string += "cmd args (self.args): |w%s|n\n" % self.args
|
string += "cmd args (self.args): |w%s|n\n" % self.args
|
||||||
string += "cmd switches (self.switches): |w%s|n\n" % self.switches
|
string += "cmd switches (self.switches): |w%s|n\n" % self.switches
|
||||||
string += "cmd options (self.switch_options): |w%s|n\n" % self.switch_options
|
string += "cmd options (self.switch_options): |w%s|n\n" % self.switch_options
|
||||||
string += "cmd parse left/right using (self.rhs_split): |w%s|n\n" % self.rhs_split
|
string += (
|
||||||
|
"cmd parse left/right using (self.rhs_split): |w%s|n\n" % self.rhs_split
|
||||||
|
)
|
||||||
string += "space-separated arg list (self.arglist): |w%s|n\n" % self.arglist
|
string += "space-separated arg list (self.arglist): |w%s|n\n" % self.arglist
|
||||||
string += "lhs, left-hand side of '=' (self.lhs): |w%s|n\n" % self.lhs
|
string += "lhs, left-hand side of '=' (self.lhs): |w%s|n\n" % self.lhs
|
||||||
string += "lhs, comma separated (self.lhslist): |w%s|n\n" % self.lhslist
|
string += "lhs, comma separated (self.lhslist): |w%s|n\n" % self.lhslist
|
||||||
|
|
@ -261,4 +280,6 @@ class MuxAccountCommand(MuxCommand):
|
||||||
character is actually attached to this Account and Session.
|
character is actually attached to this Account and Session.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
account_caller = True # Using MuxAccountCommand explicitly defaults the caller to an account
|
account_caller = (
|
||||||
|
True
|
||||||
|
) # Using MuxAccountCommand explicitly defaults the caller to an account
|
||||||
|
|
|
||||||
|
|
@ -103,7 +103,9 @@ class SystemMultimatch(COMMAND_DEFAULT_CLASS):
|
||||||
# evennia.commands.cmdparse.create_match for more details.
|
# evennia.commands.cmdparse.create_match for more details.
|
||||||
matches = self.matches
|
matches = self.matches
|
||||||
# at_search_result will itself msg the multimatch options to the caller.
|
# 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
|
# Command called when the command given at the command line
|
||||||
|
|
|
||||||
|
|
@ -150,7 +150,12 @@ def _py_code(caller, buf):
|
||||||
string = "Executing code%s ..." % (" (measure timing)" if measure_time else "")
|
string = "Executing code%s ..." % (" (measure timing)" if measure_time else "")
|
||||||
caller.msg(string)
|
caller.msg(string)
|
||||||
_run_code_snippet(
|
_run_code_snippet(
|
||||||
caller, buf, mode="exec", measure_time=measure_time, client_raw=client_raw, show_input=False
|
caller,
|
||||||
|
buf,
|
||||||
|
mode="exec",
|
||||||
|
measure_time=measure_time,
|
||||||
|
client_raw=client_raw,
|
||||||
|
show_input=False,
|
||||||
)
|
)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
@ -235,7 +240,9 @@ def _run_code_snippet(
|
||||||
|
|
||||||
for session in sessions:
|
for session in sessions:
|
||||||
try:
|
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:
|
except TypeError:
|
||||||
caller.msg(ret, options={"raw": True, "client_raw": client_raw})
|
caller.msg(ret, options={"raw": True, "client_raw": client_raw})
|
||||||
|
|
||||||
|
|
@ -477,7 +484,9 @@ class CmdScripts(COMMAND_DEFAULT_CLASS):
|
||||||
if new_script:
|
if new_script:
|
||||||
caller.msg("Global script %s was started successfully." % args)
|
caller.msg("Global script %s was started successfully." % args)
|
||||||
else:
|
else:
|
||||||
caller.msg("Global script %s could not start correctly. See logs." % args)
|
caller.msg(
|
||||||
|
"Global script %s could not start correctly. See logs." % args
|
||||||
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
# test first if this is a script match
|
# test first if this is a script match
|
||||||
|
|
@ -498,7 +507,10 @@ class CmdScripts(COMMAND_DEFAULT_CLASS):
|
||||||
return
|
return
|
||||||
|
|
||||||
if not scripts:
|
if not scripts:
|
||||||
string = "No scripts found with a key '%s', or on an object named '%s'." % (args, args)
|
string = "No scripts found with a key '%s', or on an object named '%s'." % (
|
||||||
|
args,
|
||||||
|
args,
|
||||||
|
)
|
||||||
caller.msg(string)
|
caller.msg(string)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
@ -585,7 +597,9 @@ class CmdObjects(COMMAND_DEFAULT_CLASS):
|
||||||
nexits,
|
nexits,
|
||||||
"%.2f" % ((float(nexits) / nobjs) * 100),
|
"%.2f" % ((float(nexits) / nobjs) * 100),
|
||||||
)
|
)
|
||||||
totaltable.add_row("Other", "", nother, "%.2f" % ((float(nother) / nobjs) * 100))
|
totaltable.add_row(
|
||||||
|
"Other", "", nother, "%.2f" % ((float(nother) / nobjs) * 100)
|
||||||
|
)
|
||||||
|
|
||||||
# typeclass table
|
# typeclass table
|
||||||
typetable = self.styled_table(
|
typetable = self.styled_table(
|
||||||
|
|
@ -597,9 +611,16 @@ class CmdObjects(COMMAND_DEFAULT_CLASS):
|
||||||
typetable.add_row(path, count, "%.2f" % ((float(count) / nobjs) * 100))
|
typetable.add_row(path, count, "%.2f" % ((float(count) / nobjs) * 100))
|
||||||
|
|
||||||
# last N table
|
# last N table
|
||||||
objs = ObjectDB.objects.all().order_by("db_date_created")[max(0, nobjs - nlim) :]
|
objs = ObjectDB.objects.all().order_by("db_date_created")[
|
||||||
|
max(0, nobjs - nlim) :
|
||||||
|
]
|
||||||
latesttable = self.styled_table(
|
latesttable = self.styled_table(
|
||||||
"|wcreated|n", "|wdbref|n", "|wname|n", "|wtypeclass|n", align="l", border="table"
|
"|wcreated|n",
|
||||||
|
"|wdbref|n",
|
||||||
|
"|wname|n",
|
||||||
|
"|wtypeclass|n",
|
||||||
|
align="l",
|
||||||
|
border="table",
|
||||||
)
|
)
|
||||||
latesttable.align = "l"
|
latesttable.align = "l"
|
||||||
for obj in objs:
|
for obj in objs:
|
||||||
|
|
@ -607,7 +628,10 @@ class CmdObjects(COMMAND_DEFAULT_CLASS):
|
||||||
utils.datetime_format(obj.date_created), obj.dbref, obj.key, obj.path
|
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 subtype totals (out of %i Objects):|n\n%s" % (
|
||||||
|
nobjs,
|
||||||
|
totaltable,
|
||||||
|
)
|
||||||
string += "\n|wObject typeclass distribution:|n\n%s" % typetable
|
string += "\n|wObject typeclass distribution:|n\n%s" % typetable
|
||||||
string += "\n|wLast %s Objects created:|n\n%s" % (min(nobjs, nlim), latesttable)
|
string += "\n|wLast %s Objects created:|n\n%s" % (min(nobjs, nlim), latesttable)
|
||||||
caller.msg(string)
|
caller.msg(string)
|
||||||
|
|
@ -660,7 +684,9 @@ class CmdAccounts(COMMAND_DEFAULT_CLASS):
|
||||||
return
|
return
|
||||||
if len(accounts) > 1:
|
if len(accounts) > 1:
|
||||||
string = "There were multiple matches:\n"
|
string = "There were multiple matches:\n"
|
||||||
string += "\n".join(" %s %s" % (account.id, account.key) for account in accounts)
|
string += "\n".join(
|
||||||
|
" %s %s" % (account.id, account.key) for account in accounts
|
||||||
|
)
|
||||||
self.msg(string)
|
self.msg(string)
|
||||||
return
|
return
|
||||||
account = accounts.first()
|
account = accounts.first()
|
||||||
|
|
@ -709,9 +735,16 @@ class CmdAccounts(COMMAND_DEFAULT_CLASS):
|
||||||
for path, count in dbtotals.items():
|
for path, count in dbtotals.items():
|
||||||
typetable.add_row(path, count, "%.2f" % ((float(count) / naccounts) * 100))
|
typetable.add_row(path, count, "%.2f" % ((float(count) / naccounts) * 100))
|
||||||
# last N table
|
# last N table
|
||||||
plyrs = AccountDB.objects.all().order_by("db_date_created")[max(0, naccounts - nlim) :]
|
plyrs = AccountDB.objects.all().order_by("db_date_created")[
|
||||||
|
max(0, naccounts - nlim) :
|
||||||
|
]
|
||||||
latesttable = self.styled_table(
|
latesttable = self.styled_table(
|
||||||
"|wcreated|n", "|wdbref|n", "|wname|n", "|wtypeclass|n", border="cells", align="l"
|
"|wcreated|n",
|
||||||
|
"|wdbref|n",
|
||||||
|
"|wname|n",
|
||||||
|
"|wtypeclass|n",
|
||||||
|
border="cells",
|
||||||
|
align="l",
|
||||||
)
|
)
|
||||||
for ply in plyrs:
|
for ply in plyrs:
|
||||||
latesttable.add_row(
|
latesttable.add_row(
|
||||||
|
|
@ -719,7 +752,10 @@ class CmdAccounts(COMMAND_DEFAULT_CLASS):
|
||||||
)
|
)
|
||||||
|
|
||||||
string = "\n|wAccount typeclass distribution:|n\n%s" % typetable
|
string = "\n|wAccount typeclass distribution:|n\n%s" % typetable
|
||||||
string += "\n|wLast %s Accounts created:|n\n%s" % (min(naccounts, nlim), latesttable)
|
string += "\n|wLast %s Accounts created:|n\n%s" % (
|
||||||
|
min(naccounts, nlim),
|
||||||
|
latesttable,
|
||||||
|
)
|
||||||
caller.msg(string)
|
caller.msg(string)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -769,7 +805,9 @@ class CmdService(COMMAND_DEFAULT_CLASS):
|
||||||
"|wService|n (use services/start|stop|delete)", "|wstatus", align="l"
|
"|wService|n (use services/start|stop|delete)", "|wstatus", align="l"
|
||||||
)
|
)
|
||||||
for service in service_collection.services:
|
for service in service_collection.services:
|
||||||
table.add_row(service.name, service.running and "|gRunning" or "|rNot Running")
|
table.add_row(
|
||||||
|
service.name, service.running and "|gRunning" or "|rNot Running"
|
||||||
|
)
|
||||||
caller.msg(str(table))
|
caller.msg(str(table))
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
@ -779,7 +817,9 @@ class CmdService(COMMAND_DEFAULT_CLASS):
|
||||||
service = service_collection.getServiceNamed(self.args)
|
service = service_collection.getServiceNamed(self.args)
|
||||||
except Exception:
|
except Exception:
|
||||||
string = "Invalid service name. This command is case-sensitive. "
|
string = "Invalid service name. This command is case-sensitive. "
|
||||||
string += "See service/list for valid service name (enter the full name exactly)."
|
string += (
|
||||||
|
"See service/list for valid service name (enter the full name exactly)."
|
||||||
|
)
|
||||||
caller.msg(string)
|
caller.msg(string)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
@ -793,7 +833,9 @@ class CmdService(COMMAND_DEFAULT_CLASS):
|
||||||
return
|
return
|
||||||
if service.name[:7] == "Evennia":
|
if service.name[:7] == "Evennia":
|
||||||
if delmode:
|
if delmode:
|
||||||
caller.msg("You cannot remove a core Evennia service (named 'Evennia***').")
|
caller.msg(
|
||||||
|
"You cannot remove a core Evennia service (named 'Evennia***')."
|
||||||
|
)
|
||||||
return
|
return
|
||||||
string = "You seem to be shutting down a core Evennia service (named 'Evennia***'). Note that"
|
string = "You seem to be shutting down a core Evennia service (named 'Evennia***'). Note that"
|
||||||
string += "stopping some TCP port services will *not* disconnect users *already*"
|
string += "stopping some TCP port services will *not* disconnect users *already*"
|
||||||
|
|
@ -885,7 +927,9 @@ class CmdTime(COMMAND_DEFAULT_CLASS):
|
||||||
table1.add_row("Current uptime", utils.time_format(gametime.uptime(), 3))
|
table1.add_row("Current uptime", utils.time_format(gametime.uptime(), 3))
|
||||||
table1.add_row("Portal uptime", utils.time_format(gametime.portal_uptime(), 3))
|
table1.add_row("Portal uptime", utils.time_format(gametime.portal_uptime(), 3))
|
||||||
table1.add_row("Total runtime", utils.time_format(gametime.runtime(), 2))
|
table1.add_row("Total runtime", utils.time_format(gametime.runtime(), 2))
|
||||||
table1.add_row("First start", datetime.datetime.fromtimestamp(gametime.server_epoch()))
|
table1.add_row(
|
||||||
|
"First start", datetime.datetime.fromtimestamp(gametime.server_epoch())
|
||||||
|
)
|
||||||
table1.add_row("Current time", datetime.datetime.now())
|
table1.add_row("Current time", datetime.datetime.now())
|
||||||
table1.reformat_column(0, width=30)
|
table1.reformat_column(0, width=30)
|
||||||
table2 = self.styled_table(
|
table2 = self.styled_table(
|
||||||
|
|
@ -895,11 +939,14 @@ class CmdTime(COMMAND_DEFAULT_CLASS):
|
||||||
width=77,
|
width=77,
|
||||||
border_top=0,
|
border_top=0,
|
||||||
)
|
)
|
||||||
epochtxt = "Epoch (%s)" % ("from settings" if settings.TIME_GAME_EPOCH else "server start")
|
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(epochtxt, datetime.datetime.fromtimestamp(gametime.game_epoch()))
|
||||||
table2.add_row("Total time passed:", utils.time_format(gametime.gametime(), 2))
|
table2.add_row("Total time passed:", utils.time_format(gametime.gametime(), 2))
|
||||||
table2.add_row(
|
table2.add_row(
|
||||||
"Current time ", datetime.datetime.fromtimestamp(gametime.gametime(absolute=True))
|
"Current time ",
|
||||||
|
datetime.datetime.fromtimestamp(gametime.gametime(absolute=True)),
|
||||||
)
|
)
|
||||||
table2.reformat_column(0, width=30)
|
table2.reformat_column(0, width=30)
|
||||||
self.caller.msg(str(table1) + "\n" + str(table2))
|
self.caller.msg(str(table1) + "\n" + str(table2))
|
||||||
|
|
@ -996,7 +1043,9 @@ class CmdServerLoad(COMMAND_DEFAULT_CLASS):
|
||||||
# Display table
|
# Display table
|
||||||
loadtable = self.styled_table("property", "statistic", align="l")
|
loadtable = self.styled_table("property", "statistic", align="l")
|
||||||
loadtable.add_row("Total CPU load", "%g %%" % loadavg)
|
loadtable.add_row("Total CPU load", "%g %%" % loadavg)
|
||||||
loadtable.add_row("Total computer memory usage", "%g MB (%g%%)" % (rmem, pmem))
|
loadtable.add_row(
|
||||||
|
"Total computer memory usage", "%g MB (%g%%)" % (rmem, pmem)
|
||||||
|
)
|
||||||
loadtable.add_row("Process ID", "%g" % pid),
|
loadtable.add_row("Process ID", "%g" % pid),
|
||||||
else:
|
else:
|
||||||
loadtable = (
|
loadtable = (
|
||||||
|
|
@ -1013,10 +1062,12 @@ class CmdServerLoad(COMMAND_DEFAULT_CLASS):
|
||||||
|
|
||||||
loadavg = os.getloadavg()[0]
|
loadavg = os.getloadavg()[0]
|
||||||
rmem = (
|
rmem = (
|
||||||
float(os.popen("ps -p %d -o %s | tail -1" % (pid, "rss")).read()) / 1000.0
|
float(os.popen("ps -p %d -o %s | tail -1" % (pid, "rss")).read())
|
||||||
|
/ 1000.0
|
||||||
) # resident memory
|
) # resident memory
|
||||||
vmem = (
|
vmem = (
|
||||||
float(os.popen("ps -p %d -o %s | tail -1" % (pid, "vsz")).read()) / 1000.0
|
float(os.popen("ps -p %d -o %s | tail -1" % (pid, "vsz")).read())
|
||||||
|
/ 1000.0
|
||||||
) # virtual memory
|
) # virtual memory
|
||||||
pmem = float(
|
pmem = float(
|
||||||
os.popen("ps -p %d -o %s | tail -1" % (pid, "%mem")).read()
|
os.popen("ps -p %d -o %s | tail -1" % (pid, "%mem")).read()
|
||||||
|
|
@ -1048,9 +1099,12 @@ class CmdServerLoad(COMMAND_DEFAULT_CLASS):
|
||||||
% (rusage.ru_majflt, rusage.ru_minflt, rusage.ru_nswap),
|
% (rusage.ru_majflt, rusage.ru_minflt, rusage.ru_nswap),
|
||||||
)
|
)
|
||||||
loadtable.add_row(
|
loadtable.add_row(
|
||||||
"Disk I/O", "%g reads, %g writes" % (rusage.ru_inblock, rusage.ru_oublock)
|
"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("Network I/O", "%g in, %g out" % (rusage.ru_msgrcv, rusage.ru_msgsnd))
|
|
||||||
loadtable.add_row(
|
loadtable.add_row(
|
||||||
"Context switching",
|
"Context switching",
|
||||||
"%g vol, %g forced, %g signals"
|
"%g vol, %g forced, %g signals"
|
||||||
|
|
@ -1070,7 +1124,9 @@ class CmdServerLoad(COMMAND_DEFAULT_CLASS):
|
||||||
)
|
)
|
||||||
memtable = self.styled_table("entity name", "number", "idmapper %", align="l")
|
memtable = self.styled_table("entity name", "number", "idmapper %", align="l")
|
||||||
for tup in sorted_cache:
|
for tup in sorted_cache:
|
||||||
memtable.add_row(tup[0], "%i" % tup[1], "%.2f" % (float(tup[1]) / total_num * 100))
|
memtable.add_row(
|
||||||
|
tup[0], "%i" % tup[1], "%.2f" % (float(tup[1]) / total_num * 100)
|
||||||
|
)
|
||||||
|
|
||||||
string += "\n|w Entity idmapper cache:|n %i items\n%s" % (total_num, memtable)
|
string += "\n|w Entity idmapper cache:|n %i items\n%s" % (total_num, memtable)
|
||||||
|
|
||||||
|
|
@ -1102,14 +1158,18 @@ class CmdTickers(COMMAND_DEFAULT_CLASS):
|
||||||
if not all_subs:
|
if not all_subs:
|
||||||
self.caller.msg("No tickers are currently active.")
|
self.caller.msg("No tickers are currently active.")
|
||||||
return
|
return
|
||||||
table = self.styled_table("interval (s)", "object", "path/methodname", "idstring", "db")
|
table = self.styled_table(
|
||||||
|
"interval (s)", "object", "path/methodname", "idstring", "db"
|
||||||
|
)
|
||||||
for sub in all_subs:
|
for sub in all_subs:
|
||||||
table.add_row(
|
table.add_row(
|
||||||
sub[3],
|
sub[3],
|
||||||
"%s%s"
|
"%s%s"
|
||||||
% (
|
% (
|
||||||
sub[0] or "[None]",
|
sub[0] or "[None]",
|
||||||
sub[0] and " (#%s)" % (sub[0].id if hasattr(sub[0], "id") else "") or "",
|
sub[0]
|
||||||
|
and " (#%s)" % (sub[0].id if hasattr(sub[0], "id") else "")
|
||||||
|
or "",
|
||||||
),
|
),
|
||||||
sub[1] if sub[1] else sub[2],
|
sub[1] if sub[1] else sub[2],
|
||||||
sub[4] or "[Unset]",
|
sub[4] or "[Unset]",
|
||||||
|
|
|
||||||
|
|
@ -99,7 +99,9 @@ class CommandTest(EvenniaTest):
|
||||||
cmdobj.cmdset = cmdset
|
cmdobj.cmdset = cmdset
|
||||||
cmdobj.session = SESSIONS.session_from_sessid(1)
|
cmdobj.session = SESSIONS.session_from_sessid(1)
|
||||||
cmdobj.account = self.account
|
cmdobj.account = self.account
|
||||||
cmdobj.raw_string = raw_string if raw_string is not None else cmdobj.key + " " + args
|
cmdobj.raw_string = (
|
||||||
|
raw_string if raw_string is not None else cmdobj.key + " " + args
|
||||||
|
)
|
||||||
cmdobj.obj = obj or (caller if caller else self.char1)
|
cmdobj.obj = obj or (caller if caller else self.char1)
|
||||||
# test
|
# test
|
||||||
old_msg = receiver.msg
|
old_msg = receiver.msg
|
||||||
|
|
@ -140,14 +142,18 @@ class CommandTest(EvenniaTest):
|
||||||
for name, args, kwargs in receiver.msg.mock_calls
|
for name, args, kwargs in receiver.msg.mock_calls
|
||||||
]
|
]
|
||||||
# Get the first element of a tuple if msg received a tuple instead of a string
|
# Get the first element of a tuple if msg received a tuple instead of a string
|
||||||
stored_msg = [str(smsg[0]) if isinstance(smsg, tuple) else str(smsg) for smsg in stored_msg]
|
stored_msg = [
|
||||||
|
str(smsg[0]) if isinstance(smsg, tuple) else str(smsg)
|
||||||
|
for smsg in stored_msg
|
||||||
|
]
|
||||||
if msg is not None:
|
if msg is not None:
|
||||||
msg = str(msg) # to be safe, e.g. `py` command may return ints
|
msg = str(msg) # to be safe, e.g. `py` command may return ints
|
||||||
# set our separator for returned messages based on parsing ansi or not
|
# set our separator for returned messages based on parsing ansi or not
|
||||||
msg_sep = "|" if noansi else "||"
|
msg_sep = "|" if noansi else "||"
|
||||||
# Have to strip ansi for each returned message for the regex to handle it correctly
|
# Have to strip ansi for each returned message for the regex to handle it correctly
|
||||||
returned_msg = msg_sep.join(
|
returned_msg = msg_sep.join(
|
||||||
_RE.sub("", ansi.parse_ansi(mess, strip_ansi=noansi)) for mess in stored_msg
|
_RE.sub("", ansi.parse_ansi(mess, strip_ansi=noansi))
|
||||||
|
for mess in stored_msg
|
||||||
).strip()
|
).strip()
|
||||||
if msg == "" and returned_msg or not returned_msg.startswith(msg.strip()):
|
if msg == "" and returned_msg or not returned_msg.startswith(msg.strip()):
|
||||||
sep1 = "\n" + "=" * 30 + "Wanted message" + "=" * 34 + "\n"
|
sep1 = "\n" + "=" * 30 + "Wanted message" + "=" * 34 + "\n"
|
||||||
|
|
@ -202,8 +208,12 @@ class TestGeneral(CommandTest):
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
"testaliasedstring2", self.char1.nicks.get("testalias", category="account")
|
"testaliasedstring2", self.char1.nicks.get("testalias", category="account")
|
||||||
)
|
)
|
||||||
self.assertEqual(None, self.char1.account.nicks.get("testalias", category="account"))
|
self.assertEqual(
|
||||||
self.assertEqual("testaliasedstring3", self.char1.nicks.get("testalias", category="object"))
|
None, self.char1.account.nicks.get("testalias", category="account")
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
"testaliasedstring3", self.char1.nicks.get("testalias", category="object")
|
||||||
|
)
|
||||||
|
|
||||||
def test_get_and_drop(self):
|
def test_get_and_drop(self):
|
||||||
self.call(general.CmdGet(), "Obj", "You pick up Obj.")
|
self.call(general.CmdGet(), "Obj", "You pick up Obj.")
|
||||||
|
|
@ -230,9 +240,13 @@ class TestGeneral(CommandTest):
|
||||||
"Switches matched: ['test', 'testswitch', 'testswitch2']",
|
"Switches matched: ['test', 'testswitch', 'testswitch2']",
|
||||||
)
|
)
|
||||||
self.call(CmdTest(), "/test", "Switches matched: ['test']")
|
self.call(CmdTest(), "/test", "Switches matched: ['test']")
|
||||||
self.call(CmdTest(), "/test/testswitch", "Switches matched: ['test', 'testswitch']")
|
|
||||||
self.call(
|
self.call(
|
||||||
CmdTest(), "/testswitch/testswitch2", "Switches matched: ['testswitch', 'testswitch2']"
|
CmdTest(), "/test/testswitch", "Switches matched: ['test', 'testswitch']"
|
||||||
|
)
|
||||||
|
self.call(
|
||||||
|
CmdTest(),
|
||||||
|
"/testswitch/testswitch2",
|
||||||
|
"Switches matched: ['testswitch', 'testswitch2']",
|
||||||
)
|
)
|
||||||
self.call(CmdTest(), "/testswitch", "Switches matched: ['testswitch']")
|
self.call(CmdTest(), "/testswitch", "Switches matched: ['testswitch']")
|
||||||
self.call(CmdTest(), "/testswitch2", "Switches matched: ['testswitch2']")
|
self.call(CmdTest(), "/testswitch2", "Switches matched: ['testswitch2']")
|
||||||
|
|
@ -274,7 +288,9 @@ class TestHelp(CommandTest):
|
||||||
"testhelp, General = This is a test",
|
"testhelp, General = This is a test",
|
||||||
"Topic 'testhelp' was successfully created.",
|
"Topic 'testhelp' was successfully created.",
|
||||||
)
|
)
|
||||||
self.call(help.CmdHelp(), "testhelp", "Help for testhelp", cmdset=CharacterCmdSet())
|
self.call(
|
||||||
|
help.CmdHelp(), "testhelp", "Help for testhelp", cmdset=CharacterCmdSet()
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class TestSystem(CommandTest):
|
class TestSystem(CommandTest):
|
||||||
|
|
@ -332,7 +348,10 @@ class TestAccount(CommandTest):
|
||||||
def test_ooc_look(self):
|
def test_ooc_look(self):
|
||||||
if settings.MULTISESSION_MODE < 2:
|
if settings.MULTISESSION_MODE < 2:
|
||||||
self.call(
|
self.call(
|
||||||
account.CmdOOCLook(), "", "You are out-of-character (OOC).", caller=self.account
|
account.CmdOOCLook(),
|
||||||
|
"",
|
||||||
|
"You are out-of-character (OOC).",
|
||||||
|
caller=self.account,
|
||||||
)
|
)
|
||||||
if settings.MULTISESSION_MODE == 2:
|
if settings.MULTISESSION_MODE == 2:
|
||||||
self.call(
|
self.call(
|
||||||
|
|
@ -348,7 +367,11 @@ class TestAccount(CommandTest):
|
||||||
def test_ic(self):
|
def test_ic(self):
|
||||||
self.account.unpuppet_object(self.session)
|
self.account.unpuppet_object(self.session)
|
||||||
self.call(
|
self.call(
|
||||||
account.CmdIC(), "Char", "You become Char.", caller=self.account, receiver=self.char1
|
account.CmdIC(),
|
||||||
|
"Char",
|
||||||
|
"You become Char.",
|
||||||
|
caller=self.account,
|
||||||
|
receiver=self.char1,
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_password(self):
|
def test_password(self):
|
||||||
|
|
@ -367,11 +390,16 @@ class TestAccount(CommandTest):
|
||||||
|
|
||||||
def test_quit(self):
|
def test_quit(self):
|
||||||
self.call(
|
self.call(
|
||||||
account.CmdQuit(), "", "Quitting. Hope to see you again, soon.", caller=self.account
|
account.CmdQuit(),
|
||||||
|
"",
|
||||||
|
"Quitting. Hope to see you again, soon.",
|
||||||
|
caller=self.account,
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_sessions(self):
|
def test_sessions(self):
|
||||||
self.call(account.CmdSessions(), "", "Your current session(s):", caller=self.account)
|
self.call(
|
||||||
|
account.CmdSessions(), "", "Your current session(s):", caller=self.account
|
||||||
|
)
|
||||||
|
|
||||||
def test_color_test(self):
|
def test_color_test(self):
|
||||||
self.call(account.CmdColorTest(), "ansi", "ANSI colors:", caller=self.account)
|
self.call(account.CmdColorTest(), "ansi", "ANSI colors:", caller=self.account)
|
||||||
|
|
@ -456,7 +484,11 @@ class TestBuilding(CommandTest):
|
||||||
self.call(building.CmdExamine(), "*TestAccount", "Name/key: TestAccount")
|
self.call(building.CmdExamine(), "*TestAccount", "Name/key: TestAccount")
|
||||||
|
|
||||||
self.char1.db.test = "testval"
|
self.char1.db.test = "testval"
|
||||||
self.call(building.CmdExamine(), "self/test", "Persistent attributes:\n test = testval")
|
self.call(
|
||||||
|
building.CmdExamine(),
|
||||||
|
"self/test",
|
||||||
|
"Persistent attributes:\n test = testval",
|
||||||
|
)
|
||||||
self.call(building.CmdExamine(), "NotFound", "Could not find 'NotFound'.")
|
self.call(building.CmdExamine(), "NotFound", "Could not find 'NotFound'.")
|
||||||
self.call(building.CmdExamine(), "out", "Name/key: out")
|
self.call(building.CmdExamine(), "out", "Name/key: out")
|
||||||
|
|
||||||
|
|
@ -476,7 +508,11 @@ class TestBuilding(CommandTest):
|
||||||
self.call(building.CmdSetObjAlias(), "", "Usage: ")
|
self.call(building.CmdSetObjAlias(), "", "Usage: ")
|
||||||
self.call(building.CmdSetObjAlias(), "NotFound =", "Could not find 'NotFound'.")
|
self.call(building.CmdSetObjAlias(), "NotFound =", "Could not find 'NotFound'.")
|
||||||
|
|
||||||
self.call(building.CmdSetObjAlias(), "Obj", "Aliases for Obj(#{}): 'testobj1b'".format(oid))
|
self.call(
|
||||||
|
building.CmdSetObjAlias(),
|
||||||
|
"Obj",
|
||||||
|
"Aliases for Obj(#{}): 'testobj1b'".format(oid),
|
||||||
|
)
|
||||||
self.call(building.CmdSetObjAlias(), "Obj2 =", "Cleared aliases from Obj2")
|
self.call(building.CmdSetObjAlias(), "Obj2 =", "Cleared aliases from Obj2")
|
||||||
self.call(building.CmdSetObjAlias(), "Obj2 =", "No aliases to clear.")
|
self.call(building.CmdSetObjAlias(), "Obj2 =", "No aliases to clear.")
|
||||||
|
|
||||||
|
|
@ -487,7 +523,11 @@ class TestBuilding(CommandTest):
|
||||||
"Copied Obj to 'TestObj3' (aliases: ['TestObj3b']",
|
"Copied Obj to 'TestObj3' (aliases: ['TestObj3b']",
|
||||||
)
|
)
|
||||||
self.call(building.CmdCopy(), "", "Usage: ")
|
self.call(building.CmdCopy(), "", "Usage: ")
|
||||||
self.call(building.CmdCopy(), "Obj", "Identical copy of Obj, named 'Obj_copy' was created.")
|
self.call(
|
||||||
|
building.CmdCopy(),
|
||||||
|
"Obj",
|
||||||
|
"Identical copy of Obj, named 'Obj_copy' was created.",
|
||||||
|
)
|
||||||
self.call(building.CmdCopy(), "NotFound = Foo", "Could not find 'NotFound'.")
|
self.call(building.CmdCopy(), "NotFound = Foo", "Could not find 'NotFound'.")
|
||||||
|
|
||||||
def test_attribute_commands(self):
|
def test_attribute_commands(self):
|
||||||
|
|
@ -502,8 +542,14 @@ class TestBuilding(CommandTest):
|
||||||
'Obj2/test2="value2"',
|
'Obj2/test2="value2"',
|
||||||
"Created attribute Obj2/test2 = 'value2'",
|
"Created attribute Obj2/test2 = 'value2'",
|
||||||
)
|
)
|
||||||
self.call(building.CmdSetAttribute(), "Obj2/test2", "Attribute Obj2/test2 = value2")
|
self.call(
|
||||||
self.call(building.CmdSetAttribute(), "Obj2/NotFound", "Obj2 has no attribute 'notfound'.")
|
building.CmdSetAttribute(), "Obj2/test2", "Attribute Obj2/test2 = value2"
|
||||||
|
)
|
||||||
|
self.call(
|
||||||
|
building.CmdSetAttribute(),
|
||||||
|
"Obj2/NotFound",
|
||||||
|
"Obj2 has no attribute 'notfound'.",
|
||||||
|
)
|
||||||
|
|
||||||
with mock.patch("evennia.commands.default.building.EvEditor") as mock_ed:
|
with mock.patch("evennia.commands.default.building.EvEditor") as mock_ed:
|
||||||
self.call(building.CmdSetAttribute(), "/edit Obj2/test3")
|
self.call(building.CmdSetAttribute(), "/edit Obj2/test3")
|
||||||
|
|
@ -527,35 +573,59 @@ class TestBuilding(CommandTest):
|
||||||
"(value: 'value2')",
|
"(value: 'value2')",
|
||||||
)
|
)
|
||||||
self.call(building.CmdMvAttr(), "", "Usage: ")
|
self.call(building.CmdMvAttr(), "", "Usage: ")
|
||||||
self.call(building.CmdMvAttr(), "Obj2/test2 = Obj/test3", "Moved Obj2.test2 -> Obj.test3")
|
self.call(
|
||||||
|
building.CmdMvAttr(),
|
||||||
|
"Obj2/test2 = Obj/test3",
|
||||||
|
"Moved Obj2.test2 -> Obj.test3",
|
||||||
|
)
|
||||||
self.call(building.CmdCpAttr(), "", "Usage: ")
|
self.call(building.CmdCpAttr(), "", "Usage: ")
|
||||||
self.call(building.CmdCpAttr(), "Obj/test1 = Obj2/test3", "Copied Obj.test1 -> Obj2.test3")
|
self.call(
|
||||||
|
building.CmdCpAttr(),
|
||||||
|
"Obj/test1 = Obj2/test3",
|
||||||
|
"Copied Obj.test1 -> Obj2.test3",
|
||||||
|
)
|
||||||
|
|
||||||
self.call(building.CmdWipe(), "", "Usage: ")
|
self.call(building.CmdWipe(), "", "Usage: ")
|
||||||
self.call(building.CmdWipe(), "Obj2/test2/test3", "Wiped attributes test2,test3 on Obj2.")
|
self.call(
|
||||||
|
building.CmdWipe(),
|
||||||
|
"Obj2/test2/test3",
|
||||||
|
"Wiped attributes test2,test3 on Obj2.",
|
||||||
|
)
|
||||||
self.call(building.CmdWipe(), "Obj2", "Wiped all attributes on Obj2.")
|
self.call(building.CmdWipe(), "Obj2", "Wiped all attributes on Obj2.")
|
||||||
|
|
||||||
def test_nested_attribute_commands(self):
|
def test_nested_attribute_commands(self):
|
||||||
# list - adding white space proves real parsing
|
# list - adding white space proves real parsing
|
||||||
self.call(
|
self.call(
|
||||||
building.CmdSetAttribute(), "Obj/test1=[1,2]", "Created attribute Obj/test1 = [1, 2]"
|
building.CmdSetAttribute(),
|
||||||
|
"Obj/test1=[1,2]",
|
||||||
|
"Created attribute Obj/test1 = [1, 2]",
|
||||||
|
)
|
||||||
|
self.call(
|
||||||
|
building.CmdSetAttribute(), "Obj/test1", "Attribute Obj/test1 = [1, 2]"
|
||||||
|
)
|
||||||
|
self.call(
|
||||||
|
building.CmdSetAttribute(), "Obj/test1[0]", "Attribute Obj/test1[0] = 1"
|
||||||
|
)
|
||||||
|
self.call(
|
||||||
|
building.CmdSetAttribute(), "Obj/test1[1]", "Attribute Obj/test1[1] = 2"
|
||||||
)
|
)
|
||||||
self.call(building.CmdSetAttribute(), "Obj/test1", "Attribute Obj/test1 = [1, 2]")
|
|
||||||
self.call(building.CmdSetAttribute(), "Obj/test1[0]", "Attribute Obj/test1[0] = 1")
|
|
||||||
self.call(building.CmdSetAttribute(), "Obj/test1[1]", "Attribute Obj/test1[1] = 2")
|
|
||||||
self.call(
|
self.call(
|
||||||
building.CmdSetAttribute(),
|
building.CmdSetAttribute(),
|
||||||
"Obj/test1[0] = 99",
|
"Obj/test1[0] = 99",
|
||||||
"Modified attribute Obj/test1 = [99, 2]",
|
"Modified attribute Obj/test1 = [99, 2]",
|
||||||
)
|
)
|
||||||
self.call(building.CmdSetAttribute(), "Obj/test1[0]", "Attribute Obj/test1[0] = 99")
|
self.call(
|
||||||
|
building.CmdSetAttribute(), "Obj/test1[0]", "Attribute Obj/test1[0] = 99"
|
||||||
|
)
|
||||||
# list delete
|
# list delete
|
||||||
self.call(
|
self.call(
|
||||||
building.CmdSetAttribute(),
|
building.CmdSetAttribute(),
|
||||||
"Obj/test1[0] =",
|
"Obj/test1[0] =",
|
||||||
"Deleted attribute 'test1[0]' (= nested) from Obj.",
|
"Deleted attribute 'test1[0]' (= nested) from Obj.",
|
||||||
)
|
)
|
||||||
self.call(building.CmdSetAttribute(), "Obj/test1[0]", "Attribute Obj/test1[0] = 2")
|
self.call(
|
||||||
|
building.CmdSetAttribute(), "Obj/test1[0]", "Attribute Obj/test1[0] = 2"
|
||||||
|
)
|
||||||
self.call(
|
self.call(
|
||||||
building.CmdSetAttribute(),
|
building.CmdSetAttribute(),
|
||||||
"Obj/test1[1]",
|
"Obj/test1[1]",
|
||||||
|
|
@ -586,17 +656,35 @@ class TestBuilding(CommandTest):
|
||||||
"Created attribute Obj/test2 = {'one': 1, 'two': 2}",
|
"Created attribute Obj/test2 = {'one': 1, 'two': 2}",
|
||||||
)
|
)
|
||||||
self.call(
|
self.call(
|
||||||
building.CmdSetAttribute(), "Obj/test2", "Attribute Obj/test2 = {'one': 1, 'two': 2}"
|
building.CmdSetAttribute(),
|
||||||
|
"Obj/test2",
|
||||||
|
"Attribute Obj/test2 = {'one': 1, 'two': 2}",
|
||||||
|
)
|
||||||
|
self.call(
|
||||||
|
building.CmdSetAttribute(),
|
||||||
|
"Obj/test2['one']",
|
||||||
|
"Attribute Obj/test2['one'] = 1",
|
||||||
|
)
|
||||||
|
self.call(
|
||||||
|
building.CmdSetAttribute(),
|
||||||
|
"Obj/test2['one]",
|
||||||
|
"Attribute Obj/test2['one] = 1",
|
||||||
)
|
)
|
||||||
self.call(building.CmdSetAttribute(), "Obj/test2['one']", "Attribute Obj/test2['one'] = 1")
|
|
||||||
self.call(building.CmdSetAttribute(), "Obj/test2['one]", "Attribute Obj/test2['one] = 1")
|
|
||||||
self.call(
|
self.call(
|
||||||
building.CmdSetAttribute(),
|
building.CmdSetAttribute(),
|
||||||
"Obj/test2['one']=99",
|
"Obj/test2['one']=99",
|
||||||
"Modified attribute Obj/test2 = {'one': 99, 'two': 2}",
|
"Modified attribute Obj/test2 = {'one': 99, 'two': 2}",
|
||||||
)
|
)
|
||||||
self.call(building.CmdSetAttribute(), "Obj/test2['one']", "Attribute Obj/test2['one'] = 99")
|
self.call(
|
||||||
self.call(building.CmdSetAttribute(), "Obj/test2['two']", "Attribute Obj/test2['two'] = 2")
|
building.CmdSetAttribute(),
|
||||||
|
"Obj/test2['one']",
|
||||||
|
"Attribute Obj/test2['one'] = 99",
|
||||||
|
)
|
||||||
|
self.call(
|
||||||
|
building.CmdSetAttribute(),
|
||||||
|
"Obj/test2['two']",
|
||||||
|
"Attribute Obj/test2['two'] = 2",
|
||||||
|
)
|
||||||
self.call(
|
self.call(
|
||||||
building.CmdSetAttribute(),
|
building.CmdSetAttribute(),
|
||||||
"Obj/test2[+'three']",
|
"Obj/test2[+'three']",
|
||||||
|
|
@ -629,7 +717,9 @@ class TestBuilding(CommandTest):
|
||||||
"Obj has no attribute 'test2['two']'. (Nested lookups attempted)",
|
"Obj has no attribute 'test2['two']'. (Nested lookups attempted)",
|
||||||
)
|
)
|
||||||
self.call(
|
self.call(
|
||||||
building.CmdSetAttribute(), "Obj/test2", "Attribute Obj/test2 = {'one': 99, 'three': 3}"
|
building.CmdSetAttribute(),
|
||||||
|
"Obj/test2",
|
||||||
|
"Attribute Obj/test2 = {'one': 99, 'three': 3}",
|
||||||
)
|
)
|
||||||
self.call(
|
self.call(
|
||||||
building.CmdSetAttribute(),
|
building.CmdSetAttribute(),
|
||||||
|
|
@ -654,7 +744,9 @@ class TestBuilding(CommandTest):
|
||||||
|
|
||||||
# tuple
|
# tuple
|
||||||
self.call(
|
self.call(
|
||||||
building.CmdSetAttribute(), "Obj/tup = (1,2)", "Created attribute Obj/tup = (1, 2)"
|
building.CmdSetAttribute(),
|
||||||
|
"Obj/tup = (1,2)",
|
||||||
|
"Created attribute Obj/tup = (1, 2)",
|
||||||
)
|
)
|
||||||
self.call(
|
self.call(
|
||||||
building.CmdSetAttribute(),
|
building.CmdSetAttribute(),
|
||||||
|
|
@ -685,15 +777,23 @@ class TestBuilding(CommandTest):
|
||||||
"Created attribute Obj/test3 = [{'one': 1}]",
|
"Created attribute Obj/test3 = [{'one': 1}]",
|
||||||
)
|
)
|
||||||
self.call(
|
self.call(
|
||||||
building.CmdSetAttribute(), "Obj/test3[0]['one']", "Attribute Obj/test3[0]['one'] = 1"
|
building.CmdSetAttribute(),
|
||||||
|
"Obj/test3[0]['one']",
|
||||||
|
"Attribute Obj/test3[0]['one'] = 1",
|
||||||
|
)
|
||||||
|
self.call(
|
||||||
|
building.CmdSetAttribute(),
|
||||||
|
"Obj/test3[0]",
|
||||||
|
"Attribute Obj/test3[0] = {'one': 1}",
|
||||||
)
|
)
|
||||||
self.call(building.CmdSetAttribute(), "Obj/test3[0]", "Attribute Obj/test3[0] = {'one': 1}")
|
|
||||||
self.call(
|
self.call(
|
||||||
building.CmdSetAttribute(),
|
building.CmdSetAttribute(),
|
||||||
"Obj/test3[0]['one'] =",
|
"Obj/test3[0]['one'] =",
|
||||||
"Deleted attribute 'test3[0]['one']' (= nested) from Obj.",
|
"Deleted attribute 'test3[0]['one']' (= nested) from Obj.",
|
||||||
)
|
)
|
||||||
self.call(building.CmdSetAttribute(), "Obj/test3[0]", "Attribute Obj/test3[0] = {}")
|
self.call(
|
||||||
|
building.CmdSetAttribute(), "Obj/test3[0]", "Attribute Obj/test3[0] = {}"
|
||||||
|
)
|
||||||
self.call(building.CmdSetAttribute(), "Obj/test3", "Attribute Obj/test3 = [{}]")
|
self.call(building.CmdSetAttribute(), "Obj/test3", "Attribute Obj/test3 = [{}]")
|
||||||
|
|
||||||
# Naughty keys
|
# Naughty keys
|
||||||
|
|
@ -702,23 +802,35 @@ class TestBuilding(CommandTest):
|
||||||
"Obj/test4[0]='foo'",
|
"Obj/test4[0]='foo'",
|
||||||
"Created attribute Obj/test4[0] = 'foo'",
|
"Created attribute Obj/test4[0] = 'foo'",
|
||||||
)
|
)
|
||||||
self.call(building.CmdSetAttribute(), "Obj/test4[0]", "Attribute Obj/test4[0] = foo")
|
self.call(
|
||||||
|
building.CmdSetAttribute(), "Obj/test4[0]", "Attribute Obj/test4[0] = foo"
|
||||||
|
)
|
||||||
self.call(
|
self.call(
|
||||||
building.CmdSetAttribute(),
|
building.CmdSetAttribute(),
|
||||||
"Obj/test4=[{'one': 1}]",
|
"Obj/test4=[{'one': 1}]",
|
||||||
"Created attribute Obj/test4 = [{'one': 1}]",
|
"Created attribute Obj/test4 = [{'one': 1}]",
|
||||||
)
|
)
|
||||||
self.call(
|
self.call(
|
||||||
building.CmdSetAttribute(), "Obj/test4[0]['one']", "Attribute Obj/test4[0]['one'] = 1"
|
building.CmdSetAttribute(),
|
||||||
|
"Obj/test4[0]['one']",
|
||||||
|
"Attribute Obj/test4[0]['one'] = 1",
|
||||||
)
|
)
|
||||||
# Prefer nested items
|
# Prefer nested items
|
||||||
self.call(building.CmdSetAttribute(), "Obj/test4[0]", "Attribute Obj/test4[0] = {'one': 1}")
|
|
||||||
self.call(
|
self.call(
|
||||||
building.CmdSetAttribute(), "Obj/test4[0]['one']", "Attribute Obj/test4[0]['one'] = 1"
|
building.CmdSetAttribute(),
|
||||||
|
"Obj/test4[0]",
|
||||||
|
"Attribute Obj/test4[0] = {'one': 1}",
|
||||||
|
)
|
||||||
|
self.call(
|
||||||
|
building.CmdSetAttribute(),
|
||||||
|
"Obj/test4[0]['one']",
|
||||||
|
"Attribute Obj/test4[0]['one'] = 1",
|
||||||
)
|
)
|
||||||
# Restored access
|
# Restored access
|
||||||
self.call(building.CmdWipe(), "Obj/test4", "Wiped attributes test4 on Obj.")
|
self.call(building.CmdWipe(), "Obj/test4", "Wiped attributes test4 on Obj.")
|
||||||
self.call(building.CmdSetAttribute(), "Obj/test4[0]", "Attribute Obj/test4[0] = foo")
|
self.call(
|
||||||
|
building.CmdSetAttribute(), "Obj/test4[0]", "Attribute Obj/test4[0] = foo"
|
||||||
|
)
|
||||||
self.call(
|
self.call(
|
||||||
building.CmdSetAttribute(),
|
building.CmdSetAttribute(),
|
||||||
"Obj/test4[0]['one']",
|
"Obj/test4[0]['one']",
|
||||||
|
|
@ -736,7 +848,11 @@ class TestBuilding(CommandTest):
|
||||||
# duplicate keys don't cause issues
|
# duplicate keys don't cause issues
|
||||||
"test5[0][0]": [("test5", [0, 0]), ("test5[0]", [0]), ("test5[0][0]", [])],
|
"test5[0][0]": [("test5", [0, 0]), ("test5[0]", [0]), ("test5[0][0]", [])],
|
||||||
# String ints preserved
|
# String ints preserved
|
||||||
'test6["0"][0]': [("test6", ["0", 0]), ('test6["0"]', [0]), ('test6["0"][0]', [])],
|
'test6["0"][0]': [
|
||||||
|
("test6", ["0", 0]),
|
||||||
|
('test6["0"]', [0]),
|
||||||
|
('test6["0"][0]', []),
|
||||||
|
],
|
||||||
# Unmatched []
|
# Unmatched []
|
||||||
"test7[dict": [("test7[dict", [])],
|
"test7[dict": [("test7[dict", [])],
|
||||||
}
|
}
|
||||||
|
|
@ -776,16 +892,24 @@ class TestBuilding(CommandTest):
|
||||||
"*TestAccount=TestAccountRenamed",
|
"*TestAccount=TestAccountRenamed",
|
||||||
"Account's name changed to 'TestAccountRenamed'.",
|
"Account's name changed to 'TestAccountRenamed'.",
|
||||||
)
|
)
|
||||||
self.call(building.CmdName(), "*NotFound=TestAccountRenamed", "Could not find '*NotFound'")
|
|
||||||
self.call(
|
self.call(
|
||||||
building.CmdName(), "Obj3=Obj4;foo;bar", "Object's name changed to 'Obj4' (foo, bar)."
|
building.CmdName(),
|
||||||
|
"*NotFound=TestAccountRenamed",
|
||||||
|
"Could not find '*NotFound'",
|
||||||
|
)
|
||||||
|
self.call(
|
||||||
|
building.CmdName(),
|
||||||
|
"Obj3=Obj4;foo;bar",
|
||||||
|
"Object's name changed to 'Obj4' (foo, bar).",
|
||||||
)
|
)
|
||||||
self.call(building.CmdName(), "Obj4=", "No names or aliases defined!")
|
self.call(building.CmdName(), "Obj4=", "No names or aliases defined!")
|
||||||
|
|
||||||
def test_desc(self):
|
def test_desc(self):
|
||||||
oid = self.obj2.id
|
oid = self.obj2.id
|
||||||
self.call(
|
self.call(
|
||||||
building.CmdDesc(), "Obj2=TestDesc", "The description was set on Obj2(#{}).".format(oid)
|
building.CmdDesc(),
|
||||||
|
"Obj2=TestDesc",
|
||||||
|
"The description was set on Obj2(#{}).".format(oid),
|
||||||
)
|
)
|
||||||
self.call(building.CmdDesc(), "", "Usage: ")
|
self.call(building.CmdDesc(), "", "Usage: ")
|
||||||
|
|
||||||
|
|
@ -807,7 +931,11 @@ class TestBuilding(CommandTest):
|
||||||
oid = self.obj2.id
|
oid = self.obj2.id
|
||||||
o2d = self.obj2.db.desc
|
o2d = self.obj2.db.desc
|
||||||
r1d = self.room1.db.desc
|
r1d = self.room1.db.desc
|
||||||
self.call(building.CmdDesc(), "Obj2=", "The description was set on Obj2(#{}).".format(oid))
|
self.call(
|
||||||
|
building.CmdDesc(),
|
||||||
|
"Obj2=",
|
||||||
|
"The description was set on Obj2(#{}).".format(oid),
|
||||||
|
)
|
||||||
assert self.obj2.db.desc == "" and self.obj2.db.desc != o2d
|
assert self.obj2.db.desc == "" and self.obj2.db.desc != o2d
|
||||||
assert self.room1.db.desc == r1d
|
assert self.room1.db.desc == r1d
|
||||||
|
|
||||||
|
|
@ -816,7 +944,11 @@ class TestBuilding(CommandTest):
|
||||||
rid = self.room1.id
|
rid = self.room1.id
|
||||||
o2d = self.obj2.db.desc
|
o2d = self.obj2.db.desc
|
||||||
r1d = self.room1.db.desc
|
r1d = self.room1.db.desc
|
||||||
self.call(building.CmdDesc(), "Obj2", "The description was set on Room(#{}).".format(rid))
|
self.call(
|
||||||
|
building.CmdDesc(),
|
||||||
|
"Obj2",
|
||||||
|
"The description was set on Room(#{}).".format(rid),
|
||||||
|
)
|
||||||
assert self.obj2.db.desc == o2d
|
assert self.obj2.db.desc == o2d
|
||||||
assert self.room1.db.desc == "Obj2" and self.room1.db.desc != r1d
|
assert self.room1.db.desc == "Obj2" and self.room1.db.desc != r1d
|
||||||
|
|
||||||
|
|
@ -858,14 +990,22 @@ class TestBuilding(CommandTest):
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_dig(self):
|
def test_dig(self):
|
||||||
self.call(building.CmdDig(), "TestRoom1=testroom;tr,back;b", "Created room TestRoom1")
|
self.call(
|
||||||
|
building.CmdDig(), "TestRoom1=testroom;tr,back;b", "Created room TestRoom1"
|
||||||
|
)
|
||||||
self.call(building.CmdDig(), "", "Usage: ")
|
self.call(building.CmdDig(), "", "Usage: ")
|
||||||
|
|
||||||
def test_tunnel(self):
|
def test_tunnel(self):
|
||||||
self.call(building.CmdTunnel(), "n = TestRoom2;test2", "Created room TestRoom2")
|
self.call(building.CmdTunnel(), "n = TestRoom2;test2", "Created room TestRoom2")
|
||||||
self.call(building.CmdTunnel(), "", "Usage: ")
|
self.call(building.CmdTunnel(), "", "Usage: ")
|
||||||
self.call(building.CmdTunnel(), "foo = TestRoom2;test2", "tunnel can only understand the")
|
self.call(
|
||||||
self.call(building.CmdTunnel(), "/tel e = TestRoom3;test3", "Created room TestRoom3")
|
building.CmdTunnel(),
|
||||||
|
"foo = TestRoom2;test2",
|
||||||
|
"tunnel can only understand the",
|
||||||
|
)
|
||||||
|
self.call(
|
||||||
|
building.CmdTunnel(), "/tel e = TestRoom3;test3", "Created room TestRoom3"
|
||||||
|
)
|
||||||
DefaultRoom.objects.get_family(db_key="TestRoom3")
|
DefaultRoom.objects.get_family(db_key="TestRoom3")
|
||||||
exits = DefaultExit.objects.filter_family(db_key__in=("east", "west"))
|
exits = DefaultExit.objects.filter_family(db_key__in=("east", "west"))
|
||||||
self.assertEqual(len(exits), 2)
|
self.assertEqual(len(exits), 2)
|
||||||
|
|
@ -879,20 +1019,32 @@ class TestBuilding(CommandTest):
|
||||||
|
|
||||||
def test_exit_commands(self):
|
def test_exit_commands(self):
|
||||||
self.call(
|
self.call(
|
||||||
building.CmdOpen(), "TestExit1=Room2", "Created new Exit 'TestExit1' from Room to Room2"
|
building.CmdOpen(),
|
||||||
|
"TestExit1=Room2",
|
||||||
|
"Created new Exit 'TestExit1' from Room to Room2",
|
||||||
|
)
|
||||||
|
self.call(
|
||||||
|
building.CmdLink(),
|
||||||
|
"TestExit1=Room",
|
||||||
|
"Link created TestExit1 -> Room (one way).",
|
||||||
)
|
)
|
||||||
self.call(building.CmdLink(), "TestExit1=Room", "Link created TestExit1 -> Room (one way).")
|
|
||||||
self.call(building.CmdUnLink(), "", "Usage: ")
|
self.call(building.CmdUnLink(), "", "Usage: ")
|
||||||
self.call(building.CmdLink(), "NotFound", "Could not find 'NotFound'.")
|
self.call(building.CmdLink(), "NotFound", "Could not find 'NotFound'.")
|
||||||
self.call(building.CmdLink(), "TestExit", "TestExit1 is an exit to Room.")
|
self.call(building.CmdLink(), "TestExit", "TestExit1 is an exit to Room.")
|
||||||
self.call(building.CmdLink(), "Obj", "Obj is not an exit. Its home location is Room.")
|
|
||||||
self.call(
|
self.call(
|
||||||
building.CmdUnLink(), "TestExit1", "Former exit TestExit1 no longer links anywhere."
|
building.CmdLink(), "Obj", "Obj is not an exit. Its home location is Room."
|
||||||
|
)
|
||||||
|
self.call(
|
||||||
|
building.CmdUnLink(),
|
||||||
|
"TestExit1",
|
||||||
|
"Former exit TestExit1 no longer links anywhere.",
|
||||||
)
|
)
|
||||||
|
|
||||||
self.char1.location = self.room2
|
self.char1.location = self.room2
|
||||||
self.call(
|
self.call(
|
||||||
building.CmdOpen(), "TestExit2=Room", "Created new Exit 'TestExit2' from Room2 to Room."
|
building.CmdOpen(),
|
||||||
|
"TestExit2=Room",
|
||||||
|
"Created new Exit 'TestExit2' from Room2 to Room.",
|
||||||
)
|
)
|
||||||
self.call(
|
self.call(
|
||||||
building.CmdOpen(),
|
building.CmdOpen(),
|
||||||
|
|
@ -902,7 +1054,9 @@ class TestBuilding(CommandTest):
|
||||||
|
|
||||||
# ensure it matches locally first
|
# ensure it matches locally first
|
||||||
self.call(
|
self.call(
|
||||||
building.CmdLink(), "TestExit=Room2", "Link created TestExit2 -> Room2 (one way)."
|
building.CmdLink(),
|
||||||
|
"TestExit=Room2",
|
||||||
|
"Link created TestExit2 -> Room2 (one way).",
|
||||||
)
|
)
|
||||||
self.call(
|
self.call(
|
||||||
building.CmdLink(),
|
building.CmdLink(),
|
||||||
|
|
@ -923,21 +1077,29 @@ class TestBuilding(CommandTest):
|
||||||
# ensure can still match globally when not a local name
|
# ensure can still match globally when not a local name
|
||||||
self.call(building.CmdLink(), "TestExit1=Room2", "Note: TestExit1")
|
self.call(building.CmdLink(), "TestExit1=Room2", "Note: TestExit1")
|
||||||
self.call(
|
self.call(
|
||||||
building.CmdLink(), "TestExit1=", "Former exit TestExit1 no longer links anywhere."
|
building.CmdLink(),
|
||||||
|
"TestExit1=",
|
||||||
|
"Former exit TestExit1 no longer links anywhere.",
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_set_home(self):
|
def test_set_home(self):
|
||||||
self.call(
|
self.call(
|
||||||
building.CmdSetHome(), "Obj = Room2", "Home location of Obj was changed from Room"
|
building.CmdSetHome(),
|
||||||
|
"Obj = Room2",
|
||||||
|
"Home location of Obj was changed from Room",
|
||||||
)
|
)
|
||||||
self.call(building.CmdSetHome(), "", "Usage: ")
|
self.call(building.CmdSetHome(), "", "Usage: ")
|
||||||
self.call(building.CmdSetHome(), "self", "Char's current home is Room")
|
self.call(building.CmdSetHome(), "self", "Char's current home is Room")
|
||||||
self.call(building.CmdSetHome(), "Obj", "Obj's current home is Room2")
|
self.call(building.CmdSetHome(), "Obj", "Obj's current home is Room2")
|
||||||
self.obj1.home = None
|
self.obj1.home = None
|
||||||
self.call(building.CmdSetHome(), "Obj = Room2", "Home location of Obj was set to Room")
|
self.call(
|
||||||
|
building.CmdSetHome(), "Obj = Room2", "Home location of Obj was set to Room"
|
||||||
|
)
|
||||||
|
|
||||||
def test_list_cmdsets(self):
|
def test_list_cmdsets(self):
|
||||||
self.call(building.CmdListCmdSets(), "", "<DefaultCharacter (Union, prio 0, perm)>:")
|
self.call(
|
||||||
|
building.CmdListCmdSets(), "", "<DefaultCharacter (Union, prio 0, perm)>:"
|
||||||
|
)
|
||||||
self.call(building.CmdListCmdSets(), "NotFound", "Could not find 'NotFound'")
|
self.call(building.CmdListCmdSets(), "NotFound", "Could not find 'NotFound'")
|
||||||
|
|
||||||
def test_typeclass(self):
|
def test_typeclass(self):
|
||||||
|
|
@ -971,7 +1133,9 @@ class TestBuilding(CommandTest):
|
||||||
"/force Obj = evennia.objects.objects.DefaultExit",
|
"/force Obj = evennia.objects.objects.DefaultExit",
|
||||||
"Obj updated its existing typeclass ",
|
"Obj updated its existing typeclass ",
|
||||||
)
|
)
|
||||||
self.call(building.CmdTypeclass(), "Obj = evennia.objects.objects.DefaultObject")
|
self.call(
|
||||||
|
building.CmdTypeclass(), "Obj = evennia.objects.objects.DefaultObject"
|
||||||
|
)
|
||||||
self.call(
|
self.call(
|
||||||
building.CmdTypeclass(),
|
building.CmdTypeclass(),
|
||||||
"/show Obj",
|
"/show Obj",
|
||||||
|
|
@ -993,13 +1157,19 @@ class TestBuilding(CommandTest):
|
||||||
|
|
||||||
def test_lock(self):
|
def test_lock(self):
|
||||||
self.call(building.CmdLock(), "", "Usage: ")
|
self.call(building.CmdLock(), "", "Usage: ")
|
||||||
self.call(building.CmdLock(), "Obj = test:all()", "Added lock 'test:all()' to Obj.")
|
self.call(
|
||||||
|
building.CmdLock(), "Obj = test:all()", "Added lock 'test:all()' to Obj."
|
||||||
|
)
|
||||||
self.call(
|
self.call(
|
||||||
building.CmdLock(),
|
building.CmdLock(),
|
||||||
"*TestAccount = test:all()",
|
"*TestAccount = test:all()",
|
||||||
"Added lock 'test:all()' to TestAccount",
|
"Added lock 'test:all()' to TestAccount",
|
||||||
)
|
)
|
||||||
self.call(building.CmdLock(), "Obj/notfound", "Obj has no lock of access type 'notfound'.")
|
self.call(
|
||||||
|
building.CmdLock(),
|
||||||
|
"Obj/notfound",
|
||||||
|
"Obj has no lock of access type 'notfound'.",
|
||||||
|
)
|
||||||
self.call(building.CmdLock(), "Obj/test", "test:all()")
|
self.call(building.CmdLock(), "Obj/test", "test:all()")
|
||||||
self.call(
|
self.call(
|
||||||
building.CmdLock(),
|
building.CmdLock(),
|
||||||
|
|
@ -1020,7 +1190,9 @@ class TestBuilding(CommandTest):
|
||||||
self.call(building.CmdFind(), "", "Usage: ")
|
self.call(building.CmdFind(), "", "Usage: ")
|
||||||
self.call(building.CmdFind(), "oom2", "One Match")
|
self.call(building.CmdFind(), "oom2", "One Match")
|
||||||
self.call(building.CmdFind(), "oom2 = 1-{}".format(rmax), "One Match")
|
self.call(building.CmdFind(), "oom2 = 1-{}".format(rmax), "One Match")
|
||||||
self.call(building.CmdFind(), "oom2 = 1 {}".format(rmax), "One Match") # space works too
|
self.call(
|
||||||
|
building.CmdFind(), "oom2 = 1 {}".format(rmax), "One Match"
|
||||||
|
) # space works too
|
||||||
self.call(building.CmdFind(), "Char2", "One Match", cmdstring="locate")
|
self.call(building.CmdFind(), "Char2", "One Match", cmdstring="locate")
|
||||||
self.call(
|
self.call(
|
||||||
building.CmdFind(),
|
building.CmdFind(),
|
||||||
|
|
@ -1046,7 +1218,9 @@ class TestBuilding(CommandTest):
|
||||||
def test_script(self):
|
def test_script(self):
|
||||||
self.call(building.CmdScript(), "Obj = ", "No scripts defined on Obj")
|
self.call(building.CmdScript(), "Obj = ", "No scripts defined on Obj")
|
||||||
self.call(
|
self.call(
|
||||||
building.CmdScript(), "Obj = scripts.Script", "Script scripts.Script successfully added"
|
building.CmdScript(),
|
||||||
|
"Obj = scripts.Script",
|
||||||
|
"Script scripts.Script successfully added",
|
||||||
)
|
)
|
||||||
self.call(building.CmdScript(), "", "Usage: ")
|
self.call(building.CmdScript(), "", "Usage: ")
|
||||||
self.call(
|
self.call(
|
||||||
|
|
@ -1062,7 +1236,9 @@ class TestBuilding(CommandTest):
|
||||||
self.call(building.CmdScript(), "/stop Obj", "Stopping script")
|
self.call(building.CmdScript(), "/stop Obj", "Stopping script")
|
||||||
|
|
||||||
self.call(
|
self.call(
|
||||||
building.CmdScript(), "Obj = scripts.Script", "Script scripts.Script successfully added"
|
building.CmdScript(),
|
||||||
|
"Obj = scripts.Script",
|
||||||
|
"Script scripts.Script successfully added",
|
||||||
)
|
)
|
||||||
self.call(
|
self.call(
|
||||||
building.CmdScript(),
|
building.CmdScript(),
|
||||||
|
|
@ -1093,12 +1269,18 @@ class TestBuilding(CommandTest):
|
||||||
oid, rid, rid2
|
oid, rid, rid2
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
self.call(building.CmdTeleport(), "NotFound = Room", "Could not find 'NotFound'.")
|
|
||||||
self.call(
|
self.call(
|
||||||
building.CmdTeleport(), "Obj = Obj", "You can't teleport an object inside of itself!"
|
building.CmdTeleport(), "NotFound = Room", "Could not find 'NotFound'."
|
||||||
|
)
|
||||||
|
self.call(
|
||||||
|
building.CmdTeleport(),
|
||||||
|
"Obj = Obj",
|
||||||
|
"You can't teleport an object inside of itself!",
|
||||||
)
|
)
|
||||||
|
|
||||||
self.call(building.CmdTeleport(), "/tonone Obj2", "Teleported Obj2 -> None-location.")
|
self.call(
|
||||||
|
building.CmdTeleport(), "/tonone Obj2", "Teleported Obj2 -> None-location."
|
||||||
|
)
|
||||||
self.call(building.CmdTeleport(), "/quiet Room2", "Room2(#{})".format(rid2))
|
self.call(building.CmdTeleport(), "/quiet Room2", "Room2(#{})".format(rid2))
|
||||||
self.call(
|
self.call(
|
||||||
building.CmdTeleport(),
|
building.CmdTeleport(),
|
||||||
|
|
@ -1127,19 +1309,30 @@ class TestBuilding(CommandTest):
|
||||||
self.call(
|
self.call(
|
||||||
building.CmdTag(),
|
building.CmdTag(),
|
||||||
"Obj",
|
"Obj",
|
||||||
"Tags on Obj: 'testtag', 'testtag2', " "'testtag2' (category: category1), 'testtag3'",
|
"Tags on Obj: 'testtag', 'testtag2', "
|
||||||
|
"'testtag2' (category: category1), 'testtag3'",
|
||||||
)
|
)
|
||||||
|
|
||||||
self.call(building.CmdTag(), "/search NotFound", "No objects found with tag 'NotFound'.")
|
self.call(
|
||||||
self.call(building.CmdTag(), "/search testtag", "Found 1 object with tag 'testtag':")
|
building.CmdTag(),
|
||||||
self.call(building.CmdTag(), "/search testtag2", "Found 1 object with tag 'testtag2':")
|
"/search NotFound",
|
||||||
|
"No objects found with tag 'NotFound'.",
|
||||||
|
)
|
||||||
|
self.call(
|
||||||
|
building.CmdTag(), "/search testtag", "Found 1 object with tag 'testtag':"
|
||||||
|
)
|
||||||
|
self.call(
|
||||||
|
building.CmdTag(), "/search testtag2", "Found 1 object with tag 'testtag2':"
|
||||||
|
)
|
||||||
self.call(
|
self.call(
|
||||||
building.CmdTag(),
|
building.CmdTag(),
|
||||||
"/search testtag2:category1",
|
"/search testtag2:category1",
|
||||||
"Found 1 object with tag 'testtag2' (category: 'category1'):",
|
"Found 1 object with tag 'testtag2' (category: 'category1'):",
|
||||||
)
|
)
|
||||||
|
|
||||||
self.call(building.CmdTag(), "/del Obj = testtag3", "Removed tag 'testtag3' from Obj.")
|
self.call(
|
||||||
|
building.CmdTag(), "/del Obj = testtag3", "Removed tag 'testtag3' from Obj."
|
||||||
|
)
|
||||||
self.call(
|
self.call(
|
||||||
building.CmdTag(),
|
building.CmdTag(),
|
||||||
"/del Obj",
|
"/del Obj",
|
||||||
|
|
@ -1175,7 +1368,8 @@ class TestBuilding(CommandTest):
|
||||||
|
|
||||||
self.call(
|
self.call(
|
||||||
building.CmdSpawn(),
|
building.CmdSpawn(),
|
||||||
"/save {'key':'Test Char', " "'typeclass':'evennia.objects.objects.DefaultCharacter'}",
|
"/save {'key':'Test Char', "
|
||||||
|
"'typeclass':'evennia.objects.objects.DefaultCharacter'}",
|
||||||
"To save a prototype it must have the 'prototype_key' set.",
|
"To save a prototype it must have the 'prototype_key' set.",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -1285,7 +1479,9 @@ class TestBuilding(CommandTest):
|
||||||
|
|
||||||
# spawn/edit with invalid prototype
|
# spawn/edit with invalid prototype
|
||||||
msg = self.call(
|
msg = self.call(
|
||||||
building.CmdSpawn(), "/edit NO_EXISTS", "No prototype 'NO_EXISTS' was found."
|
building.CmdSpawn(),
|
||||||
|
"/edit NO_EXISTS",
|
||||||
|
"No prototype 'NO_EXISTS' was found.",
|
||||||
)
|
)
|
||||||
|
|
||||||
# spawn/examine (missing prototype)
|
# spawn/examine (missing prototype)
|
||||||
|
|
@ -1300,7 +1496,11 @@ class TestBuilding(CommandTest):
|
||||||
|
|
||||||
# spawn/examine with invalid prototype
|
# spawn/examine with invalid prototype
|
||||||
# shows error
|
# shows error
|
||||||
self.call(building.CmdSpawn(), "/examine NO_EXISTS", "No prototype 'NO_EXISTS' was found.")
|
self.call(
|
||||||
|
building.CmdSpawn(),
|
||||||
|
"/examine NO_EXISTS",
|
||||||
|
"No prototype 'NO_EXISTS' was found.",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class TestComms(CommandTest):
|
class TestComms(CommandTest):
|
||||||
|
|
|
||||||
|
|
@ -202,11 +202,11 @@ class CmdUnconnectedCreate(COMMAND_DEFAULT_CLASS):
|
||||||
# tell the caller everything went well.
|
# tell the caller everything went well.
|
||||||
string = "A new account '%s' was created. Welcome!"
|
string = "A new account '%s' was created. Welcome!"
|
||||||
if " " in username:
|
if " " in username:
|
||||||
string += (
|
string += "\n\nYou can now log in with the command 'connect \"%s\" <your password>'."
|
||||||
"\n\nYou can now log in with the command 'connect \"%s\" <your password>'."
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
string += "\n\nYou can now log with the command 'connect %s <your password>'."
|
string += (
|
||||||
|
"\n\nYou can now log with the command 'connect %s <your password>'."
|
||||||
|
)
|
||||||
session.msg(string % (username, username))
|
session.msg(string % (username, username))
|
||||||
else:
|
else:
|
||||||
session.msg("|R%s|n" % "\n".join(errors))
|
session.msg("|R%s|n" % "\n".join(errors))
|
||||||
|
|
@ -258,9 +258,13 @@ class CmdUnconnectedLook(COMMAND_DEFAULT_CLASS):
|
||||||
if "connection_screen" in callables:
|
if "connection_screen" in callables:
|
||||||
connection_screen = callables["connection_screen"]()
|
connection_screen = callables["connection_screen"]()
|
||||||
else:
|
else:
|
||||||
connection_screen = utils.random_string_from_module(CONNECTION_SCREEN_MODULE)
|
connection_screen = utils.random_string_from_module(
|
||||||
|
CONNECTION_SCREEN_MODULE
|
||||||
|
)
|
||||||
if not connection_screen:
|
if not connection_screen:
|
||||||
connection_screen = "No connection screen found. Please contact an admin."
|
connection_screen = (
|
||||||
|
"No connection screen found. Please contact an admin."
|
||||||
|
)
|
||||||
self.caller.msg(connection_screen)
|
self.caller.msg(connection_screen)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -357,7 +361,8 @@ class CmdUnconnectedEncoding(COMMAND_DEFAULT_CLASS):
|
||||||
string = ""
|
string = ""
|
||||||
if pencoding:
|
if pencoding:
|
||||||
string += (
|
string += (
|
||||||
"Default encoding: |g%s|n (change with |wencoding <encoding>|n)" % pencoding
|
"Default encoding: |g%s|n (change with |wencoding <encoding>|n)"
|
||||||
|
% pencoding
|
||||||
)
|
)
|
||||||
encodings = settings.ENCODINGS
|
encodings = settings.ENCODINGS
|
||||||
if encodings:
|
if encodings:
|
||||||
|
|
@ -380,9 +385,9 @@ class CmdUnconnectedEncoding(COMMAND_DEFAULT_CLASS):
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
self.session.protocol_flags["ENCODING"] = encoding
|
self.session.protocol_flags["ENCODING"] = encoding
|
||||||
string = "Your custom text encoding was changed from '|w%s|n' to '|w%s|n'." % (
|
string = (
|
||||||
old_encoding,
|
"Your custom text encoding was changed from '|w%s|n' to '|w%s|n'."
|
||||||
encoding,
|
% (old_encoding, encoding)
|
||||||
)
|
)
|
||||||
sync = True
|
sync = True
|
||||||
if sync:
|
if sync:
|
||||||
|
|
@ -436,7 +441,9 @@ class CmdUnconnectedInfo(COMMAND_DEFAULT_CLASS):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def _create_account(session, accountname, password, permissions, typeclass=None, email=None):
|
def _create_account(
|
||||||
|
session, accountname, password, permissions, typeclass=None, email=None
|
||||||
|
):
|
||||||
"""
|
"""
|
||||||
Helper function, creates an account of the specified typeclass.
|
Helper function, creates an account of the specified typeclass.
|
||||||
"""
|
"""
|
||||||
|
|
@ -461,7 +468,9 @@ def _create_account(session, accountname, password, permissions, typeclass=None,
|
||||||
# join the new account to the public channel
|
# join the new account to the public channel
|
||||||
pchannel = ChannelDB.objects.get_channel(settings.DEFAULT_CHANNELS[0]["key"])
|
pchannel = ChannelDB.objects.get_channel(settings.DEFAULT_CHANNELS[0]["key"])
|
||||||
if not pchannel or not pchannel.connect(new_account):
|
if not pchannel or not pchannel.connect(new_account):
|
||||||
string = "New account '%s' could not connect to public channel!" % new_account.key
|
string = (
|
||||||
|
"New account '%s' could not connect to public channel!" % new_account.key
|
||||||
|
)
|
||||||
logger.log_err(string)
|
logger.log_err(string)
|
||||||
return new_account
|
return new_account
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -99,68 +99,116 @@ class TestCmdSetMergers(TestCase):
|
||||||
a, c = self.cmdset_a, self.cmdset_c
|
a, c = self.cmdset_a, self.cmdset_c
|
||||||
cmdset_f = a + c # same-prio
|
cmdset_f = a + c # same-prio
|
||||||
self.assertEqual(len(cmdset_f.commands), 4)
|
self.assertEqual(len(cmdset_f.commands), 4)
|
||||||
self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "A"), 2)
|
self.assertEqual(
|
||||||
self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "C"), 2)
|
sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "A"), 2
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "C"), 2
|
||||||
|
)
|
||||||
cmdset_f = c + a # same-prio, inverse order
|
cmdset_f = c + a # same-prio, inverse order
|
||||||
self.assertEqual(len(cmdset_f.commands), 4)
|
self.assertEqual(len(cmdset_f.commands), 4)
|
||||||
self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "A"), 4)
|
self.assertEqual(
|
||||||
self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "C"), 0)
|
sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "A"), 4
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "C"), 0
|
||||||
|
)
|
||||||
a.priority = 1
|
a.priority = 1
|
||||||
cmdset_f = a + c # high prio A
|
cmdset_f = a + c # high prio A
|
||||||
self.assertEqual(len(cmdset_f.commands), 4)
|
self.assertEqual(len(cmdset_f.commands), 4)
|
||||||
self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "A"), 4)
|
self.assertEqual(
|
||||||
self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "C"), 0)
|
sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "A"), 4
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "C"), 0
|
||||||
|
)
|
||||||
|
|
||||||
def test_intersect(self):
|
def test_intersect(self):
|
||||||
a, c = self.cmdset_a, self.cmdset_c
|
a, c = self.cmdset_a, self.cmdset_c
|
||||||
a.mergetype = "Intersect"
|
a.mergetype = "Intersect"
|
||||||
cmdset_f = a + c # same-prio - c's Union kicks in
|
cmdset_f = a + c # same-prio - c's Union kicks in
|
||||||
self.assertEqual(len(cmdset_f.commands), 4)
|
self.assertEqual(len(cmdset_f.commands), 4)
|
||||||
self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "A"), 2)
|
self.assertEqual(
|
||||||
self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "C"), 2)
|
sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "A"), 2
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "C"), 2
|
||||||
|
)
|
||||||
cmdset_f = c + a # same-prio - a's Intersect kicks in
|
cmdset_f = c + a # same-prio - a's Intersect kicks in
|
||||||
self.assertEqual(len(cmdset_f.commands), 2)
|
self.assertEqual(len(cmdset_f.commands), 2)
|
||||||
self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "A"), 2)
|
self.assertEqual(
|
||||||
self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "C"), 0)
|
sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "A"), 2
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "C"), 0
|
||||||
|
)
|
||||||
a.priority = 1
|
a.priority = 1
|
||||||
cmdset_f = a + c # high prio A, intersect kicks in
|
cmdset_f = a + c # high prio A, intersect kicks in
|
||||||
self.assertEqual(len(cmdset_f.commands), 2)
|
self.assertEqual(len(cmdset_f.commands), 2)
|
||||||
self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "A"), 2)
|
self.assertEqual(
|
||||||
self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "C"), 0)
|
sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "A"), 2
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "C"), 0
|
||||||
|
)
|
||||||
|
|
||||||
def test_replace(self):
|
def test_replace(self):
|
||||||
a, c = self.cmdset_a, self.cmdset_c
|
a, c = self.cmdset_a, self.cmdset_c
|
||||||
c.mergetype = "Replace"
|
c.mergetype = "Replace"
|
||||||
cmdset_f = a + c # same-prio. C's Replace kicks in
|
cmdset_f = a + c # same-prio. C's Replace kicks in
|
||||||
self.assertEqual(len(cmdset_f.commands), 2)
|
self.assertEqual(len(cmdset_f.commands), 2)
|
||||||
self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "A"), 0)
|
self.assertEqual(
|
||||||
self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "C"), 2)
|
sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "A"), 0
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "C"), 2
|
||||||
|
)
|
||||||
cmdset_f = c + a # same-prio. A's Union kicks in
|
cmdset_f = c + a # same-prio. A's Union kicks in
|
||||||
self.assertEqual(len(cmdset_f.commands), 4)
|
self.assertEqual(len(cmdset_f.commands), 4)
|
||||||
self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "A"), 4)
|
self.assertEqual(
|
||||||
self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "C"), 0)
|
sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "A"), 4
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "C"), 0
|
||||||
|
)
|
||||||
c.priority = 1
|
c.priority = 1
|
||||||
cmdset_f = c + a # c higher prio. C's Replace kicks in
|
cmdset_f = c + a # c higher prio. C's Replace kicks in
|
||||||
self.assertEqual(len(cmdset_f.commands), 2)
|
self.assertEqual(len(cmdset_f.commands), 2)
|
||||||
self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "A"), 0)
|
self.assertEqual(
|
||||||
self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "C"), 2)
|
sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "A"), 0
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "C"), 2
|
||||||
|
)
|
||||||
|
|
||||||
def test_remove(self):
|
def test_remove(self):
|
||||||
a, c = self.cmdset_a, self.cmdset_c
|
a, c = self.cmdset_a, self.cmdset_c
|
||||||
c.mergetype = "Remove"
|
c.mergetype = "Remove"
|
||||||
cmdset_f = a + c # same-prio. C's Remove kicks in
|
cmdset_f = a + c # same-prio. C's Remove kicks in
|
||||||
self.assertEqual(len(cmdset_f.commands), 2)
|
self.assertEqual(len(cmdset_f.commands), 2)
|
||||||
self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "A"), 2)
|
self.assertEqual(
|
||||||
self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "C"), 0)
|
sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "A"), 2
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "C"), 0
|
||||||
|
)
|
||||||
cmdset_f = c + a # same-prio. A's Union kicks in
|
cmdset_f = c + a # same-prio. A's Union kicks in
|
||||||
self.assertEqual(len(cmdset_f.commands), 4)
|
self.assertEqual(len(cmdset_f.commands), 4)
|
||||||
self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "A"), 4)
|
self.assertEqual(
|
||||||
self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "C"), 0)
|
sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "A"), 4
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "C"), 0
|
||||||
|
)
|
||||||
c.priority = 1
|
c.priority = 1
|
||||||
cmdset_f = c + a # c higher prio. C's Remove kicks in
|
cmdset_f = c + a # c higher prio. C's Remove kicks in
|
||||||
self.assertEqual(len(cmdset_f.commands), 2)
|
self.assertEqual(len(cmdset_f.commands), 2)
|
||||||
self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "A"), 2)
|
self.assertEqual(
|
||||||
self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "C"), 0)
|
sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "A"), 2
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "C"), 0
|
||||||
|
)
|
||||||
|
|
||||||
def test_order(self):
|
def test_order(self):
|
||||||
"Merge in reverse- and forward orders, same priorities"
|
"Merge in reverse- and forward orders, same priorities"
|
||||||
|
|
@ -169,12 +217,18 @@ class TestCmdSetMergers(TestCase):
|
||||||
self.assertEqual(cmdset_f.priority, 0)
|
self.assertEqual(cmdset_f.priority, 0)
|
||||||
self.assertEqual(cmdset_f.mergetype, "Union")
|
self.assertEqual(cmdset_f.mergetype, "Union")
|
||||||
self.assertEqual(len(cmdset_f.commands), 4)
|
self.assertEqual(len(cmdset_f.commands), 4)
|
||||||
self.assertTrue(all(True for cmd in cmdset_f.commands if cmd.from_cmdset == "A"))
|
self.assertTrue(
|
||||||
|
all(True for cmd in cmdset_f.commands if cmd.from_cmdset == "A")
|
||||||
|
)
|
||||||
cmdset_f = a + b + c + d # merge in order of priority
|
cmdset_f = a + b + c + d # merge in order of priority
|
||||||
self.assertEqual(cmdset_f.priority, 0)
|
self.assertEqual(cmdset_f.priority, 0)
|
||||||
self.assertEqual(cmdset_f.mergetype, "Union")
|
self.assertEqual(cmdset_f.mergetype, "Union")
|
||||||
self.assertEqual(len(cmdset_f.commands), 4) # duplicates setting from A transfers
|
self.assertEqual(
|
||||||
self.assertTrue(all(True for cmd in cmdset_f.commands if cmd.from_cmdset == "D"))
|
len(cmdset_f.commands), 4
|
||||||
|
) # duplicates setting from A transfers
|
||||||
|
self.assertTrue(
|
||||||
|
all(True for cmd in cmdset_f.commands if cmd.from_cmdset == "D")
|
||||||
|
)
|
||||||
|
|
||||||
def test_priority_order(self):
|
def test_priority_order(self):
|
||||||
"Merge in reverse- and forward order with well-defined prioritities"
|
"Merge in reverse- and forward order with well-defined prioritities"
|
||||||
|
|
@ -187,12 +241,16 @@ class TestCmdSetMergers(TestCase):
|
||||||
self.assertEqual(cmdset_f.priority, 2)
|
self.assertEqual(cmdset_f.priority, 2)
|
||||||
self.assertEqual(cmdset_f.mergetype, "Union")
|
self.assertEqual(cmdset_f.mergetype, "Union")
|
||||||
self.assertEqual(len(cmdset_f.commands), 4)
|
self.assertEqual(len(cmdset_f.commands), 4)
|
||||||
self.assertTrue(all(True for cmd in cmdset_f.commands if cmd.from_cmdset == "A"))
|
self.assertTrue(
|
||||||
|
all(True for cmd in cmdset_f.commands if cmd.from_cmdset == "A")
|
||||||
|
)
|
||||||
cmdset_f = a + b + c + d # merge in order of priority
|
cmdset_f = a + b + c + d # merge in order of priority
|
||||||
self.assertEqual(cmdset_f.priority, 2)
|
self.assertEqual(cmdset_f.priority, 2)
|
||||||
self.assertEqual(cmdset_f.mergetype, "Union")
|
self.assertEqual(cmdset_f.mergetype, "Union")
|
||||||
self.assertEqual(len(cmdset_f.commands), 4)
|
self.assertEqual(len(cmdset_f.commands), 4)
|
||||||
self.assertTrue(all(True for cmd in cmdset_f.commands if cmd.from_cmdset == "A"))
|
self.assertTrue(
|
||||||
|
all(True for cmd in cmdset_f.commands if cmd.from_cmdset == "A")
|
||||||
|
)
|
||||||
|
|
||||||
def test_option_transfer(self):
|
def test_option_transfer(self):
|
||||||
"Test transfer of cmdset options"
|
"Test transfer of cmdset options"
|
||||||
|
|
@ -225,7 +283,9 @@ class TestCmdSetMergers(TestCase):
|
||||||
self.assertTrue(cmdset_f.no_channels)
|
self.assertTrue(cmdset_f.no_channels)
|
||||||
self.assertTrue(cmdset_f.duplicates)
|
self.assertTrue(cmdset_f.duplicates)
|
||||||
self.assertEqual(len(cmdset_f.commands), 4)
|
self.assertEqual(len(cmdset_f.commands), 4)
|
||||||
cmdset_f = a + b + c + d # forward, A top priority. This never happens in practice.
|
cmdset_f = (
|
||||||
|
a + b + c + d
|
||||||
|
) # forward, A top priority. This never happens in practice.
|
||||||
self.assertTrue(cmdset_f.no_exits)
|
self.assertTrue(cmdset_f.no_exits)
|
||||||
self.assertTrue(cmdset_f.no_objs)
|
self.assertTrue(cmdset_f.no_objs)
|
||||||
self.assertTrue(cmdset_f.no_channels)
|
self.assertTrue(cmdset_f.no_channels)
|
||||||
|
|
@ -331,7 +391,9 @@ class TestGetAndMergeCmdSets(TwistedTestCase, EvenniaTest):
|
||||||
|
|
||||||
def test_from_object(self):
|
def test_from_object(self):
|
||||||
self.set_cmdsets(self.obj1, self.cmdset_a)
|
self.set_cmdsets(self.obj1, self.cmdset_a)
|
||||||
deferred = cmdhandler.get_and_merge_cmdsets(self.obj1, None, None, self.obj1, "object", "")
|
deferred = cmdhandler.get_and_merge_cmdsets(
|
||||||
|
self.obj1, None, None, self.obj1, "object", ""
|
||||||
|
)
|
||||||
# get_and_merge_cmdsets converts to lower-case internally.
|
# get_and_merge_cmdsets converts to lower-case internally.
|
||||||
|
|
||||||
def _callback(cmdset):
|
def _callback(cmdset):
|
||||||
|
|
@ -348,7 +410,9 @@ class TestGetAndMergeCmdSets(TwistedTestCase, EvenniaTest):
|
||||||
a.no_channels = True
|
a.no_channels = True
|
||||||
self.set_cmdsets(self.obj1, a, b, c, d)
|
self.set_cmdsets(self.obj1, a, b, c, d)
|
||||||
|
|
||||||
deferred = cmdhandler.get_and_merge_cmdsets(self.obj1, None, None, self.obj1, "object", "")
|
deferred = cmdhandler.get_and_merge_cmdsets(
|
||||||
|
self.obj1, None, None, self.obj1, "object", ""
|
||||||
|
)
|
||||||
|
|
||||||
def _callback(cmdset):
|
def _callback(cmdset):
|
||||||
self.assertTrue(cmdset.no_exits)
|
self.assertTrue(cmdset.no_exits)
|
||||||
|
|
@ -363,7 +427,9 @@ class TestGetAndMergeCmdSets(TwistedTestCase, EvenniaTest):
|
||||||
from evennia.commands.default.cmdset_account import AccountCmdSet
|
from evennia.commands.default.cmdset_account import AccountCmdSet
|
||||||
from evennia.comms.channelhandler import CHANNEL_HANDLER
|
from evennia.comms.channelhandler import CHANNEL_HANDLER
|
||||||
|
|
||||||
testchannel = evennia.create_channel("channeltest", locks="listen:all();send:all()")
|
testchannel = evennia.create_channel(
|
||||||
|
"channeltest", locks="listen:all();send:all()"
|
||||||
|
)
|
||||||
CHANNEL_HANDLER.add(testchannel)
|
CHANNEL_HANDLER.add(testchannel)
|
||||||
CHANNEL_HANDLER.update()
|
CHANNEL_HANDLER.update()
|
||||||
self.assertTrue(testchannel.connect(self.account))
|
self.assertTrue(testchannel.connect(self.account))
|
||||||
|
|
@ -377,9 +443,14 @@ class TestGetAndMergeCmdSets(TwistedTestCase, EvenniaTest):
|
||||||
def _callback(cmdset):
|
def _callback(cmdset):
|
||||||
pcmdset = AccountCmdSet()
|
pcmdset = AccountCmdSet()
|
||||||
pcmdset.at_cmdset_creation()
|
pcmdset.at_cmdset_creation()
|
||||||
pcmds = [cmd.key for cmd in pcmdset.commands] + ["a", "b", "c", "d"] + ["out"]
|
pcmds = (
|
||||||
|
[cmd.key for cmd in pcmdset.commands] + ["a", "b", "c", "d"] + ["out"]
|
||||||
|
)
|
||||||
self.assertTrue(
|
self.assertTrue(
|
||||||
all(cmd.key or hasattr(cmd, "is_channel") in pcmds for cmd in cmdset.commands)
|
all(
|
||||||
|
cmd.key or hasattr(cmd, "is_channel") in pcmds
|
||||||
|
for cmd in cmdset.commands
|
||||||
|
)
|
||||||
)
|
)
|
||||||
self.assertTrue(any(hasattr(cmd, "is_channel") for cmd in cmdset.commands))
|
self.assertTrue(any(hasattr(cmd, "is_channel") for cmd in cmdset.commands))
|
||||||
|
|
||||||
|
|
@ -393,7 +464,9 @@ class TestGetAndMergeCmdSets(TwistedTestCase, EvenniaTest):
|
||||||
b.duplicates = True
|
b.duplicates = True
|
||||||
d.duplicates = True
|
d.duplicates = True
|
||||||
self.set_cmdsets(self.obj1, a, b, c, d)
|
self.set_cmdsets(self.obj1, a, b, c, d)
|
||||||
deferred = cmdhandler.get_and_merge_cmdsets(self.obj1, None, None, self.obj1, "object", "")
|
deferred = cmdhandler.get_and_merge_cmdsets(
|
||||||
|
self.obj1, None, None, self.obj1, "object", ""
|
||||||
|
)
|
||||||
|
|
||||||
def _callback(cmdset):
|
def _callback(cmdset):
|
||||||
self.assertEqual(len(cmdset.commands), 9)
|
self.assertEqual(len(cmdset.commands), 9)
|
||||||
|
|
@ -466,7 +539,9 @@ class TestCmdParser(TestCase):
|
||||||
# test prefix exclusion on the cmd class
|
# test prefix exclusion on the cmd class
|
||||||
bcmd = [cmd for cmd in a_cmdset.commands if cmd.key == "&the third command"][0]
|
bcmd = [cmd for cmd in a_cmdset.commands if cmd.key == "&the third command"][0]
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
cmdparser.build_matches("the third command", a_cmdset, include_prefixes=False),
|
cmdparser.build_matches(
|
||||||
|
"the third command", a_cmdset, include_prefixes=False
|
||||||
|
),
|
||||||
[("the third command", "", bcmd, 17, 1.0, "&the third command")],
|
[("the third command", "", bcmd, 17, 1.0, "&the third command")],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -477,7 +552,8 @@ class TestCmdParser(TestCase):
|
||||||
self.assertEqual(cmdparser.try_num_prefixes("567-look me"), ("567", "look me"))
|
self.assertEqual(cmdparser.try_num_prefixes("567-look me"), ("567", "look me"))
|
||||||
|
|
||||||
@override_settings(
|
@override_settings(
|
||||||
SEARCH_MULTIMATCH_REGEX=r"(?P<number>[0-9]+)-(?P<name>.*)", CMD_IGNORE_PREFIXES="@&/+"
|
SEARCH_MULTIMATCH_REGEX=r"(?P<number>[0-9]+)-(?P<name>.*)",
|
||||||
|
CMD_IGNORE_PREFIXES="@&/+",
|
||||||
)
|
)
|
||||||
def test_cmdparser(self):
|
def test_cmdparser(self):
|
||||||
a_cmdset = _CmdSetTest()
|
a_cmdset = _CmdSetTest()
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,9 @@ class ChannelAdmin(admin.ModelAdmin):
|
||||||
from django.http import HttpResponseRedirect
|
from django.http import HttpResponseRedirect
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
|
|
||||||
return HttpResponseRedirect(reverse("admin:comms_channeldb_change", args=[obj.id]))
|
return HttpResponseRedirect(
|
||||||
|
reverse("admin:comms_channeldb_change", args=[obj.id])
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
admin.site.register(ChannelDB, ChannelAdmin)
|
admin.site.register(ChannelDB, ChannelAdmin)
|
||||||
|
|
|
||||||
|
|
@ -129,11 +129,16 @@ class ChannelCommand(command.Command):
|
||||||
return
|
return
|
||||||
if self.history_start is not None:
|
if self.history_start is not None:
|
||||||
# Try to view history
|
# Try to view history
|
||||||
log_file = channel.attributes.get("log_file", default="channel_%s.log" % channel.key)
|
log_file = channel.attributes.get(
|
||||||
|
"log_file", default="channel_%s.log" % channel.key
|
||||||
|
)
|
||||||
|
|
||||||
def send_msg(lines):
|
def send_msg(lines):
|
||||||
return self.msg(
|
return self.msg(
|
||||||
"".join(line.split("[-]", 1)[1] if "[-]" in line else line for line in lines)
|
"".join(
|
||||||
|
line.split("[-]", 1)[1] if "[-]" in line else line
|
||||||
|
for line in lines
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
tail_log_file(log_file, self.history_start, 20, callback=send_msg)
|
tail_log_file(log_file, self.history_start, 20, callback=send_msg)
|
||||||
|
|
|
||||||
|
|
@ -301,7 +301,13 @@ class DefaultChannel(ChannelDB, metaclass=TypeclassBase):
|
||||||
CHANNELHANDLER.update()
|
CHANNELHANDLER.update()
|
||||||
|
|
||||||
def message_transform(
|
def message_transform(
|
||||||
self, msgobj, emit=False, prefix=True, sender_strings=None, external=False, **kwargs
|
self,
|
||||||
|
msgobj,
|
||||||
|
emit=False,
|
||||||
|
prefix=True,
|
||||||
|
sender_strings=None,
|
||||||
|
external=False,
|
||||||
|
**kwargs,
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
Generates the formatted string sent to listeners on a channel.
|
Generates the formatted string sent to listeners on a channel.
|
||||||
|
|
@ -355,7 +361,9 @@ class DefaultChannel(ChannelDB, metaclass=TypeclassBase):
|
||||||
# note our addition of the from_channel keyword here. This could be checked
|
# note our addition of the from_channel keyword here. This could be checked
|
||||||
# by a custom account.msg() to treat channel-receives differently.
|
# by a custom account.msg() to treat channel-receives differently.
|
||||||
entity.msg(
|
entity.msg(
|
||||||
msgobj.message, from_obj=msgobj.senders, options={"from_channel": self.id}
|
msgobj.message,
|
||||||
|
from_obj=msgobj.senders,
|
||||||
|
options={"from_channel": self.id},
|
||||||
)
|
)
|
||||||
except AttributeError as e:
|
except AttributeError as e:
|
||||||
logger.log_trace("%s\nCannot send msg to '%s'." % (e, entity))
|
logger.log_trace("%s\nCannot send msg to '%s'." % (e, entity))
|
||||||
|
|
@ -363,7 +371,8 @@ class DefaultChannel(ChannelDB, metaclass=TypeclassBase):
|
||||||
if msgobj.keep_log:
|
if msgobj.keep_log:
|
||||||
# log to file
|
# log to file
|
||||||
logger.log_file(
|
logger.log_file(
|
||||||
msgobj.message, self.attributes.get("log_file") or "channel_%s.log" % self.key
|
msgobj.message,
|
||||||
|
self.attributes.get("log_file") or "channel_%s.log" % self.key,
|
||||||
)
|
)
|
||||||
|
|
||||||
def msg(
|
def msg(
|
||||||
|
|
@ -417,7 +426,9 @@ class DefaultChannel(ChannelDB, metaclass=TypeclassBase):
|
||||||
senders = make_iter(senders) if senders else []
|
senders = make_iter(senders) if senders else []
|
||||||
if isinstance(msgobj, str):
|
if isinstance(msgobj, str):
|
||||||
# given msgobj is a string - convert to msgobject (always TempMsg)
|
# given msgobj is a string - convert to msgobject (always TempMsg)
|
||||||
msgobj = TempMsg(senders=senders, header=header, message=msgobj, channels=[self])
|
msgobj = TempMsg(
|
||||||
|
senders=senders, header=header, message=msgobj, channels=[self]
|
||||||
|
)
|
||||||
# we store the logging setting for use in distribute_message()
|
# we store the logging setting for use in distribute_message()
|
||||||
msgobj.keep_log = keep_log if keep_log is not None else self.db.keep_log
|
msgobj.keep_log = keep_log if keep_log is not None else self.db.keep_log
|
||||||
|
|
||||||
|
|
@ -678,7 +689,8 @@ class DefaultChannel(ChannelDB, metaclass=TypeclassBase):
|
||||||
"""
|
"""
|
||||||
content_type = ContentType.objects.get_for_model(self.__class__)
|
content_type = ContentType.objects.get_for_model(self.__class__)
|
||||||
return reverse(
|
return reverse(
|
||||||
"admin:%s_%s_change" % (content_type.app_label, content_type.model), args=(self.id,)
|
"admin:%s_%s_change" % (content_type.app_label, content_type.model),
|
||||||
|
args=(self.id,),
|
||||||
)
|
)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|
|
||||||
|
|
@ -205,24 +205,30 @@ class MsgManager(TypedObjectManager):
|
||||||
# explicitly exclude channel recipients
|
# explicitly exclude channel recipients
|
||||||
if typ == "account":
|
if typ == "account":
|
||||||
return list(
|
return list(
|
||||||
self.filter(db_sender_accounts=obj, db_receivers_channels__isnull=True).exclude(
|
self.filter(
|
||||||
db_hide_from_accounts=obj
|
db_sender_accounts=obj, db_receivers_channels__isnull=True
|
||||||
)
|
).exclude(db_hide_from_accounts=obj)
|
||||||
)
|
)
|
||||||
elif typ == "object":
|
elif typ == "object":
|
||||||
return list(
|
return list(
|
||||||
self.filter(db_sender_objects=obj, db_receivers_channels__isnull=True).exclude(
|
self.filter(
|
||||||
db_hide_from_objects=obj
|
db_sender_objects=obj, db_receivers_channels__isnull=True
|
||||||
)
|
).exclude(db_hide_from_objects=obj)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
raise CommError
|
raise CommError
|
||||||
else:
|
else:
|
||||||
# get everything, channel or not
|
# get everything, channel or not
|
||||||
if typ == "account":
|
if typ == "account":
|
||||||
return list(self.filter(db_sender_accounts=obj).exclude(db_hide_from_accounts=obj))
|
return list(
|
||||||
|
self.filter(db_sender_accounts=obj).exclude(
|
||||||
|
db_hide_from_accounts=obj
|
||||||
|
)
|
||||||
|
)
|
||||||
elif typ == "object":
|
elif typ == "object":
|
||||||
return list(self.filter(db_sender_objects=obj).exclude(db_hide_from_objects=obj))
|
return list(
|
||||||
|
self.filter(db_sender_objects=obj).exclude(db_hide_from_objects=obj)
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
raise CommError
|
raise CommError
|
||||||
|
|
||||||
|
|
@ -242,11 +248,21 @@ class MsgManager(TypedObjectManager):
|
||||||
"""
|
"""
|
||||||
obj, typ = identify_object(recipient)
|
obj, typ = identify_object(recipient)
|
||||||
if typ == "account":
|
if typ == "account":
|
||||||
return list(self.filter(db_receivers_accounts=obj).exclude(db_hide_from_accounts=obj))
|
return list(
|
||||||
|
self.filter(db_receivers_accounts=obj).exclude(
|
||||||
|
db_hide_from_accounts=obj
|
||||||
|
)
|
||||||
|
)
|
||||||
elif typ == "object":
|
elif typ == "object":
|
||||||
return list(self.filter(db_receivers_objects=obj).exclude(db_hide_from_objects=obj))
|
return list(
|
||||||
|
self.filter(db_receivers_objects=obj).exclude(db_hide_from_objects=obj)
|
||||||
|
)
|
||||||
elif typ == "channel":
|
elif typ == "channel":
|
||||||
return list(self.filter(db_receivers_channels=obj).exclude(db_hide_from_channels=obj))
|
return list(
|
||||||
|
self.filter(db_receivers_channels=obj).exclude(
|
||||||
|
db_hide_from_channels=obj
|
||||||
|
)
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
raise CommError
|
raise CommError
|
||||||
|
|
||||||
|
|
@ -261,7 +277,9 @@ class MsgManager(TypedObjectManager):
|
||||||
messages (list): Persistent Msg objects saved for this channel.
|
messages (list): Persistent Msg objects saved for this channel.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.filter(db_receivers_channels=channel).exclude(db_hide_from_channels=channel)
|
return self.filter(db_receivers_channels=channel).exclude(
|
||||||
|
db_hide_from_channels=channel
|
||||||
|
)
|
||||||
|
|
||||||
def search_message(self, sender=None, receiver=None, freetext=None, dbref=None):
|
def search_message(self, sender=None, receiver=None, freetext=None, dbref=None):
|
||||||
"""
|
"""
|
||||||
|
|
@ -297,9 +315,13 @@ class MsgManager(TypedObjectManager):
|
||||||
# filter by sender
|
# filter by sender
|
||||||
sender, styp = identify_object(sender)
|
sender, styp = identify_object(sender)
|
||||||
if styp == "account":
|
if styp == "account":
|
||||||
sender_restrict = Q(db_sender_accounts=sender) & ~Q(db_hide_from_accounts=sender)
|
sender_restrict = Q(db_sender_accounts=sender) & ~Q(
|
||||||
|
db_hide_from_accounts=sender
|
||||||
|
)
|
||||||
elif styp == "object":
|
elif styp == "object":
|
||||||
sender_restrict = Q(db_sender_objects=sender) & ~Q(db_hide_from_objects=sender)
|
sender_restrict = Q(db_sender_objects=sender) & ~Q(
|
||||||
|
db_hide_from_objects=sender
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
sender_restrict = Q()
|
sender_restrict = Q()
|
||||||
# filter by receiver
|
# filter by receiver
|
||||||
|
|
@ -309,7 +331,9 @@ class MsgManager(TypedObjectManager):
|
||||||
db_hide_from_accounts=receiver
|
db_hide_from_accounts=receiver
|
||||||
)
|
)
|
||||||
elif rtyp == "object":
|
elif rtyp == "object":
|
||||||
receiver_restrict = Q(db_receivers_objects=receiver) & ~Q(db_hide_from_objects=receiver)
|
receiver_restrict = Q(db_receivers_objects=receiver) & ~Q(
|
||||||
|
db_hide_from_objects=receiver
|
||||||
|
)
|
||||||
elif rtyp == "channel":
|
elif rtyp == "channel":
|
||||||
receiver_restrict = Q(db_receivers_channels=receiver) & ~Q(
|
receiver_restrict = Q(db_receivers_channels=receiver) & ~Q(
|
||||||
db_hide_from_channels=receiver
|
db_hide_from_channels=receiver
|
||||||
|
|
@ -318,11 +342,15 @@ class MsgManager(TypedObjectManager):
|
||||||
receiver_restrict = Q()
|
receiver_restrict = Q()
|
||||||
# filter by full text
|
# filter by full text
|
||||||
if freetext:
|
if freetext:
|
||||||
fulltext_restrict = Q(db_header__icontains=freetext) | Q(db_message__icontains=freetext)
|
fulltext_restrict = Q(db_header__icontains=freetext) | Q(
|
||||||
|
db_message__icontains=freetext
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
fulltext_restrict = Q()
|
fulltext_restrict = Q()
|
||||||
# execute the query
|
# execute the query
|
||||||
return list(self.filter(sender_restrict & receiver_restrict & fulltext_restrict))
|
return list(
|
||||||
|
self.filter(sender_restrict & receiver_restrict & fulltext_restrict)
|
||||||
|
)
|
||||||
|
|
||||||
# back-compatibility alias
|
# back-compatibility alias
|
||||||
message_search = search_message
|
message_search = search_message
|
||||||
|
|
@ -419,12 +447,17 @@ class ChannelDBManager(TypedObjectManager):
|
||||||
if exact:
|
if exact:
|
||||||
channels = self.filter(
|
channels = self.filter(
|
||||||
Q(db_key__iexact=ostring)
|
Q(db_key__iexact=ostring)
|
||||||
| Q(db_tags__db_tagtype__iexact="alias", db_tags__db_key__iexact=ostring)
|
| Q(
|
||||||
|
db_tags__db_tagtype__iexact="alias", db_tags__db_key__iexact=ostring
|
||||||
|
)
|
||||||
).distinct()
|
).distinct()
|
||||||
else:
|
else:
|
||||||
channels = self.filter(
|
channels = self.filter(
|
||||||
Q(db_key__icontains=ostring)
|
Q(db_key__icontains=ostring)
|
||||||
| Q(db_tags__db_tagtype__iexact="alias", db_tags__db_key__icontains=ostring)
|
| Q(
|
||||||
|
db_tags__db_tagtype__iexact="alias",
|
||||||
|
db_tags__db_key__icontains=ostring,
|
||||||
|
)
|
||||||
).distinct()
|
).distinct()
|
||||||
return channels
|
return channels
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,10 +15,16 @@ class Migration(migrations.Migration):
|
||||||
(
|
(
|
||||||
"id",
|
"id",
|
||||||
models.AutoField(
|
models.AutoField(
|
||||||
verbose_name="ID", serialize=False, auto_created=True, primary_key=True
|
verbose_name="ID",
|
||||||
|
serialize=False,
|
||||||
|
auto_created=True,
|
||||||
|
primary_key=True,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
("db_key", models.CharField(max_length=255, verbose_name="key", db_index=True)),
|
(
|
||||||
|
"db_key",
|
||||||
|
models.CharField(max_length=255, verbose_name="key", db_index=True),
|
||||||
|
),
|
||||||
(
|
(
|
||||||
"db_typeclass_path",
|
"db_typeclass_path",
|
||||||
models.CharField(
|
models.CharField(
|
||||||
|
|
@ -30,7 +36,9 @@ class Migration(migrations.Migration):
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"db_date_created",
|
"db_date_created",
|
||||||
models.DateTimeField(auto_now_add=True, verbose_name="creation date"),
|
models.DateTimeField(
|
||||||
|
auto_now_add=True, verbose_name="creation date"
|
||||||
|
),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"db_lock_storage",
|
"db_lock_storage",
|
||||||
|
|
@ -50,7 +58,10 @@ class Migration(migrations.Migration):
|
||||||
(
|
(
|
||||||
"id",
|
"id",
|
||||||
models.AutoField(
|
models.AutoField(
|
||||||
verbose_name="ID", serialize=False, auto_created=True, primary_key=True
|
verbose_name="ID",
|
||||||
|
serialize=False,
|
||||||
|
auto_created=True,
|
||||||
|
primary_key=True,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
|
|
@ -63,7 +74,10 @@ class Migration(migrations.Migration):
|
||||||
db_index=True,
|
db_index=True,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
("db_header", models.TextField(null=True, verbose_name="header", blank=True)),
|
(
|
||||||
|
"db_header",
|
||||||
|
models.TextField(null=True, verbose_name="header", blank=True),
|
||||||
|
),
|
||||||
("db_message", models.TextField(verbose_name="messsage")),
|
("db_message", models.TextField(verbose_name="messsage")),
|
||||||
(
|
(
|
||||||
"db_date_sent",
|
"db_date_sent",
|
||||||
|
|
@ -74,13 +88,17 @@ class Migration(migrations.Migration):
|
||||||
(
|
(
|
||||||
"db_lock_storage",
|
"db_lock_storage",
|
||||||
models.TextField(
|
models.TextField(
|
||||||
help_text="access locks on this message.", verbose_name="locks", blank=True
|
help_text="access locks on this message.",
|
||||||
|
verbose_name="locks",
|
||||||
|
blank=True,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"db_hide_from_channels",
|
"db_hide_from_channels",
|
||||||
models.ManyToManyField(
|
models.ManyToManyField(
|
||||||
related_name="hide_from_channels_set", null=True, to="comms.ChannelDB"
|
related_name="hide_from_channels_set",
|
||||||
|
null=True,
|
||||||
|
to="comms.ChannelDB",
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,9 @@ class Migration(migrations.Migration):
|
||||||
model_name="msg",
|
model_name="msg",
|
||||||
name="db_hide_from_accounts",
|
name="db_hide_from_accounts",
|
||||||
field=models.ManyToManyField(
|
field=models.ManyToManyField(
|
||||||
related_name="hide_from_accounts_set", null=True, to=settings.AUTH_USER_MODEL
|
related_name="hide_from_accounts_set",
|
||||||
|
null=True,
|
||||||
|
to=settings.AUTH_USER_MODEL,
|
||||||
),
|
),
|
||||||
preserve_default=True,
|
preserve_default=True,
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,9 @@ from django.db import models, migrations
|
||||||
|
|
||||||
def convert_defaults(apps, schema_editor):
|
def convert_defaults(apps, schema_editor):
|
||||||
ChannelDB = apps.get_model("comms", "ChannelDB")
|
ChannelDB = apps.get_model("comms", "ChannelDB")
|
||||||
for channel in ChannelDB.objects.filter(db_typeclass_path="src.comms.comms.Channel"):
|
for channel in ChannelDB.objects.filter(
|
||||||
|
db_typeclass_path="src.comms.comms.Channel"
|
||||||
|
):
|
||||||
channel.db_typeclass_path = "typeclasses.channels.Channel"
|
channel.db_typeclass_path = "typeclasses.channels.Channel"
|
||||||
channel.save()
|
channel.save()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,10 @@ from django.db import models, migrations
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [("objects", "0004_auto_20150118_1622"), ("comms", "0005_auto_20150223_1517")]
|
dependencies = [
|
||||||
|
("objects", "0004_auto_20150118_1622"),
|
||||||
|
("comms", "0005_auto_20150223_1517"),
|
||||||
|
]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
|
|
|
||||||
|
|
@ -15,14 +15,20 @@ class Migration(migrations.Migration):
|
||||||
model_name="msg",
|
model_name="msg",
|
||||||
name="db_hide_from_channels",
|
name="db_hide_from_channels",
|
||||||
field=models.ManyToManyField(
|
field=models.ManyToManyField(
|
||||||
blank=True, null=True, related_name="hide_from_channels_set", to="comms.ChannelDB"
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
related_name="hide_from_channels_set",
|
||||||
|
to="comms.ChannelDB",
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name="msg",
|
model_name="msg",
|
||||||
name="db_hide_from_objects",
|
name="db_hide_from_objects",
|
||||||
field=models.ManyToManyField(
|
field=models.ManyToManyField(
|
||||||
blank=True, null=True, related_name="hide_from_objects_set", to="objects.ObjectDB"
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
related_name="hide_from_objects_set",
|
||||||
|
to="objects.ObjectDB",
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,10 @@ from django.db import migrations, models
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [("scripts", "0007_auto_20150403_2339"), ("comms", "0010_auto_20161206_1912")]
|
dependencies = [
|
||||||
|
("scripts", "0007_auto_20150403_2339"),
|
||||||
|
("comms", "0010_auto_20161206_1912"),
|
||||||
|
]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,9 @@ class Migration(migrations.Migration):
|
||||||
model_name="msg",
|
model_name="msg",
|
||||||
name="db_hide_from_accounts",
|
name="db_hide_from_accounts",
|
||||||
field=models.ManyToManyField(
|
field=models.ManyToManyField(
|
||||||
blank=True, related_name="hide_from_accounts_set", to=settings.AUTH_USER_MODEL
|
blank=True,
|
||||||
|
related_name="hide_from_accounts_set",
|
||||||
|
to=settings.AUTH_USER_MODEL,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,9 @@ from django.db import migrations
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [("comms", "0011_auto_20170606_1731"), ("comms", "0011_auto_20170217_2039")]
|
dependencies = [
|
||||||
|
("comms", "0011_auto_20170606_1731"),
|
||||||
|
("comms", "0011_auto_20170217_2039"),
|
||||||
|
]
|
||||||
|
|
||||||
operations = []
|
operations = []
|
||||||
|
|
|
||||||
|
|
@ -116,7 +116,9 @@ class Migration(migrations.Migration):
|
||||||
model_name="msg",
|
model_name="msg",
|
||||||
name="db_hide_from_accounts",
|
name="db_hide_from_accounts",
|
||||||
field=models.ManyToManyField(
|
field=models.ManyToManyField(
|
||||||
blank=True, related_name="hide_from_accounts_set", to="accounts.AccountDB"
|
blank=True,
|
||||||
|
related_name="hide_from_accounts_set",
|
||||||
|
to="accounts.AccountDB",
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,8 @@ class Migration(migrations.Migration):
|
||||||
operations = [
|
operations = [
|
||||||
migrations.RemoveField(model_name="channeldb", name="db_subscriptions"),
|
migrations.RemoveField(model_name="channeldb", name="db_subscriptions"),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name="msg", name="db_message", field=models.TextField(verbose_name="message")
|
model_name="msg",
|
||||||
|
name="db_message",
|
||||||
|
field=models.TextField(verbose_name="message"),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -80,7 +80,9 @@ class Migration(migrations.Migration):
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name="msg",
|
model_name="msg",
|
||||||
name="db_date_created",
|
name="db_date_created",
|
||||||
field=models.DateTimeField(auto_now_add=True, db_index=True, verbose_name="date sent"),
|
field=models.DateTimeField(
|
||||||
|
auto_now_add=True, db_index=True, verbose_name="date sent"
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name="msg",
|
model_name="msg",
|
||||||
|
|
@ -91,11 +93,15 @@ class Migration(migrations.Migration):
|
||||||
model_name="msg",
|
model_name="msg",
|
||||||
name="db_lock_storage",
|
name="db_lock_storage",
|
||||||
field=models.TextField(
|
field=models.TextField(
|
||||||
blank=True, help_text="access locks on this message.", verbose_name="locks"
|
blank=True,
|
||||||
|
help_text="access locks on this message.",
|
||||||
|
verbose_name="locks",
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name="msg", name="db_message", field=models.TextField(verbose_name="message")
|
model_name="msg",
|
||||||
|
name="db_message",
|
||||||
|
field=models.TextField(verbose_name="message"),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name="msg",
|
model_name="msg",
|
||||||
|
|
|
||||||
|
|
@ -5,14 +5,18 @@ from django.db import migrations, models
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("comms", "0017_auto_20190128_1820")]
|
||||||
('comms', '0017_auto_20190128_1820'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='channeldb',
|
model_name="channeldb",
|
||||||
name='db_typeclass_path',
|
name="db_typeclass_path",
|
||||||
field=models.CharField(db_index=True, help_text="this defines what 'type' of entity this is. This variable holds a Python path to a module with a valid Evennia Typeclass.", max_length=255, null=True, verbose_name='typeclass'),
|
field=models.CharField(
|
||||||
|
db_index=True,
|
||||||
|
help_text="this defines what 'type' of entity this is. This variable holds a Python path to a module with a valid Evennia Typeclass.",
|
||||||
|
max_length=255,
|
||||||
|
null=True,
|
||||||
|
verbose_name="typeclass",
|
||||||
),
|
),
|
||||||
|
)
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -134,7 +134,10 @@ class Msg(SharedMemoryModel):
|
||||||
help_text="script_receivers",
|
help_text="script_receivers",
|
||||||
)
|
)
|
||||||
db_receivers_channels = models.ManyToManyField(
|
db_receivers_channels = models.ManyToManyField(
|
||||||
"ChannelDB", related_name="channel_set", blank=True, help_text="channel recievers"
|
"ChannelDB",
|
||||||
|
related_name="channel_set",
|
||||||
|
blank=True,
|
||||||
|
help_text="channel recievers",
|
||||||
)
|
)
|
||||||
|
|
||||||
# header could be used for meta-info about the message if your system needs
|
# header could be used for meta-info about the message if your system needs
|
||||||
|
|
@ -400,10 +403,11 @@ class Msg(SharedMemoryModel):
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
"This handles what is shown when e.g. printing the message"
|
"This handles what is shown when e.g. printing the message"
|
||||||
senders = ",".join(getattr(obj, 'key', str(obj)) for obj in self.senders)
|
senders = ",".join(getattr(obj, "key", str(obj)) for obj in self.senders)
|
||||||
|
|
||||||
receivers = ",".join(
|
receivers = ",".join(
|
||||||
["[%s]" % getattr(obj, 'key', str(obj)) for obj in self.channels] + [getattr(obj, 'key', str(obj)) for obj in self.receivers]
|
["[%s]" % getattr(obj, "key", str(obj)) for obj in self.channels]
|
||||||
|
+ [getattr(obj, "key", str(obj)) for obj in self.receivers]
|
||||||
)
|
)
|
||||||
return "%s->%s: %s" % (senders, receivers, crop(self.message, width=40))
|
return "%s->%s: %s" % (senders, receivers, crop(self.message, width=40))
|
||||||
|
|
||||||
|
|
@ -483,7 +487,8 @@ class TempMsg(object):
|
||||||
"""
|
"""
|
||||||
senders = ",".join(obj.key for obj in self.senders)
|
senders = ",".join(obj.key for obj in self.senders)
|
||||||
receivers = ",".join(
|
receivers = ",".join(
|
||||||
["[%s]" % obj.key for obj in self.channels] + [obj.key for obj in self.receivers]
|
["[%s]" % obj.key for obj in self.channels]
|
||||||
|
+ [obj.key for obj in self.receivers]
|
||||||
)
|
)
|
||||||
return "%s->%s: %s" % (senders, receivers, crop(self.message, width=40))
|
return "%s->%s: %s" % (senders, receivers, crop(self.message, width=40))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,6 @@ class ObjectCreationTest(EvenniaTest):
|
||||||
self.assertEqual(description, obj.db.desc)
|
self.assertEqual(description, obj.db.desc)
|
||||||
|
|
||||||
def test_message_create(self):
|
def test_message_create(self):
|
||||||
msg = create_message('peewee herman', 'heh-heh!', header='mail time!')
|
msg = create_message("peewee herman", "heh-heh!", header="mail time!")
|
||||||
self.assertTrue(msg)
|
self.assertTrue(msg)
|
||||||
self.assertEqual(str(msg), 'peewee herman->: heh-heh!')
|
self.assertEqual(str(msg), "peewee herman->: heh-heh!")
|
||||||
|
|
|
||||||
|
|
@ -414,9 +414,13 @@ class CmdTradeBase(Command):
|
||||||
self.args, self.emote = [part.strip() for part in self.args.rsplit(":", 1)]
|
self.args, self.emote = [part.strip() for part in self.args.rsplit(":", 1)]
|
||||||
self.str_caller = 'You say, "' + self.emote + '"\n [%s]'
|
self.str_caller = 'You say, "' + self.emote + '"\n [%s]'
|
||||||
if self.caller.has_account:
|
if self.caller.has_account:
|
||||||
self.str_other = '|c%s|n says, "' % self.caller.key + self.emote + '"\n [%s]'
|
self.str_other = (
|
||||||
|
'|c%s|n says, "' % self.caller.key + self.emote + '"\n [%s]'
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
self.str_other = '%s says, "' % self.caller.key + self.emote + '"\n [%s]'
|
self.str_other = (
|
||||||
|
'%s says, "' % self.caller.key + self.emote + '"\n [%s]'
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# trade help
|
# trade help
|
||||||
|
|
@ -566,7 +570,9 @@ class CmdAccept(CmdTradeBase):
|
||||||
)
|
)
|
||||||
self.msg_other(
|
self.msg_other(
|
||||||
caller,
|
caller,
|
||||||
self.str_other % "%s |Gaccepts|n the offer. You must now also accept." % caller.key,
|
self.str_other
|
||||||
|
% "%s |Gaccepts|n the offer. You must now also accept."
|
||||||
|
% caller.key,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -602,7 +608,10 @@ class CmdDecline(CmdTradeBase):
|
||||||
return
|
return
|
||||||
if self.tradehandler.decline(self.caller):
|
if self.tradehandler.decline(self.caller):
|
||||||
# changed a previous accept
|
# changed a previous accept
|
||||||
caller.msg(self.str_caller % "You change your mind, |Rdeclining|n the current offer.")
|
caller.msg(
|
||||||
|
self.str_caller
|
||||||
|
% "You change your mind, |Rdeclining|n the current offer."
|
||||||
|
)
|
||||||
self.msg_other(
|
self.msg_other(
|
||||||
caller,
|
caller,
|
||||||
self.str_other
|
self.str_other
|
||||||
|
|
@ -612,7 +621,9 @@ class CmdDecline(CmdTradeBase):
|
||||||
else:
|
else:
|
||||||
# no acceptance to change
|
# no acceptance to change
|
||||||
caller.msg(self.str_caller % "You |Rdecline|n the current offer.")
|
caller.msg(self.str_caller % "You |Rdecline|n the current offer.")
|
||||||
self.msg_other(caller, self.str_other % "%s declines the current offer." % caller.key)
|
self.msg_other(
|
||||||
|
caller, self.str_other % "%s declines the current offer." % caller.key
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# evaluate
|
# evaluate
|
||||||
|
|
@ -746,7 +757,8 @@ class CmdFinish(CmdTradeBase):
|
||||||
self.tradehandler.finish(force=True)
|
self.tradehandler.finish(force=True)
|
||||||
caller.msg(self.str_caller % "You |raborted|n trade. No deal was made.")
|
caller.msg(self.str_caller % "You |raborted|n trade. No deal was made.")
|
||||||
self.msg_other(
|
self.msg_other(
|
||||||
caller, self.str_other % "%s |raborted|n trade. No deal was made." % caller.key
|
caller,
|
||||||
|
self.str_other % "%s |raborted|n trade. No deal was made." % caller.key,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -802,8 +814,13 @@ class CmdTrade(Command):
|
||||||
"""Initiate trade"""
|
"""Initiate trade"""
|
||||||
|
|
||||||
if not self.args:
|
if not self.args:
|
||||||
if self.caller.ndb.tradehandler and self.caller.ndb.tradeevent.trade_started:
|
if (
|
||||||
self.caller.msg("You are already in a trade. Use 'end trade' to abort it.")
|
self.caller.ndb.tradehandler
|
||||||
|
and self.caller.ndb.tradeevent.trade_started
|
||||||
|
):
|
||||||
|
self.caller.msg(
|
||||||
|
"You are already in a trade. Use 'end trade' to abort it."
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
self.caller.msg("Usage: trade <other party> [accept|decline] [:emote]")
|
self.caller.msg("Usage: trade <other party> [accept|decline] [:emote]")
|
||||||
return
|
return
|
||||||
|
|
@ -852,7 +869,9 @@ class CmdTrade(Command):
|
||||||
if self.caller.ndb.tradehandler:
|
if self.caller.ndb.tradehandler:
|
||||||
# trying to start trade without stopping a previous one
|
# trying to start trade without stopping a previous one
|
||||||
if self.caller.ndb.tradehandler.trade_started:
|
if self.caller.ndb.tradehandler.trade_started:
|
||||||
string = "You are already in trade with %s. You need to end trade first."
|
string = (
|
||||||
|
"You are already in trade with %s. You need to end trade first."
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
string = "You are already trying to initiate trade with %s. You need to decline that trade first."
|
string = "You are already trying to initiate trade with %s. You need to decline that trade first."
|
||||||
self.caller.msg(string % part_b.key)
|
self.caller.msg(string % part_b.key)
|
||||||
|
|
@ -865,7 +884,9 @@ class CmdTrade(Command):
|
||||||
# initiate a new trade
|
# initiate a new trade
|
||||||
TradeHandler(part_a, part_b)
|
TradeHandler(part_a, part_b)
|
||||||
part_a.msg(selfemote + str_init_a % (part_b.key, TRADE_TIMEOUT))
|
part_a.msg(selfemote + str_init_a % (part_b.key, TRADE_TIMEOUT))
|
||||||
part_b.msg(theiremote + str_init_b % (part_a.key, part_a.key, TRADE_TIMEOUT))
|
part_b.msg(
|
||||||
|
theiremote + str_init_b % (part_a.key, part_a.key, TRADE_TIMEOUT)
|
||||||
|
)
|
||||||
part_a.scripts.add(TradeTimeout)
|
part_a.scripts.add(TradeTimeout)
|
||||||
return
|
return
|
||||||
elif accept:
|
elif accept:
|
||||||
|
|
@ -873,7 +894,8 @@ class CmdTrade(Command):
|
||||||
if part_a.ndb.tradehandler:
|
if part_a.ndb.tradehandler:
|
||||||
# already in a trade
|
# already in a trade
|
||||||
part_a.msg(
|
part_a.msg(
|
||||||
"You are already in trade with %s. You need to end that first." % part_b.key
|
"You are already in trade with %s. You need to end that first."
|
||||||
|
% part_b.key
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
if part_b.ndb.tradehandler.join(part_a):
|
if part_b.ndb.tradehandler.join(part_a):
|
||||||
|
|
@ -888,7 +910,9 @@ class CmdTrade(Command):
|
||||||
# stopping an invite
|
# stopping an invite
|
||||||
part_a.ndb.tradehandler.finish(force=True)
|
part_a.ndb.tradehandler.finish(force=True)
|
||||||
part_b.msg(theiremote + "%s aborted trade attempt with you." % part_a)
|
part_b.msg(theiremote + "%s aborted trade attempt with you." % part_a)
|
||||||
part_a.msg(selfemote + "You aborted the trade attempt with %s." % part_b)
|
part_a.msg(
|
||||||
|
selfemote + "You aborted the trade attempt with %s." % part_b
|
||||||
|
)
|
||||||
elif part_b.ndb.tradehandler and part_b.ndb.tradehandler.unjoin(part_a):
|
elif part_b.ndb.tradehandler and part_b.ndb.tradehandler.unjoin(part_a):
|
||||||
part_b.msg(theiremote + str_noinit_a % part_a.key)
|
part_b.msg(theiremote + str_noinit_a % part_a.key)
|
||||||
part_a.msg(selfemote + str_noinit_b % part_b.key)
|
part_a.msg(selfemote + str_noinit_b % part_b.key)
|
||||||
|
|
|
||||||
|
|
@ -162,7 +162,9 @@ def _menu_savefunc(caller, buf):
|
||||||
def _menu_quitfunc(caller):
|
def _menu_quitfunc(caller):
|
||||||
caller.cmdset.add(
|
caller.cmdset.add(
|
||||||
BuildingMenuCmdSet,
|
BuildingMenuCmdSet,
|
||||||
permanent=caller.ndb._building_menu and caller.ndb._building_menu.persistent or False,
|
permanent=caller.ndb._building_menu
|
||||||
|
and caller.ndb._building_menu.persistent
|
||||||
|
or False,
|
||||||
)
|
)
|
||||||
if caller.ndb._building_menu:
|
if caller.ndb._building_menu:
|
||||||
caller.ndb._building_menu.move(back=True)
|
caller.ndb._building_menu.move(back=True)
|
||||||
|
|
@ -209,7 +211,9 @@ def _call_or_get(value, menu=None, choice=None, string=None, obj=None, caller=No
|
||||||
spec = getargspec(value)
|
spec = getargspec(value)
|
||||||
args = spec.args
|
args = spec.args
|
||||||
if spec.keywords:
|
if spec.keywords:
|
||||||
kwargs.update(dict(menu=menu, choice=choice, string=string, obj=obj, caller=caller))
|
kwargs.update(
|
||||||
|
dict(menu=menu, choice=choice, string=string, obj=obj, caller=caller)
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
if "menu" in args:
|
if "menu" in args:
|
||||||
kwargs["menu"] = menu
|
kwargs["menu"] = menu
|
||||||
|
|
@ -343,7 +347,9 @@ class CmdNoInput(Command):
|
||||||
self.menu.display()
|
self.menu.display()
|
||||||
else:
|
else:
|
||||||
log_err("When CMDNOINPUT was called, the building menu couldn't be found")
|
log_err("When CMDNOINPUT was called, the building menu couldn't be found")
|
||||||
self.caller.msg("|rThe building menu couldn't be found, remove the CmdSet.|n")
|
self.caller.msg(
|
||||||
|
"|rThe building menu couldn't be found, remove the CmdSet.|n"
|
||||||
|
)
|
||||||
self.caller.cmdset.delete(BuildingMenuCmdSet)
|
self.caller.cmdset.delete(BuildingMenuCmdSet)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -363,7 +369,9 @@ class CmdNoMatch(Command):
|
||||||
raw_string = self.args.rstrip()
|
raw_string = self.args.rstrip()
|
||||||
if self.menu is None:
|
if self.menu is None:
|
||||||
log_err("When CMDNOMATCH was called, the building menu couldn't be found")
|
log_err("When CMDNOMATCH was called, the building menu couldn't be found")
|
||||||
self.caller.msg("|rThe building menu couldn't be found, remove the CmdSet.|n")
|
self.caller.msg(
|
||||||
|
"|rThe building menu couldn't be found, remove the CmdSet.|n"
|
||||||
|
)
|
||||||
self.caller.cmdset.delete(BuildingMenuCmdSet)
|
self.caller.cmdset.delete(BuildingMenuCmdSet)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
@ -485,7 +493,12 @@ class Choice(object):
|
||||||
text = ""
|
text = ""
|
||||||
if self.text:
|
if self.text:
|
||||||
text = _call_or_get(
|
text = _call_or_get(
|
||||||
self.text, menu=self.menu, choice=self, string="", caller=self.caller, obj=self.obj
|
self.text,
|
||||||
|
menu=self.menu,
|
||||||
|
choice=self,
|
||||||
|
string="",
|
||||||
|
caller=self.caller,
|
||||||
|
obj=self.obj,
|
||||||
)
|
)
|
||||||
text = dedent(text.strip("\n"))
|
text = dedent(text.strip("\n"))
|
||||||
text = text.format(obj=self.obj, caller=self.caller)
|
text = text.format(obj=self.obj, caller=self.caller)
|
||||||
|
|
@ -849,7 +862,9 @@ class BuildingMenu(object):
|
||||||
|
|
||||||
Current value: |c{{{obj_attr}}}|n
|
Current value: |c{{{obj_attr}}}|n
|
||||||
""".format(
|
""".format(
|
||||||
attr=attr, obj_attr="obj." + attr, back="|n or |y".join(self.keys_go_back)
|
attr=attr,
|
||||||
|
obj_attr="obj." + attr,
|
||||||
|
back="|n or |y".join(self.keys_go_back),
|
||||||
)
|
)
|
||||||
|
|
||||||
choice = Choice(
|
choice = Choice(
|
||||||
|
|
@ -908,10 +923,18 @@ class BuildingMenu(object):
|
||||||
"""
|
"""
|
||||||
on_enter = on_enter or menu_edit
|
on_enter = on_enter or menu_edit
|
||||||
return self.add_choice(
|
return self.add_choice(
|
||||||
title, key=key, aliases=aliases, attr=attr, glance=glance, on_enter=on_enter, text=""
|
title,
|
||||||
|
key=key,
|
||||||
|
aliases=aliases,
|
||||||
|
attr=attr,
|
||||||
|
glance=glance,
|
||||||
|
on_enter=on_enter,
|
||||||
|
text="",
|
||||||
)
|
)
|
||||||
|
|
||||||
def add_choice_quit(self, title="quit the menu", key="q", aliases=None, on_enter=None):
|
def add_choice_quit(
|
||||||
|
self, title="quit the menu", key="q", aliases=None, on_enter=None
|
||||||
|
):
|
||||||
"""
|
"""
|
||||||
Add a simple choice just to quit the building menu.
|
Add a simple choice just to quit the building menu.
|
||||||
|
|
||||||
|
|
@ -975,7 +998,9 @@ class BuildingMenu(object):
|
||||||
menu_class = class_from_module(parent_class)
|
menu_class = class_from_module(parent_class)
|
||||||
except Exception:
|
except Exception:
|
||||||
log_trace(
|
log_trace(
|
||||||
"BuildingMenu: attempting to load class {} failed".format(repr(parent_class))
|
"BuildingMenu: attempting to load class {} failed".format(
|
||||||
|
repr(parent_class)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
@ -986,7 +1011,9 @@ class BuildingMenu(object):
|
||||||
)
|
)
|
||||||
except Exception:
|
except Exception:
|
||||||
log_trace(
|
log_trace(
|
||||||
"An error occurred while creating building menu {}".format(repr(parent_class))
|
"An error occurred while creating building menu {}".format(
|
||||||
|
repr(parent_class)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
|
|
@ -1014,7 +1041,9 @@ class BuildingMenu(object):
|
||||||
"""
|
"""
|
||||||
parent_keys = parent_keys or []
|
parent_keys = parent_keys or []
|
||||||
parents = list(self.parents)
|
parents = list(self.parents)
|
||||||
parents.append((type(self).__module__ + "." + type(self).__name__, self.obj, parent_keys))
|
parents.append(
|
||||||
|
(type(self).__module__ + "." + type(self).__name__, self.obj, parent_keys)
|
||||||
|
)
|
||||||
if self.caller.cmdset.has(BuildingMenuCmdSet):
|
if self.caller.cmdset.has(BuildingMenuCmdSet):
|
||||||
self.caller.cmdset.remove(BuildingMenuCmdSet)
|
self.caller.cmdset.remove(BuildingMenuCmdSet)
|
||||||
|
|
||||||
|
|
@ -1023,7 +1052,9 @@ class BuildingMenu(object):
|
||||||
menu_class = class_from_module(submenu_class)
|
menu_class = class_from_module(submenu_class)
|
||||||
except Exception:
|
except Exception:
|
||||||
log_trace(
|
log_trace(
|
||||||
"BuildingMenu: attempting to load class {} failed".format(repr(submenu_class))
|
"BuildingMenu: attempting to load class {} failed".format(
|
||||||
|
repr(submenu_class)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
@ -1032,7 +1063,9 @@ class BuildingMenu(object):
|
||||||
building_menu = menu_class(self.caller, submenu_obj, parents=parents)
|
building_menu = menu_class(self.caller, submenu_obj, parents=parents)
|
||||||
except Exception:
|
except Exception:
|
||||||
log_trace(
|
log_trace(
|
||||||
"An error occurred while creating building menu {}".format(repr(submenu_class))
|
"An error occurred while creating building menu {}".format(
|
||||||
|
repr(submenu_class)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
|
|
@ -1068,7 +1101,9 @@ class BuildingMenu(object):
|
||||||
|
|
||||||
if not back: # Move forward
|
if not back: # Move forward
|
||||||
if not key:
|
if not key:
|
||||||
raise ValueError("you are asking to move forward, you should specify a key.")
|
raise ValueError(
|
||||||
|
"you are asking to move forward, you should specify a key."
|
||||||
|
)
|
||||||
|
|
||||||
self.keys.append(key)
|
self.keys.append(key)
|
||||||
else: # Move backward
|
else: # Move backward
|
||||||
|
|
@ -1099,9 +1134,9 @@ class BuildingMenu(object):
|
||||||
# Display methods. Override for customization
|
# Display methods. Override for customization
|
||||||
def display_title(self):
|
def display_title(self):
|
||||||
"""Return the menu title to be displayed."""
|
"""Return the menu title to be displayed."""
|
||||||
return _call_or_get(self.title, menu=self, obj=self.obj, caller=self.caller).format(
|
return _call_or_get(
|
||||||
obj=self.obj
|
self.title, menu=self, obj=self.obj, caller=self.caller
|
||||||
)
|
).format(obj=self.obj)
|
||||||
|
|
||||||
def display_choice(self, choice):
|
def display_choice(self, choice):
|
||||||
"""Display the specified choice.
|
"""Display the specified choice.
|
||||||
|
|
@ -1117,13 +1152,24 @@ class BuildingMenu(object):
|
||||||
pos = clear_title.find(choice.key.lower())
|
pos = clear_title.find(choice.key.lower())
|
||||||
ret = " "
|
ret = " "
|
||||||
if pos >= 0:
|
if pos >= 0:
|
||||||
ret += title[:pos] + "[|y" + choice.key.title() + "|n]" + title[pos + len(choice.key) :]
|
ret += (
|
||||||
|
title[:pos]
|
||||||
|
+ "[|y"
|
||||||
|
+ choice.key.title()
|
||||||
|
+ "|n]"
|
||||||
|
+ title[pos + len(choice.key) :]
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
ret += "[|y" + choice.key.title() + "|n] " + title
|
ret += "[|y" + choice.key.title() + "|n] " + title
|
||||||
|
|
||||||
if choice.glance:
|
if choice.glance:
|
||||||
glance = _call_or_get(
|
glance = _call_or_get(
|
||||||
choice.glance, menu=self, choice=choice, caller=self.caller, string="", obj=self.obj
|
choice.glance,
|
||||||
|
menu=self,
|
||||||
|
choice=choice,
|
||||||
|
caller=self.caller,
|
||||||
|
string="",
|
||||||
|
obj=self.obj,
|
||||||
)
|
)
|
||||||
glance = glance.format(obj=self.obj, caller=self.caller)
|
glance = glance.format(obj=self.obj, caller=self.caller)
|
||||||
|
|
||||||
|
|
@ -1161,7 +1207,9 @@ class BuildingMenu(object):
|
||||||
if not class_name:
|
if not class_name:
|
||||||
log_err(
|
log_err(
|
||||||
"BuildingMenu: on caller {}, a persistent attribute holds building menu "
|
"BuildingMenu: on caller {}, a persistent attribute holds building menu "
|
||||||
"data, but no class could be found to restore the menu".format(caller)
|
"data, but no class could be found to restore the menu".format(
|
||||||
|
caller
|
||||||
|
)
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
@ -1169,7 +1217,9 @@ class BuildingMenu(object):
|
||||||
menu_class = class_from_module(class_name)
|
menu_class = class_from_module(class_name)
|
||||||
except Exception:
|
except Exception:
|
||||||
log_trace(
|
log_trace(
|
||||||
"BuildingMenu: attempting to load class {} failed".format(repr(class_name))
|
"BuildingMenu: attempting to load class {} failed".format(
|
||||||
|
repr(class_name)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
@ -1181,11 +1231,18 @@ class BuildingMenu(object):
|
||||||
persistent = menu.get("persistent", False)
|
persistent = menu.get("persistent", False)
|
||||||
try:
|
try:
|
||||||
building_menu = menu_class(
|
building_menu = menu_class(
|
||||||
caller, obj, title=title, keys=keys, parents=parents, persistent=persistent
|
caller,
|
||||||
|
obj,
|
||||||
|
title=title,
|
||||||
|
keys=keys,
|
||||||
|
parents=parents,
|
||||||
|
persistent=persistent,
|
||||||
)
|
)
|
||||||
except Exception:
|
except Exception:
|
||||||
log_trace(
|
log_trace(
|
||||||
"An error occurred while creating building menu {}".format(repr(class_name))
|
"An error occurred while creating building menu {}".format(
|
||||||
|
repr(class_name)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
@ -1256,7 +1313,9 @@ class GenericBuildingCmd(Command):
|
||||||
|
|
||||||
def func(self):
|
def func(self):
|
||||||
if not self.args.strip():
|
if not self.args.strip():
|
||||||
self.msg("You should provide an argument to this function: the object to edit.")
|
self.msg(
|
||||||
|
"You should provide an argument to this function: the object to edit."
|
||||||
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
obj = self.caller.search(self.args.strip(), global_search=True)
|
obj = self.caller.search(self.args.strip(), global_search=True)
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,9 @@ class CmdOOCLook(default_cmds.CmdLook):
|
||||||
if self.args:
|
if self.args:
|
||||||
# Maybe the caller wants to look at a character
|
# Maybe the caller wants to look at a character
|
||||||
if not avail_chars:
|
if not avail_chars:
|
||||||
self.caller.msg("You have no characters to look at. Why not create one?")
|
self.caller.msg(
|
||||||
|
"You have no characters to look at. Why not create one?"
|
||||||
|
)
|
||||||
return
|
return
|
||||||
objs = managers.objects.get_objs_with_key_and_typeclass(
|
objs = managers.objects.get_objs_with_key_and_typeclass(
|
||||||
self.args.strip(), CHARACTER_TYPECLASS
|
self.args.strip(), CHARACTER_TYPECLASS
|
||||||
|
|
@ -99,8 +101,12 @@ class CmdOOCLook(default_cmds.CmdLook):
|
||||||
charnames = [charobj.key for charobj in charobjs if charobj]
|
charnames = [charobj.key for charobj in charobjs if charobj]
|
||||||
if charnames:
|
if charnames:
|
||||||
charlist = "The following Character(s) are available:\n\n"
|
charlist = "The following Character(s) are available:\n\n"
|
||||||
charlist += "\n\r".join(["|w %s|n" % charname for charname in charnames])
|
charlist += "\n\r".join(
|
||||||
charlist += "\n\n Use |w@ic <character name>|n to switch to that Character."
|
["|w %s|n" % charname for charname in charnames]
|
||||||
|
)
|
||||||
|
charlist += (
|
||||||
|
"\n\n Use |w@ic <character name>|n to switch to that Character."
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
charlist = "You have no Characters."
|
charlist = "You have no Characters."
|
||||||
string = """ You, %s, are an |wOOC ghost|n without form. The world is hidden
|
string = """ You, %s, are an |wOOC ghost|n without form. The world is hidden
|
||||||
|
|
@ -155,7 +161,9 @@ class CmdOOCCharacterCreate(Command):
|
||||||
self.caller.msg("Usage: create <character name>")
|
self.caller.msg("Usage: create <character name>")
|
||||||
return
|
return
|
||||||
charname = self.args.strip()
|
charname = self.args.strip()
|
||||||
old_char = managers.objects.get_objs_with_key_and_typeclass(charname, CHARACTER_TYPECLASS)
|
old_char = managers.objects.get_objs_with_key_and_typeclass(
|
||||||
|
charname, CHARACTER_TYPECLASS
|
||||||
|
)
|
||||||
if old_char:
|
if old_char:
|
||||||
self.caller.msg("Character |c%s|n already exists." % charname)
|
self.caller.msg("Character |c%s|n already exists." % charname)
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -254,7 +254,8 @@ class Clothing(DefaultObject):
|
||||||
for garment in get_worn_clothes(wearer):
|
for garment in get_worn_clothes(wearer):
|
||||||
if (
|
if (
|
||||||
garment.db.clothing_type
|
garment.db.clothing_type
|
||||||
and garment.db.clothing_type in CLOTHING_TYPE_AUTOCOVER[self.db.clothing_type]
|
and garment.db.clothing_type
|
||||||
|
in CLOTHING_TYPE_AUTOCOVER[self.db.clothing_type]
|
||||||
):
|
):
|
||||||
to_cover.append(garment)
|
to_cover.append(garment)
|
||||||
garment.db.covered_by = self
|
garment.db.covered_by = self
|
||||||
|
|
@ -394,13 +395,18 @@ class CmdWear(MuxCommand):
|
||||||
return
|
return
|
||||||
|
|
||||||
# Enforce overall clothing limit.
|
# Enforce overall clothing limit.
|
||||||
if CLOTHING_OVERALL_LIMIT and len(get_worn_clothes(self.caller)) >= CLOTHING_OVERALL_LIMIT:
|
if (
|
||||||
|
CLOTHING_OVERALL_LIMIT
|
||||||
|
and len(get_worn_clothes(self.caller)) >= CLOTHING_OVERALL_LIMIT
|
||||||
|
):
|
||||||
self.caller.msg("You can't wear any more clothes.")
|
self.caller.msg("You can't wear any more clothes.")
|
||||||
return
|
return
|
||||||
|
|
||||||
# Apply individual clothing type limits.
|
# Apply individual clothing type limits.
|
||||||
if clothing.db.clothing_type and not clothing.db.worn:
|
if clothing.db.clothing_type and not clothing.db.worn:
|
||||||
type_count = single_type_count(get_worn_clothes(self.caller), clothing.db.clothing_type)
|
type_count = single_type_count(
|
||||||
|
get_worn_clothes(self.caller), clothing.db.clothing_type
|
||||||
|
)
|
||||||
if clothing.db.clothing_type in list(CLOTHING_TYPE_LIMIT.keys()):
|
if clothing.db.clothing_type in list(CLOTHING_TYPE_LIMIT.keys()):
|
||||||
if type_count >= CLOTHING_TYPE_LIMIT[clothing.db.clothing_type]:
|
if type_count >= CLOTHING_TYPE_LIMIT[clothing.db.clothing_type]:
|
||||||
self.caller.msg(
|
self.caller.msg(
|
||||||
|
|
@ -414,7 +420,9 @@ class CmdWear(MuxCommand):
|
||||||
return
|
return
|
||||||
if len(self.arglist) > 1: # If wearstyle arguments given
|
if len(self.arglist) > 1: # If wearstyle arguments given
|
||||||
wearstyle_list = self.arglist # Split arguments into a list of words
|
wearstyle_list = self.arglist # Split arguments into a list of words
|
||||||
del wearstyle_list[0] # Leave first argument (the clothing item) out of the wearstyle
|
del wearstyle_list[
|
||||||
|
0
|
||||||
|
] # Leave first argument (the clothing item) out of the wearstyle
|
||||||
wearstring = " ".join(
|
wearstring = " ".join(
|
||||||
str(e) for e in wearstyle_list
|
str(e) for e in wearstyle_list
|
||||||
) # Join list of args back into one string
|
) # Join list of args back into one string
|
||||||
|
|
@ -457,7 +465,9 @@ class CmdRemove(MuxCommand):
|
||||||
self.caller.msg("You're not wearing that!")
|
self.caller.msg("You're not wearing that!")
|
||||||
return
|
return
|
||||||
if clothing.db.covered_by:
|
if clothing.db.covered_by:
|
||||||
self.caller.msg("You have to take off %s first." % clothing.db.covered_by.name)
|
self.caller.msg(
|
||||||
|
"You have to take off %s first." % clothing.db.covered_by.name
|
||||||
|
)
|
||||||
return
|
return
|
||||||
clothing.remove(self.caller)
|
clothing.remove(self.caller)
|
||||||
|
|
||||||
|
|
@ -489,13 +499,17 @@ class CmdCover(MuxCommand):
|
||||||
if self.arglist[1].lower() == "with" and len(self.arglist) > 2:
|
if self.arglist[1].lower() == "with" and len(self.arglist) > 2:
|
||||||
del self.arglist[1]
|
del self.arglist[1]
|
||||||
to_cover = self.caller.search(self.arglist[0], candidates=self.caller.contents)
|
to_cover = self.caller.search(self.arglist[0], candidates=self.caller.contents)
|
||||||
cover_with = self.caller.search(self.arglist[1], candidates=self.caller.contents)
|
cover_with = self.caller.search(
|
||||||
|
self.arglist[1], candidates=self.caller.contents
|
||||||
|
)
|
||||||
if not to_cover or not cover_with:
|
if not to_cover or not cover_with:
|
||||||
return
|
return
|
||||||
if not to_cover.is_typeclass("evennia.contrib.clothing.Clothing", exact=False):
|
if not to_cover.is_typeclass("evennia.contrib.clothing.Clothing", exact=False):
|
||||||
self.caller.msg("%s isn't clothes!" % to_cover.name)
|
self.caller.msg("%s isn't clothes!" % to_cover.name)
|
||||||
return
|
return
|
||||||
if not cover_with.is_typeclass("evennia.contrib.clothing.Clothing", exact=False):
|
if not cover_with.is_typeclass(
|
||||||
|
"evennia.contrib.clothing.Clothing", exact=False
|
||||||
|
):
|
||||||
self.caller.msg("%s isn't clothes!" % cover_with.name)
|
self.caller.msg("%s isn't clothes!" % cover_with.name)
|
||||||
return
|
return
|
||||||
if cover_with.db.clothing_type:
|
if cover_with.db.clothing_type:
|
||||||
|
|
@ -513,7 +527,8 @@ class CmdCover(MuxCommand):
|
||||||
return
|
return
|
||||||
if to_cover.db.covered_by:
|
if to_cover.db.covered_by:
|
||||||
self.caller.msg(
|
self.caller.msg(
|
||||||
"%s is already covered by %s." % (cover_with.name, to_cover.db.covered_by.name)
|
"%s is already covered by %s."
|
||||||
|
% (cover_with.name, to_cover.db.covered_by.name)
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
if not cover_with.db.worn:
|
if not cover_with.db.worn:
|
||||||
|
|
@ -562,9 +577,13 @@ class CmdUncover(MuxCommand):
|
||||||
return
|
return
|
||||||
covered_by = to_uncover.db.covered_by
|
covered_by = to_uncover.db.covered_by
|
||||||
if covered_by.db.covered_by:
|
if covered_by.db.covered_by:
|
||||||
self.caller.msg("%s is under too many layers to uncover." % (to_uncover.name))
|
self.caller.msg(
|
||||||
|
"%s is under too many layers to uncover." % (to_uncover.name)
|
||||||
|
)
|
||||||
return
|
return
|
||||||
self.caller.location.msg_contents("%s uncovers %s." % (self.caller, to_uncover.name))
|
self.caller.location.msg_contents(
|
||||||
|
"%s uncovers %s." % (self.caller, to_uncover.name)
|
||||||
|
)
|
||||||
to_uncover.db.covered_by = None
|
to_uncover.db.covered_by = None
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -605,7 +624,9 @@ class CmdDrop(MuxCommand):
|
||||||
# This part is new!
|
# This part is new!
|
||||||
# You can't drop clothing items that are covered.
|
# You can't drop clothing items that are covered.
|
||||||
if obj.db.covered_by:
|
if obj.db.covered_by:
|
||||||
caller.msg("You can't drop that because it's covered by %s." % obj.db.covered_by)
|
caller.msg(
|
||||||
|
"You can't drop that because it's covered by %s." % obj.db.covered_by
|
||||||
|
)
|
||||||
return
|
return
|
||||||
# Remove clothes if they're dropped.
|
# Remove clothes if they're dropped.
|
||||||
if obj.db.worn:
|
if obj.db.worn:
|
||||||
|
|
@ -613,7 +634,9 @@ class CmdDrop(MuxCommand):
|
||||||
|
|
||||||
obj.move_to(caller.location, quiet=True)
|
obj.move_to(caller.location, quiet=True)
|
||||||
caller.msg("You drop %s." % (obj.name,))
|
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.
|
# Call the object script's at_drop() method.
|
||||||
obj.at_drop(caller)
|
obj.at_drop(caller)
|
||||||
|
|
||||||
|
|
@ -658,7 +681,8 @@ class CmdGive(MuxCommand):
|
||||||
# This is new! Can't give away something that's worn.
|
# This is new! Can't give away something that's worn.
|
||||||
if to_give.db.covered_by:
|
if to_give.db.covered_by:
|
||||||
caller.msg(
|
caller.msg(
|
||||||
"You can't give that away because it's covered by %s." % to_give.db.covered_by
|
"You can't give that away because it's covered by %s."
|
||||||
|
% to_give.db.covered_by
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
# Remove clothes if they're given.
|
# Remove clothes if they're given.
|
||||||
|
|
|
||||||
|
|
@ -115,7 +115,10 @@ CURLY_COLOR_ANSI_EXTRA_MAP = [
|
||||||
(r"{-", _ANSI_TAB), # tab
|
(r"{-", _ANSI_TAB), # tab
|
||||||
(r"{_", _ANSI_SPACE), # space
|
(r"{_", _ANSI_SPACE), # space
|
||||||
(r"{*", _ANSI_INVERSE), # invert
|
(r"{*", _ANSI_INVERSE), # invert
|
||||||
(r"{^", _ANSI_BLINK), # blinking text (very annoying and not supported by all clients)
|
(
|
||||||
|
r"{^",
|
||||||
|
_ANSI_BLINK,
|
||||||
|
), # blinking text (very annoying and not supported by all clients)
|
||||||
(r"{u", _ANSI_UNDERLINE), # underline
|
(r"{u", _ANSI_UNDERLINE), # underline
|
||||||
(r"{r", _ANSI_HILITE + _ANSI_RED),
|
(r"{r", _ANSI_HILITE + _ANSI_RED),
|
||||||
(r"{g", _ANSI_HILITE + _ANSI_GREEN),
|
(r"{g", _ANSI_HILITE + _ANSI_GREEN),
|
||||||
|
|
@ -156,7 +159,9 @@ CURLY_COLOR_ANSI_EXTRA_MAP = [
|
||||||
]
|
]
|
||||||
|
|
||||||
CURLY_COLOR_XTERM256_EXTRA_FG = [r"\{([0-5])([0-5])([0-5])"] # |123 - foreground colour
|
CURLY_COLOR_XTERM256_EXTRA_FG = [r"\{([0-5])([0-5])([0-5])"] # |123 - foreground colour
|
||||||
CURLY_COLOR_XTERM256_EXTRA_BG = [r"\{\[([0-5])([0-5])([0-5])"] # |[123 - background colour
|
CURLY_COLOR_XTERM256_EXTRA_BG = [
|
||||||
|
r"\{\[([0-5])([0-5])([0-5])"
|
||||||
|
] # |[123 - background colour
|
||||||
CURLY_COLOR_XTERM256_EXTRA_GFG = [r"\{=([a-z])"] # |=a - greyscale foreground
|
CURLY_COLOR_XTERM256_EXTRA_GFG = [r"\{=([a-z])"] # |=a - greyscale foreground
|
||||||
CURLY_COLOR_XTERM256_EXTRA_GBG = [r"\{\[=([a-z])"] # |[=a - greyscale background
|
CURLY_COLOR_XTERM256_EXTRA_GBG = [r"\{\[=([a-z])"] # |[=a - greyscale background
|
||||||
|
|
||||||
|
|
@ -215,7 +220,9 @@ MUX_COLOR_ANSI_EXTRA_MAP = [
|
||||||
]
|
]
|
||||||
|
|
||||||
MUX_COLOR_XTERM256_EXTRA_FG = [r"%c([0-5])([0-5])([0-5])"] # %c123 - foreground colour
|
MUX_COLOR_XTERM256_EXTRA_FG = [r"%c([0-5])([0-5])([0-5])"] # %c123 - foreground colour
|
||||||
MUX_COLOR_XTERM256_EXTRA_BG = [r"%c\[([0-5])([0-5])([0-5])"] # %c[123 - background colour
|
MUX_COLOR_XTERM256_EXTRA_BG = [
|
||||||
|
r"%c\[([0-5])([0-5])([0-5])"
|
||||||
|
] # %c[123 - background colour
|
||||||
MUX_COLOR_XTERM256_EXTRA_GFG = [r"%c=([a-z])"] # %c=a - greyscale foreground
|
MUX_COLOR_XTERM256_EXTRA_GFG = [r"%c=([a-z])"] # %c=a - greyscale foreground
|
||||||
MUX_COLOR_XTERM256_EXTRA_GBG = [r"%c\[=([a-z])"] # %c[=a - greyscale background
|
MUX_COLOR_XTERM256_EXTRA_GBG = [r"%c\[=([a-z])"] # %c[=a - greyscale background
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,9 @@ def gametime_to_realtime(format=False, **kwargs):
|
||||||
name = name[:-1]
|
name = name[:-1]
|
||||||
|
|
||||||
if name not in UNITS:
|
if name not in UNITS:
|
||||||
raise ValueError("the unit {} isn't defined as a valid " "game time unit".format(name))
|
raise ValueError(
|
||||||
|
"the unit {} isn't defined as a valid " "game time unit".format(name)
|
||||||
|
)
|
||||||
rtime += value * UNITS[name]
|
rtime += value * UNITS[name]
|
||||||
rtime /= TIMEFACTOR
|
rtime /= TIMEFACTOR
|
||||||
if format:
|
if format:
|
||||||
|
|
@ -125,7 +127,9 @@ def gametime_to_realtime(format=False, **kwargs):
|
||||||
return rtime
|
return rtime
|
||||||
|
|
||||||
|
|
||||||
def realtime_to_gametime(secs=0, mins=0, hrs=0, days=0, weeks=0, months=0, yrs=0, format=False):
|
def realtime_to_gametime(
|
||||||
|
secs=0, mins=0, hrs=0, days=0, weeks=0, months=0, yrs=0, format=False
|
||||||
|
):
|
||||||
"""
|
"""
|
||||||
This method calculates how much in-game time a real-world time
|
This method calculates how much in-game time a real-world time
|
||||||
interval would correspond to. This is usually a lot less
|
interval would correspond to. This is usually a lot less
|
||||||
|
|
|
||||||
|
|
@ -177,7 +177,9 @@ class CmdDice(default_cmds.MuxCommand):
|
||||||
ndicelimit = 10000 # Maximum number of dice
|
ndicelimit = 10000 # Maximum number of dice
|
||||||
nsidelimit = 10000 # Maximum number of sides
|
nsidelimit = 10000 # Maximum number of sides
|
||||||
if int(parts[0]) > ndicelimit or int(parts[2]) > nsidelimit:
|
if int(parts[0]) > ndicelimit or int(parts[2]) > nsidelimit:
|
||||||
self.caller.msg("The maximum roll allowed is %sd%s." % (ndicelimit, nsidelimit))
|
self.caller.msg(
|
||||||
|
"The maximum roll allowed is %sd%s." % (ndicelimit, nsidelimit)
|
||||||
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
ndice, nsides = parts[0], parts[2]
|
ndice, nsides = parts[0], parts[2]
|
||||||
|
|
@ -201,7 +203,11 @@ class CmdDice(default_cmds.MuxCommand):
|
||||||
# do the roll
|
# do the roll
|
||||||
try:
|
try:
|
||||||
result, outcome, diff, rolls = roll_dice(
|
result, outcome, diff, rolls = roll_dice(
|
||||||
ndice, nsides, modifier=modifier, conditional=conditional, return_tuple=True
|
ndice,
|
||||||
|
nsides,
|
||||||
|
modifier=modifier,
|
||||||
|
conditional=conditional,
|
||||||
|
return_tuple=True,
|
||||||
)
|
)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
self.caller.msg(
|
self.caller.msg(
|
||||||
|
|
@ -211,7 +217,9 @@ class CmdDice(default_cmds.MuxCommand):
|
||||||
return
|
return
|
||||||
# format output
|
# format output
|
||||||
if len(rolls) > 1:
|
if len(rolls) > 1:
|
||||||
rolls = ", ".join(str(roll) for roll in rolls[:-1]) + " and " + str(rolls[-1])
|
rolls = (
|
||||||
|
", ".join(str(roll) for roll in rolls[:-1]) + " and " + str(rolls[-1])
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
rolls = rolls[0]
|
rolls = rolls[0]
|
||||||
if outcome is None:
|
if outcome is None:
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,9 @@ MULTISESSION_MODE = settings.MULTISESSION_MODE
|
||||||
CONNECTION_SCREEN_MODULE = settings.CONNECTION_SCREEN_MODULE
|
CONNECTION_SCREEN_MODULE = settings.CONNECTION_SCREEN_MODULE
|
||||||
CONNECTION_SCREEN = ""
|
CONNECTION_SCREEN = ""
|
||||||
try:
|
try:
|
||||||
CONNECTION_SCREEN = ansi.parse_ansi(utils.random_string_from_module(CONNECTION_SCREEN_MODULE))
|
CONNECTION_SCREEN = ansi.parse_ansi(
|
||||||
|
utils.random_string_from_module(CONNECTION_SCREEN_MODULE)
|
||||||
|
)
|
||||||
except Exception:
|
except Exception:
|
||||||
# malformed connection screen or no screen given
|
# malformed connection screen or no screen given
|
||||||
pass
|
pass
|
||||||
|
|
@ -176,18 +178,24 @@ class CmdUnconnectedCreate(MuxCommand):
|
||||||
try:
|
try:
|
||||||
accountname, email, password = self.accountinfo
|
accountname, email, password = self.accountinfo
|
||||||
except ValueError:
|
except ValueError:
|
||||||
string = '\n\r Usage (without <>): create "<accountname>" <email> <password>'
|
string = (
|
||||||
|
'\n\r Usage (without <>): create "<accountname>" <email> <password>'
|
||||||
|
)
|
||||||
session.msg(string)
|
session.msg(string)
|
||||||
return
|
return
|
||||||
if not email or not password:
|
if not email or not password:
|
||||||
session.msg("\n\r You have to supply an e-mail address followed by a password.")
|
session.msg(
|
||||||
|
"\n\r You have to supply an e-mail address followed by a password."
|
||||||
|
)
|
||||||
return
|
return
|
||||||
if not utils.validate_email_address(email):
|
if not utils.validate_email_address(email):
|
||||||
# check so the email at least looks ok.
|
# check so the email at least looks ok.
|
||||||
session.msg("'%s' is not a valid e-mail address." % email)
|
session.msg("'%s' is not a valid e-mail address." % email)
|
||||||
return
|
return
|
||||||
# sanity checks
|
# sanity checks
|
||||||
if not re.findall(r"^[\w. @+\-']+$", accountname) or not (0 < len(accountname) <= 30):
|
if not re.findall(r"^[\w. @+\-']+$", accountname) or not (
|
||||||
|
0 < len(accountname) <= 30
|
||||||
|
):
|
||||||
# this echoes the restrictions made by django's auth
|
# this echoes the restrictions made by django's auth
|
||||||
# module (except not allowing spaces, for convenience of
|
# module (except not allowing spaces, for convenience of
|
||||||
# logging in).
|
# logging in).
|
||||||
|
|
@ -198,7 +206,9 @@ class CmdUnconnectedCreate(MuxCommand):
|
||||||
accountname = re.sub(r"\s+", " ", accountname).strip()
|
accountname = re.sub(r"\s+", " ", accountname).strip()
|
||||||
if AccountDB.objects.filter(username__iexact=accountname):
|
if AccountDB.objects.filter(username__iexact=accountname):
|
||||||
# account already exists (we also ignore capitalization here)
|
# account already exists (we also ignore capitalization here)
|
||||||
session.msg("Sorry, there is already an account with the name '%s'." % accountname)
|
session.msg(
|
||||||
|
"Sorry, there is already an account with the name '%s'." % accountname
|
||||||
|
)
|
||||||
return
|
return
|
||||||
if AccountDB.objects.get_account_from_email(email):
|
if AccountDB.objects.get_account_from_email(email):
|
||||||
# email already set on an account
|
# email already set on an account
|
||||||
|
|
@ -251,9 +261,7 @@ class CmdUnconnectedCreate(MuxCommand):
|
||||||
# tell the caller everything went well.
|
# tell the caller everything went well.
|
||||||
string = "A new account '%s' was created. Welcome!"
|
string = "A new account '%s' was created. Welcome!"
|
||||||
if " " in accountname:
|
if " " in accountname:
|
||||||
string += (
|
string += "\n\nYou can now log in with the command 'connect \"%s\" <your password>'."
|
||||||
"\n\nYou can now log in with the command 'connect \"%s\" <your password>'."
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
string += "\n\nYou can now log with the command 'connect %s <your password>'."
|
string += "\n\nYou can now log with the command 'connect %s <your password>'."
|
||||||
session.msg(string % (accountname, email))
|
session.msg(string % (accountname, email))
|
||||||
|
|
@ -262,7 +270,9 @@ class CmdUnconnectedCreate(MuxCommand):
|
||||||
# We are in the middle between logged in and -not, so we have
|
# We are in the middle between logged in and -not, so we have
|
||||||
# to handle tracebacks ourselves at this point. If we don't,
|
# to handle tracebacks ourselves at this point. If we don't,
|
||||||
# we won't see any errors at all.
|
# we won't see any errors at all.
|
||||||
session.msg("An error occurred. Please e-mail an admin if the problem persists.")
|
session.msg(
|
||||||
|
"An error occurred. Please e-mail an admin if the problem persists."
|
||||||
|
)
|
||||||
logger.log_trace()
|
logger.log_trace()
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -234,7 +234,9 @@ class CmdGiveUp(CmdEvscapeRoom):
|
||||||
self.room.log(f"QUIT: {self.caller.key} used the quit command")
|
self.room.log(f"QUIT: {self.caller.key} used the quit command")
|
||||||
|
|
||||||
# manually call move hooks
|
# manually call move hooks
|
||||||
self.room.msg_room(self.caller, f"|r{self.caller.key} gave up and was whisked away!|n")
|
self.room.msg_room(
|
||||||
|
self.caller, f"|r{self.caller.key} gave up and was whisked away!|n"
|
||||||
|
)
|
||||||
self.room.at_object_leave(self.caller, self.caller.home)
|
self.room.at_object_leave(self.caller, self.caller.home)
|
||||||
self.caller.move_to(self.caller.home, quiet=True, move_hooks=False)
|
self.caller.move_to(self.caller.home, quiet=True, move_hooks=False)
|
||||||
|
|
||||||
|
|
@ -313,7 +315,9 @@ class CmdWho(CmdEvscapeRoom, default_cmds.CmdWho):
|
||||||
for obj in self.room.get_all_characters()
|
for obj in self.room.get_all_characters()
|
||||||
if obj != caller
|
if obj != caller
|
||||||
]
|
]
|
||||||
chars = "\n".join([f"{caller.key} - {caller.db.desc.strip()} (you)"] + chars)
|
chars = "\n".join(
|
||||||
|
[f"{caller.key} - {caller.db.desc.strip()} (you)"] + chars
|
||||||
|
)
|
||||||
txt = f"|cPlayers in this room (room-name '{self.room.name}')|n:\n {chars}"
|
txt = f"|cPlayers in this room (room-name '{self.room.name}')|n:\n {chars}"
|
||||||
caller.msg(txt)
|
caller.msg(txt)
|
||||||
|
|
||||||
|
|
@ -389,7 +393,9 @@ class CmdEmote(Command):
|
||||||
emote = self.args.strip()
|
emote = self.args.strip()
|
||||||
|
|
||||||
if not emote:
|
if not emote:
|
||||||
self.caller.msg('Usage: emote /me points to /door, saying "look over there!"')
|
self.caller.msg(
|
||||||
|
'Usage: emote /me points to /door, saying "look over there!"'
|
||||||
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
speech_clr = "|c"
|
speech_clr = "|c"
|
||||||
|
|
@ -429,7 +435,9 @@ class CmdEmote(Command):
|
||||||
if target == self.caller:
|
if target == self.caller:
|
||||||
txt = [f"{self_clr}{self.caller.get_display_name(target)}|n "] + txt
|
txt = [f"{self_clr}{self.caller.get_display_name(target)}|n "] + txt
|
||||||
else:
|
else:
|
||||||
txt = [f"{player_clr}{self.caller.get_display_name(target)}|n "] + txt
|
txt = [
|
||||||
|
f"{player_clr}{self.caller.get_display_name(target)}|n "
|
||||||
|
] + txt
|
||||||
txt = "".join(txt).strip() + ("." if add_period else "")
|
txt = "".join(txt).strip() + ("." if add_period else "")
|
||||||
if not logged and hasattr(self.caller.location, "log"):
|
if not logged and hasattr(self.caller.location, "log"):
|
||||||
self.caller.location.log(f"emote: {txt}")
|
self.caller.location.log(f"emote: {txt}")
|
||||||
|
|
@ -531,7 +539,10 @@ class CmdRerouter(default_cmds.MuxCommand):
|
||||||
from evennia.commands import cmdhandler
|
from evennia.commands import cmdhandler
|
||||||
|
|
||||||
cmdhandler.cmdhandler(
|
cmdhandler.cmdhandler(
|
||||||
self.session, self.raw_string, cmdobj=CmdFocusInteraction(), cmdobj_key=self.cmdname
|
self.session,
|
||||||
|
self.raw_string,
|
||||||
|
cmdobj=CmdFocusInteraction(),
|
||||||
|
cmdobj_key=self.cmdname,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -603,7 +614,9 @@ class CmdStand(CmdEvscapeRoom):
|
||||||
obj, position = pos
|
obj, position = pos
|
||||||
self.caller.attributes.remove("position", category=self.room.tagcategory)
|
self.caller.attributes.remove("position", category=self.room.tagcategory)
|
||||||
del obj.db.positions[self.caller]
|
del obj.db.positions[self.caller]
|
||||||
self.room.msg_room(self.caller, "~You ~are back standing on the floor again.")
|
self.room.msg_room(
|
||||||
|
self.caller, "~You ~are back standing on the floor again."
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
self.caller.msg("You are already standing.")
|
self.caller.msg("You are already standing.")
|
||||||
|
|
||||||
|
|
@ -679,7 +692,9 @@ class CmdCreateObj(CmdEvscapeRoom):
|
||||||
else:
|
else:
|
||||||
name = args.strip()
|
name = args.strip()
|
||||||
|
|
||||||
obj = create_evscaperoom_object(typeclass=typeclass, key=name, location=self.room)
|
obj = create_evscaperoom_object(
|
||||||
|
typeclass=typeclass, key=name, location=self.room
|
||||||
|
)
|
||||||
caller.msg(f"Created new object {name} ({obj.typeclass_path}).")
|
caller.msg(f"Created new object {name} ({obj.typeclass_path}).")
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -151,7 +151,9 @@ def node_set_desc(caller, raw_string, **kwargs):
|
||||||
current_desc = kwargs.get("desc", caller.db.desc)
|
current_desc = kwargs.get("desc", caller.db.desc)
|
||||||
|
|
||||||
text = (
|
text = (
|
||||||
"Your current description is\n\n " f' "{current_desc}"' "\n\nEnter your new description!"
|
"Your current description is\n\n "
|
||||||
|
f' "{current_desc}"'
|
||||||
|
"\n\nEnter your new description!"
|
||||||
)
|
)
|
||||||
|
|
||||||
def _temp_description(caller, raw_string, **kwargs):
|
def _temp_description(caller, raw_string, **kwargs):
|
||||||
|
|
@ -169,7 +171,10 @@ def node_set_desc(caller, raw_string, **kwargs):
|
||||||
|
|
||||||
options = (
|
options = (
|
||||||
{"key": "_default", "goto": _temp_description},
|
{"key": "_default", "goto": _temp_description},
|
||||||
{"key": ("|g[a]ccept", "a"), "goto": (_set_description, {"desc": current_desc})},
|
{
|
||||||
|
"key": ("|g[a]ccept", "a"),
|
||||||
|
"goto": (_set_description, {"desc": current_desc}),
|
||||||
|
},
|
||||||
{"key": ("|r[c]ancel", "c"), "goto": "node_start"},
|
{"key": ("|r[c]ancel", "c"), "goto": "node_start"},
|
||||||
)
|
)
|
||||||
return text, options
|
return text, options
|
||||||
|
|
@ -180,7 +185,10 @@ def node_create_room(caller, raw_string, **kwargs):
|
||||||
text = _CREATE_ROOM_TEXT
|
text = _CREATE_ROOM_TEXT
|
||||||
|
|
||||||
options = (
|
options = (
|
||||||
{"key": ("|g[c]reate new room and start game|n", "c"), "goto": _create_new_room},
|
{
|
||||||
|
"key": ("|g[c]reate new room and start game|n", "c"),
|
||||||
|
"goto": _create_new_room,
|
||||||
|
},
|
||||||
{"key": ("|r[a]bort and go back|n", "a"), "goto": "node_start"},
|
{"key": ("|r[a]bort and go back|n", "a"), "goto": "node_start"},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -221,7 +229,10 @@ def node_quit(caller, raw_string, **kwargs):
|
||||||
from evennia import default_cmds
|
from evennia import default_cmds
|
||||||
|
|
||||||
cmdhandler.cmdhandler(
|
cmdhandler.cmdhandler(
|
||||||
caller.ndb._menutree._session, "", cmdobj=default_cmds.CmdQuit(), cmdobj_key="@quit"
|
caller.ndb._menutree._session,
|
||||||
|
"",
|
||||||
|
cmdobj=default_cmds.CmdQuit(),
|
||||||
|
cmdobj_key="@quit",
|
||||||
)
|
)
|
||||||
|
|
||||||
return text, None # empty options exit the menu
|
return text, None # empty options exit the menu
|
||||||
|
|
@ -248,7 +259,9 @@ class EvscaperoomMenu(EvMenu):
|
||||||
main_options.append(key)
|
main_options.append(key)
|
||||||
main_options = " | ".join(main_options)
|
main_options = " | ".join(main_options)
|
||||||
room_choices = super().options_formatter(room_choices)
|
room_choices = super().options_formatter(room_choices)
|
||||||
return "{}{}{}".format(main_options, "\n\n" if room_choices else "", room_choices)
|
return "{}{}{}".format(
|
||||||
|
main_options, "\n\n" if room_choices else "", room_choices
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# access function
|
# access function
|
||||||
|
|
@ -265,7 +278,9 @@ def run_evscaperoom_menu(caller):
|
||||||
"node_join_room": node_join_room,
|
"node_join_room": node_join_room,
|
||||||
}
|
}
|
||||||
|
|
||||||
EvscaperoomMenu(caller, menutree, startnode="node_start", cmd_on_exit=None, auto_quit=True)
|
EvscaperoomMenu(
|
||||||
|
caller, menutree, startnode="node_start", cmd_on_exit=None, auto_quit=True
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# ------------------------------------------------------------
|
# ------------------------------------------------------------
|
||||||
|
|
@ -285,7 +300,9 @@ def _toggle_screen_reader(caller, raw_string, **kwargs):
|
||||||
|
|
||||||
session = kwargs["session"]
|
session = kwargs["session"]
|
||||||
# flip old setting
|
# flip old setting
|
||||||
session.protocol_flags["SCREENREADER"] = not session.protocol_flags.get("SCREENREADER", False)
|
session.protocol_flags["SCREENREADER"] = not session.protocol_flags.get(
|
||||||
|
"SCREENREADER", False
|
||||||
|
)
|
||||||
# sync setting with portal
|
# sync setting with portal
|
||||||
session.sessionhandler.session_portal_sync(session)
|
session.sessionhandler.session_portal_sync(session)
|
||||||
return None, kwargs # rerun node
|
return None, kwargs # rerun node
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,12 @@ class EvscaperoomObject(DefaultObject):
|
||||||
|
|
||||||
# this mapping allows for prettier descriptions of our current
|
# this mapping allows for prettier descriptions of our current
|
||||||
# position
|
# position
|
||||||
position_prep_map = {"sit": "sitting", "kneel": "kneeling", "lie": "lying", "climb": "standing"}
|
position_prep_map = {
|
||||||
|
"sit": "sitting",
|
||||||
|
"kneel": "kneeling",
|
||||||
|
"lie": "lying",
|
||||||
|
"climb": "standing",
|
||||||
|
}
|
||||||
|
|
||||||
def at_object_creation(self):
|
def at_object_creation(self):
|
||||||
"""
|
"""
|
||||||
|
|
@ -161,7 +166,9 @@ class EvscaperoomObject(DefaultObject):
|
||||||
you = caller.key if caller else "they"
|
you = caller.key if caller else "they"
|
||||||
first_person, third_person = parse_for_perspectives(string, you=you)
|
first_person, third_person = parse_for_perspectives(string, you=you)
|
||||||
for char in self.room.get_all_characters():
|
for char in self.room.get_all_characters():
|
||||||
options = char.attributes.get("options", category=self.room.tagcategory, default={})
|
options = char.attributes.get(
|
||||||
|
"options", category=self.room.tagcategory, default={}
|
||||||
|
)
|
||||||
style = options.get("things_style", 2)
|
style = options.get("things_style", 2)
|
||||||
if char == caller:
|
if char == caller:
|
||||||
if not skip_caller:
|
if not skip_caller:
|
||||||
|
|
@ -178,7 +185,9 @@ class EvscaperoomObject(DefaultObject):
|
||||||
"""
|
"""
|
||||||
# we must clean away markers
|
# we must clean away markers
|
||||||
first_person, _ = parse_for_perspectives(string)
|
first_person, _ = parse_for_perspectives(string)
|
||||||
options = caller.attributes.get("options", category=self.room.tagcategory, default={})
|
options = caller.attributes.get(
|
||||||
|
"options", category=self.room.tagcategory, default={}
|
||||||
|
)
|
||||||
style = options.get("things_style", 2)
|
style = options.get("things_style", 2)
|
||||||
txt = parse_for_things(first_person, things_style=style)
|
txt = parse_for_things(first_person, things_style=style)
|
||||||
caller.msg((txt, {"type": client_type}))
|
caller.msg((txt, {"type": client_type}))
|
||||||
|
|
@ -276,7 +285,9 @@ class EvscaperoomObject(DefaultObject):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
args = re.sub(
|
args = re.sub(
|
||||||
r"|".join(r"^{}\s".format(prep) for prep in self.action_prepositions), "", args
|
r"|".join(r"^{}\s".format(prep) for prep in self.action_prepositions),
|
||||||
|
"",
|
||||||
|
args,
|
||||||
)
|
)
|
||||||
return args
|
return args
|
||||||
|
|
||||||
|
|
@ -307,7 +318,8 @@ class EvscaperoomObject(DefaultObject):
|
||||||
helpstr = f"It looks like {self.key} may be " "suitable to {callsigns}."
|
helpstr = f"It looks like {self.key} may be " "suitable to {callsigns}."
|
||||||
else:
|
else:
|
||||||
helpstr = (
|
helpstr = (
|
||||||
f"At first glance, it looks like {self.key} might be " "suitable to {callsigns}."
|
f"At first glance, it looks like {self.key} might be "
|
||||||
|
"suitable to {callsigns}."
|
||||||
)
|
)
|
||||||
return command_signatures, helpstr
|
return command_signatures, helpstr
|
||||||
|
|
||||||
|
|
@ -330,10 +342,14 @@ class EvscaperoomObject(DefaultObject):
|
||||||
# custom-created signatures. We don't sort these
|
# custom-created signatures. We don't sort these
|
||||||
command_signatures, helpstr = self.get_cmd_signatures()
|
command_signatures, helpstr = self.get_cmd_signatures()
|
||||||
|
|
||||||
callsigns = list_to_string(["*" + sig for sig in command_signatures], endsep="or")
|
callsigns = list_to_string(
|
||||||
|
["*" + sig for sig in command_signatures], endsep="or"
|
||||||
|
)
|
||||||
|
|
||||||
# parse for *thing markers (use these as items)
|
# parse for *thing markers (use these as items)
|
||||||
options = caller.attributes.get("options", category=self.room.tagcategory, default={})
|
options = caller.attributes.get(
|
||||||
|
"options", category=self.room.tagcategory, default={}
|
||||||
|
)
|
||||||
style = options.get("things_style", 2)
|
style = options.get("things_style", 2)
|
||||||
|
|
||||||
helpstr = helpstr.format(callsigns=callsigns)
|
helpstr = helpstr.format(callsigns=callsigns)
|
||||||
|
|
@ -521,7 +537,11 @@ class IndexReadable(Readable):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# keys should be lower-key
|
# keys should be lower-key
|
||||||
index = {"page1": "This is page1", "page2": "This is page2", "page two": "page2"} # alias
|
index = {
|
||||||
|
"page1": "This is page1",
|
||||||
|
"page2": "This is page2",
|
||||||
|
"page two": "page2",
|
||||||
|
} # alias
|
||||||
|
|
||||||
def at_focus_read(self, caller, **kwargs):
|
def at_focus_read(self, caller, **kwargs):
|
||||||
|
|
||||||
|
|
@ -800,7 +820,8 @@ class Combinable(BaseApplicable):
|
||||||
new_obj = create_evscaperoom_object(**create_dict)
|
new_obj = create_evscaperoom_object(**create_dict)
|
||||||
if new_obj and self.destroy_components:
|
if new_obj and self.destroy_components:
|
||||||
self.msg_char(
|
self.msg_char(
|
||||||
caller, f"You combine *{self.key} with {other_obj.key} to make {new_obj.key}!"
|
caller,
|
||||||
|
f"You combine *{self.key} with {other_obj.key} to make {new_obj.key}!",
|
||||||
)
|
)
|
||||||
other_obj.delete()
|
other_obj.delete()
|
||||||
self.delete()
|
self.delete()
|
||||||
|
|
@ -1020,7 +1041,8 @@ class BasePositionable(EvscaperoomObject):
|
||||||
|
|
||||||
def at_again_position(self, caller, position):
|
def at_again_position(self, caller, position):
|
||||||
self.msg_char(
|
self.msg_char(
|
||||||
caller, f"But you are already {self.position_prep_map[position]} on *{self.key}?"
|
caller,
|
||||||
|
f"But you are already {self.position_prep_map[position]} on *{self.key}?",
|
||||||
)
|
)
|
||||||
|
|
||||||
def at_position(self, caller, position):
|
def at_position(self, caller, position):
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,9 @@ class EvscapeRoom(EvscaperoomObject, DefaultRoom):
|
||||||
if achievement not in achievements:
|
if achievement not in achievements:
|
||||||
self.log(f"achievement: {caller} earned '{achievement}' - {subtext}")
|
self.log(f"achievement: {caller} earned '{achievement}' - {subtext}")
|
||||||
achievements[achievement] = subtext
|
achievements[achievement] = subtext
|
||||||
caller.attributes.add("achievements", achievements, category=self.tagcategory)
|
caller.attributes.add(
|
||||||
|
"achievements", achievements, category=self.tagcategory
|
||||||
|
)
|
||||||
|
|
||||||
def get_all_characters(self):
|
def get_all_characters(self):
|
||||||
"""
|
"""
|
||||||
|
|
@ -224,7 +226,8 @@ class EvscapeRoom(EvscaperoomObject, DefaultRoom):
|
||||||
def return_appearance(self, looker, **kwargs):
|
def return_appearance(self, looker, **kwargs):
|
||||||
obj, pos = self.get_position(looker)
|
obj, pos = self.get_position(looker)
|
||||||
pos = (
|
pos = (
|
||||||
f"\n|x[{self.position_prep_map[pos]} on " f"{obj.get_display_name(looker)}]|n"
|
f"\n|x[{self.position_prep_map[pos]} on "
|
||||||
|
f"{obj.get_display_name(looker)}]|n"
|
||||||
if obj
|
if obj
|
||||||
else ""
|
else ""
|
||||||
)
|
)
|
||||||
|
|
@ -232,7 +235,9 @@ class EvscapeRoom(EvscaperoomObject, DefaultRoom):
|
||||||
admin_only = ""
|
admin_only = ""
|
||||||
if self.check_perm(looker, "Admin"):
|
if self.check_perm(looker, "Admin"):
|
||||||
# only for admins
|
# only for admins
|
||||||
objs = DefaultObject.objects.filter_family(db_location=self).exclude(id=looker.id)
|
objs = DefaultObject.objects.filter_family(db_location=self).exclude(
|
||||||
|
id=looker.id
|
||||||
|
)
|
||||||
admin_only = "\n|xAdmin only: " + list_to_string(
|
admin_only = "\n|xAdmin only: " + list_to_string(
|
||||||
[obj.get_display_name(looker) for obj in objs]
|
[obj.get_display_name(looker) for obj in objs]
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,9 @@ class StateHandler(object):
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
logger.log_trace()
|
logger.log_trace()
|
||||||
self.room.msg_room(None, f"|rBUG: Could not load state {statename}: {err}!")
|
self.room.msg_room(None, f"|rBUG: Could not load state {statename}: {err}!")
|
||||||
self.room.msg_room(None, f"|rBUG: Falling back to {self.current_state_name}")
|
self.room.msg_room(
|
||||||
|
None, f"|rBUG: Falling back to {self.current_state_name}"
|
||||||
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
state = mod.State(self, self.room)
|
state = mod.State(self, self.room)
|
||||||
|
|
@ -202,7 +204,9 @@ class BaseState(object):
|
||||||
if cinematic:
|
if cinematic:
|
||||||
message = msg_cinematic(message, borders=borders)
|
message = msg_cinematic(message, borders=borders)
|
||||||
if target:
|
if target:
|
||||||
options = target.attributes.get("options", category=self.room.tagcategory, default={})
|
options = target.attributes.get(
|
||||||
|
"options", category=self.room.tagcategory, default={}
|
||||||
|
)
|
||||||
style = options.get("things_style", 2)
|
style = options.get("things_style", 2)
|
||||||
# we assume this is a char
|
# we assume this is a char
|
||||||
target.msg(parse_for_things(message, things_style=style))
|
target.msg(parse_for_things(message, things_style=style))
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,9 @@ class HelpButton(objects.EvscaperoomObject):
|
||||||
self.msg_char(caller, "There are no more hints to be had.")
|
self.msg_char(caller, "There are no more hints to be had.")
|
||||||
else:
|
else:
|
||||||
self.msg_room(
|
self.msg_room(
|
||||||
caller, f"{caller.key} pushes *button and gets the " f'hint:\n "{hint.strip()}"|n'
|
caller,
|
||||||
|
f"{caller.key} pushes *button and gets the "
|
||||||
|
f'hint:\n "{hint.strip()}"|n',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,9 @@ from . import utils
|
||||||
class TestEvscaperoomCommands(CommandTest):
|
class TestEvscaperoomCommands(CommandTest):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super().setUp()
|
super().setUp()
|
||||||
self.room1 = utils.create_evscaperoom_object("evscaperoom.room.EvscapeRoom", key="Testroom")
|
self.room1 = utils.create_evscaperoom_object(
|
||||||
|
"evscaperoom.room.EvscapeRoom", key="Testroom"
|
||||||
|
)
|
||||||
self.char1.location = self.room1
|
self.char1.location = self.room1
|
||||||
self.obj1.location = self.room1
|
self.obj1.location = self.room1
|
||||||
|
|
||||||
|
|
@ -151,19 +153,24 @@ class TestEvscaperoomCommands(CommandTest):
|
||||||
cmd.room = self.room1
|
cmd.room = self.room1
|
||||||
cmd.focus = self.obj1
|
cmd.focus = self.obj1
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
self.char1.attributes.get("focus", category=self.room1.tagcategory), self.obj1
|
self.char1.attributes.get("focus", category=self.room1.tagcategory),
|
||||||
|
self.obj1,
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_focus(self):
|
def test_focus(self):
|
||||||
# don't focus on a non-room object
|
# don't focus on a non-room object
|
||||||
self.call(commands.CmdFocus(), "obj")
|
self.call(commands.CmdFocus(), "obj")
|
||||||
self.assertEqual(self.char1.attributes.get("focus", category=self.room1.tagcategory), None)
|
self.assertEqual(
|
||||||
|
self.char1.attributes.get("focus", category=self.room1.tagcategory), None
|
||||||
|
)
|
||||||
# should focus correctly
|
# should focus correctly
|
||||||
myobj = utils.create_evscaperoom_object(
|
myobj = utils.create_evscaperoom_object(
|
||||||
objects.EvscaperoomObject, "mytestobj", location=self.room1
|
objects.EvscaperoomObject, "mytestobj", location=self.room1
|
||||||
)
|
)
|
||||||
self.call(commands.CmdFocus(), "mytestobj")
|
self.call(commands.CmdFocus(), "mytestobj")
|
||||||
self.assertEqual(self.char1.attributes.get("focus", category=self.room1.tagcategory), myobj)
|
self.assertEqual(
|
||||||
|
self.char1.attributes.get("focus", category=self.room1.tagcategory), myobj
|
||||||
|
)
|
||||||
|
|
||||||
def test_look(self):
|
def test_look(self):
|
||||||
self.call(commands.CmdLook(), "at obj", "Obj")
|
self.call(commands.CmdLook(), "at obj", "Obj")
|
||||||
|
|
@ -173,13 +180,19 @@ class TestEvscaperoomCommands(CommandTest):
|
||||||
def test_speech(self):
|
def test_speech(self):
|
||||||
self.call(commands.CmdSpeak(), "", "What do you want to say?", cmdstring="")
|
self.call(commands.CmdSpeak(), "", "What do you want to say?", cmdstring="")
|
||||||
self.call(commands.CmdSpeak(), "Hello!", "You say: Hello!", cmdstring="")
|
self.call(commands.CmdSpeak(), "Hello!", "You say: Hello!", cmdstring="")
|
||||||
self.call(commands.CmdSpeak(), "", "What do you want to whisper?", cmdstring="whisper")
|
self.call(
|
||||||
|
commands.CmdSpeak(), "", "What do you want to whisper?", cmdstring="whisper"
|
||||||
|
)
|
||||||
self.call(commands.CmdSpeak(), "Hi.", "You whisper: Hi.", cmdstring="whisper")
|
self.call(commands.CmdSpeak(), "Hi.", "You whisper: Hi.", cmdstring="whisper")
|
||||||
self.call(commands.CmdSpeak(), "Hi.", "You whisper: Hi.", cmdstring="whisper")
|
self.call(commands.CmdSpeak(), "Hi.", "You whisper: Hi.", cmdstring="whisper")
|
||||||
self.call(commands.CmdSpeak(), "HELLO!", "You shout: HELLO!", cmdstring="shout")
|
self.call(commands.CmdSpeak(), "HELLO!", "You shout: HELLO!", cmdstring="shout")
|
||||||
|
|
||||||
self.call(commands.CmdSpeak(), "Hello to obj", "You say: Hello", cmdstring="say")
|
self.call(
|
||||||
self.call(commands.CmdSpeak(), "Hello to obj", "You shout: Hello", cmdstring="shout")
|
commands.CmdSpeak(), "Hello to obj", "You say: Hello", cmdstring="say"
|
||||||
|
)
|
||||||
|
self.call(
|
||||||
|
commands.CmdSpeak(), "Hello to obj", "You shout: Hello", cmdstring="shout"
|
||||||
|
)
|
||||||
|
|
||||||
def test_emote(self):
|
def test_emote(self):
|
||||||
self.call(
|
self.call(
|
||||||
|
|
@ -194,7 +207,9 @@ class TestEvscaperoomCommands(CommandTest):
|
||||||
|
|
||||||
class TestUtils(EvenniaTest):
|
class TestUtils(EvenniaTest):
|
||||||
def test_overwrite(self):
|
def test_overwrite(self):
|
||||||
room = utils.create_evscaperoom_object("evscaperoom.room.EvscapeRoom", key="Testroom")
|
room = utils.create_evscaperoom_object(
|
||||||
|
"evscaperoom.room.EvscapeRoom", key="Testroom"
|
||||||
|
)
|
||||||
obj1 = utils.create_evscaperoom_object(
|
obj1 = utils.create_evscaperoom_object(
|
||||||
objects.EvscaperoomObject, key="testobj", location=room
|
objects.EvscaperoomObject, key="testobj", location=room
|
||||||
)
|
)
|
||||||
|
|
@ -212,11 +227,15 @@ class TestUtils(EvenniaTest):
|
||||||
|
|
||||||
def test_parse_for_perspectives(self):
|
def test_parse_for_perspectives(self):
|
||||||
|
|
||||||
second, third = utils.parse_for_perspectives("~You ~look at the nice book", "TestGuy")
|
second, third = utils.parse_for_perspectives(
|
||||||
|
"~You ~look at the nice book", "TestGuy"
|
||||||
|
)
|
||||||
self.assertTrue(second, "You look at the nice book")
|
self.assertTrue(second, "You look at the nice book")
|
||||||
self.assertTrue(third, "TestGuy looks at the nice book")
|
self.assertTrue(third, "TestGuy looks at the nice book")
|
||||||
# irregular
|
# irregular
|
||||||
second, third = utils.parse_for_perspectives("With a smile, ~you ~were gone", "TestGuy")
|
second, third = utils.parse_for_perspectives(
|
||||||
|
"With a smile, ~you ~were gone", "TestGuy"
|
||||||
|
)
|
||||||
self.assertTrue(second, "With a smile, you were gone")
|
self.assertTrue(second, "With a smile, you were gone")
|
||||||
self.assertTrue(third, "With a smile, TestGuy was gone")
|
self.assertTrue(third, "With a smile, TestGuy was gone")
|
||||||
|
|
||||||
|
|
@ -224,8 +243,12 @@ class TestUtils(EvenniaTest):
|
||||||
|
|
||||||
string = "Looking at *book and *key."
|
string = "Looking at *book and *key."
|
||||||
self.assertEqual(utils.parse_for_things(string, 0), "Looking at book and key.")
|
self.assertEqual(utils.parse_for_things(string, 0), "Looking at book and key.")
|
||||||
self.assertEqual(utils.parse_for_things(string, 1), "Looking at |ybook|n and |ykey|n.")
|
self.assertEqual(
|
||||||
self.assertEqual(utils.parse_for_things(string, 2), "Looking at |y[book]|n and |y[key]|n.")
|
utils.parse_for_things(string, 1), "Looking at |ybook|n and |ykey|n."
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
utils.parse_for_things(string, 2), "Looking at |y[book]|n and |y[key]|n."
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class TestEvScapeRoom(EvenniaTest):
|
class TestEvScapeRoom(EvenniaTest):
|
||||||
|
|
@ -248,10 +271,14 @@ class TestEvScapeRoom(EvenniaTest):
|
||||||
self.assertEqual(list(room.get_all_characters()), [self.char1])
|
self.assertEqual(list(room.get_all_characters()), [self.char1])
|
||||||
|
|
||||||
room.tag_character(self.char1, "opened_door")
|
room.tag_character(self.char1, "opened_door")
|
||||||
self.assertEqual(self.char1.tags.get("opened_door", category=self.roomtag), "opened_door")
|
self.assertEqual(
|
||||||
|
self.char1.tags.get("opened_door", category=self.roomtag), "opened_door"
|
||||||
|
)
|
||||||
|
|
||||||
room.tag_all_characters("tagged_all")
|
room.tag_all_characters("tagged_all")
|
||||||
self.assertEqual(self.char1.tags.get("tagged_all", category=self.roomtag), "tagged_all")
|
self.assertEqual(
|
||||||
|
self.char1.tags.get("tagged_all", category=self.roomtag), "tagged_all"
|
||||||
|
)
|
||||||
|
|
||||||
room.character_cleanup(self.char1)
|
room.character_cleanup(self.char1)
|
||||||
self.assertEqual(self.char1.tags.get(category=self.roomtag), None)
|
self.assertEqual(self.char1.tags.get(category=self.roomtag), None)
|
||||||
|
|
|
||||||
|
|
@ -94,7 +94,9 @@ from evennia import utils
|
||||||
from evennia import CmdSet
|
from evennia import CmdSet
|
||||||
|
|
||||||
# error return function, needed by Extended Look command
|
# error return function, needed by Extended Look command
|
||||||
_AT_SEARCH_RESULT = utils.variable_from_module(*settings.SEARCH_AT_RESULT.rsplit(".", 1))
|
_AT_SEARCH_RESULT = utils.variable_from_module(
|
||||||
|
*settings.SEARCH_AT_RESULT.rsplit(".", 1)
|
||||||
|
)
|
||||||
|
|
||||||
# regexes for in-desc replacements
|
# regexes for in-desc replacements
|
||||||
RE_MORNING = re.compile(r"<morning>(.*?)</morning>", re.IGNORECASE)
|
RE_MORNING = re.compile(r"<morning>(.*?)</morning>", re.IGNORECASE)
|
||||||
|
|
@ -444,7 +446,12 @@ class CmdExtendedRoomDesc(default_cmds.CmdDesc):
|
||||||
string += " |wgeneral:|n %s" % location.db.general_desc
|
string += " |wgeneral:|n %s" % location.db.general_desc
|
||||||
caller.msg(string)
|
caller.msg(string)
|
||||||
return
|
return
|
||||||
if self.switches and self.switches[0] in ("spring", "summer", "autumn", "winter"):
|
if self.switches and self.switches[0] in (
|
||||||
|
"spring",
|
||||||
|
"summer",
|
||||||
|
"autumn",
|
||||||
|
"winter",
|
||||||
|
):
|
||||||
# a seasonal switch was given
|
# a seasonal switch was given
|
||||||
if self.rhs:
|
if self.rhs:
|
||||||
caller.msg("Seasonal descs only work with rooms, not objects.")
|
caller.msg("Seasonal descs only work with rooms, not objects.")
|
||||||
|
|
@ -519,9 +526,13 @@ class CmdExtendedRoomDetail(default_cmds.MuxCommand):
|
||||||
if not self.args:
|
if not self.args:
|
||||||
details = location.db.details
|
details = location.db.details
|
||||||
if not details:
|
if not details:
|
||||||
self.msg("|rThe room {} doesn't have any detail set.|n".format(location))
|
self.msg(
|
||||||
|
"|rThe room {} doesn't have any detail set.|n".format(location)
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
details = sorted(["|y{}|n: {}".format(key, desc) for key, desc in details.items()])
|
details = sorted(
|
||||||
|
["|y{}|n: {}".format(key, desc) for key, desc in details.items()]
|
||||||
|
)
|
||||||
self.msg("Details on Room:\n" + "\n".join(details))
|
self.msg("Details on Room:\n" + "\n".join(details))
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -278,7 +278,11 @@ def menunode_fieldfill(caller, raw_string, **kwargs):
|
||||||
# Display current form data
|
# Display current form data
|
||||||
text = (
|
text = (
|
||||||
display_formdata(
|
display_formdata(
|
||||||
formtemplate, formdata, pretext=pretext, posttext=posttext, borderstyle=borderstyle
|
formtemplate,
|
||||||
|
formdata,
|
||||||
|
pretext=pretext,
|
||||||
|
posttext=posttext,
|
||||||
|
borderstyle=borderstyle,
|
||||||
),
|
),
|
||||||
formhelptext,
|
formhelptext,
|
||||||
)
|
)
|
||||||
|
|
@ -292,7 +296,10 @@ def menunode_fieldfill(caller, raw_string, **kwargs):
|
||||||
for field in formtemplate:
|
for field in formtemplate:
|
||||||
if "required" in field.keys():
|
if "required" in field.keys():
|
||||||
# If field is required but current form data for field is blank
|
# If field is required but current form data for field is blank
|
||||||
if field["required"] is True and formdata[field["fieldname"]] is None:
|
if (
|
||||||
|
field["required"] is True
|
||||||
|
and formdata[field["fieldname"]] is None
|
||||||
|
):
|
||||||
# Add to blank and required fields
|
# Add to blank and required fields
|
||||||
blank_and_required.append(field["fieldname"])
|
blank_and_required.append(field["fieldname"])
|
||||||
if len(blank_and_required) > 0:
|
if len(blank_and_required) > 0:
|
||||||
|
|
@ -428,22 +435,30 @@ def menunode_fieldfill(caller, raw_string, **kwargs):
|
||||||
# Test for max/min
|
# Test for max/min
|
||||||
if max_value is not None:
|
if max_value is not None:
|
||||||
if newvalue > max_value:
|
if newvalue > max_value:
|
||||||
caller.msg("Field '%s' has a maximum value of %i." % (matched_field, max_value))
|
caller.msg(
|
||||||
|
"Field '%s' has a maximum value of %i."
|
||||||
|
% (matched_field, max_value)
|
||||||
|
)
|
||||||
text = (None, formhelptext)
|
text = (None, formhelptext)
|
||||||
return text, options
|
return text, options
|
||||||
if min_value is not None:
|
if min_value is not None:
|
||||||
if newvalue < min_value:
|
if newvalue < min_value:
|
||||||
caller.msg(
|
caller.msg(
|
||||||
"Field '%s' reqiures a minimum value of %i." % (matched_field, min_value)
|
"Field '%s' reqiures a minimum value of %i."
|
||||||
|
% (matched_field, min_value)
|
||||||
)
|
)
|
||||||
text = (None, formhelptext)
|
text = (None, formhelptext)
|
||||||
return text, options
|
return text, options
|
||||||
|
|
||||||
# Field type bool verification
|
# Field type bool verification
|
||||||
if fieldtype == "bool":
|
if fieldtype == "bool":
|
||||||
if newvalue.lower() != truestr.lower() and newvalue.lower() != falsestr.lower():
|
if (
|
||||||
|
newvalue.lower() != truestr.lower()
|
||||||
|
and newvalue.lower() != falsestr.lower()
|
||||||
|
):
|
||||||
caller.msg(
|
caller.msg(
|
||||||
"Please enter '%s' or '%s' for field '%s'." % (truestr, falsestr, matched_field)
|
"Please enter '%s' or '%s' for field '%s'."
|
||||||
|
% (truestr, falsestr, matched_field)
|
||||||
)
|
)
|
||||||
text = (None, formhelptext)
|
text = (None, formhelptext)
|
||||||
return text, options
|
return text, options
|
||||||
|
|
@ -509,7 +524,9 @@ def form_template_to_dict(formtemplate):
|
||||||
return formdata
|
return formdata
|
||||||
|
|
||||||
|
|
||||||
def display_formdata(formtemplate, formdata, pretext="", posttext="", borderstyle="cells"):
|
def display_formdata(
|
||||||
|
formtemplate, formdata, pretext="", posttext="", borderstyle="cells"
|
||||||
|
):
|
||||||
"""
|
"""
|
||||||
Displays a form's current data as a table. Used in the form menu.
|
Displays a form's current data as a table. Used in the form menu.
|
||||||
|
|
||||||
|
|
@ -660,9 +677,7 @@ class CmdTestMenu(Command):
|
||||||
"""
|
"""
|
||||||
This performs the actual command.
|
This performs the actual command.
|
||||||
"""
|
"""
|
||||||
pretext = (
|
pretext = "|cSend a delayed message to another player ---------------------------------------|n"
|
||||||
"|cSend a delayed message to another player ---------------------------------------|n"
|
|
||||||
)
|
|
||||||
posttext = (
|
posttext = (
|
||||||
"|c--------------------------------------------------------------------------------|n|/"
|
"|c--------------------------------------------------------------------------------|n|/"
|
||||||
"Syntax: type |c<field> = <new value>|n to change the values of the form. Given|/"
|
"Syntax: type |c<field> = <new value>|n to change the values of the form. Given|/"
|
||||||
|
|
|
||||||
|
|
@ -101,7 +101,12 @@ class CallbackHandler(object):
|
||||||
if handler:
|
if handler:
|
||||||
return self.format_callback(
|
return self.format_callback(
|
||||||
handler.add_callback(
|
handler.add_callback(
|
||||||
self.obj, callback_name, code, author=author, valid=valid, parameters=parameters
|
self.obj,
|
||||||
|
callback_name,
|
||||||
|
code,
|
||||||
|
author=author,
|
||||||
|
valid=valid,
|
||||||
|
parameters=parameters,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -136,7 +136,9 @@ class CmdCallback(COMMAND_DEFAULT_CLASS):
|
||||||
self.is_validator = validator
|
self.is_validator = validator
|
||||||
self.autovalid = autovalid
|
self.autovalid = autovalid
|
||||||
if self.handler is None:
|
if self.handler is None:
|
||||||
caller.msg("The event handler is not running, can't " "access the event system.")
|
caller.msg(
|
||||||
|
"The event handler is not running, can't " "access the event system."
|
||||||
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
# Before the equal sign, there is an object name or nothing
|
# Before the equal sign, there is an object name or nothing
|
||||||
|
|
@ -164,7 +166,9 @@ class CmdCallback(COMMAND_DEFAULT_CLASS):
|
||||||
elif switch in ["tasks", "task"]:
|
elif switch in ["tasks", "task"]:
|
||||||
self.list_tasks()
|
self.list_tasks()
|
||||||
else:
|
else:
|
||||||
caller.msg("Mutually exclusive or invalid switches were " "used, cannot proceed.")
|
caller.msg(
|
||||||
|
"Mutually exclusive or invalid switches were " "used, cannot proceed."
|
||||||
|
)
|
||||||
|
|
||||||
def list_callbacks(self):
|
def list_callbacks(self):
|
||||||
"""Display the list of callbacks connected to the object."""
|
"""Display the list of callbacks connected to the object."""
|
||||||
|
|
@ -178,7 +182,9 @@ class CmdCallback(COMMAND_DEFAULT_CLASS):
|
||||||
# Check that the callback name can be found in this object
|
# Check that the callback name can be found in this object
|
||||||
created = callbacks.get(callback_name)
|
created = callbacks.get(callback_name)
|
||||||
if created is None:
|
if created is None:
|
||||||
self.msg("No callback {} has been set on {}.".format(callback_name, obj))
|
self.msg(
|
||||||
|
"No callback {} has been set on {}.".format(callback_name, obj)
|
||||||
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
if parameters:
|
if parameters:
|
||||||
|
|
@ -202,11 +208,15 @@ class CmdCallback(COMMAND_DEFAULT_CLASS):
|
||||||
updated_by = updated_by.key if updated_by else "|gUnknown|n"
|
updated_by = updated_by.key if updated_by else "|gUnknown|n"
|
||||||
created_on = callback.get("created_on")
|
created_on = callback.get("created_on")
|
||||||
created_on = (
|
created_on = (
|
||||||
created_on.strftime("%Y-%m-%d %H:%M:%S") if created_on else "|gUnknown|n"
|
created_on.strftime("%Y-%m-%d %H:%M:%S")
|
||||||
|
if created_on
|
||||||
|
else "|gUnknown|n"
|
||||||
)
|
)
|
||||||
updated_on = callback.get("updated_on")
|
updated_on = callback.get("updated_on")
|
||||||
updated_on = (
|
updated_on = (
|
||||||
updated_on.strftime("%Y-%m-%d %H:%M:%S") if updated_on else "|gUnknown|n"
|
updated_on.strftime("%Y-%m-%d %H:%M:%S")
|
||||||
|
if updated_on
|
||||||
|
else "|gUnknown|n"
|
||||||
)
|
)
|
||||||
msg = "Callback {} {} of {}:".format(callback_name, parameters, obj)
|
msg = "Callback {} {} of {}:".format(callback_name, parameters, obj)
|
||||||
msg += "\nCreated by {} on {}.".format(author, created_on)
|
msg += "\nCreated by {} on {}.".format(author, created_on)
|
||||||
|
|
@ -254,13 +264,17 @@ class CmdCallback(COMMAND_DEFAULT_CLASS):
|
||||||
self.msg(str(table))
|
self.msg(str(table))
|
||||||
else:
|
else:
|
||||||
names = list(set(list(types.keys()) + list(callbacks.keys())))
|
names = list(set(list(types.keys()) + list(callbacks.keys())))
|
||||||
table = EvTable("Callback name", "Number", "Description", valign="t", width=78)
|
table = EvTable(
|
||||||
|
"Callback name", "Number", "Description", valign="t", width=78
|
||||||
|
)
|
||||||
table.reformat_column(0, width=20)
|
table.reformat_column(0, width=20)
|
||||||
table.reformat_column(1, width=10, align="r")
|
table.reformat_column(1, width=10, align="r")
|
||||||
table.reformat_column(2, width=48)
|
table.reformat_column(2, width=48)
|
||||||
for name in sorted(names):
|
for name in sorted(names):
|
||||||
number = len(callbacks.get(name, []))
|
number = len(callbacks.get(name, []))
|
||||||
lines = sum(len(e["code"].splitlines()) for e in callbacks.get(name, []))
|
lines = sum(
|
||||||
|
len(e["code"].splitlines()) for e in callbacks.get(name, [])
|
||||||
|
)
|
||||||
no = "{} ({})".format(number, lines)
|
no = "{} ({})".format(number, lines)
|
||||||
description = types.get(name, (None, "Chained event."))[1]
|
description = types.get(name, (None, "Chained event."))[1]
|
||||||
description = description.strip("\n").splitlines()[0]
|
description = description.strip("\n").splitlines()[0]
|
||||||
|
|
@ -321,7 +335,9 @@ class CmdCallback(COMMAND_DEFAULT_CLASS):
|
||||||
|
|
||||||
# Check that the callback exists
|
# Check that the callback exists
|
||||||
if callback_name not in callbacks:
|
if callback_name not in callbacks:
|
||||||
self.msg("The callback name {} can't be found in {}.".format(callback_name, obj))
|
self.msg(
|
||||||
|
"The callback name {} can't be found in {}.".format(callback_name, obj)
|
||||||
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
# If there's only one callback, just edit it
|
# If there's only one callback, just edit it
|
||||||
|
|
@ -393,7 +409,9 @@ class CmdCallback(COMMAND_DEFAULT_CLASS):
|
||||||
|
|
||||||
# Check that the callback exists
|
# Check that the callback exists
|
||||||
if callback_name not in callbacks:
|
if callback_name not in callbacks:
|
||||||
self.msg("The callback name {} can't be found in {}.".format(callback_name, obj))
|
self.msg(
|
||||||
|
"The callback name {} can't be found in {}.".format(callback_name, obj)
|
||||||
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
# If there's only one callback, just delete it
|
# If there's only one callback, just delete it
|
||||||
|
|
@ -432,7 +450,11 @@ class CmdCallback(COMMAND_DEFAULT_CLASS):
|
||||||
|
|
||||||
# Delete the callback
|
# Delete the callback
|
||||||
self.handler.del_callback(obj, callback_name, number)
|
self.handler.del_callback(obj, callback_name, number)
|
||||||
self.msg("The callback {}[{}] of {} was deleted.".format(callback_name, number + 1, obj))
|
self.msg(
|
||||||
|
"The callback {}[{}] of {} was deleted.".format(
|
||||||
|
callback_name, number + 1, obj
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
def accept_callback(self):
|
def accept_callback(self):
|
||||||
"""Accept a callback."""
|
"""Accept a callback."""
|
||||||
|
|
@ -442,7 +464,9 @@ class CmdCallback(COMMAND_DEFAULT_CLASS):
|
||||||
|
|
||||||
# If no object, display the list of callbacks to be checked
|
# If no object, display the list of callbacks to be checked
|
||||||
if obj is None:
|
if obj is None:
|
||||||
table = EvTable("ID", "Type", "Object", "Name", "Updated by", "On", width=78)
|
table = EvTable(
|
||||||
|
"ID", "Type", "Object", "Name", "Updated by", "On", width=78
|
||||||
|
)
|
||||||
table.reformat_column(0, align="r")
|
table.reformat_column(0, align="r")
|
||||||
now = datetime.now()
|
now = datetime.now()
|
||||||
for obj, name, number in self.handler.db.to_valid:
|
for obj, name, number in self.handler.db.to_valid:
|
||||||
|
|
@ -484,7 +508,9 @@ class CmdCallback(COMMAND_DEFAULT_CLASS):
|
||||||
|
|
||||||
# Check that the callback exists
|
# Check that the callback exists
|
||||||
if callback_name not in callbacks:
|
if callback_name not in callbacks:
|
||||||
self.msg("The callback name {} can't be found in {}.".format(callback_name, obj))
|
self.msg(
|
||||||
|
"The callback name {} can't be found in {}.".format(callback_name, obj)
|
||||||
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
if not parameters:
|
if not parameters:
|
||||||
|
|
@ -499,7 +525,9 @@ class CmdCallback(COMMAND_DEFAULT_CLASS):
|
||||||
callback = callbacks[callback_name][number]
|
callback = callbacks[callback_name][number]
|
||||||
except (ValueError, AssertionError, IndexError):
|
except (ValueError, AssertionError, IndexError):
|
||||||
self.msg(
|
self.msg(
|
||||||
"The callback {} {} cannot be found in {}.".format(callback_name, parameters, obj)
|
"The callback {} {} cannot be found in {}.".format(
|
||||||
|
callback_name, parameters, obj
|
||||||
|
)
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
@ -509,7 +537,9 @@ class CmdCallback(COMMAND_DEFAULT_CLASS):
|
||||||
else:
|
else:
|
||||||
self.handler.accept_callback(obj, callback_name, number)
|
self.handler.accept_callback(obj, callback_name, number)
|
||||||
self.msg(
|
self.msg(
|
||||||
"The callback {} {} of {} has been accepted.".format(callback_name, parameters, obj)
|
"The callback {} {} of {} has been accepted.".format(
|
||||||
|
callback_name, parameters, obj
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
def list_tasks(self):
|
def list_tasks(self):
|
||||||
|
|
@ -557,10 +587,17 @@ def _ev_save(caller, buf):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if (callback["obj"], callback["name"], callback["number"]) in handler.db.locked:
|
if (callback["obj"], callback["name"], callback["number"]) in handler.db.locked:
|
||||||
handler.db.locked.remove((callback["obj"], callback["name"], callback["number"]))
|
handler.db.locked.remove(
|
||||||
|
(callback["obj"], callback["name"], callback["number"])
|
||||||
|
)
|
||||||
|
|
||||||
handler.edit_callback(
|
handler.edit_callback(
|
||||||
callback["obj"], callback["name"], callback["number"], buf, caller, valid=autovalid
|
callback["obj"],
|
||||||
|
callback["name"],
|
||||||
|
callback["number"],
|
||||||
|
buf,
|
||||||
|
caller,
|
||||||
|
valid=autovalid,
|
||||||
)
|
)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
@ -577,7 +614,9 @@ def _ev_quit(caller):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if (callback["obj"], callback["name"], callback["number"]) in handler.db.locked:
|
if (callback["obj"], callback["name"], callback["number"]) in handler.db.locked:
|
||||||
handler.db.locked.remove((callback["obj"], callback["name"], callback["number"]))
|
handler.db.locked.remove(
|
||||||
|
(callback["obj"], callback["name"], callback["number"])
|
||||||
|
)
|
||||||
|
|
||||||
del caller.db._callback
|
del caller.db._callback
|
||||||
caller.msg("Exited the code editor.")
|
caller.msg("Exited the code editor.")
|
||||||
|
|
|
||||||
|
|
@ -64,13 +64,17 @@ class EventHandler(DefaultScript):
|
||||||
"""
|
"""
|
||||||
self.ndb.events = {}
|
self.ndb.events = {}
|
||||||
for typeclass, name, variables, help_text, custom_call, custom_add in EVENTS:
|
for typeclass, name, variables, help_text, custom_call, custom_add in EVENTS:
|
||||||
self.add_event(typeclass, name, variables, help_text, custom_call, custom_add)
|
self.add_event(
|
||||||
|
typeclass, name, variables, help_text, custom_call, custom_add
|
||||||
|
)
|
||||||
|
|
||||||
# Generate locals
|
# Generate locals
|
||||||
self.ndb.current_locals = {}
|
self.ndb.current_locals = {}
|
||||||
self.ndb.fresh_locals = {}
|
self.ndb.fresh_locals = {}
|
||||||
addresses = ["evennia.contrib.ingame_python.eventfuncs"]
|
addresses = ["evennia.contrib.ingame_python.eventfuncs"]
|
||||||
addresses.extend(getattr(settings, "EVENTFUNCS_LOCATIONS", ["world.eventfuncs"]))
|
addresses.extend(
|
||||||
|
getattr(settings, "EVENTFUNCS_LOCATIONS", ["world.eventfuncs"])
|
||||||
|
)
|
||||||
for address in addresses:
|
for address in addresses:
|
||||||
if pypath_to_realpath(address):
|
if pypath_to_realpath(address):
|
||||||
self.ndb.fresh_locals.update(all_from_module(address))
|
self.ndb.fresh_locals.update(all_from_module(address))
|
||||||
|
|
@ -204,7 +208,9 @@ class EventHandler(DefaultScript):
|
||||||
|
|
||||||
return callbacks
|
return callbacks
|
||||||
|
|
||||||
def add_callback(self, obj, callback_name, code, author=None, valid=False, parameters=""):
|
def add_callback(
|
||||||
|
self, obj, callback_name, code, author=None, valid=False, parameters=""
|
||||||
|
):
|
||||||
"""
|
"""
|
||||||
Add the specified callback.
|
Add the specified callback.
|
||||||
|
|
||||||
|
|
@ -246,7 +252,9 @@ class EventHandler(DefaultScript):
|
||||||
self.db.to_valid.append((obj, callback_name, len(callbacks) - 1))
|
self.db.to_valid.append((obj, callback_name, len(callbacks) - 1))
|
||||||
|
|
||||||
# Call the custom_add if needed
|
# Call the custom_add if needed
|
||||||
custom_add = self.get_events(obj).get(callback_name, [None, None, None, None])[3]
|
custom_add = self.get_events(obj).get(callback_name, [None, None, None, None])[
|
||||||
|
3
|
||||||
|
]
|
||||||
if custom_add:
|
if custom_add:
|
||||||
custom_add(obj, callback_name, len(callbacks) - 1, parameters)
|
custom_add(obj, callback_name, len(callbacks) - 1, parameters)
|
||||||
|
|
||||||
|
|
@ -292,7 +300,12 @@ class EventHandler(DefaultScript):
|
||||||
|
|
||||||
# Edit the callback
|
# Edit the callback
|
||||||
callbacks[number].update(
|
callbacks[number].update(
|
||||||
{"updated_on": datetime.now(), "updated_by": author, "valid": valid, "code": code}
|
{
|
||||||
|
"updated_on": datetime.now(),
|
||||||
|
"updated_by": author,
|
||||||
|
"valid": valid,
|
||||||
|
"code": code,
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
# If not valid, set it in 'to_valid'
|
# If not valid, set it in 'to_valid'
|
||||||
|
|
@ -335,7 +348,9 @@ class EventHandler(DefaultScript):
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
logger.log_info(
|
logger.log_info(
|
||||||
"Deleting callback {} {} of {}:\n{}".format(callback_name, number, obj, code)
|
"Deleting callback {} {} of {}:\n{}".format(
|
||||||
|
callback_name, number, obj, code
|
||||||
|
)
|
||||||
)
|
)
|
||||||
del callbacks[number]
|
del callbacks[number]
|
||||||
|
|
||||||
|
|
@ -416,7 +431,8 @@ class EventHandler(DefaultScript):
|
||||||
allowed = ("number", "parameters", "locals")
|
allowed = ("number", "parameters", "locals")
|
||||||
if any(k for k in kwargs if k not in allowed):
|
if any(k for k in kwargs if k not in allowed):
|
||||||
raise TypeError(
|
raise TypeError(
|
||||||
"Unknown keyword arguments were specified " "to call callbacks: {}".format(kwargs)
|
"Unknown keyword arguments were specified "
|
||||||
|
"to call callbacks: {}".format(kwargs)
|
||||||
)
|
)
|
||||||
|
|
||||||
event = self.get_events(obj).get(callback_name)
|
event = self.get_events(obj).get(callback_name)
|
||||||
|
|
@ -436,7 +452,9 @@ class EventHandler(DefaultScript):
|
||||||
except IndexError:
|
except IndexError:
|
||||||
logger.log_trace(
|
logger.log_trace(
|
||||||
"callback {} of {} ({}): need variable "
|
"callback {} of {} ({}): need variable "
|
||||||
"{} in position {}".format(callback_name, obj, type(obj), variable, i)
|
"{} in position {}".format(
|
||||||
|
callback_name, obj, type(obj), variable, i
|
||||||
|
)
|
||||||
)
|
)
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
|
|
@ -489,7 +507,9 @@ class EventHandler(DefaultScript):
|
||||||
oid = obj.id
|
oid = obj.id
|
||||||
logger.log_err(
|
logger.log_err(
|
||||||
"An error occurred during the callback {} of "
|
"An error occurred during the callback {} of "
|
||||||
"{} (#{}), number {}\n{}".format(callback_name, obj, oid, number + 1, "\n".join(trace))
|
"{} (#{}), number {}\n{}".format(
|
||||||
|
callback_name, obj, oid, number + 1, "\n".join(trace)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
# Create the error message
|
# Create the error message
|
||||||
|
|
@ -522,9 +542,12 @@ class EventHandler(DefaultScript):
|
||||||
if updater and updater.sessions.all():
|
if updater and updater.sessions.all():
|
||||||
updater.msg(err_msg)
|
updater.msg(err_msg)
|
||||||
else:
|
else:
|
||||||
err_msg = "Error in {} of {} (#{})[{}], line {}:" " {}\n {}".format(
|
err_msg = (
|
||||||
|
"Error in {} of {} (#{})[{}], line {}:"
|
||||||
|
" {}\n {}".format(
|
||||||
callback_name, obj, oid, number + 1, lineno, line, exc
|
callback_name, obj, oid, number + 1, lineno, line, exc
|
||||||
)
|
)
|
||||||
|
)
|
||||||
self.ndb.channel.msg(err_msg)
|
self.ndb.channel.msg(err_msg)
|
||||||
|
|
||||||
def add_event(self, typeclass, name, variables, help_text, custom_call, custom_add):
|
def add_event(self, typeclass, name, variables, help_text, custom_call, custom_add):
|
||||||
|
|
@ -661,7 +684,9 @@ def complete_task(task_id):
|
||||||
return
|
return
|
||||||
|
|
||||||
if task_id not in script.db.tasks:
|
if task_id not in script.db.tasks:
|
||||||
logger.log_err("The task #{} was scheduled, but it cannot be " "found".format(task_id))
|
logger.log_err(
|
||||||
|
"The task #{} was scheduled, but it cannot be " "found".format(task_id)
|
||||||
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
delta, obj, callback_name, locals = script.db.tasks.pop(task_id)
|
delta, obj, callback_name, locals = script.db.tasks.pop(task_id)
|
||||||
|
|
|
||||||
|
|
@ -31,15 +31,21 @@ class TestEventHandler(EvenniaTest):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
"""Create the event handler."""
|
"""Create the event handler."""
|
||||||
super().setUp()
|
super().setUp()
|
||||||
self.handler = create_script("evennia.contrib.ingame_python.scripts.EventHandler")
|
self.handler = create_script(
|
||||||
|
"evennia.contrib.ingame_python.scripts.EventHandler"
|
||||||
|
)
|
||||||
|
|
||||||
# Copy old events if necessary
|
# Copy old events if necessary
|
||||||
if OLD_EVENTS:
|
if OLD_EVENTS:
|
||||||
self.handler.ndb.events = dict(OLD_EVENTS)
|
self.handler.ndb.events = dict(OLD_EVENTS)
|
||||||
|
|
||||||
# Alter typeclasses
|
# Alter typeclasses
|
||||||
self.char1.swap_typeclass("evennia.contrib.ingame_python.typeclasses.EventCharacter")
|
self.char1.swap_typeclass(
|
||||||
self.char2.swap_typeclass("evennia.contrib.ingame_python.typeclasses.EventCharacter")
|
"evennia.contrib.ingame_python.typeclasses.EventCharacter"
|
||||||
|
)
|
||||||
|
self.char2.swap_typeclass(
|
||||||
|
"evennia.contrib.ingame_python.typeclasses.EventCharacter"
|
||||||
|
)
|
||||||
self.room1.swap_typeclass("evennia.contrib.ingame_python.typeclasses.EventRoom")
|
self.room1.swap_typeclass("evennia.contrib.ingame_python.typeclasses.EventRoom")
|
||||||
self.room2.swap_typeclass("evennia.contrib.ingame_python.typeclasses.EventRoom")
|
self.room2.swap_typeclass("evennia.contrib.ingame_python.typeclasses.EventRoom")
|
||||||
self.exit.swap_typeclass("evennia.contrib.ingame_python.typeclasses.EventExit")
|
self.exit.swap_typeclass("evennia.contrib.ingame_python.typeclasses.EventExit")
|
||||||
|
|
@ -64,7 +70,11 @@ class TestEventHandler(EvenniaTest):
|
||||||
"""Add a callback while needing validation."""
|
"""Add a callback while needing validation."""
|
||||||
author = self.char1
|
author = self.char1
|
||||||
self.handler.add_callback(
|
self.handler.add_callback(
|
||||||
self.room1, "dummy", "character.db.strength = 40", author=author, valid=False
|
self.room1,
|
||||||
|
"dummy",
|
||||||
|
"character.db.strength = 40",
|
||||||
|
author=author,
|
||||||
|
valid=False,
|
||||||
)
|
)
|
||||||
callback = self.handler.get_callbacks(self.room1).get("dummy")
|
callback = self.handler.get_callbacks(self.room1).get("dummy")
|
||||||
callback = callback[0]
|
callback = callback[0]
|
||||||
|
|
@ -90,7 +100,12 @@ class TestEventHandler(EvenniaTest):
|
||||||
|
|
||||||
# Edit it right away
|
# Edit it right away
|
||||||
self.handler.edit_callback(
|
self.handler.edit_callback(
|
||||||
self.room1, "dummy", 0, "character.db.strength = 65", author=self.char2, valid=True
|
self.room1,
|
||||||
|
"dummy",
|
||||||
|
0,
|
||||||
|
"character.db.strength = 65",
|
||||||
|
author=self.char2,
|
||||||
|
valid=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Check that the callback was written
|
# Check that the callback was written
|
||||||
|
|
@ -116,7 +131,12 @@ class TestEventHandler(EvenniaTest):
|
||||||
|
|
||||||
# Edit it right away
|
# Edit it right away
|
||||||
self.handler.edit_callback(
|
self.handler.edit_callback(
|
||||||
self.room1, "dummy", 0, "character.db.strength = 80", author=self.char2, valid=False
|
self.room1,
|
||||||
|
"dummy",
|
||||||
|
0,
|
||||||
|
"character.db.strength = 80",
|
||||||
|
author=self.char2,
|
||||||
|
valid=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Run this dummy callback (shouldn't do anything)
|
# Run this dummy callback (shouldn't do anything)
|
||||||
|
|
@ -129,13 +149,25 @@ class TestEventHandler(EvenniaTest):
|
||||||
"""Try to delete a callback."""
|
"""Try to delete a callback."""
|
||||||
# Add 3 callbacks
|
# Add 3 callbacks
|
||||||
self.handler.add_callback(
|
self.handler.add_callback(
|
||||||
self.room1, "dummy", "character.db.strength = 5", author=self.char1, valid=True
|
self.room1,
|
||||||
|
"dummy",
|
||||||
|
"character.db.strength = 5",
|
||||||
|
author=self.char1,
|
||||||
|
valid=True,
|
||||||
)
|
)
|
||||||
self.handler.add_callback(
|
self.handler.add_callback(
|
||||||
self.room1, "dummy", "character.db.strength = 8", author=self.char2, valid=False
|
self.room1,
|
||||||
|
"dummy",
|
||||||
|
"character.db.strength = 8",
|
||||||
|
author=self.char2,
|
||||||
|
valid=False,
|
||||||
)
|
)
|
||||||
self.handler.add_callback(
|
self.handler.add_callback(
|
||||||
self.room1, "dummy", "character.db.strength = 9", author=self.char1, valid=True
|
self.room1,
|
||||||
|
"dummy",
|
||||||
|
"character.db.strength = 9",
|
||||||
|
author=self.char1,
|
||||||
|
valid=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Note that the second callback isn't valid
|
# Note that the second callback isn't valid
|
||||||
|
|
@ -171,10 +203,18 @@ class TestEventHandler(EvenniaTest):
|
||||||
"""Accept an callback."""
|
"""Accept an callback."""
|
||||||
# Add 2 callbacks
|
# Add 2 callbacks
|
||||||
self.handler.add_callback(
|
self.handler.add_callback(
|
||||||
self.room1, "dummy", "character.db.strength = 5", author=self.char1, valid=True
|
self.room1,
|
||||||
|
"dummy",
|
||||||
|
"character.db.strength = 5",
|
||||||
|
author=self.char1,
|
||||||
|
valid=True,
|
||||||
)
|
)
|
||||||
self.handler.add_callback(
|
self.handler.add_callback(
|
||||||
self.room1, "dummy", "character.db.strength = 8", author=self.char2, valid=False
|
self.room1,
|
||||||
|
"dummy",
|
||||||
|
"character.db.strength = 8",
|
||||||
|
author=self.char2,
|
||||||
|
valid=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Note that the second callback isn't valid
|
# Note that the second callback isn't valid
|
||||||
|
|
@ -209,12 +249,18 @@ class TestEventHandler(EvenniaTest):
|
||||||
"\n"
|
"\n"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
self.handler.add_callback(self.room1, "dummy", code, author=self.char1, valid=True)
|
self.handler.add_callback(
|
||||||
|
self.room1, "dummy", code, author=self.char1, valid=True
|
||||||
|
)
|
||||||
|
|
||||||
# Call the dummy callback
|
# Call the dummy callback
|
||||||
self.assertTrue(self.handler.call(self.room1, "dummy", locals={"character": self.char1}))
|
self.assertTrue(
|
||||||
|
self.handler.call(self.room1, "dummy", locals={"character": self.char1})
|
||||||
|
)
|
||||||
self.assertEqual(self.char1.db.health, 50)
|
self.assertEqual(self.char1.db.health, 50)
|
||||||
self.assertTrue(self.handler.call(self.room1, "dummy", locals={"character": self.char2}))
|
self.assertTrue(
|
||||||
|
self.handler.call(self.room1, "dummy", locals={"character": self.char2})
|
||||||
|
)
|
||||||
self.assertEqual(self.char2.db.health, 0)
|
self.assertEqual(self.char2.db.health, 0)
|
||||||
|
|
||||||
def test_handler(self):
|
def test_handler(self):
|
||||||
|
|
@ -222,7 +268,9 @@ class TestEventHandler(EvenniaTest):
|
||||||
self.assertIsNotNone(self.char1.callbacks)
|
self.assertIsNotNone(self.char1.callbacks)
|
||||||
|
|
||||||
# Add an callback
|
# Add an callback
|
||||||
callback = self.room1.callbacks.add("dummy", "pass", author=self.char1, valid=True)
|
callback = self.room1.callbacks.add(
|
||||||
|
"dummy", "pass", author=self.char1, valid=True
|
||||||
|
)
|
||||||
self.assertEqual(callback.obj, self.room1)
|
self.assertEqual(callback.obj, self.room1)
|
||||||
self.assertEqual(callback.name, "dummy")
|
self.assertEqual(callback.name, "dummy")
|
||||||
self.assertEqual(callback.code, "pass")
|
self.assertEqual(callback.code, "pass")
|
||||||
|
|
@ -238,7 +286,9 @@ class TestEventHandler(EvenniaTest):
|
||||||
self.assertNotIn([callback], list(self.room1.callbacks.all().values()))
|
self.assertNotIn([callback], list(self.room1.callbacks.all().values()))
|
||||||
|
|
||||||
# Try to call this callback
|
# Try to call this callback
|
||||||
self.assertTrue(self.room1.callbacks.call("dummy", locals={"character": self.char2}))
|
self.assertTrue(
|
||||||
|
self.room1.callbacks.call("dummy", locals={"character": self.char2})
|
||||||
|
)
|
||||||
self.assertTrue(self.char2.db.say)
|
self.assertTrue(self.char2.db.say)
|
||||||
|
|
||||||
# Delete the callback
|
# Delete the callback
|
||||||
|
|
@ -253,15 +303,21 @@ class TestCmdCallback(CommandTest):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
"""Create the callback handler."""
|
"""Create the callback handler."""
|
||||||
super().setUp()
|
super().setUp()
|
||||||
self.handler = create_script("evennia.contrib.ingame_python.scripts.EventHandler")
|
self.handler = create_script(
|
||||||
|
"evennia.contrib.ingame_python.scripts.EventHandler"
|
||||||
|
)
|
||||||
|
|
||||||
# Copy old events if necessary
|
# Copy old events if necessary
|
||||||
if OLD_EVENTS:
|
if OLD_EVENTS:
|
||||||
self.handler.ndb.events = dict(OLD_EVENTS)
|
self.handler.ndb.events = dict(OLD_EVENTS)
|
||||||
|
|
||||||
# Alter typeclasses
|
# Alter typeclasses
|
||||||
self.char1.swap_typeclass("evennia.contrib.ingame_python.typeclasses.EventCharacter")
|
self.char1.swap_typeclass(
|
||||||
self.char2.swap_typeclass("evennia.contrib.ingame_python.typeclasses.EventCharacter")
|
"evennia.contrib.ingame_python.typeclasses.EventCharacter"
|
||||||
|
)
|
||||||
|
self.char2.swap_typeclass(
|
||||||
|
"evennia.contrib.ingame_python.typeclasses.EventCharacter"
|
||||||
|
)
|
||||||
self.room1.swap_typeclass("evennia.contrib.ingame_python.typeclasses.EventRoom")
|
self.room1.swap_typeclass("evennia.contrib.ingame_python.typeclasses.EventRoom")
|
||||||
self.room2.swap_typeclass("evennia.contrib.ingame_python.typeclasses.EventRoom")
|
self.room2.swap_typeclass("evennia.contrib.ingame_python.typeclasses.EventRoom")
|
||||||
self.exit.swap_typeclass("evennia.contrib.ingame_python.typeclasses.EventExit")
|
self.exit.swap_typeclass("evennia.contrib.ingame_python.typeclasses.EventExit")
|
||||||
|
|
@ -291,7 +347,9 @@ class TestCmdCallback(CommandTest):
|
||||||
self.assertIn(cols[2].strip(), ("0 (0)", ""))
|
self.assertIn(cols[2].strip(), ("0 (0)", ""))
|
||||||
|
|
||||||
# Add some callback
|
# Add some callback
|
||||||
self.handler.add_callback(self.exit, "traverse", "pass", author=self.char1, valid=True)
|
self.handler.add_callback(
|
||||||
|
self.exit, "traverse", "pass", author=self.char1, valid=True
|
||||||
|
)
|
||||||
|
|
||||||
# Try to obtain more details on a specific callback on exit
|
# Try to obtain more details on a specific callback on exit
|
||||||
table = self.call(CmdCallback(), "out = traverse")
|
table = self.call(CmdCallback(), "out = traverse")
|
||||||
|
|
@ -370,16 +428,22 @@ class TestCmdCallback(CommandTest):
|
||||||
|
|
||||||
def test_del(self):
|
def test_del(self):
|
||||||
"""Add and remove an callback."""
|
"""Add and remove an callback."""
|
||||||
self.handler.add_callback(self.exit, "traverse", "pass", author=self.char1, valid=True)
|
self.handler.add_callback(
|
||||||
|
self.exit, "traverse", "pass", author=self.char1, valid=True
|
||||||
|
)
|
||||||
|
|
||||||
# Try to delete the callback
|
# Try to delete the callback
|
||||||
# char2 shouldn't be allowed to do so (that's not HIS callback)
|
# char2 shouldn't be allowed to do so (that's not HIS callback)
|
||||||
self.call(CmdCallback(), "/del out = traverse 1", caller=self.char2)
|
self.call(CmdCallback(), "/del out = traverse 1", caller=self.char2)
|
||||||
self.assertTrue(len(self.handler.get_callbacks(self.exit).get("traverse", [])) == 1)
|
self.assertTrue(
|
||||||
|
len(self.handler.get_callbacks(self.exit).get("traverse", [])) == 1
|
||||||
|
)
|
||||||
|
|
||||||
# Now, char1 should be allowed to delete it
|
# Now, char1 should be allowed to delete it
|
||||||
self.call(CmdCallback(), "/del out = traverse 1")
|
self.call(CmdCallback(), "/del out = traverse 1")
|
||||||
self.assertTrue(len(self.handler.get_callbacks(self.exit).get("traverse", [])) == 0)
|
self.assertTrue(
|
||||||
|
len(self.handler.get_callbacks(self.exit).get("traverse", [])) == 0
|
||||||
|
)
|
||||||
|
|
||||||
def test_lock(self):
|
def test_lock(self):
|
||||||
"""Test the lock of multiple editing."""
|
"""Test the lock of multiple editing."""
|
||||||
|
|
@ -432,15 +496,21 @@ class TestDefaultCallbacks(CommandTest):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
"""Create the callback handler."""
|
"""Create the callback handler."""
|
||||||
super().setUp()
|
super().setUp()
|
||||||
self.handler = create_script("evennia.contrib.ingame_python.scripts.EventHandler")
|
self.handler = create_script(
|
||||||
|
"evennia.contrib.ingame_python.scripts.EventHandler"
|
||||||
|
)
|
||||||
|
|
||||||
# Copy old events if necessary
|
# Copy old events if necessary
|
||||||
if OLD_EVENTS:
|
if OLD_EVENTS:
|
||||||
self.handler.ndb.events = dict(OLD_EVENTS)
|
self.handler.ndb.events = dict(OLD_EVENTS)
|
||||||
|
|
||||||
# Alter typeclasses
|
# Alter typeclasses
|
||||||
self.char1.swap_typeclass("evennia.contrib.ingame_python.typeclasses.EventCharacter")
|
self.char1.swap_typeclass(
|
||||||
self.char2.swap_typeclass("evennia.contrib.ingame_python.typeclasses.EventCharacter")
|
"evennia.contrib.ingame_python.typeclasses.EventCharacter"
|
||||||
|
)
|
||||||
|
self.char2.swap_typeclass(
|
||||||
|
"evennia.contrib.ingame_python.typeclasses.EventCharacter"
|
||||||
|
)
|
||||||
self.room1.swap_typeclass("evennia.contrib.ingame_python.typeclasses.EventRoom")
|
self.room1.swap_typeclass("evennia.contrib.ingame_python.typeclasses.EventRoom")
|
||||||
self.room2.swap_typeclass("evennia.contrib.ingame_python.typeclasses.EventRoom")
|
self.room2.swap_typeclass("evennia.contrib.ingame_python.typeclasses.EventRoom")
|
||||||
self.exit.swap_typeclass("evennia.contrib.ingame_python.typeclasses.EventExit")
|
self.exit.swap_typeclass("evennia.contrib.ingame_python.typeclasses.EventExit")
|
||||||
|
|
@ -471,20 +541,28 @@ class TestDefaultCallbacks(CommandTest):
|
||||||
self.exit.destination = self.room2
|
self.exit.destination = self.room2
|
||||||
|
|
||||||
# Try the can_traverse callback
|
# Try the can_traverse callback
|
||||||
self.handler.add_callback(self.exit, "can_traverse", code, author=self.char1, valid=True)
|
self.handler.add_callback(
|
||||||
|
self.exit, "can_traverse", code, author=self.char1, valid=True
|
||||||
|
)
|
||||||
|
|
||||||
# Have char1 move through the exit
|
# Have char1 move through the exit
|
||||||
self.call(ExitCommand(), "", "You can leave.", obj=self.exit)
|
self.call(ExitCommand(), "", "You can leave.", obj=self.exit)
|
||||||
self.assertIs(self.char1.location, self.room2)
|
self.assertIs(self.char1.location, self.room2)
|
||||||
|
|
||||||
# Have char2 move through this exit
|
# Have char2 move through this exit
|
||||||
self.call(ExitCommand(), "", "You cannot leave.", obj=self.exit, caller=self.char2)
|
self.call(
|
||||||
|
ExitCommand(), "", "You cannot leave.", obj=self.exit, caller=self.char2
|
||||||
|
)
|
||||||
self.assertIs(self.char2.location, self.room1)
|
self.assertIs(self.char2.location, self.room1)
|
||||||
|
|
||||||
# Try the traverse callback
|
# Try the traverse callback
|
||||||
self.handler.del_callback(self.exit, "can_traverse", 0)
|
self.handler.del_callback(self.exit, "can_traverse", 0)
|
||||||
self.handler.add_callback(
|
self.handler.add_callback(
|
||||||
self.exit, "traverse", "character.msg('Fine!')", author=self.char1, valid=True
|
self.exit,
|
||||||
|
"traverse",
|
||||||
|
"character.msg('Fine!')",
|
||||||
|
author=self.char1,
|
||||||
|
valid=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Have char2 move through the exit
|
# Have char2 move through the exit
|
||||||
|
|
@ -498,7 +576,9 @@ class TestDefaultCallbacks(CommandTest):
|
||||||
|
|
||||||
# Test msg_arrive and msg_leave
|
# Test msg_arrive and msg_leave
|
||||||
code = 'message = "{character} goes out."'
|
code = 'message = "{character} goes out."'
|
||||||
self.handler.add_callback(self.exit, "msg_leave", code, author=self.char1, valid=True)
|
self.handler.add_callback(
|
||||||
|
self.exit, "msg_leave", code, author=self.char1, valid=True
|
||||||
|
)
|
||||||
|
|
||||||
# Have char1 move through the exit
|
# Have char1 move through the exit
|
||||||
old_msg = self.char2.msg
|
old_msg = self.char2.msg
|
||||||
|
|
@ -506,11 +586,15 @@ class TestDefaultCallbacks(CommandTest):
|
||||||
self.char2.msg = Mock()
|
self.char2.msg = Mock()
|
||||||
self.call(ExitCommand(), "", obj=self.exit)
|
self.call(ExitCommand(), "", obj=self.exit)
|
||||||
stored_msg = [
|
stored_msg = [
|
||||||
args[0] if args and args[0] else kwargs.get("text", utils.to_str(kwargs))
|
args[0]
|
||||||
|
if args and args[0]
|
||||||
|
else kwargs.get("text", utils.to_str(kwargs))
|
||||||
for name, args, kwargs in self.char2.msg.mock_calls
|
for name, args, kwargs in self.char2.msg.mock_calls
|
||||||
]
|
]
|
||||||
# Get the first element of a tuple if msg received a tuple instead of a string
|
# Get the first element of a tuple if msg received a tuple instead of a string
|
||||||
stored_msg = [smsg[0] if isinstance(smsg, tuple) else smsg for smsg in stored_msg]
|
stored_msg = [
|
||||||
|
smsg[0] if isinstance(smsg, tuple) else smsg for smsg in stored_msg
|
||||||
|
]
|
||||||
returned_msg = ansi.parse_ansi("\n".join(stored_msg), strip_ansi=True)
|
returned_msg = ansi.parse_ansi("\n".join(stored_msg), strip_ansi=True)
|
||||||
self.assertEqual(returned_msg, "char1 goes out.")
|
self.assertEqual(returned_msg, "char1 goes out.")
|
||||||
finally:
|
finally:
|
||||||
|
|
@ -524,7 +608,9 @@ class TestDefaultCallbacks(CommandTest):
|
||||||
destination=self.room1,
|
destination=self.room1,
|
||||||
)
|
)
|
||||||
code = 'message = "{character} goes in."'
|
code = 'message = "{character} goes in."'
|
||||||
self.handler.add_callback(self.exit, "msg_arrive", code, author=self.char1, valid=True)
|
self.handler.add_callback(
|
||||||
|
self.exit, "msg_arrive", code, author=self.char1, valid=True
|
||||||
|
)
|
||||||
|
|
||||||
# Have char1 move through the exit
|
# Have char1 move through the exit
|
||||||
old_msg = self.char2.msg
|
old_msg = self.char2.msg
|
||||||
|
|
@ -532,11 +618,15 @@ class TestDefaultCallbacks(CommandTest):
|
||||||
self.char2.msg = Mock()
|
self.char2.msg = Mock()
|
||||||
self.call(ExitCommand(), "", obj=back)
|
self.call(ExitCommand(), "", obj=back)
|
||||||
stored_msg = [
|
stored_msg = [
|
||||||
args[0] if args and args[0] else kwargs.get("text", utils.to_str(kwargs))
|
args[0]
|
||||||
|
if args and args[0]
|
||||||
|
else kwargs.get("text", utils.to_str(kwargs))
|
||||||
for name, args, kwargs in self.char2.msg.mock_calls
|
for name, args, kwargs in self.char2.msg.mock_calls
|
||||||
]
|
]
|
||||||
# Get the first element of a tuple if msg received a tuple instead of a string
|
# Get the first element of a tuple if msg received a tuple instead of a string
|
||||||
stored_msg = [smsg[0] if isinstance(smsg, tuple) else smsg for smsg in stored_msg]
|
stored_msg = [
|
||||||
|
smsg[0] if isinstance(smsg, tuple) else smsg for smsg in stored_msg
|
||||||
|
]
|
||||||
returned_msg = ansi.parse_ansi("\n".join(stored_msg), strip_ansi=True)
|
returned_msg = ansi.parse_ansi("\n".join(stored_msg), strip_ansi=True)
|
||||||
self.assertEqual(returned_msg, "char1 goes in.")
|
self.assertEqual(returned_msg, "char1 goes in.")
|
||||||
finally:
|
finally:
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,11 @@ from evennia import DefaultCharacter, DefaultExit, DefaultObject, DefaultRoom
|
||||||
from evennia import ScriptDB
|
from evennia import ScriptDB
|
||||||
from evennia.utils.utils import delay, inherits_from, lazy_property
|
from evennia.utils.utils import delay, inherits_from, lazy_property
|
||||||
from evennia.contrib.ingame_python.callbackhandler import CallbackHandler
|
from evennia.contrib.ingame_python.callbackhandler import CallbackHandler
|
||||||
from evennia.contrib.ingame_python.utils import register_events, time_event, phrase_event
|
from evennia.contrib.ingame_python.utils import (
|
||||||
|
register_events,
|
||||||
|
time_event,
|
||||||
|
phrase_event,
|
||||||
|
)
|
||||||
|
|
||||||
# Character help
|
# Character help
|
||||||
CHARACTER_CAN_DELETE = """
|
CHARACTER_CAN_DELETE = """
|
||||||
|
|
@ -170,7 +174,11 @@ class EventCharacter(DefaultCharacter):
|
||||||
"can_delete": (["character"], CHARACTER_CAN_DELETE),
|
"can_delete": (["character"], CHARACTER_CAN_DELETE),
|
||||||
"can_move": (["character", "origin", "destination"], CHARACTER_CAN_MOVE),
|
"can_move": (["character", "origin", "destination"], CHARACTER_CAN_MOVE),
|
||||||
"can_part": (["character", "departing"], CHARACTER_CAN_PART),
|
"can_part": (["character", "departing"], CHARACTER_CAN_PART),
|
||||||
"can_say": (["speaker", "character", "message"], CHARACTER_CAN_SAY, phrase_event),
|
"can_say": (
|
||||||
|
["speaker", "character", "message"],
|
||||||
|
CHARACTER_CAN_SAY,
|
||||||
|
phrase_event,
|
||||||
|
),
|
||||||
"delete": (["character"], CHARACTER_DELETE),
|
"delete": (["character"], CHARACTER_DELETE),
|
||||||
"greet": (["character", "newcomer"], CHARACTER_GREET),
|
"greet": (["character", "newcomer"], CHARACTER_GREET),
|
||||||
"move": (["character", "origin", "destination"], CHARACTER_MOVE),
|
"move": (["character", "origin", "destination"], CHARACTER_MOVE),
|
||||||
|
|
@ -213,7 +221,9 @@ class EventCharacter(DefaultCharacter):
|
||||||
# Get the exit from location to destination
|
# Get the exit from location to destination
|
||||||
location = self.location
|
location = self.location
|
||||||
exits = [
|
exits = [
|
||||||
o for o in location.contents if o.location is location and o.destination is destination
|
o
|
||||||
|
for o in location.contents
|
||||||
|
if o.location is location and o.destination is destination
|
||||||
]
|
]
|
||||||
mapping = mapping or {}
|
mapping = mapping or {}
|
||||||
mapping.update({"character": self})
|
mapping.update({"character": self})
|
||||||
|
|
@ -255,7 +265,9 @@ class EventCharacter(DefaultCharacter):
|
||||||
if not source_location and self.location.has_account:
|
if not source_location and self.location.has_account:
|
||||||
# This was created from nowhere and added to an account's
|
# This was created from nowhere and added to an account's
|
||||||
# inventory; it's probably the result of a create command.
|
# inventory; it's probably the result of a create command.
|
||||||
string = "You now have %s in your possession." % self.get_display_name(self.location)
|
string = "You now have %s in your possession." % self.get_display_name(
|
||||||
|
self.location
|
||||||
|
)
|
||||||
self.location.msg(string)
|
self.location.msg(string)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
@ -351,7 +363,9 @@ class EventCharacter(DefaultCharacter):
|
||||||
|
|
||||||
# Call the 'greet' event of characters in the location
|
# Call the 'greet' event of characters in the location
|
||||||
for present in [
|
for present in [
|
||||||
o for o in destination.contents if isinstance(o, DefaultCharacter) and o is not self
|
o
|
||||||
|
for o in destination.contents
|
||||||
|
if isinstance(o, DefaultCharacter) and o is not self
|
||||||
]:
|
]:
|
||||||
present.callbacks.call("greet", present, self)
|
present.callbacks.call("greet", present, self)
|
||||||
|
|
||||||
|
|
@ -436,11 +450,14 @@ class EventCharacter(DefaultCharacter):
|
||||||
location = getattr(self, "location", None)
|
location = getattr(self, "location", None)
|
||||||
location = (
|
location = (
|
||||||
location
|
location
|
||||||
if location and inherits_from(location, "evennia.objects.objects.DefaultRoom")
|
if location
|
||||||
|
and inherits_from(location, "evennia.objects.objects.DefaultRoom")
|
||||||
else None
|
else None
|
||||||
)
|
)
|
||||||
if location and not kwargs.get("whisper", False):
|
if location and not kwargs.get("whisper", False):
|
||||||
allow = location.callbacks.call("can_say", self, location, message, parameters=message)
|
allow = location.callbacks.call(
|
||||||
|
"can_say", self, location, message, parameters=message
|
||||||
|
)
|
||||||
message = location.callbacks.get_variable("message")
|
message = location.callbacks.get_variable("message")
|
||||||
if not allow or not message:
|
if not allow or not message:
|
||||||
return
|
return
|
||||||
|
|
@ -452,7 +469,9 @@ class EventCharacter(DefaultCharacter):
|
||||||
):
|
):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
allow = obj.callbacks.call("can_say", self, obj, message, parameters=message)
|
allow = obj.callbacks.call(
|
||||||
|
"can_say", self, obj, message, parameters=message
|
||||||
|
)
|
||||||
message = obj.callbacks.get_variable("message")
|
message = obj.callbacks.get_variable("message")
|
||||||
if not allow or not message:
|
if not allow or not message:
|
||||||
return
|
return
|
||||||
|
|
@ -505,7 +524,8 @@ class EventCharacter(DefaultCharacter):
|
||||||
location = getattr(self, "location", None)
|
location = getattr(self, "location", None)
|
||||||
location = (
|
location = (
|
||||||
location
|
location
|
||||||
if location and inherits_from(location, "evennia.objects.objects.DefaultRoom")
|
if location
|
||||||
|
and inherits_from(location, "evennia.objects.objects.DefaultRoom")
|
||||||
else None
|
else None
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -520,7 +540,9 @@ class EventCharacter(DefaultCharacter):
|
||||||
and inherits_from(obj, "evennia.objects.objects.DefaultCharacter")
|
and inherits_from(obj, "evennia.objects.objects.DefaultCharacter")
|
||||||
]
|
]
|
||||||
for present in presents:
|
for present in presents:
|
||||||
present.callbacks.call("say", self, present, message, parameters=message)
|
present.callbacks.call(
|
||||||
|
"say", self, present, message, parameters=message
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# Exit help
|
# Exit help
|
||||||
|
|
@ -657,7 +679,9 @@ class EventExit(DefaultExit):
|
||||||
"""
|
"""
|
||||||
is_character = inherits_from(traversing_object, DefaultCharacter)
|
is_character = inherits_from(traversing_object, DefaultCharacter)
|
||||||
if is_character:
|
if is_character:
|
||||||
allow = self.callbacks.call("can_traverse", traversing_object, self, self.location)
|
allow = self.callbacks.call(
|
||||||
|
"can_traverse", traversing_object, self, self.location
|
||||||
|
)
|
||||||
if not allow:
|
if not allow:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -79,9 +79,13 @@ def register_events(path_or_typeclass):
|
||||||
variables = help_text = custom_call = custom_add = None
|
variables = help_text = custom_call = custom_add = None
|
||||||
|
|
||||||
if isinstance(storage, list):
|
if isinstance(storage, list):
|
||||||
storage.append((typeclass_name, name, variables, help_text, custom_call, custom_add))
|
storage.append(
|
||||||
|
(typeclass_name, name, variables, help_text, custom_call, custom_add)
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
storage.add_event(typeclass_name, name, variables, help_text, custom_call, custom_add)
|
storage.add_event(
|
||||||
|
typeclass_name, name, variables, help_text, custom_call, custom_add
|
||||||
|
)
|
||||||
|
|
||||||
return typeclass
|
return typeclass
|
||||||
|
|
||||||
|
|
@ -139,7 +143,8 @@ def get_next_wait(format):
|
||||||
|
|
||||||
if not piece.isdigit():
|
if not piece.isdigit():
|
||||||
logger.log_trace(
|
logger.log_trace(
|
||||||
"The time specified '{}' in {} isn't " "a valid number".format(piece, format)
|
"The time specified '{}' in {} isn't "
|
||||||
|
"a valid number".format(piece, format)
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
@ -176,7 +181,9 @@ def time_event(obj, event_name, number, parameters):
|
||||||
"""
|
"""
|
||||||
seconds, usual, key = get_next_wait(parameters)
|
seconds, usual, key = get_next_wait(parameters)
|
||||||
script = create_script(
|
script = create_script(
|
||||||
"evennia.contrib.ingame_python.scripts.TimeEventScript", interval=seconds, obj=obj
|
"evennia.contrib.ingame_python.scripts.TimeEventScript",
|
||||||
|
interval=seconds,
|
||||||
|
obj=obj,
|
||||||
)
|
)
|
||||||
script.key = key
|
script.key = key
|
||||||
script.desc = "event on {}".format(key)
|
script.desc = "event on {}".format(key)
|
||||||
|
|
|
||||||
|
|
@ -126,9 +126,13 @@ class CmdMail(default_cmds.MuxAccountCommand):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if self.caller_is_account:
|
if self.caller_is_account:
|
||||||
return Msg.objects.get_by_tag(category="mail").filter(db_receivers_accounts=self.caller)
|
return Msg.objects.get_by_tag(category="mail").filter(
|
||||||
|
db_receivers_accounts=self.caller
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
return Msg.objects.get_by_tag(category="mail").filter(db_receivers_objects=self.caller)
|
return Msg.objects.get_by_tag(category="mail").filter(
|
||||||
|
db_receivers_objects=self.caller
|
||||||
|
)
|
||||||
|
|
||||||
def send_mail(self, recipients, subject, message, caller):
|
def send_mail(self, recipients, subject, message, caller):
|
||||||
"""
|
"""
|
||||||
|
|
@ -177,7 +181,9 @@ class CmdMail(default_cmds.MuxAccountCommand):
|
||||||
mind = max(0, min(mind_max, int(self.lhs) - 1))
|
mind = max(0, min(mind_max, int(self.lhs) - 1))
|
||||||
if all_mail[mind]:
|
if all_mail[mind]:
|
||||||
mail = all_mail[mind]
|
mail = all_mail[mind]
|
||||||
question = "Delete message {} ({}) [Y]/N?".format(mind + 1, mail.header)
|
question = "Delete message {} ({}) [Y]/N?".format(
|
||||||
|
mind + 1, mail.header
|
||||||
|
)
|
||||||
ret = yield (question)
|
ret = yield (question)
|
||||||
# handle not ret, it will be None during unit testing
|
# handle not ret, it will be None during unit testing
|
||||||
if not ret or ret.strip().upper() not in ("N", "No"):
|
if not ret or ret.strip().upper() not in ("N", "No"):
|
||||||
|
|
@ -195,7 +201,8 @@ class CmdMail(default_cmds.MuxAccountCommand):
|
||||||
try:
|
try:
|
||||||
if not self.rhs:
|
if not self.rhs:
|
||||||
self.caller.msg(
|
self.caller.msg(
|
||||||
"Cannot forward a message without a target list. " "Please try again."
|
"Cannot forward a message without a target list. "
|
||||||
|
"Please try again."
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
elif not self.lhs:
|
elif not self.lhs:
|
||||||
|
|
@ -229,7 +236,8 @@ class CmdMail(default_cmds.MuxAccountCommand):
|
||||||
self.send_mail(
|
self.send_mail(
|
||||||
self.search_targets(self.lhslist),
|
self.search_targets(self.lhslist),
|
||||||
"FWD: " + old_message.header,
|
"FWD: " + old_message.header,
|
||||||
"\n---- Original Message ----\n" + old_message.message,
|
"\n---- Original Message ----\n"
|
||||||
|
+ old_message.message,
|
||||||
self.caller,
|
self.caller,
|
||||||
)
|
)
|
||||||
self.caller.msg("Message forwarded.")
|
self.caller.msg("Message forwarded.")
|
||||||
|
|
@ -240,7 +248,9 @@ class CmdMail(default_cmds.MuxAccountCommand):
|
||||||
except IndexError:
|
except IndexError:
|
||||||
self.caller.msg("Message does not exixt.")
|
self.caller.msg("Message does not exixt.")
|
||||||
except ValueError:
|
except ValueError:
|
||||||
self.caller.msg("Usage: @mail/forward <account list>=<#>[/<Message>]")
|
self.caller.msg(
|
||||||
|
"Usage: @mail/forward <account list>=<#>[/<Message>]"
|
||||||
|
)
|
||||||
elif "reply" in self.switches or "rep" in self.switches:
|
elif "reply" in self.switches or "rep" in self.switches:
|
||||||
try:
|
try:
|
||||||
if not self.rhs:
|
if not self.rhs:
|
||||||
|
|
@ -258,7 +268,9 @@ class CmdMail(default_cmds.MuxAccountCommand):
|
||||||
self.send_mail(
|
self.send_mail(
|
||||||
old_message.senders,
|
old_message.senders,
|
||||||
"RE: " + old_message.header,
|
"RE: " + old_message.header,
|
||||||
self.rhs + "\n---- Original Message ----\n" + old_message.message,
|
self.rhs
|
||||||
|
+ "\n---- Original Message ----\n"
|
||||||
|
+ old_message.message,
|
||||||
self.caller,
|
self.caller,
|
||||||
)
|
)
|
||||||
old_message.tags.remove("new", category="mail")
|
old_message.tags.remove("new", category="mail")
|
||||||
|
|
@ -277,7 +289,9 @@ class CmdMail(default_cmds.MuxAccountCommand):
|
||||||
subject, body = self.rhs.split("/", 1)
|
subject, body = self.rhs.split("/", 1)
|
||||||
else:
|
else:
|
||||||
body = self.rhs
|
body = self.rhs
|
||||||
self.send_mail(self.search_targets(self.lhslist), subject, body, self.caller)
|
self.send_mail(
|
||||||
|
self.search_targets(self.lhslist), subject, body, self.caller
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
all_mail = self.get_all_mail()
|
all_mail = self.get_all_mail()
|
||||||
mind_max = max(0, all_mail.count() - 1)
|
mind_max = max(0, all_mail.count() - 1)
|
||||||
|
|
@ -292,13 +306,16 @@ class CmdMail(default_cmds.MuxAccountCommand):
|
||||||
if message:
|
if message:
|
||||||
messageForm.append(_HEAD_CHAR * _WIDTH)
|
messageForm.append(_HEAD_CHAR * _WIDTH)
|
||||||
messageForm.append(
|
messageForm.append(
|
||||||
"|wFrom:|n %s" % (message.senders[0].get_display_name(self.caller))
|
"|wFrom:|n %s"
|
||||||
|
% (message.senders[0].get_display_name(self.caller))
|
||||||
)
|
)
|
||||||
# note that we cannot use %-d format here since Windows does not support it
|
# note that we cannot use %-d format here since Windows does not support it
|
||||||
day = message.db_date_created.day
|
day = message.db_date_created.day
|
||||||
messageForm.append(
|
messageForm.append(
|
||||||
"|wSent:|n %s"
|
"|wSent:|n %s"
|
||||||
% message.db_date_created.strftime(f"%b {day}, %Y - %H:%M:%S")
|
% message.db_date_created.strftime(
|
||||||
|
f"%b {day}, %Y - %H:%M:%S"
|
||||||
|
)
|
||||||
)
|
)
|
||||||
messageForm.append("|wSubject:|n %s" % message.header)
|
messageForm.append("|wSubject:|n %s" % message.header)
|
||||||
messageForm.append(_SUB_HEAD_CHAR * _WIDTH)
|
messageForm.append(_SUB_HEAD_CHAR * _WIDTH)
|
||||||
|
|
|
||||||
|
|
@ -237,11 +237,19 @@ def example2_build_verticle_exit(x, y, **kwargs):
|
||||||
|
|
||||||
# create exits in the rooms
|
# create exits in the rooms
|
||||||
create_object(
|
create_object(
|
||||||
exits.Exit, key="south", aliases=["s"], location=north_room, destination=south_room
|
exits.Exit,
|
||||||
|
key="south",
|
||||||
|
aliases=["s"],
|
||||||
|
location=north_room,
|
||||||
|
destination=south_room,
|
||||||
)
|
)
|
||||||
|
|
||||||
create_object(
|
create_object(
|
||||||
exits.Exit, key="north", aliases=["n"], location=south_room, destination=north_room
|
exits.Exit,
|
||||||
|
key="north",
|
||||||
|
aliases=["n"],
|
||||||
|
location=south_room,
|
||||||
|
destination=north_room,
|
||||||
)
|
)
|
||||||
|
|
||||||
kwargs["caller"].msg("Connected: " + north_room.key + " & " + south_room.key)
|
kwargs["caller"].msg("Connected: " + north_room.key + " & " + south_room.key)
|
||||||
|
|
@ -256,9 +264,13 @@ def example2_build_horizontal_exit(x, y, **kwargs):
|
||||||
west_room = kwargs["room_dict"][(x - 1, y)]
|
west_room = kwargs["room_dict"][(x - 1, y)]
|
||||||
east_room = kwargs["room_dict"][(x + 1, y)]
|
east_room = kwargs["room_dict"][(x + 1, y)]
|
||||||
|
|
||||||
create_object(exits.Exit, key="east", aliases=["e"], location=west_room, destination=east_room)
|
create_object(
|
||||||
|
exits.Exit, key="east", aliases=["e"], location=west_room, destination=east_room
|
||||||
|
)
|
||||||
|
|
||||||
create_object(exits.Exit, key="west", aliases=["w"], location=east_room, destination=west_room)
|
create_object(
|
||||||
|
exits.Exit, key="west", aliases=["w"], location=east_room, destination=west_room
|
||||||
|
)
|
||||||
|
|
||||||
kwargs["caller"].msg("Connected: " + west_room.key + " & " + east_room.key)
|
kwargs["caller"].msg("Connected: " + west_room.key + " & " + east_room.key)
|
||||||
|
|
||||||
|
|
@ -328,7 +340,11 @@ def build_map(caller, game_map, legend, iterations=1, build_exits=True):
|
||||||
# obs - we must use == for strings
|
# obs - we must use == for strings
|
||||||
if game_map[y][x] == key:
|
if game_map[y][x] == key:
|
||||||
room = legend[key](
|
room = legend[key](
|
||||||
x, y, iteration=iteration, room_dict=room_dict, caller=caller
|
x,
|
||||||
|
y,
|
||||||
|
iteration=iteration,
|
||||||
|
room_dict=room_dict,
|
||||||
|
caller=caller,
|
||||||
)
|
)
|
||||||
if iteration == 0:
|
if iteration == 0:
|
||||||
room_dict[(x, y)] = room
|
room_dict[(x, y)] = room
|
||||||
|
|
@ -432,7 +448,10 @@ class CmdMapBuilder(COMMAND_DEFAULT_CLASS):
|
||||||
|
|
||||||
# Check if arguments passed.
|
# Check if arguments passed.
|
||||||
if not self.args or (len(args) != 2):
|
if not self.args or (len(args) != 2):
|
||||||
caller.msg("Usage: @mapbuilder <path.to.module.VARNAME> " "<path.to.module.MAP_LEGEND>")
|
caller.msg(
|
||||||
|
"Usage: @mapbuilder <path.to.module.VARNAME> "
|
||||||
|
"<path.to.module.MAP_LEGEND>"
|
||||||
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
# Set up base variables.
|
# Set up base variables.
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,11 @@ from django.conf import settings
|
||||||
from evennia import Command, CmdSet
|
from evennia import Command, CmdSet
|
||||||
from evennia import syscmdkeys
|
from evennia import syscmdkeys
|
||||||
from evennia.utils.evmenu import EvMenu
|
from evennia.utils.evmenu import EvMenu
|
||||||
from evennia.utils.utils import random_string_from_module, class_from_module, callables_from_module
|
from evennia.utils.utils import (
|
||||||
|
random_string_from_module,
|
||||||
|
class_from_module,
|
||||||
|
callables_from_module,
|
||||||
|
)
|
||||||
|
|
||||||
_CONNECTION_SCREEN_MODULE = settings.CONNECTION_SCREEN_MODULE
|
_CONNECTION_SCREEN_MODULE = settings.CONNECTION_SCREEN_MODULE
|
||||||
_GUEST_ENABLED = settings.GUEST_ENABLED
|
_GUEST_ENABLED = settings.GUEST_ENABLED
|
||||||
|
|
@ -32,7 +36,8 @@ _ACCOUNT = class_from_module(settings.BASE_ACCOUNT_TYPECLASS)
|
||||||
_GUEST = class_from_module(settings.BASE_GUEST_TYPECLASS)
|
_GUEST = class_from_module(settings.BASE_GUEST_TYPECLASS)
|
||||||
|
|
||||||
_ACCOUNT_HELP = (
|
_ACCOUNT_HELP = (
|
||||||
"Enter the name you used to log into the game before, " "or a new account-name if you are new."
|
"Enter the name you used to log into the game before, "
|
||||||
|
"or a new account-name if you are new."
|
||||||
)
|
)
|
||||||
_PASSWORD_HELP = (
|
_PASSWORD_HELP = (
|
||||||
"Password should be a minimum of 8 characters (preferably longer) and "
|
"Password should be a minimum of 8 characters (preferably longer) and "
|
||||||
|
|
@ -106,7 +111,10 @@ def node_enter_username(caller, raw_text, **kwargs):
|
||||||
options = (
|
options = (
|
||||||
{"key": "", "goto": "node_enter_username"},
|
{"key": "", "goto": "node_enter_username"},
|
||||||
{"key": ("quit", "q"), "goto": "node_quit_or_login"},
|
{"key": ("quit", "q"), "goto": "node_quit_or_login"},
|
||||||
{"key": ("help", "h"), "goto": (_show_help, {"help_entry": _ACCOUNT_HELP, **kwargs})},
|
{
|
||||||
|
"key": ("help", "h"),
|
||||||
|
"goto": (_show_help, {"help_entry": _ACCOUNT_HELP, **kwargs}),
|
||||||
|
},
|
||||||
{"key": "_default", "goto": _check_input},
|
{"key": "_default", "goto": _check_input},
|
||||||
)
|
)
|
||||||
return text, options
|
return text, options
|
||||||
|
|
@ -150,7 +158,9 @@ def node_enter_password(caller, raw_string, **kwargs):
|
||||||
|
|
||||||
if account:
|
if account:
|
||||||
if new_user:
|
if new_user:
|
||||||
session.msg("|gA new account |c{}|g was created. Welcome!|n".format(username))
|
session.msg(
|
||||||
|
"|gA new account |c{}|g was created. Welcome!|n".format(username)
|
||||||
|
)
|
||||||
# pass login info to login node
|
# pass login info to login node
|
||||||
return "node_quit_or_login", {"login": True, "account": account}
|
return "node_quit_or_login", {"login": True, "account": account}
|
||||||
else:
|
else:
|
||||||
|
|
@ -170,15 +180,21 @@ def node_enter_password(caller, raw_string, **kwargs):
|
||||||
# Attempting to fix password
|
# Attempting to fix password
|
||||||
text = "Enter a new password:"
|
text = "Enter a new password:"
|
||||||
else:
|
else:
|
||||||
text = "Creating a new account |c{}|n. " "Enter a password (empty to abort):".format(
|
text = (
|
||||||
username
|
"Creating a new account |c{}|n. "
|
||||||
|
"Enter a password (empty to abort):".format(username)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
text = "Enter the password for account |c{}|n (empty to abort):".format(username)
|
text = "Enter the password for account |c{}|n (empty to abort):".format(
|
||||||
|
username
|
||||||
|
)
|
||||||
options = (
|
options = (
|
||||||
{"key": "", "goto": _restart_login},
|
{"key": "", "goto": _restart_login},
|
||||||
{"key": ("quit", "q"), "goto": "node_quit_or_login"},
|
{"key": ("quit", "q"), "goto": "node_quit_or_login"},
|
||||||
{"key": ("help", "h"), "goto": (_show_help, {"help_entry": _PASSWORD_HELP, **kwargs})},
|
{
|
||||||
|
"key": ("help", "h"),
|
||||||
|
"goto": (_show_help, {"help_entry": _PASSWORD_HELP, **kwargs}),
|
||||||
|
},
|
||||||
{"key": "_default", "goto": (_check_input, kwargs)},
|
{"key": "_default", "goto": (_check_input, kwargs)},
|
||||||
)
|
)
|
||||||
return text, options
|
return text, options
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,11 @@ def _update_store(caller, key=None, desc=None, delete=False, swapkey=None):
|
||||||
elif swapkey:
|
elif swapkey:
|
||||||
# swap positions
|
# swap positions
|
||||||
loswapkey = swapkey.lower()
|
loswapkey = swapkey.lower()
|
||||||
swapmatch = [ind for ind, tup in enumerate(caller.db.multidesc) if tup[0] == loswapkey]
|
swapmatch = [
|
||||||
|
ind
|
||||||
|
for ind, tup in enumerate(caller.db.multidesc)
|
||||||
|
if tup[0] == loswapkey
|
||||||
|
]
|
||||||
if swapmatch:
|
if swapmatch:
|
||||||
iswap = swapmatch[0]
|
iswap = swapmatch[0]
|
||||||
if idesc == iswap:
|
if idesc == iswap:
|
||||||
|
|
@ -171,7 +175,8 @@ class CmdMultiDesc(default_cmds.MuxCommand):
|
||||||
do_crop = "full" not in switches
|
do_crop = "full" not in switches
|
||||||
if do_crop:
|
if do_crop:
|
||||||
outtext = [
|
outtext = [
|
||||||
"|w%s:|n %s" % (key, crop(desc)) for key, desc in caller.db.multidesc
|
"|w%s:|n %s" % (key, crop(desc))
|
||||||
|
for key, desc in caller.db.multidesc
|
||||||
]
|
]
|
||||||
else:
|
else:
|
||||||
outtext = [
|
outtext = [
|
||||||
|
|
@ -240,7 +245,9 @@ class CmdMultiDesc(default_cmds.MuxCommand):
|
||||||
new_desc.append(key)
|
new_desc.append(key)
|
||||||
new_desc = "".join(new_desc)
|
new_desc = "".join(new_desc)
|
||||||
caller.db.desc = new_desc
|
caller.db.desc = new_desc
|
||||||
caller.msg("%s\n\n|wThe above was set as the current description.|n" % new_desc)
|
caller.msg(
|
||||||
|
"%s\n\n|wThe above was set as the current description.|n" % new_desc
|
||||||
|
)
|
||||||
|
|
||||||
elif self.rhs or "add" in switches:
|
elif self.rhs or "add" in switches:
|
||||||
# add text directly to a new entry or an existing one.
|
# add text directly to a new entry or an existing one.
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,9 @@ _PUZZLES_TAG_RECIPE = "puzzle_recipe"
|
||||||
# puzzle part and puzzle result
|
# puzzle part and puzzle result
|
||||||
_PUZZLES_TAG_MEMBER = "puzzle_member"
|
_PUZZLES_TAG_MEMBER = "puzzle_member"
|
||||||
|
|
||||||
_PUZZLE_DEFAULT_FAIL_USE_MESSAGE = "You try to utilize %s but nothing happens ... something amiss?"
|
_PUZZLE_DEFAULT_FAIL_USE_MESSAGE = (
|
||||||
|
"You try to utilize %s but nothing happens ... something amiss?"
|
||||||
|
)
|
||||||
_PUZZLE_DEFAULT_SUCCESS_USE_MESSAGE = "You are a Genius!!!"
|
_PUZZLE_DEFAULT_SUCCESS_USE_MESSAGE = "You are a Genius!!!"
|
||||||
_PUZZLE_DEFAULT_SUCCESS_USE_LOCATION_MESSAGE = "|c{caller}|n performs some kind of tribal dance and |y{result_names}|n seems to appear from thin air"
|
_PUZZLE_DEFAULT_SUCCESS_USE_LOCATION_MESSAGE = "|c{caller}|n performs some kind of tribal dance and |y{result_names}|n seems to appear from thin air"
|
||||||
|
|
||||||
|
|
@ -140,7 +142,9 @@ def _colorize_message(msg):
|
||||||
return msg
|
return msg
|
||||||
|
|
||||||
|
|
||||||
_PUZZLE_DEFAULT_SUCCESS_USE_MESSAGE = _colorize_message(_PUZZLE_DEFAULT_SUCCESS_USE_MESSAGE)
|
_PUZZLE_DEFAULT_SUCCESS_USE_MESSAGE = _colorize_message(
|
||||||
|
_PUZZLE_DEFAULT_SUCCESS_USE_MESSAGE
|
||||||
|
)
|
||||||
|
|
||||||
# ------------------------------------------
|
# ------------------------------------------
|
||||||
|
|
||||||
|
|
@ -157,7 +161,9 @@ class PuzzleRecipe(DefaultScript):
|
||||||
self.db.mask = tuple()
|
self.db.mask = tuple()
|
||||||
self.tags.add(_PUZZLES_TAG_RECIPE, category=_PUZZLES_TAG_CATEGORY)
|
self.tags.add(_PUZZLES_TAG_RECIPE, category=_PUZZLES_TAG_CATEGORY)
|
||||||
self.db.use_success_message = _PUZZLE_DEFAULT_SUCCESS_USE_MESSAGE
|
self.db.use_success_message = _PUZZLE_DEFAULT_SUCCESS_USE_MESSAGE
|
||||||
self.db.use_success_location_message = _PUZZLE_DEFAULT_SUCCESS_USE_LOCATION_MESSAGE
|
self.db.use_success_location_message = (
|
||||||
|
_PUZZLE_DEFAULT_SUCCESS_USE_LOCATION_MESSAGE
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class CmdCreatePuzzleRecipe(MuxCommand):
|
class CmdCreatePuzzleRecipe(MuxCommand):
|
||||||
|
|
@ -301,7 +307,9 @@ class CmdCreatePuzzleRecipe(MuxCommand):
|
||||||
caller.msg(
|
caller.msg(
|
||||||
"You may now dispose of all parts and results. \n"
|
"You may now dispose of all parts and results. \n"
|
||||||
"Use @puzzleedit #{dbref} to customize this puzzle further. \n"
|
"Use @puzzleedit #{dbref} to customize this puzzle further. \n"
|
||||||
"Use @armpuzzle #{dbref} to arm a new puzzle instance.".format(dbref=puzzle.dbref)
|
"Use @armpuzzle #{dbref} to arm a new puzzle instance.".format(
|
||||||
|
dbref=puzzle.dbref
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -364,7 +372,9 @@ class CmdEditPuzzle(MuxCommand):
|
||||||
puzzle_name_id = "%s(%s)" % (puzzle.name, puzzle.dbref)
|
puzzle_name_id = "%s(%s)" % (puzzle.name, puzzle.dbref)
|
||||||
|
|
||||||
if "delete" in self.switches:
|
if "delete" in self.switches:
|
||||||
if not (puzzle.access(caller, "control") or puzzle.access(caller, "delete")):
|
if not (
|
||||||
|
puzzle.access(caller, "control") or puzzle.access(caller, "delete")
|
||||||
|
):
|
||||||
caller.msg("You don't have permission to delete %s." % puzzle_name_id)
|
caller.msg("You don't have permission to delete %s." % puzzle_name_id)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
@ -646,7 +656,9 @@ class CmdUsePuzzleParts(MuxCommand):
|
||||||
# Create lookup dict of puzzles by dbref
|
# Create lookup dict of puzzles by dbref
|
||||||
puzzles_dict = dict((puzzle.dbref, puzzle) for puzzle in puzzles)
|
puzzles_dict = dict((puzzle.dbref, puzzle) for puzzle in puzzles)
|
||||||
# Check if parts can be combined to solve a puzzle
|
# Check if parts can be combined to solve a puzzle
|
||||||
matched_puzzles = _matching_puzzles(puzzles, puzzlename_tags_dict, puzzle_ingredients)
|
matched_puzzles = _matching_puzzles(
|
||||||
|
puzzles, puzzlename_tags_dict, puzzle_ingredients
|
||||||
|
)
|
||||||
|
|
||||||
if len(matched_puzzles) == 0:
|
if len(matched_puzzles) == 0:
|
||||||
# TODO: we could use part.fail_message instead, if there was one
|
# TODO: we could use part.fail_message instead, if there was one
|
||||||
|
|
@ -655,7 +667,9 @@ class CmdUsePuzzleParts(MuxCommand):
|
||||||
caller.msg(_PUZZLE_DEFAULT_FAIL_USE_MESSAGE % (many))
|
caller.msg(_PUZZLE_DEFAULT_FAIL_USE_MESSAGE % (many))
|
||||||
return
|
return
|
||||||
|
|
||||||
puzzletuples = sorted(matched_puzzles.items(), key=lambda t: len(t[1]), reverse=True)
|
puzzletuples = sorted(
|
||||||
|
matched_puzzles.items(), key=lambda t: len(t[1]), reverse=True
|
||||||
|
)
|
||||||
|
|
||||||
logger.log_info("MATCHED PUZZLES %r" % (puzzletuples))
|
logger.log_info("MATCHED PUZZLES %r" % (puzzletuples))
|
||||||
|
|
||||||
|
|
@ -663,7 +677,9 @@ class CmdUsePuzzleParts(MuxCommand):
|
||||||
puzzledbref, matched_dbrefparts = puzzletuples[0]
|
puzzledbref, matched_dbrefparts = puzzletuples[0]
|
||||||
nparts = len(matched_dbrefparts)
|
nparts = len(matched_dbrefparts)
|
||||||
puzzle = puzzles_dict[puzzledbref]
|
puzzle = puzzles_dict[puzzledbref]
|
||||||
largest_puzzles = list(itertools.takewhile(lambda t: len(t[1]) == nparts, puzzletuples))
|
largest_puzzles = list(
|
||||||
|
itertools.takewhile(lambda t: len(t[1]) == nparts, puzzletuples)
|
||||||
|
)
|
||||||
|
|
||||||
# if there are more than one, choose one at random.
|
# if there are more than one, choose one at random.
|
||||||
# we could show the names of all those that can be resolved
|
# we could show the names of all those that can be resolved
|
||||||
|
|
@ -694,7 +710,9 @@ class CmdUsePuzzleParts(MuxCommand):
|
||||||
result_names = ", ".join(result_names)
|
result_names = ", ".join(result_names)
|
||||||
caller.msg(puzzle.db.use_success_message)
|
caller.msg(puzzle.db.use_success_message)
|
||||||
caller.location.msg_contents(
|
caller.location.msg_contents(
|
||||||
puzzle.db.use_success_location_message.format(caller=caller, result_names=result_names),
|
puzzle.db.use_success_location_message.format(
|
||||||
|
caller=caller, result_names=result_names
|
||||||
|
),
|
||||||
exclude=(caller,),
|
exclude=(caller,),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -714,17 +732,25 @@ class CmdListPuzzleRecipes(MuxCommand):
|
||||||
def func(self):
|
def func(self):
|
||||||
caller = self.caller
|
caller = self.caller
|
||||||
|
|
||||||
recipes = search.search_script_tag(_PUZZLES_TAG_RECIPE, category=_PUZZLES_TAG_CATEGORY)
|
recipes = search.search_script_tag(
|
||||||
|
_PUZZLES_TAG_RECIPE, category=_PUZZLES_TAG_CATEGORY
|
||||||
|
)
|
||||||
|
|
||||||
div = "-" * 60
|
div = "-" * 60
|
||||||
text = [div]
|
text = [div]
|
||||||
msgf_recipe = "Puzzle |y'%s' %s(%s)|n"
|
msgf_recipe = "Puzzle |y'%s' %s(%s)|n"
|
||||||
msgf_item = "%2s|c%15s|n: |w%s|n"
|
msgf_item = "%2s|c%15s|n: |w%s|n"
|
||||||
for recipe in recipes:
|
for recipe in recipes:
|
||||||
text.append(msgf_recipe % (recipe.db.puzzle_name, recipe.name, recipe.dbref))
|
|
||||||
text.append("Success Caller message:\n" + recipe.db.use_success_message + "\n")
|
|
||||||
text.append(
|
text.append(
|
||||||
"Success Location message:\n" + recipe.db.use_success_location_message + "\n"
|
msgf_recipe % (recipe.db.puzzle_name, recipe.name, recipe.dbref)
|
||||||
|
)
|
||||||
|
text.append(
|
||||||
|
"Success Caller message:\n" + recipe.db.use_success_message + "\n"
|
||||||
|
)
|
||||||
|
text.append(
|
||||||
|
"Success Location message:\n"
|
||||||
|
+ recipe.db.use_success_location_message
|
||||||
|
+ "\n"
|
||||||
)
|
)
|
||||||
text.append("Mask:\n" + str(recipe.db.mask) + "\n")
|
text.append("Mask:\n" + str(recipe.db.mask) + "\n")
|
||||||
text.append("Parts")
|
text.append("Parts")
|
||||||
|
|
@ -761,10 +787,13 @@ class CmdListArmedPuzzles(MuxCommand):
|
||||||
def func(self):
|
def func(self):
|
||||||
caller = self.caller
|
caller = self.caller
|
||||||
|
|
||||||
armed_puzzles = search.search_tag(_PUZZLES_TAG_MEMBER, category=_PUZZLES_TAG_CATEGORY)
|
armed_puzzles = search.search_tag(
|
||||||
|
_PUZZLES_TAG_MEMBER, category=_PUZZLES_TAG_CATEGORY
|
||||||
|
)
|
||||||
|
|
||||||
armed_puzzles = dict(
|
armed_puzzles = dict(
|
||||||
(k, list(g)) for k, g in itertools.groupby(armed_puzzles, lambda ap: ap.db.puzzle_name)
|
(k, list(g))
|
||||||
|
for k, g in itertools.groupby(armed_puzzles, lambda ap: ap.db.puzzle_name)
|
||||||
)
|
)
|
||||||
|
|
||||||
div = "-" * 60
|
div = "-" * 60
|
||||||
|
|
@ -775,7 +804,8 @@ class CmdListArmedPuzzles(MuxCommand):
|
||||||
text.append(msgf_pznm % (pzname))
|
text.append(msgf_pznm % (pzname))
|
||||||
for item in items:
|
for item in items:
|
||||||
text.append(
|
text.append(
|
||||||
msgf_item % (item.name, item.dbref, item.location.name, item.location.dbref)
|
msgf_item
|
||||||
|
% (item.name, item.dbref, item.location.name, item.location.dbref)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
text.append(div)
|
text.append(div)
|
||||||
|
|
|
||||||
|
|
@ -168,7 +168,9 @@ class RandomStringGenerator(object):
|
||||||
try:
|
try:
|
||||||
script = ScriptDB.objects.get(db_key="generator_script")
|
script = ScriptDB.objects.get(db_key="generator_script")
|
||||||
except ScriptDB.DoesNotExist:
|
except ScriptDB.DoesNotExist:
|
||||||
script = create_script("contrib.random_string_generator.RandomStringGeneratorScript")
|
script = create_script(
|
||||||
|
"contrib.random_string_generator.RandomStringGeneratorScript"
|
||||||
|
)
|
||||||
|
|
||||||
type(self).script = script
|
type(self).script = script
|
||||||
return script
|
return script
|
||||||
|
|
@ -200,7 +202,9 @@ class RandomStringGenerator(object):
|
||||||
# Either the beginning or end, we ignore it
|
# Either the beginning or end, we ignore it
|
||||||
continue
|
continue
|
||||||
elif name == "min_repeat":
|
elif name == "min_repeat":
|
||||||
raise RejectedRegex("you have to provide a maximum number of this character class")
|
raise RejectedRegex(
|
||||||
|
"you have to provide a maximum number of this character class"
|
||||||
|
)
|
||||||
elif name == "max_repeat":
|
elif name == "max_repeat":
|
||||||
desc["min"] = element[1][0]
|
desc["min"] = element[1][0]
|
||||||
desc["max"] = element[1][1]
|
desc["max"] = element[1][1]
|
||||||
|
|
|
||||||
|
|
@ -112,7 +112,9 @@ _VOWELS = "eaoiuy"
|
||||||
# these must be able to be constructed from phonemes (so for example,
|
# these must be able to be constructed from phonemes (so for example,
|
||||||
# if you have v here, there must exist at least one single-character
|
# if you have v here, there must exist at least one single-character
|
||||||
# vowel phoneme defined above)
|
# vowel phoneme defined above)
|
||||||
_GRAMMAR = "v cv vc cvv vcc vcv cvcc vccv cvccv cvcvcc cvccvcv vccvccvc cvcvccvv cvcvcvcvv"
|
_GRAMMAR = (
|
||||||
|
"v cv vc cvv vcc vcv cvcc vccv cvccv cvcvcc cvccvcv vccvccvc cvcvccvv cvcvcvcvv"
|
||||||
|
)
|
||||||
|
|
||||||
_RE_FLAGS = re.MULTILINE + re.IGNORECASE + re.DOTALL + re.UNICODE
|
_RE_FLAGS = re.MULTILINE + re.IGNORECASE + re.DOTALL + re.UNICODE
|
||||||
_RE_GRAMMAR = re.compile(r"vv|cc|v|c", _RE_FLAGS)
|
_RE_GRAMMAR = re.compile(r"vv|cc|v|c", _RE_FLAGS)
|
||||||
|
|
@ -246,7 +248,9 @@ class LanguageHandler(DefaultScript):
|
||||||
grammar2phonemes = defaultdict(list)
|
grammar2phonemes = defaultdict(list)
|
||||||
for phoneme in phonemes.split():
|
for phoneme in phonemes.split():
|
||||||
if re.search("\W", phoneme):
|
if re.search("\W", phoneme):
|
||||||
raise LanguageError("The phoneme '%s' contains an invalid character" % phoneme)
|
raise LanguageError(
|
||||||
|
"The phoneme '%s' contains an invalid character" % phoneme
|
||||||
|
)
|
||||||
gram = "".join(["v" if char in vowels else "c" for char in phoneme])
|
gram = "".join(["v" if char in vowels else "c" for char in phoneme])
|
||||||
grammar2phonemes[gram].append(phoneme)
|
grammar2phonemes[gram].append(phoneme)
|
||||||
|
|
||||||
|
|
@ -272,7 +276,9 @@ class LanguageHandler(DefaultScript):
|
||||||
word = word.strip()
|
word = word.strip()
|
||||||
lword = len(word)
|
lword = len(word)
|
||||||
new_word = ""
|
new_word = ""
|
||||||
wlen = max(0, lword + sum(randint(-1, 1) for i in range(word_length_variance)))
|
wlen = max(
|
||||||
|
0, lword + sum(randint(-1, 1) for i in range(word_length_variance))
|
||||||
|
)
|
||||||
if wlen not in grammar:
|
if wlen not in grammar:
|
||||||
# always create a translation, use random length
|
# always create a translation, use random length
|
||||||
structure = choice(grammar[choice(list(grammar))])
|
structure = choice(grammar[choice(list(grammar))])
|
||||||
|
|
@ -286,7 +292,10 @@ class LanguageHandler(DefaultScript):
|
||||||
if manual_translations:
|
if manual_translations:
|
||||||
# update with manual translations
|
# update with manual translations
|
||||||
translation.update(
|
translation.update(
|
||||||
dict((key.lower(), value.lower()) for key, value in manual_translations.items())
|
dict(
|
||||||
|
(key.lower(), value.lower())
|
||||||
|
for key, value in manual_translations.items()
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
# store data
|
# store data
|
||||||
|
|
@ -338,7 +347,10 @@ class LanguageHandler(DefaultScript):
|
||||||
wlen = max(
|
wlen = max(
|
||||||
0,
|
0,
|
||||||
lword
|
lword
|
||||||
+ sum(randint(-1, 1) for i in range(self.language["word_length_variance"])),
|
+ sum(
|
||||||
|
randint(-1, 1)
|
||||||
|
for i in range(self.language["word_length_variance"])
|
||||||
|
),
|
||||||
)
|
)
|
||||||
grammar = self.language["grammar"]
|
grammar = self.language["grammar"]
|
||||||
if wlen not in grammar:
|
if wlen not in grammar:
|
||||||
|
|
@ -368,7 +380,9 @@ class LanguageHandler(DefaultScript):
|
||||||
|
|
||||||
if word.istitle():
|
if word.istitle():
|
||||||
title_word = ""
|
title_word = ""
|
||||||
if not start_sentence and not self.language.get("noun_translate", False):
|
if not start_sentence and not self.language.get(
|
||||||
|
"noun_translate", False
|
||||||
|
):
|
||||||
# don't translate what we identify as proper nouns (names)
|
# don't translate what we identify as proper nouns (names)
|
||||||
title_word = word
|
title_word = word
|
||||||
elif new_word:
|
elif new_word:
|
||||||
|
|
@ -511,7 +525,9 @@ _RE_WHISPER_OBSCURE = [
|
||||||
re.compile(r"[ae]", _RE_FLAGS), # This -s - Test! #1 add uy
|
re.compile(r"[ae]", _RE_FLAGS), # This -s - Test! #1 add uy
|
||||||
re.compile(r"[aeuy]", _RE_FLAGS), # This -s - Test! #2 add oue
|
re.compile(r"[aeuy]", _RE_FLAGS), # This -s - Test! #2 add oue
|
||||||
re.compile(r"[aeiouy]", _RE_FLAGS), # Th-s -s - T-st! #3 add all consonants
|
re.compile(r"[aeiouy]", _RE_FLAGS), # Th-s -s - T-st! #3 add all consonants
|
||||||
re.compile(r"[aeiouybdhjlmnpqrv]", _RE_FLAGS), # T--s -s - T-st! #4 add hard consonants
|
re.compile(
|
||||||
|
r"[aeiouybdhjlmnpqrv]", _RE_FLAGS
|
||||||
|
), # T--s -s - T-st! #4 add hard consonants
|
||||||
re.compile(r"[a-eg-rt-z]", _RE_FLAGS), # T--s -s - T-s-! #5 add all capitals
|
re.compile(r"[a-eg-rt-z]", _RE_FLAGS), # T--s -s - T-s-! #5 add all capitals
|
||||||
re.compile(r"[A-EG-RT-Za-eg-rt-z]", _RE_FLAGS), # ---s -s - --s-! #6 add f
|
re.compile(r"[A-EG-RT-Za-eg-rt-z]", _RE_FLAGS), # ---s -s - --s-! #6 add f
|
||||||
re.compile(r"[A-EG-RT-Za-rt-z]", _RE_FLAGS), # ---s -s - --s-! #7 add s
|
re.compile(r"[A-EG-RT-Za-rt-z]", _RE_FLAGS), # ---s -s - --s-! #7 add s
|
||||||
|
|
|
||||||
|
|
@ -137,7 +137,9 @@ _RE_PREFIX = re.compile(r"^%s" % _PREFIX, re.UNICODE)
|
||||||
# separate multimatches from one another and word is the first word in the
|
# separate multimatches from one another and word is the first word in the
|
||||||
# marker. So entering "/tall man" will return groups ("", "tall")
|
# marker. So entering "/tall man" will return groups ("", "tall")
|
||||||
# and "/2-tall man" will return groups ("2", "tall").
|
# and "/2-tall man" will return groups ("2", "tall").
|
||||||
_RE_OBJ_REF_START = re.compile(r"%s(?:([0-9]+)%s)*(\w+)" % (_PREFIX, _NUM_SEP), _RE_FLAGS)
|
_RE_OBJ_REF_START = re.compile(
|
||||||
|
r"%s(?:([0-9]+)%s)*(\w+)" % (_PREFIX, _NUM_SEP), _RE_FLAGS
|
||||||
|
)
|
||||||
|
|
||||||
_RE_LEFT_BRACKETS = re.compile(r"\{+", _RE_FLAGS)
|
_RE_LEFT_BRACKETS = re.compile(r"\{+", _RE_FLAGS)
|
||||||
_RE_RIGHT_BRACKETS = re.compile(r"\}+", _RE_FLAGS)
|
_RE_RIGHT_BRACKETS = re.compile(r"\}+", _RE_FLAGS)
|
||||||
|
|
@ -232,7 +234,8 @@ def ordered_permutation_regex(sentence):
|
||||||
if comb:
|
if comb:
|
||||||
solution.append(
|
solution.append(
|
||||||
_PREFIX
|
_PREFIX
|
||||||
+ r"[0-9]*%s*%s(?=\W|$)+" % (_NUM_SEP, re_escape(" ".join(comb)).rstrip("\\"))
|
+ r"[0-9]*%s*%s(?=\W|$)+"
|
||||||
|
% (_NUM_SEP, re_escape(" ".join(comb)).rstrip("\\"))
|
||||||
)
|
)
|
||||||
|
|
||||||
# combine into a match regex, first matching the longest down to the shortest components
|
# combine into a match regex, first matching the longest down to the shortest components
|
||||||
|
|
@ -258,7 +261,10 @@ def regex_tuple_from_key_alias(obj):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return (
|
return (
|
||||||
re.compile(ordered_permutation_regex(" ".join([obj.key] + obj.aliases.all())), _RE_FLAGS),
|
re.compile(
|
||||||
|
ordered_permutation_regex(" ".join([obj.key] + obj.aliases.all())),
|
||||||
|
_RE_FLAGS,
|
||||||
|
),
|
||||||
obj,
|
obj,
|
||||||
obj.key,
|
obj.key,
|
||||||
)
|
)
|
||||||
|
|
@ -360,7 +366,11 @@ def parse_sdescs_and_recogs(sender, candidates, string, search_mode=False):
|
||||||
"""
|
"""
|
||||||
# Load all candidate regex tuples [(regex, obj, sdesc/recog),...]
|
# Load all candidate regex tuples [(regex, obj, sdesc/recog),...]
|
||||||
candidate_regexes = (
|
candidate_regexes = (
|
||||||
([(_RE_SELF_REF, sender, sender.sdesc.get())] if hasattr(sender, "sdesc") else [])
|
(
|
||||||
|
[(_RE_SELF_REF, sender, sender.sdesc.get())]
|
||||||
|
if hasattr(sender, "sdesc")
|
||||||
|
else []
|
||||||
|
)
|
||||||
+ (
|
+ (
|
||||||
[sender.recog.get_regex_tuple(obj) for obj in candidates]
|
[sender.recog.get_regex_tuple(obj) for obj in candidates]
|
||||||
if hasattr(sender, "recog")
|
if hasattr(sender, "recog")
|
||||||
|
|
@ -395,19 +405,28 @@ def parse_sdescs_and_recogs(sender, candidates, string, search_mode=False):
|
||||||
# start index forward for all candidates.
|
# start index forward for all candidates.
|
||||||
|
|
||||||
# first see if there is a number given (e.g. 1-tall)
|
# first see if there is a number given (e.g. 1-tall)
|
||||||
num_identifier, _ = marker_match.groups("") # return "" if no match, rather than None
|
num_identifier, _ = marker_match.groups(
|
||||||
|
""
|
||||||
|
) # return "" if no match, rather than None
|
||||||
istart0 = marker_match.start()
|
istart0 = marker_match.start()
|
||||||
istart = istart0
|
istart = istart0
|
||||||
|
|
||||||
# loop over all candidate regexes and match against the string following the match
|
# loop over all candidate regexes and match against the string following the match
|
||||||
matches = ((reg.match(string[istart:]), obj, text) for reg, obj, text in candidate_regexes)
|
matches = (
|
||||||
|
(reg.match(string[istart:]), obj, text)
|
||||||
|
for reg, obj, text in candidate_regexes
|
||||||
|
)
|
||||||
|
|
||||||
# score matches by how long part of the string was matched
|
# score matches by how long part of the string was matched
|
||||||
matches = [(match.end() if match else -1, obj, text) for match, obj, text in matches]
|
matches = [
|
||||||
|
(match.end() if match else -1, obj, text) for match, obj, text in matches
|
||||||
|
]
|
||||||
maxscore = max(score for score, obj, text in matches)
|
maxscore = max(score for score, obj, text in matches)
|
||||||
|
|
||||||
# we have a valid maxscore, extract all matches with this value
|
# we have a valid maxscore, extract all matches with this value
|
||||||
bestmatches = [(obj, text) for score, obj, text in matches if maxscore == score != -1]
|
bestmatches = [
|
||||||
|
(obj, text) for score, obj, text in matches if maxscore == score != -1
|
||||||
|
]
|
||||||
nmatches = len(bestmatches)
|
nmatches = len(bestmatches)
|
||||||
|
|
||||||
if not nmatches:
|
if not nmatches:
|
||||||
|
|
@ -426,7 +445,11 @@ def parse_sdescs_and_recogs(sender, candidates, string, search_mode=False):
|
||||||
else:
|
else:
|
||||||
# multi-match.
|
# multi-match.
|
||||||
# was a numerical identifier given to help us separate the multi-match?
|
# was a numerical identifier given to help us separate the multi-match?
|
||||||
inum = min(max(0, int(num_identifier) - 1), nmatches - 1) if num_identifier else None
|
inum = (
|
||||||
|
min(max(0, int(num_identifier) - 1), nmatches - 1)
|
||||||
|
if num_identifier
|
||||||
|
else None
|
||||||
|
)
|
||||||
if inum is not None:
|
if inum is not None:
|
||||||
# A valid inum is given. Use this to separate data.
|
# A valid inum is given. Use this to separate data.
|
||||||
obj = bestmatches[inum][0]
|
obj = bestmatches[inum][0]
|
||||||
|
|
@ -548,7 +571,8 @@ def send_emote(sender, receivers, emote, anonymous_add="first"):
|
||||||
try:
|
try:
|
||||||
recog_get = receiver.recog.get
|
recog_get = receiver.recog.get
|
||||||
receiver_sdesc_mapping = dict(
|
receiver_sdesc_mapping = dict(
|
||||||
(ref, process_recog(recog_get(obj), obj)) for ref, obj in obj_mapping.items()
|
(ref, process_recog(recog_get(obj), obj))
|
||||||
|
for ref, obj in obj_mapping.items()
|
||||||
)
|
)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
receiver_sdesc_mapping = dict(
|
receiver_sdesc_mapping = dict(
|
||||||
|
|
@ -632,7 +656,9 @@ class SdescHandler(object):
|
||||||
r"\1",
|
r"\1",
|
||||||
_RE_REF_LANG.sub(
|
_RE_REF_LANG.sub(
|
||||||
r"\1",
|
r"\1",
|
||||||
_RE_SELF_REF.sub(r"", _RE_LANGUAGE.sub(r"", _RE_OBJ_REF_START.sub(r"", sdesc))),
|
_RE_SELF_REF.sub(
|
||||||
|
r"", _RE_LANGUAGE.sub(r"", _RE_OBJ_REF_START.sub(r"", sdesc))
|
||||||
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -714,7 +740,9 @@ class RecogHandler(object):
|
||||||
obj2regex = self.obj.attributes.get("_recog_obj2regex", default={})
|
obj2regex = self.obj.attributes.get("_recog_obj2regex", default={})
|
||||||
obj2recog = self.obj.attributes.get("_recog_obj2recog", default={})
|
obj2recog = self.obj.attributes.get("_recog_obj2recog", default={})
|
||||||
self.obj2regex = dict(
|
self.obj2regex = dict(
|
||||||
(obj, re.compile(regex, _RE_FLAGS)) for obj, regex in obj2regex.items() if obj
|
(obj, re.compile(regex, _RE_FLAGS))
|
||||||
|
for obj, regex in obj2regex.items()
|
||||||
|
if obj
|
||||||
)
|
)
|
||||||
self.obj2recog = dict((obj, recog) for obj, recog in obj2recog.items() if obj)
|
self.obj2recog = dict((obj, recog) for obj, recog in obj2recog.items() if obj)
|
||||||
|
|
||||||
|
|
@ -746,7 +774,9 @@ class RecogHandler(object):
|
||||||
r"\1",
|
r"\1",
|
||||||
_RE_REF_LANG.sub(
|
_RE_REF_LANG.sub(
|
||||||
r"\1",
|
r"\1",
|
||||||
_RE_SELF_REF.sub(r"", _RE_LANGUAGE.sub(r"", _RE_OBJ_REF_START.sub(r"", recog))),
|
_RE_SELF_REF.sub(
|
||||||
|
r"", _RE_LANGUAGE.sub(r"", _RE_OBJ_REF_START.sub(r"", recog))
|
||||||
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -793,7 +823,9 @@ class RecogHandler(object):
|
||||||
# check an eventual recog_masked lock on the object
|
# check an eventual recog_masked lock on the object
|
||||||
# to avoid revealing masked characters. If lock
|
# to avoid revealing masked characters. If lock
|
||||||
# does not exist, pass automatically.
|
# does not exist, pass automatically.
|
||||||
return self.obj2recog.get(obj, obj.sdesc.get() if hasattr(obj, "sdesc") else obj.key)
|
return self.obj2recog.get(
|
||||||
|
obj, obj.sdesc.get() if hasattr(obj, "sdesc") else obj.key
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
# recog_mask log not passed, disable recog
|
# recog_mask log not passed, disable recog
|
||||||
return obj.sdesc.get() if hasattr(obj, "sdesc") else obj.key
|
return obj.sdesc.get() if hasattr(obj, "sdesc") else obj.key
|
||||||
|
|
@ -1020,7 +1052,9 @@ class CmdPose(RPCommand): # set current pose and default pose
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
# set the pose. We do one-time ref->sdesc mapping here.
|
# set the pose. We do one-time ref->sdesc mapping here.
|
||||||
parsed, mapping = parse_sdescs_and_recogs(caller, caller.location.contents, pose)
|
parsed, mapping = parse_sdescs_and_recogs(
|
||||||
|
caller, caller.location.contents, pose
|
||||||
|
)
|
||||||
mapping = dict(
|
mapping = dict(
|
||||||
(ref, obj.sdesc.get() if hasattr(obj, "sdesc") else obj.key)
|
(ref, obj.sdesc.get() if hasattr(obj, "sdesc") else obj.key)
|
||||||
for ref, obj in mapping.items()
|
for ref, obj in mapping.items()
|
||||||
|
|
@ -1059,11 +1093,15 @@ class CmdRecog(RPCommand): # assign personal alias to object in room
|
||||||
def parse(self):
|
def parse(self):
|
||||||
"Parse for the sdesc as alias structure"
|
"Parse for the sdesc as alias structure"
|
||||||
if " as " in self.args:
|
if " as " in self.args:
|
||||||
self.sdesc, self.alias = [part.strip() for part in self.args.split(" as ", 2)]
|
self.sdesc, self.alias = [
|
||||||
|
part.strip() for part in self.args.split(" as ", 2)
|
||||||
|
]
|
||||||
elif self.args:
|
elif self.args:
|
||||||
# try to split by space instead
|
# try to split by space instead
|
||||||
try:
|
try:
|
||||||
self.sdesc, self.alias = [part.strip() for part in self.args.split(None, 1)]
|
self.sdesc, self.alias = [
|
||||||
|
part.strip() for part in self.args.split(None, 1)
|
||||||
|
]
|
||||||
except ValueError:
|
except ValueError:
|
||||||
self.sdesc, self.alias = self.args.strip(), ""
|
self.sdesc, self.alias = self.args.strip(), ""
|
||||||
|
|
||||||
|
|
@ -1077,7 +1115,9 @@ class CmdRecog(RPCommand): # assign personal alias to object in room
|
||||||
alias = self.alias.rstrip(".?!")
|
alias = self.alias.rstrip(".?!")
|
||||||
prefixed_sdesc = sdesc if sdesc.startswith(_PREFIX) else _PREFIX + sdesc
|
prefixed_sdesc = sdesc if sdesc.startswith(_PREFIX) else _PREFIX + sdesc
|
||||||
candidates = caller.location.contents
|
candidates = caller.location.contents
|
||||||
matches = parse_sdescs_and_recogs(caller, candidates, prefixed_sdesc, search_mode=True)
|
matches = parse_sdescs_and_recogs(
|
||||||
|
caller, candidates, prefixed_sdesc, search_mode=True
|
||||||
|
)
|
||||||
nmatches = len(matches)
|
nmatches = len(matches)
|
||||||
# handle 0, 1 and >1 matches
|
# handle 0, 1 and >1 matches
|
||||||
if nmatches == 0:
|
if nmatches == 0:
|
||||||
|
|
@ -1094,7 +1134,11 @@ class CmdRecog(RPCommand): # assign personal alias to object in room
|
||||||
)
|
)
|
||||||
for inum, obj in enumerate(matches)
|
for inum, obj in enumerate(matches)
|
||||||
]
|
]
|
||||||
caller.msg(_EMOTE_MULTIMATCH_ERROR.format(ref=sdesc, reflist="\n ".join(reflist)))
|
caller.msg(
|
||||||
|
_EMOTE_MULTIMATCH_ERROR.format(
|
||||||
|
ref=sdesc, reflist="\n ".join(reflist)
|
||||||
|
)
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
obj = matches[0]
|
obj = matches[0]
|
||||||
if not obj.access(self.obj, "enable_recog", default=True):
|
if not obj.access(self.obj, "enable_recog", default=True):
|
||||||
|
|
@ -1104,7 +1148,9 @@ class CmdRecog(RPCommand): # assign personal alias to object in room
|
||||||
if self.cmdstring == "forget":
|
if self.cmdstring == "forget":
|
||||||
# remove existing recog
|
# remove existing recog
|
||||||
caller.recog.remove(obj)
|
caller.recog.remove(obj)
|
||||||
caller.msg("%s will now know only '%s'." % (caller.key, obj.recog.get(obj)))
|
caller.msg(
|
||||||
|
"%s will now know only '%s'." % (caller.key, obj.recog.get(obj))
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
sdesc = obj.sdesc.get() if hasattr(obj, "sdesc") else obj.key
|
sdesc = obj.sdesc.get() if hasattr(obj, "sdesc") else obj.key
|
||||||
try:
|
try:
|
||||||
|
|
@ -1112,7 +1158,10 @@ class CmdRecog(RPCommand): # assign personal alias to object in room
|
||||||
except RecogError as err:
|
except RecogError as err:
|
||||||
caller.msg(err)
|
caller.msg(err)
|
||||||
return
|
return
|
||||||
caller.msg("%s will now remember |w%s|n as |w%s|n." % (caller.key, sdesc, alias))
|
caller.msg(
|
||||||
|
"%s will now remember |w%s|n as |w%s|n."
|
||||||
|
% (caller.key, sdesc, alias)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class CmdMask(RPCommand):
|
class CmdMask(RPCommand):
|
||||||
|
|
@ -1349,7 +1398,9 @@ class ContribRPObject(DefaultObject):
|
||||||
# in eventual error reporting later (not their keys). Doing
|
# in eventual error reporting later (not their keys). Doing
|
||||||
# it like this e.g. allows for use of the typeclass kwarg
|
# it like this e.g. allows for use of the typeclass kwarg
|
||||||
# limiter.
|
# limiter.
|
||||||
results.extend([obj for obj in search_obj(candidate.key) if obj not in results])
|
results.extend(
|
||||||
|
[obj for obj in search_obj(candidate.key) if obj not in results]
|
||||||
|
)
|
||||||
|
|
||||||
if not results and is_builder:
|
if not results and is_builder:
|
||||||
# builders get a chance to search only by key+alias
|
# builders get a chance to search only by key+alias
|
||||||
|
|
@ -1414,7 +1465,9 @@ class ContribRPObject(DefaultObject):
|
||||||
if not looker:
|
if not looker:
|
||||||
return ""
|
return ""
|
||||||
# get and identify all objects
|
# get and identify all objects
|
||||||
visible = (con for con in self.contents if con != looker and con.access(looker, "view"))
|
visible = (
|
||||||
|
con for con in self.contents if con != looker and con.access(looker, "view")
|
||||||
|
)
|
||||||
exits, users, things = [], [], []
|
exits, users, things = [], [], []
|
||||||
for con in visible:
|
for con in visible:
|
||||||
key = con.get_display_name(looker, pose=True)
|
key = con.get_display_name(looker, pose=True)
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,9 @@ AUDIT_MASKS = [
|
||||||
{"connect": r"^[@\s]*[connect]{5,8}\s+(?P<secret>[\w]+)"},
|
{"connect": r"^[@\s]*[connect]{5,8}\s+(?P<secret>[\w]+)"},
|
||||||
{"create": r"^[^@]?[create]{5,6}\s+(\w+|\".+?\")\s+(?P<secret>[\w]+)"},
|
{"create": r"^[^@]?[create]{5,6}\s+(\w+|\".+?\")\s+(?P<secret>[\w]+)"},
|
||||||
{"create": r"^[^@]?[create]{5,6}\s+(?P<secret>[\w]+)"},
|
{"create": r"^[^@]?[create]{5,6}\s+(?P<secret>[\w]+)"},
|
||||||
{"userpassword": r"^[@\s]*[userpassword]{11,14}\s+(\w+|\".+?\")\s+=*\s*(?P<secret>[\w]+)"},
|
{
|
||||||
|
"userpassword": r"^[@\s]*[userpassword]{11,14}\s+(\w+|\".+?\")\s+=*\s*(?P<secret>[\w]+)"
|
||||||
|
},
|
||||||
{"userpassword": r"^.*new password set to '(?P<secret>[^']+)'\."},
|
{"userpassword": r"^.*new password set to '(?P<secret>[^']+)'\."},
|
||||||
{"userpassword": r"^.* has changed your password to '(?P<secret>[^']+)'\."},
|
{"userpassword": r"^.* has changed your password to '(?P<secret>[^']+)'\."},
|
||||||
{"password": r"^[@\s]*[password]{6,9}\s+(?P<secret>.*)"},
|
{"password": r"^[@\s]*[password]{6,9}\s+(?P<secret>.*)"},
|
||||||
|
|
@ -36,7 +38,8 @@ AUDIT_MASKS = [
|
||||||
if AUDIT_CALLBACK:
|
if AUDIT_CALLBACK:
|
||||||
try:
|
try:
|
||||||
AUDIT_CALLBACK = getattr(
|
AUDIT_CALLBACK = getattr(
|
||||||
mod_import(".".join(AUDIT_CALLBACK.split(".")[:-1])), AUDIT_CALLBACK.split(".")[-1]
|
mod_import(".".join(AUDIT_CALLBACK.split(".")[:-1])),
|
||||||
|
AUDIT_CALLBACK.split(".")[-1],
|
||||||
)
|
)
|
||||||
logger.log_sec("Auditing module online.")
|
logger.log_sec("Auditing module online.")
|
||||||
logger.log_sec(
|
logger.log_sec(
|
||||||
|
|
@ -182,7 +185,9 @@ class AuditedServerSession(ServerSession):
|
||||||
# Check to see if the command is embedded within server output
|
# Check to see if the command is embedded within server output
|
||||||
_msg = msg
|
_msg = msg
|
||||||
is_embedded = False
|
is_embedded = False
|
||||||
match = re.match(".*Command.*'(.+)'.*is not available.*", msg, flags=re.IGNORECASE)
|
match = re.match(
|
||||||
|
".*Command.*'(.+)'.*is not available.*", msg, flags=re.IGNORECASE
|
||||||
|
)
|
||||||
if match:
|
if match:
|
||||||
msg = match.group(1).replace("\\", "")
|
msg = match.group(1).replace("\\", "")
|
||||||
submsg = msg
|
submsg = msg
|
||||||
|
|
@ -203,7 +208,10 @@ class AuditedServerSession(ServerSession):
|
||||||
|
|
||||||
if is_embedded:
|
if is_embedded:
|
||||||
msg = re.sub(
|
msg = re.sub(
|
||||||
submsg, "%s <Masked: %s>" % (masked, command), _msg, flags=re.IGNORECASE
|
submsg,
|
||||||
|
"%s <Masked: %s>" % (masked, command),
|
||||||
|
_msg,
|
||||||
|
flags=re.IGNORECASE,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
msg = masked
|
msg = masked
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,9 @@ settings.AUDIT_OUT = True
|
||||||
settings.AUDIT_ALLOW_SPARSE = True
|
settings.AUDIT_ALLOW_SPARSE = True
|
||||||
|
|
||||||
# Configure settings to use custom session - TODO: This is bad practice, changing global settings
|
# Configure settings to use custom session - TODO: This is bad practice, changing global settings
|
||||||
settings.SERVER_SESSION_CLASS = "evennia.contrib.security.auditing.server.AuditedServerSession"
|
settings.SERVER_SESSION_CLASS = (
|
||||||
|
"evennia.contrib.security.auditing.server.AuditedServerSession"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class AuditingTest(EvenniaTest):
|
class AuditingTest(EvenniaTest):
|
||||||
|
|
@ -55,13 +57,28 @@ class AuditingTest(EvenniaTest):
|
||||||
("connect johnny password123", "connect johnny ***********"),
|
("connect johnny password123", "connect johnny ***********"),
|
||||||
("concnct johnny password123", "concnct johnny ***********"),
|
("concnct johnny password123", "concnct johnny ***********"),
|
||||||
("concnct johnnypassword123", "concnct *****************"),
|
("concnct johnnypassword123", "concnct *****************"),
|
||||||
('connect "johnny five" "password 123"', 'connect "johnny five" **************'),
|
(
|
||||||
|
'connect "johnny five" "password 123"',
|
||||||
|
'connect "johnny five" **************',
|
||||||
|
),
|
||||||
('connect johnny "password 123"', "connect johnny **************"),
|
('connect johnny "password 123"', "connect johnny **************"),
|
||||||
("create johnny password123", "create johnny ***********"),
|
("create johnny password123", "create johnny ***********"),
|
||||||
("@password password1234 = password2345", "@password ***************************"),
|
(
|
||||||
("@password password1234 password2345", "@password *************************"),
|
"@password password1234 = password2345",
|
||||||
("@passwd password1234 = password2345", "@passwd ***************************"),
|
"@password ***************************",
|
||||||
("@userpassword johnny = password234", "@userpassword johnny = ***********"),
|
),
|
||||||
|
(
|
||||||
|
"@password password1234 password2345",
|
||||||
|
"@password *************************",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"@passwd password1234 = password2345",
|
||||||
|
"@passwd ***************************",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"@userpassword johnny = password234",
|
||||||
|
"@userpassword johnny = ***********",
|
||||||
|
),
|
||||||
("craete johnnypassword123", "craete *****************"),
|
("craete johnnypassword123", "craete *****************"),
|
||||||
(
|
(
|
||||||
"Command 'conncect teddy teddy' is not available. Maybe you meant \"@encode\"?",
|
"Command 'conncect teddy teddy' is not available. Maybe you meant \"@encode\"?",
|
||||||
|
|
@ -74,7 +91,9 @@ class AuditingTest(EvenniaTest):
|
||||||
)
|
)
|
||||||
|
|
||||||
for index, (unsafe, safe) in enumerate(unsafe_cmds):
|
for index, (unsafe, safe) in enumerate(unsafe_cmds):
|
||||||
self.assertEqual(re.sub(" <Masked: .+>", "", self.session.mask(unsafe)).strip(), safe)
|
self.assertEqual(
|
||||||
|
re.sub(" <Masked: .+>", "", self.session.mask(unsafe)).strip(), safe
|
||||||
|
)
|
||||||
|
|
||||||
# Make sure scrubbing is not being abused to evade monitoring
|
# Make sure scrubbing is not being abused to evade monitoring
|
||||||
secrets = [
|
secrets = [
|
||||||
|
|
@ -93,7 +112,9 @@ class AuditingTest(EvenniaTest):
|
||||||
"""
|
"""
|
||||||
log = self.session.audit(src="client", text=[["hello"]])
|
log = self.session.audit(src="client", text=[["hello"]])
|
||||||
obj = {
|
obj = {
|
||||||
k: v for k, v in log.items() if k in ("direction", "protocol", "application", "text")
|
k: v
|
||||||
|
for k, v in log.items()
|
||||||
|
if k in ("direction", "protocol", "application", "text")
|
||||||
}
|
}
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
obj,
|
obj,
|
||||||
|
|
@ -107,7 +128,10 @@ class AuditingTest(EvenniaTest):
|
||||||
|
|
||||||
# Make sure OOB data is being recorded
|
# Make sure OOB data is being recorded
|
||||||
log = self.session.audit(
|
log = self.session.audit(
|
||||||
src="client", text="connect johnny password123", prompt="hp=20|st=10|ma=15", pane=2
|
src="client",
|
||||||
|
text="connect johnny password123",
|
||||||
|
prompt="hp=20|st=10|ma=15",
|
||||||
|
pane=2,
|
||||||
)
|
)
|
||||||
self.assertEqual(log["text"], "connect johnny ***********")
|
self.assertEqual(log["text"], "connect johnny ***********")
|
||||||
self.assertEqual(log["data"]["prompt"], "hp=20|st=10|ma=15")
|
self.assertEqual(log["data"]["prompt"], "hp=20|st=10|ma=15")
|
||||||
|
|
|
||||||
|
|
@ -97,13 +97,19 @@ class CmdOpen(default_cmds.CmdOpen):
|
||||||
__doc__ = default_cmds.CmdOpen.__doc__
|
__doc__ = default_cmds.CmdOpen.__doc__
|
||||||
# overloading parts of the default CmdOpen command to support doors.
|
# overloading parts of the default CmdOpen command to support doors.
|
||||||
|
|
||||||
def create_exit(self, exit_name, location, destination, exit_aliases=None, typeclass=None):
|
def create_exit(
|
||||||
|
self, exit_name, location, destination, exit_aliases=None, typeclass=None
|
||||||
|
):
|
||||||
"""
|
"""
|
||||||
Simple wrapper for the default CmdOpen.create_exit
|
Simple wrapper for the default CmdOpen.create_exit
|
||||||
"""
|
"""
|
||||||
# create a new exit as normal
|
# create a new exit as normal
|
||||||
new_exit = super().create_exit(
|
new_exit = super().create_exit(
|
||||||
exit_name, location, destination, exit_aliases=exit_aliases, typeclass=typeclass
|
exit_name,
|
||||||
|
location,
|
||||||
|
destination,
|
||||||
|
exit_aliases=exit_aliases,
|
||||||
|
typeclass=typeclass,
|
||||||
)
|
)
|
||||||
if hasattr(self, "return_exit_already_created"):
|
if hasattr(self, "return_exit_already_created"):
|
||||||
# we don't create a return exit if it was already created (because
|
# we don't create a return exit if it was already created (because
|
||||||
|
|
@ -118,7 +124,11 @@ class CmdOpen(default_cmds.CmdOpen):
|
||||||
)
|
)
|
||||||
self.return_exit_already_created = True
|
self.return_exit_already_created = True
|
||||||
back_exit = self.create_exit(
|
back_exit = self.create_exit(
|
||||||
exit_name, destination, location, exit_aliases=exit_aliases, typeclass=typeclass
|
exit_name,
|
||||||
|
destination,
|
||||||
|
location,
|
||||||
|
exit_aliases=exit_aliases,
|
||||||
|
typeclass=typeclass,
|
||||||
)
|
)
|
||||||
new_exit.db.return_exit = back_exit
|
new_exit.db.return_exit = back_exit
|
||||||
back_exit.db.return_exit = new_exit
|
back_exit.db.return_exit = new_exit
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,12 @@ class SlowExit(DefaultExit):
|
||||||
# set speed - command
|
# set speed - command
|
||||||
#
|
#
|
||||||
|
|
||||||
SPEED_DESCS = {"stroll": "strolling", "walk": "walking", "run": "running", "sprint": "sprinting"}
|
SPEED_DESCS = {
|
||||||
|
"stroll": "strolling",
|
||||||
|
"walk": "walking",
|
||||||
|
"run": "running",
|
||||||
|
"sprint": "sprinting",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class CmdSetSpeed(Command):
|
class CmdSetSpeed(Command):
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,10 @@ def menu_start_node(caller):
|
||||||
text = "'Hello there, how can I help you?'"
|
text = "'Hello there, how can I help you?'"
|
||||||
|
|
||||||
options = (
|
options = (
|
||||||
{"desc": "Hey, do you know what this 'Evennia' thing is all about?", "goto": "info1"},
|
{
|
||||||
|
"desc": "Hey, do you know what this 'Evennia' thing is all about?",
|
||||||
|
"goto": "info1",
|
||||||
|
},
|
||||||
{"desc": "What's your name, little NPC?", "goto": "info2"},
|
{"desc": "What's your name, little NPC?", "goto": "info2"},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -41,7 +44,10 @@ def info1(caller):
|
||||||
text = "'Oh, Evennia is where you are right now! Don't you feel the power?'"
|
text = "'Oh, Evennia is where you are right now! Don't you feel the power?'"
|
||||||
|
|
||||||
options = (
|
options = (
|
||||||
{"desc": "Sure, *I* do, not sure how you do though. You are just an NPC.", "goto": "info3"},
|
{
|
||||||
|
"desc": "Sure, *I* do, not sure how you do though. You are just an NPC.",
|
||||||
|
"goto": "info3",
|
||||||
|
},
|
||||||
{"desc": "Sure I do. What's yer name, NPC?", "goto": "info2"},
|
{"desc": "Sure I do. What's yer name, NPC?", "goto": "info2"},
|
||||||
{"desc": "Ok, bye for now then.", "goto": "END"},
|
{"desc": "Ok, bye for now then.", "goto": "END"},
|
||||||
)
|
)
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -422,7 +422,10 @@ def optlist_to_menuoptions(treestr, optlist, index, mark_category, go_back):
|
||||||
gobackitem = {
|
gobackitem = {
|
||||||
"key": ["<< Go Back", "go back", "back"],
|
"key": ["<< Go Back", "go back", "back"],
|
||||||
"desc": "Return to the previous menu.",
|
"desc": "Return to the previous menu.",
|
||||||
"goto": ["menunode_treeselect", {"newindex": go_up_one_category(treestr, index)}],
|
"goto": [
|
||||||
|
"menunode_treeselect",
|
||||||
|
{"newindex": go_up_one_category(treestr, index)},
|
||||||
|
],
|
||||||
}
|
}
|
||||||
menuoptions.append(gobackitem)
|
menuoptions.append(gobackitem)
|
||||||
return menuoptions
|
return menuoptions
|
||||||
|
|
@ -461,7 +464,9 @@ def menunode_treeselect(caller, raw_string, **kwargs):
|
||||||
|
|
||||||
# Otherwise, convert optlist to a list of menu options.
|
# Otherwise, convert optlist to a list of menu options.
|
||||||
else:
|
else:
|
||||||
options = optlist_to_menuoptions(treestr, optlist, index, mark_category, go_back)
|
options = optlist_to_menuoptions(
|
||||||
|
treestr, optlist, index, mark_category, go_back
|
||||||
|
)
|
||||||
if index == None:
|
if index == None:
|
||||||
# Use start_text for the menu text on the top level
|
# Use start_text for the menu text on the top level
|
||||||
text = start_text
|
text = start_text
|
||||||
|
|
@ -525,7 +530,10 @@ class CmdNameColor(Command):
|
||||||
def func(self):
|
def func(self):
|
||||||
# This is all you have to do to initialize a menu!
|
# This is all you have to do to initialize a menu!
|
||||||
init_tree_selection(
|
init_tree_selection(
|
||||||
NAMECOLOR_MENU, self.caller, change_name_color, start_text="Name color options:"
|
NAMECOLOR_MENU,
|
||||||
|
self.caller,
|
||||||
|
change_name_color,
|
||||||
|
start_text="Name color options:",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -573,5 +581,7 @@ def change_name_color(caller, treestr, index, selection):
|
||||||
caller.msg("Name color removed.")
|
caller.msg("Name color removed.")
|
||||||
elif selection in colordict:
|
elif selection in colordict:
|
||||||
newcolor = colordict[selection] # Retrieve color code based on menu selection
|
newcolor = colordict[selection] # Retrieve color code based on menu selection
|
||||||
caller.key = newcolor + caller.db.uncolored_name + "|n" # Add color code to caller's name
|
caller.key = (
|
||||||
|
newcolor + caller.db.uncolored_name + "|n"
|
||||||
|
) # Add color code to caller's name
|
||||||
caller.msg(newcolor + ("Name color changed to %s!" % selection) + "|n")
|
caller.msg(newcolor + ("Name color changed to %s!" % selection) + "|n")
|
||||||
|
|
|
||||||
|
|
@ -291,7 +291,9 @@ def spend_action(character, actions, action_name=None):
|
||||||
character.db.combat_actionsleft -= actions # Use up actions.
|
character.db.combat_actionsleft -= actions # Use up actions.
|
||||||
if character.db.combat_actionsleft < 0:
|
if character.db.combat_actionsleft < 0:
|
||||||
character.db.combat_actionsleft = 0 # Can't have fewer than 0 actions
|
character.db.combat_actionsleft = 0 # Can't have fewer than 0 actions
|
||||||
character.db.combat_turnhandler.turn_end_check(character) # Signal potential end of turn.
|
character.db.combat_turnhandler.turn_end_check(
|
||||||
|
character
|
||||||
|
) # Signal potential end of turn.
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
@ -394,7 +396,9 @@ class TBBasicTurnHandler(DefaultScript):
|
||||||
self.db.fighters = ordered_by_roll
|
self.db.fighters = ordered_by_roll
|
||||||
|
|
||||||
# Announce the turn order.
|
# Announce the turn order.
|
||||||
self.obj.msg_contents("Turn order is: %s " % ", ".join(obj.key for obj in self.db.fighters))
|
self.obj.msg_contents(
|
||||||
|
"Turn order is: %s " % ", ".join(obj.key for obj in self.db.fighters)
|
||||||
|
)
|
||||||
|
|
||||||
# Start first fighter's turn.
|
# Start first fighter's turn.
|
||||||
self.start_turn(self.db.fighters[0])
|
self.start_turn(self.db.fighters[0])
|
||||||
|
|
@ -409,7 +413,9 @@ class TBBasicTurnHandler(DefaultScript):
|
||||||
"""
|
"""
|
||||||
for fighter in self.db.fighters:
|
for fighter in self.db.fighters:
|
||||||
combat_cleanup(fighter) # Clean up the combat attributes for every fighter.
|
combat_cleanup(fighter) # Clean up the combat attributes for every fighter.
|
||||||
self.obj.db.combat_turnhandler = None # Remove reference to turn handler in location
|
self.obj.db.combat_turnhandler = (
|
||||||
|
None
|
||||||
|
) # Remove reference to turn handler in location
|
||||||
|
|
||||||
def at_repeat(self):
|
def at_repeat(self):
|
||||||
"""
|
"""
|
||||||
|
|
@ -427,7 +433,9 @@ class TBBasicTurnHandler(DefaultScript):
|
||||||
currentchar, "all", action_name="disengage"
|
currentchar, "all", action_name="disengage"
|
||||||
) # Spend all remaining actions.
|
) # Spend all remaining actions.
|
||||||
return
|
return
|
||||||
elif self.db.timer <= 10 and not self.db.timeout_warning_given: # 10 seconds left
|
elif (
|
||||||
|
self.db.timer <= 10 and not self.db.timeout_warning_given
|
||||||
|
): # 10 seconds left
|
||||||
# Warn the current character if they're about to time out.
|
# Warn the current character if they're about to time out.
|
||||||
currentchar.msg("WARNING: About to time out!")
|
currentchar.msg("WARNING: About to time out!")
|
||||||
self.db.timeout_warning_given = True
|
self.db.timeout_warning_given = True
|
||||||
|
|
@ -439,7 +447,9 @@ class TBBasicTurnHandler(DefaultScript):
|
||||||
Args:
|
Args:
|
||||||
character (obj): Character to initialize for combat.
|
character (obj): Character to initialize for combat.
|
||||||
"""
|
"""
|
||||||
combat_cleanup(character) # Clean up leftover combat attributes beforehand, just in case.
|
combat_cleanup(
|
||||||
|
character
|
||||||
|
) # Clean up leftover combat attributes beforehand, just in case.
|
||||||
character.db.combat_actionsleft = (
|
character.db.combat_actionsleft = (
|
||||||
0
|
0
|
||||||
) # Actions remaining - start of turn adds to this, turn ends when it reaches 0
|
) # Actions remaining - start of turn adds to this, turn ends when it reaches 0
|
||||||
|
|
@ -488,13 +498,17 @@ class TBBasicTurnHandler(DefaultScript):
|
||||||
defeated_characters = 0
|
defeated_characters = 0
|
||||||
for fighter in self.db.fighters:
|
for fighter in self.db.fighters:
|
||||||
if fighter.db.HP == 0:
|
if fighter.db.HP == 0:
|
||||||
defeated_characters += 1 # Add 1 for every fighter with 0 HP left (defeated)
|
defeated_characters += (
|
||||||
|
1
|
||||||
|
) # Add 1 for every fighter with 0 HP left (defeated)
|
||||||
if defeated_characters == (
|
if defeated_characters == (
|
||||||
len(self.db.fighters) - 1
|
len(self.db.fighters) - 1
|
||||||
): # If only one character isn't defeated
|
): # If only one character isn't defeated
|
||||||
for fighter in self.db.fighters:
|
for fighter in self.db.fighters:
|
||||||
if fighter.db.HP != 0:
|
if fighter.db.HP != 0:
|
||||||
LastStanding = fighter # Pick the one fighter left with HP remaining
|
LastStanding = (
|
||||||
|
fighter
|
||||||
|
) # Pick the one fighter left with HP remaining
|
||||||
self.obj.msg_contents("Only %s remains! Combat is over!" % LastStanding)
|
self.obj.msg_contents("Only %s remains! Combat is over!" % LastStanding)
|
||||||
self.stop() # Stop this script and end combat.
|
self.stop() # Stop this script and end combat.
|
||||||
return
|
return
|
||||||
|
|
@ -503,11 +517,15 @@ class TBBasicTurnHandler(DefaultScript):
|
||||||
currentchar = self.db.fighters[self.db.turn]
|
currentchar = self.db.fighters[self.db.turn]
|
||||||
self.db.turn += 1 # Go to the next in the turn order.
|
self.db.turn += 1 # Go to the next in the turn order.
|
||||||
if self.db.turn > len(self.db.fighters) - 1:
|
if self.db.turn > len(self.db.fighters) - 1:
|
||||||
self.db.turn = 0 # Go back to the first in the turn order once you reach the end.
|
self.db.turn = (
|
||||||
|
0
|
||||||
|
) # Go back to the first in the turn order once you reach the end.
|
||||||
newchar = self.db.fighters[self.db.turn] # Note the new character
|
newchar = self.db.fighters[self.db.turn] # Note the new character
|
||||||
self.db.timer = TURN_TIMEOUT + self.time_until_next_repeat() # Reset the timer.
|
self.db.timer = TURN_TIMEOUT + self.time_until_next_repeat() # Reset the timer.
|
||||||
self.db.timeout_warning_given = False # Reset the timeout warning.
|
self.db.timeout_warning_given = False # Reset the timeout warning.
|
||||||
self.obj.msg_contents("%s's turn ends - %s's turn begins!" % (currentchar, newchar))
|
self.obj.msg_contents(
|
||||||
|
"%s's turn ends - %s's turn begins!" % (currentchar, newchar)
|
||||||
|
)
|
||||||
self.start_turn(newchar) # Start the new character's turn.
|
self.start_turn(newchar) # Start the new character's turn.
|
||||||
|
|
||||||
def turn_end_check(self, character):
|
def turn_end_check(self, character):
|
||||||
|
|
@ -571,7 +589,9 @@ class CmdFight(Command):
|
||||||
if is_in_combat(self.caller): # Already in a fight
|
if is_in_combat(self.caller): # Already in a fight
|
||||||
self.caller.msg("You're already in a fight!")
|
self.caller.msg("You're already in a fight!")
|
||||||
return
|
return
|
||||||
for thing in here.contents: # Test everything in the room to add it to the fight.
|
for (
|
||||||
|
thing
|
||||||
|
) in here.contents: # Test everything in the room to add it to the fight.
|
||||||
if thing.db.HP: # If the object has HP...
|
if thing.db.HP: # If the object has HP...
|
||||||
fighters.append(thing) # ...then add it to the fight.
|
fighters.append(thing) # ...then add it to the fight.
|
||||||
if len(fighters) <= 1: # If you're the only able fighter in the room
|
if len(fighters) <= 1: # If you're the only able fighter in the room
|
||||||
|
|
@ -666,7 +686,9 @@ class CmdPass(Command):
|
||||||
self.caller.location.msg_contents(
|
self.caller.location.msg_contents(
|
||||||
"%s takes no further action, passing the turn." % self.caller
|
"%s takes no further action, passing the turn." % self.caller
|
||||||
)
|
)
|
||||||
spend_action(self.caller, "all", action_name="pass") # Spend all remaining actions.
|
spend_action(
|
||||||
|
self.caller, "all", action_name="pass"
|
||||||
|
) # Spend all remaining actions.
|
||||||
|
|
||||||
|
|
||||||
class CmdDisengage(Command):
|
class CmdDisengage(Command):
|
||||||
|
|
@ -697,8 +719,12 @@ class CmdDisengage(Command):
|
||||||
self.caller.msg("You can only do that on your turn.")
|
self.caller.msg("You can only do that on your turn.")
|
||||||
return
|
return
|
||||||
|
|
||||||
self.caller.location.msg_contents("%s disengages, ready to stop fighting." % self.caller)
|
self.caller.location.msg_contents(
|
||||||
spend_action(self.caller, "all", action_name="disengage") # Spend all remaining actions.
|
"%s disengages, ready to stop fighting." % self.caller
|
||||||
|
)
|
||||||
|
spend_action(
|
||||||
|
self.caller, "all", action_name="disengage"
|
||||||
|
) # Spend all remaining actions.
|
||||||
"""
|
"""
|
||||||
The action_name kwarg sets the character's last action to "disengage", which is checked by
|
The action_name kwarg sets the character's last action to "disengage", which is checked by
|
||||||
the turn handler script to see if all fighters have disengaged.
|
the turn handler script to see if all fighters have disengaged.
|
||||||
|
|
@ -750,7 +776,9 @@ class CmdCombatHelp(CmdHelp):
|
||||||
# tips on combat when used in a fight with no arguments.
|
# tips on combat when used in a fight with no arguments.
|
||||||
|
|
||||||
def func(self):
|
def func(self):
|
||||||
if is_in_combat(self.caller) and not self.args: # In combat and entered 'help' alone
|
if (
|
||||||
|
is_in_combat(self.caller) and not self.args
|
||||||
|
): # In combat and entered 'help' alone
|
||||||
self.caller.msg(
|
self.caller.msg(
|
||||||
"Available combat commands:|/"
|
"Available combat commands:|/"
|
||||||
+ "|wAttack:|n Attack a target, attempting to deal damage.|/"
|
+ "|wAttack:|n Attack a target, attempting to deal damage.|/"
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,13 @@ in your game and using it as-is.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from random import randint
|
from random import randint
|
||||||
from evennia import DefaultCharacter, Command, default_cmds, DefaultScript, DefaultObject
|
from evennia import (
|
||||||
|
DefaultCharacter,
|
||||||
|
Command,
|
||||||
|
default_cmds,
|
||||||
|
DefaultScript,
|
||||||
|
DefaultObject,
|
||||||
|
)
|
||||||
from evennia.commands.default.help import CmdHelp
|
from evennia.commands.default.help import CmdHelp
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
@ -270,7 +276,8 @@ def resolve_attack(attacker, defender, attack_value=None, defense_value=None):
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
attacker.location.msg_contents(
|
attacker.location.msg_contents(
|
||||||
"%s's %s bounces harmlessly off %s!" % (attacker, attackers_weapon, defender)
|
"%s's %s bounces harmlessly off %s!"
|
||||||
|
% (attacker, attackers_weapon, defender)
|
||||||
)
|
)
|
||||||
apply_damage(defender, damage_value)
|
apply_damage(defender, damage_value)
|
||||||
# If defender HP is reduced to 0 or less, call at_defeat.
|
# If defender HP is reduced to 0 or less, call at_defeat.
|
||||||
|
|
@ -342,7 +349,9 @@ def spend_action(character, actions, action_name=None):
|
||||||
character.db.combat_actionsleft -= actions # Use up actions.
|
character.db.combat_actionsleft -= actions # Use up actions.
|
||||||
if character.db.combat_actionsleft < 0:
|
if character.db.combat_actionsleft < 0:
|
||||||
character.db.combat_actionsleft = 0 # Can't have fewer than 0 actions
|
character.db.combat_actionsleft = 0 # Can't have fewer than 0 actions
|
||||||
character.db.combat_turnhandler.turn_end_check(character) # Signal potential end of turn.
|
character.db.combat_turnhandler.turn_end_check(
|
||||||
|
character
|
||||||
|
) # Signal potential end of turn.
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
@ -391,7 +400,9 @@ class TBEquipTurnHandler(DefaultScript):
|
||||||
self.db.fighters = ordered_by_roll
|
self.db.fighters = ordered_by_roll
|
||||||
|
|
||||||
# Announce the turn order.
|
# Announce the turn order.
|
||||||
self.obj.msg_contents("Turn order is: %s " % ", ".join(obj.key for obj in self.db.fighters))
|
self.obj.msg_contents(
|
||||||
|
"Turn order is: %s " % ", ".join(obj.key for obj in self.db.fighters)
|
||||||
|
)
|
||||||
|
|
||||||
# Start first fighter's turn.
|
# Start first fighter's turn.
|
||||||
self.start_turn(self.db.fighters[0])
|
self.start_turn(self.db.fighters[0])
|
||||||
|
|
@ -406,7 +417,9 @@ class TBEquipTurnHandler(DefaultScript):
|
||||||
"""
|
"""
|
||||||
for fighter in self.db.fighters:
|
for fighter in self.db.fighters:
|
||||||
combat_cleanup(fighter) # Clean up the combat attributes for every fighter.
|
combat_cleanup(fighter) # Clean up the combat attributes for every fighter.
|
||||||
self.obj.db.combat_turnhandler = None # Remove reference to turn handler in location
|
self.obj.db.combat_turnhandler = (
|
||||||
|
None
|
||||||
|
) # Remove reference to turn handler in location
|
||||||
|
|
||||||
def at_repeat(self):
|
def at_repeat(self):
|
||||||
"""
|
"""
|
||||||
|
|
@ -424,7 +437,9 @@ class TBEquipTurnHandler(DefaultScript):
|
||||||
currentchar, "all", action_name="disengage"
|
currentchar, "all", action_name="disengage"
|
||||||
) # Spend all remaining actions.
|
) # Spend all remaining actions.
|
||||||
return
|
return
|
||||||
elif self.db.timer <= 10 and not self.db.timeout_warning_given: # 10 seconds left
|
elif (
|
||||||
|
self.db.timer <= 10 and not self.db.timeout_warning_given
|
||||||
|
): # 10 seconds left
|
||||||
# Warn the current character if they're about to time out.
|
# Warn the current character if they're about to time out.
|
||||||
currentchar.msg("WARNING: About to time out!")
|
currentchar.msg("WARNING: About to time out!")
|
||||||
self.db.timeout_warning_given = True
|
self.db.timeout_warning_given = True
|
||||||
|
|
@ -436,7 +451,9 @@ class TBEquipTurnHandler(DefaultScript):
|
||||||
Args:
|
Args:
|
||||||
character (obj): Character to initialize for combat.
|
character (obj): Character to initialize for combat.
|
||||||
"""
|
"""
|
||||||
combat_cleanup(character) # Clean up leftover combat attributes beforehand, just in case.
|
combat_cleanup(
|
||||||
|
character
|
||||||
|
) # Clean up leftover combat attributes beforehand, just in case.
|
||||||
character.db.combat_actionsleft = (
|
character.db.combat_actionsleft = (
|
||||||
0
|
0
|
||||||
) # Actions remaining - start of turn adds to this, turn ends when it reaches 0
|
) # Actions remaining - start of turn adds to this, turn ends when it reaches 0
|
||||||
|
|
@ -485,13 +502,17 @@ class TBEquipTurnHandler(DefaultScript):
|
||||||
defeated_characters = 0
|
defeated_characters = 0
|
||||||
for fighter in self.db.fighters:
|
for fighter in self.db.fighters:
|
||||||
if fighter.db.HP == 0:
|
if fighter.db.HP == 0:
|
||||||
defeated_characters += 1 # Add 1 for every fighter with 0 HP left (defeated)
|
defeated_characters += (
|
||||||
|
1
|
||||||
|
) # Add 1 for every fighter with 0 HP left (defeated)
|
||||||
if defeated_characters == (
|
if defeated_characters == (
|
||||||
len(self.db.fighters) - 1
|
len(self.db.fighters) - 1
|
||||||
): # If only one character isn't defeated
|
): # If only one character isn't defeated
|
||||||
for fighter in self.db.fighters:
|
for fighter in self.db.fighters:
|
||||||
if fighter.db.HP != 0:
|
if fighter.db.HP != 0:
|
||||||
LastStanding = fighter # Pick the one fighter left with HP remaining
|
LastStanding = (
|
||||||
|
fighter
|
||||||
|
) # Pick the one fighter left with HP remaining
|
||||||
self.obj.msg_contents("Only %s remains! Combat is over!" % LastStanding)
|
self.obj.msg_contents("Only %s remains! Combat is over!" % LastStanding)
|
||||||
self.stop() # Stop this script and end combat.
|
self.stop() # Stop this script and end combat.
|
||||||
return
|
return
|
||||||
|
|
@ -500,11 +521,15 @@ class TBEquipTurnHandler(DefaultScript):
|
||||||
currentchar = self.db.fighters[self.db.turn]
|
currentchar = self.db.fighters[self.db.turn]
|
||||||
self.db.turn += 1 # Go to the next in the turn order.
|
self.db.turn += 1 # Go to the next in the turn order.
|
||||||
if self.db.turn > len(self.db.fighters) - 1:
|
if self.db.turn > len(self.db.fighters) - 1:
|
||||||
self.db.turn = 0 # Go back to the first in the turn order once you reach the end.
|
self.db.turn = (
|
||||||
|
0
|
||||||
|
) # Go back to the first in the turn order once you reach the end.
|
||||||
newchar = self.db.fighters[self.db.turn] # Note the new character
|
newchar = self.db.fighters[self.db.turn] # Note the new character
|
||||||
self.db.timer = TURN_TIMEOUT + self.time_until_next_repeat() # Reset the timer.
|
self.db.timer = TURN_TIMEOUT + self.time_until_next_repeat() # Reset the timer.
|
||||||
self.db.timeout_warning_given = False # Reset the timeout warning.
|
self.db.timeout_warning_given = False # Reset the timeout warning.
|
||||||
self.obj.msg_contents("%s's turn ends - %s's turn begins!" % (currentchar, newchar))
|
self.obj.msg_contents(
|
||||||
|
"%s's turn ends - %s's turn begins!" % (currentchar, newchar)
|
||||||
|
)
|
||||||
self.start_turn(newchar) # Start the new character's turn.
|
self.start_turn(newchar) # Start the new character's turn.
|
||||||
|
|
||||||
def turn_end_check(self, character):
|
def turn_end_check(self, character):
|
||||||
|
|
@ -710,7 +735,9 @@ class CmdFight(Command):
|
||||||
if is_in_combat(self.caller): # Already in a fight
|
if is_in_combat(self.caller): # Already in a fight
|
||||||
self.caller.msg("You're already in a fight!")
|
self.caller.msg("You're already in a fight!")
|
||||||
return
|
return
|
||||||
for thing in here.contents: # Test everything in the room to add it to the fight.
|
for (
|
||||||
|
thing
|
||||||
|
) in here.contents: # Test everything in the room to add it to the fight.
|
||||||
if thing.db.HP: # If the object has HP...
|
if thing.db.HP: # If the object has HP...
|
||||||
fighters.append(thing) # ...then add it to the fight.
|
fighters.append(thing) # ...then add it to the fight.
|
||||||
if len(fighters) <= 1: # If you're the only able fighter in the room
|
if len(fighters) <= 1: # If you're the only able fighter in the room
|
||||||
|
|
@ -805,7 +832,9 @@ class CmdPass(Command):
|
||||||
self.caller.location.msg_contents(
|
self.caller.location.msg_contents(
|
||||||
"%s takes no further action, passing the turn." % self.caller
|
"%s takes no further action, passing the turn." % self.caller
|
||||||
)
|
)
|
||||||
spend_action(self.caller, "all", action_name="pass") # Spend all remaining actions.
|
spend_action(
|
||||||
|
self.caller, "all", action_name="pass"
|
||||||
|
) # Spend all remaining actions.
|
||||||
|
|
||||||
|
|
||||||
class CmdDisengage(Command):
|
class CmdDisengage(Command):
|
||||||
|
|
@ -836,8 +865,12 @@ class CmdDisengage(Command):
|
||||||
self.caller.msg("You can only do that on your turn.")
|
self.caller.msg("You can only do that on your turn.")
|
||||||
return
|
return
|
||||||
|
|
||||||
self.caller.location.msg_contents("%s disengages, ready to stop fighting." % self.caller)
|
self.caller.location.msg_contents(
|
||||||
spend_action(self.caller, "all", action_name="disengage") # Spend all remaining actions.
|
"%s disengages, ready to stop fighting." % self.caller
|
||||||
|
)
|
||||||
|
spend_action(
|
||||||
|
self.caller, "all", action_name="disengage"
|
||||||
|
) # Spend all remaining actions.
|
||||||
"""
|
"""
|
||||||
The action_name kwarg sets the character's last action to "disengage", which is checked by
|
The action_name kwarg sets the character's last action to "disengage", which is checked by
|
||||||
the turn handler script to see if all fighters have disengaged.
|
the turn handler script to see if all fighters have disengaged.
|
||||||
|
|
@ -889,7 +922,9 @@ class CmdCombatHelp(CmdHelp):
|
||||||
# tips on combat when used in a fight with no arguments.
|
# tips on combat when used in a fight with no arguments.
|
||||||
|
|
||||||
def func(self):
|
def func(self):
|
||||||
if is_in_combat(self.caller) and not self.args: # In combat and entered 'help' alone
|
if (
|
||||||
|
is_in_combat(self.caller) and not self.args
|
||||||
|
): # In combat and entered 'help' alone
|
||||||
self.caller.msg(
|
self.caller.msg(
|
||||||
"Available combat commands:|/"
|
"Available combat commands:|/"
|
||||||
+ "|wAttack:|n Attack a target, attempting to deal damage.|/"
|
+ "|wAttack:|n Attack a target, attempting to deal damage.|/"
|
||||||
|
|
@ -980,7 +1015,9 @@ class CmdUnwield(Command):
|
||||||
else:
|
else:
|
||||||
old_weapon = self.caller.db.wielded_weapon
|
old_weapon = self.caller.db.wielded_weapon
|
||||||
self.caller.db.wielded_weapon = None
|
self.caller.db.wielded_weapon = None
|
||||||
self.caller.location.msg_contents("%s lowers %s." % (self.caller, old_weapon))
|
self.caller.location.msg_contents(
|
||||||
|
"%s lowers %s." % (self.caller, old_weapon)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class CmdDon(Command):
|
class CmdDon(Command):
|
||||||
|
|
@ -1056,7 +1093,9 @@ class CmdDoff(Command):
|
||||||
else:
|
else:
|
||||||
old_armor = self.caller.db.worn_armor
|
old_armor = self.caller.db.worn_armor
|
||||||
self.caller.db.worn_armor = None
|
self.caller.db.worn_armor = None
|
||||||
self.caller.location.msg_contents("%s removes %s." % (self.caller, old_armor))
|
self.caller.location.msg_contents(
|
||||||
|
"%s removes %s." % (self.caller, old_armor)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class BattleCmdSet(default_cmds.CharacterCmdSet):
|
class BattleCmdSet(default_cmds.CharacterCmdSet):
|
||||||
|
|
|
||||||
|
|
@ -360,7 +360,9 @@ def spend_action(character, actions, action_name=None):
|
||||||
character.db.combat_actionsleft -= actions # Use up actions.
|
character.db.combat_actionsleft -= actions # Use up actions.
|
||||||
if character.db.combat_actionsleft < 0:
|
if character.db.combat_actionsleft < 0:
|
||||||
character.db.combat_actionsleft = 0 # Can't have fewer than 0 actions
|
character.db.combat_actionsleft = 0 # Can't have fewer than 0 actions
|
||||||
character.db.combat_turnhandler.turn_end_check(character) # Signal potential end of turn.
|
character.db.combat_turnhandler.turn_end_check(
|
||||||
|
character
|
||||||
|
) # Signal potential end of turn.
|
||||||
|
|
||||||
|
|
||||||
def spend_item_use(item, user):
|
def spend_item_use(item, user):
|
||||||
|
|
@ -381,7 +383,9 @@ def spend_item_use(item, user):
|
||||||
|
|
||||||
if item.db.item_uses > 0: # Has uses remaining
|
if item.db.item_uses > 0: # Has uses remaining
|
||||||
# Inform the player
|
# Inform the player
|
||||||
user.msg("%s has %i uses remaining." % (item.key.capitalize(), item.db.item_uses))
|
user.msg(
|
||||||
|
"%s has %i uses remaining." % (item.key.capitalize(), item.db.item_uses)
|
||||||
|
)
|
||||||
|
|
||||||
else: # All uses spent
|
else: # All uses spent
|
||||||
|
|
||||||
|
|
@ -390,13 +394,19 @@ def spend_item_use(item, user):
|
||||||
user.msg("%s has no uses remaining." % item.key.capitalize())
|
user.msg("%s has no uses remaining." % item.key.capitalize())
|
||||||
|
|
||||||
else: # If item is consumable
|
else: # If item is consumable
|
||||||
if item.db.item_consumable == True: # If the value is 'True', just destroy the item
|
if (
|
||||||
|
item.db.item_consumable == True
|
||||||
|
): # If the value is 'True', just destroy the item
|
||||||
user.msg("%s has been consumed." % item.key.capitalize())
|
user.msg("%s has been consumed." % item.key.capitalize())
|
||||||
item.delete() # Delete the spent item
|
item.delete() # Delete the spent item
|
||||||
|
|
||||||
else: # If a string, use value of item_consumable to spawn an object in its place
|
else: # If a string, use value of item_consumable to spawn an object in its place
|
||||||
residue = spawn({"prototype": item.db.item_consumable})[0] # Spawn the residue
|
residue = spawn({"prototype": item.db.item_consumable})[
|
||||||
residue.location = item.location # Move the residue to the same place as the item
|
0
|
||||||
|
] # Spawn the residue
|
||||||
|
residue.location = (
|
||||||
|
item.location
|
||||||
|
) # Move the residue to the same place as the item
|
||||||
user.msg("After using %s, you are left with %s." % (item, residue))
|
user.msg("After using %s, you are left with %s." % (item, residue))
|
||||||
item.delete() # Delete the spent item
|
item.delete() # Delete the spent item
|
||||||
|
|
||||||
|
|
@ -491,7 +501,9 @@ def add_condition(character, turnchar, condition, duration):
|
||||||
# The first value is the remaining turns - the second value is whose turn to count down on.
|
# The first value is the remaining turns - the second value is whose turn to count down on.
|
||||||
character.db.conditions.update({condition: [duration, turnchar]})
|
character.db.conditions.update({condition: [duration, turnchar]})
|
||||||
# Tell everyone!
|
# Tell everyone!
|
||||||
character.location.msg_contents("%s gains the '%s' condition." % (character, condition))
|
character.location.msg_contents(
|
||||||
|
"%s gains the '%s' condition." % (character, condition)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
@ -577,13 +589,17 @@ class TBItemsCharacter(DefaultCharacter):
|
||||||
if self.db.hp + to_heal > self.db.max_hp:
|
if self.db.hp + to_heal > self.db.max_hp:
|
||||||
to_heal = self.db.max_hp - self.db.hp # Cap healing to max HP
|
to_heal = self.db.max_hp - self.db.hp # Cap healing to max HP
|
||||||
self.db.hp += to_heal
|
self.db.hp += to_heal
|
||||||
self.location.msg_contents("%s regains %i HP from Regeneration." % (self, to_heal))
|
self.location.msg_contents(
|
||||||
|
"%s regains %i HP from Regeneration." % (self, to_heal)
|
||||||
|
)
|
||||||
|
|
||||||
# Poisoned: does 4 to 8 damage at the start of character's turn
|
# Poisoned: does 4 to 8 damage at the start of character's turn
|
||||||
if "Poisoned" in self.db.conditions:
|
if "Poisoned" in self.db.conditions:
|
||||||
to_hurt = randint(POISON_RATE[0], POISON_RATE[1]) # Deal damage
|
to_hurt = randint(POISON_RATE[0], POISON_RATE[1]) # Deal damage
|
||||||
apply_damage(self, to_hurt)
|
apply_damage(self, to_hurt)
|
||||||
self.location.msg_contents("%s takes %i damage from being Poisoned." % (self, to_hurt))
|
self.location.msg_contents(
|
||||||
|
"%s takes %i damage from being Poisoned." % (self, to_hurt)
|
||||||
|
)
|
||||||
if self.db.hp <= 0:
|
if self.db.hp <= 0:
|
||||||
# Call at_defeat if poison defeats the character
|
# Call at_defeat if poison defeats the character
|
||||||
at_defeat(self)
|
at_defeat(self)
|
||||||
|
|
@ -596,7 +612,9 @@ class TBItemsCharacter(DefaultCharacter):
|
||||||
# Paralyzed: Have no actions in combat.
|
# Paralyzed: Have no actions in combat.
|
||||||
if is_in_combat(self) and "Paralyzed" in self.db.conditions:
|
if is_in_combat(self) and "Paralyzed" in self.db.conditions:
|
||||||
self.db.combat_actionsleft = 0
|
self.db.combat_actionsleft = 0
|
||||||
self.location.msg_contents("%s is Paralyzed, and can't act this turn!" % self)
|
self.location.msg_contents(
|
||||||
|
"%s is Paralyzed, and can't act this turn!" % self
|
||||||
|
)
|
||||||
self.db.combat_turnhandler.turn_end_check(self)
|
self.db.combat_turnhandler.turn_end_check(self)
|
||||||
|
|
||||||
def at_update(self):
|
def at_update(self):
|
||||||
|
|
@ -671,7 +689,9 @@ class TBItemsTurnHandler(DefaultScript):
|
||||||
self.db.fighters = ordered_by_roll
|
self.db.fighters = ordered_by_roll
|
||||||
|
|
||||||
# Announce the turn order.
|
# Announce the turn order.
|
||||||
self.obj.msg_contents("Turn order is: %s " % ", ".join(obj.key for obj in self.db.fighters))
|
self.obj.msg_contents(
|
||||||
|
"Turn order is: %s " % ", ".join(obj.key for obj in self.db.fighters)
|
||||||
|
)
|
||||||
|
|
||||||
# Start first fighter's turn.
|
# Start first fighter's turn.
|
||||||
self.start_turn(self.db.fighters[0])
|
self.start_turn(self.db.fighters[0])
|
||||||
|
|
@ -686,7 +706,9 @@ class TBItemsTurnHandler(DefaultScript):
|
||||||
"""
|
"""
|
||||||
for fighter in self.db.fighters:
|
for fighter in self.db.fighters:
|
||||||
combat_cleanup(fighter) # Clean up the combat attributes for every fighter.
|
combat_cleanup(fighter) # Clean up the combat attributes for every fighter.
|
||||||
self.obj.db.combat_turnhandler = None # Remove reference to turn handler in location
|
self.obj.db.combat_turnhandler = (
|
||||||
|
None
|
||||||
|
) # Remove reference to turn handler in location
|
||||||
|
|
||||||
def at_repeat(self):
|
def at_repeat(self):
|
||||||
"""
|
"""
|
||||||
|
|
@ -704,7 +726,9 @@ class TBItemsTurnHandler(DefaultScript):
|
||||||
currentchar, "all", action_name="disengage"
|
currentchar, "all", action_name="disengage"
|
||||||
) # Spend all remaining actions.
|
) # Spend all remaining actions.
|
||||||
return
|
return
|
||||||
elif self.db.timer <= 10 and not self.db.timeout_warning_given: # 10 seconds left
|
elif (
|
||||||
|
self.db.timer <= 10 and not self.db.timeout_warning_given
|
||||||
|
): # 10 seconds left
|
||||||
# Warn the current character if they're about to time out.
|
# Warn the current character if they're about to time out.
|
||||||
currentchar.msg("WARNING: About to time out!")
|
currentchar.msg("WARNING: About to time out!")
|
||||||
self.db.timeout_warning_given = True
|
self.db.timeout_warning_given = True
|
||||||
|
|
@ -716,7 +740,9 @@ class TBItemsTurnHandler(DefaultScript):
|
||||||
Args:
|
Args:
|
||||||
character (obj): Character to initialize for combat.
|
character (obj): Character to initialize for combat.
|
||||||
"""
|
"""
|
||||||
combat_cleanup(character) # Clean up leftover combat attributes beforehand, just in case.
|
combat_cleanup(
|
||||||
|
character
|
||||||
|
) # Clean up leftover combat attributes beforehand, just in case.
|
||||||
character.db.combat_actionsleft = (
|
character.db.combat_actionsleft = (
|
||||||
0
|
0
|
||||||
) # Actions remaining - start of turn adds to this, turn ends when it reaches 0
|
) # Actions remaining - start of turn adds to this, turn ends when it reaches 0
|
||||||
|
|
@ -765,13 +791,17 @@ class TBItemsTurnHandler(DefaultScript):
|
||||||
defeated_characters = 0
|
defeated_characters = 0
|
||||||
for fighter in self.db.fighters:
|
for fighter in self.db.fighters:
|
||||||
if fighter.db.HP == 0:
|
if fighter.db.HP == 0:
|
||||||
defeated_characters += 1 # Add 1 for every fighter with 0 HP left (defeated)
|
defeated_characters += (
|
||||||
|
1
|
||||||
|
) # Add 1 for every fighter with 0 HP left (defeated)
|
||||||
if defeated_characters == (
|
if defeated_characters == (
|
||||||
len(self.db.fighters) - 1
|
len(self.db.fighters) - 1
|
||||||
): # If only one character isn't defeated
|
): # If only one character isn't defeated
|
||||||
for fighter in self.db.fighters:
|
for fighter in self.db.fighters:
|
||||||
if fighter.db.HP != 0:
|
if fighter.db.HP != 0:
|
||||||
LastStanding = fighter # Pick the one fighter left with HP remaining
|
LastStanding = (
|
||||||
|
fighter
|
||||||
|
) # Pick the one fighter left with HP remaining
|
||||||
self.obj.msg_contents("Only %s remains! Combat is over!" % LastStanding)
|
self.obj.msg_contents("Only %s remains! Combat is over!" % LastStanding)
|
||||||
self.stop() # Stop this script and end combat.
|
self.stop() # Stop this script and end combat.
|
||||||
return
|
return
|
||||||
|
|
@ -780,13 +810,17 @@ class TBItemsTurnHandler(DefaultScript):
|
||||||
currentchar = self.db.fighters[self.db.turn]
|
currentchar = self.db.fighters[self.db.turn]
|
||||||
self.db.turn += 1 # Go to the next in the turn order.
|
self.db.turn += 1 # Go to the next in the turn order.
|
||||||
if self.db.turn > len(self.db.fighters) - 1:
|
if self.db.turn > len(self.db.fighters) - 1:
|
||||||
self.db.turn = 0 # Go back to the first in the turn order once you reach the end.
|
self.db.turn = (
|
||||||
|
0
|
||||||
|
) # Go back to the first in the turn order once you reach the end.
|
||||||
|
|
||||||
newchar = self.db.fighters[self.db.turn] # Note the new character
|
newchar = self.db.fighters[self.db.turn] # Note the new character
|
||||||
|
|
||||||
self.db.timer = TURN_TIMEOUT + self.time_until_next_repeat() # Reset the timer.
|
self.db.timer = TURN_TIMEOUT + self.time_until_next_repeat() # Reset the timer.
|
||||||
self.db.timeout_warning_given = False # Reset the timeout warning.
|
self.db.timeout_warning_given = False # Reset the timeout warning.
|
||||||
self.obj.msg_contents("%s's turn ends - %s's turn begins!" % (currentchar, newchar))
|
self.obj.msg_contents(
|
||||||
|
"%s's turn ends - %s's turn begins!" % (currentchar, newchar)
|
||||||
|
)
|
||||||
self.start_turn(newchar) # Start the new character's turn.
|
self.start_turn(newchar) # Start the new character's turn.
|
||||||
|
|
||||||
# Count down condition timers.
|
# Count down condition timers.
|
||||||
|
|
@ -854,7 +888,9 @@ class CmdFight(Command):
|
||||||
if is_in_combat(self.caller): # Already in a fight
|
if is_in_combat(self.caller): # Already in a fight
|
||||||
self.caller.msg("You're already in a fight!")
|
self.caller.msg("You're already in a fight!")
|
||||||
return
|
return
|
||||||
for thing in here.contents: # Test everything in the room to add it to the fight.
|
for (
|
||||||
|
thing
|
||||||
|
) in here.contents: # Test everything in the room to add it to the fight.
|
||||||
if thing.db.HP: # If the object has HP...
|
if thing.db.HP: # If the object has HP...
|
||||||
fighters.append(thing) # ...then add it to the fight.
|
fighters.append(thing) # ...then add it to the fight.
|
||||||
if len(fighters) <= 1: # If you're the only able fighter in the room
|
if len(fighters) <= 1: # If you're the only able fighter in the room
|
||||||
|
|
@ -953,7 +989,9 @@ class CmdPass(Command):
|
||||||
self.caller.location.msg_contents(
|
self.caller.location.msg_contents(
|
||||||
"%s takes no further action, passing the turn." % self.caller
|
"%s takes no further action, passing the turn." % self.caller
|
||||||
)
|
)
|
||||||
spend_action(self.caller, "all", action_name="pass") # Spend all remaining actions.
|
spend_action(
|
||||||
|
self.caller, "all", action_name="pass"
|
||||||
|
) # Spend all remaining actions.
|
||||||
|
|
||||||
|
|
||||||
class CmdDisengage(Command):
|
class CmdDisengage(Command):
|
||||||
|
|
@ -984,8 +1022,12 @@ class CmdDisengage(Command):
|
||||||
self.caller.msg("You can only do that on your turn.")
|
self.caller.msg("You can only do that on your turn.")
|
||||||
return
|
return
|
||||||
|
|
||||||
self.caller.location.msg_contents("%s disengages, ready to stop fighting." % self.caller)
|
self.caller.location.msg_contents(
|
||||||
spend_action(self.caller, "all", action_name="disengage") # Spend all remaining actions.
|
"%s disengages, ready to stop fighting." % self.caller
|
||||||
|
)
|
||||||
|
spend_action(
|
||||||
|
self.caller, "all", action_name="disengage"
|
||||||
|
) # Spend all remaining actions.
|
||||||
"""
|
"""
|
||||||
The action_name kwarg sets the character's last action to "disengage", which is checked by
|
The action_name kwarg sets the character's last action to "disengage", which is checked by
|
||||||
the turn handler script to see if all fighters have disengaged.
|
the turn handler script to see if all fighters have disengaged.
|
||||||
|
|
@ -1037,7 +1079,9 @@ class CmdCombatHelp(CmdHelp):
|
||||||
# tips on combat when used in a fight with no arguments.
|
# tips on combat when used in a fight with no arguments.
|
||||||
|
|
||||||
def func(self):
|
def func(self):
|
||||||
if is_in_combat(self.caller) and not self.args: # In combat and entered 'help' alone
|
if (
|
||||||
|
is_in_combat(self.caller) and not self.args
|
||||||
|
): # In combat and entered 'help' alone
|
||||||
self.caller.msg(
|
self.caller.msg(
|
||||||
"Available combat commands:|/"
|
"Available combat commands:|/"
|
||||||
+ "|wAttack:|n Attack a target, attempting to deal damage.|/"
|
+ "|wAttack:|n Attack a target, attempting to deal damage.|/"
|
||||||
|
|
@ -1175,7 +1219,9 @@ def itemfunc_heal(item, user, target, **kwargs):
|
||||||
to_heal = target.db.max_hp - target.db.hp # Cap healing to max HP
|
to_heal = target.db.max_hp - target.db.hp # Cap healing to max HP
|
||||||
target.db.hp += to_heal
|
target.db.hp += to_heal
|
||||||
|
|
||||||
user.location.msg_contents("%s uses %s! %s regains %i HP!" % (user, item, target, to_heal))
|
user.location.msg_contents(
|
||||||
|
"%s uses %s! %s regains %i HP!" % (user, item, target, to_heal)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def itemfunc_add_condition(item, user, target, **kwargs):
|
def itemfunc_add_condition(item, user, target, **kwargs):
|
||||||
|
|
@ -1235,7 +1281,10 @@ def itemfunc_cure_condition(item, user, target, **kwargs):
|
||||||
for key in target.db.conditions:
|
for key in target.db.conditions:
|
||||||
if key in to_cure:
|
if key in to_cure:
|
||||||
# If condition specified in to_cure, remove it.
|
# If condition specified in to_cure, remove it.
|
||||||
item_msg += "%s no longer has the '%s' condition. " % (str(target), str(key))
|
item_msg += "%s no longer has the '%s' condition. " % (
|
||||||
|
str(target),
|
||||||
|
str(key),
|
||||||
|
)
|
||||||
del target.db.conditions[key]
|
del target.db.conditions[key]
|
||||||
|
|
||||||
user.location.msg_contents(item_msg)
|
user.location.msg_contents(item_msg)
|
||||||
|
|
@ -1261,7 +1310,9 @@ def itemfunc_attack(item, user, target, **kwargs):
|
||||||
return False # Returning false aborts the item use
|
return False # Returning false aborts the item use
|
||||||
|
|
||||||
if not target:
|
if not target:
|
||||||
user.msg("You have to specify a target to use %s! (use <item> = <target>)" % item)
|
user.msg(
|
||||||
|
"You have to specify a target to use %s! (use <item> = <target>)" % item
|
||||||
|
)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if target == user:
|
if target == user:
|
||||||
|
|
@ -1445,7 +1496,9 @@ AMULET_OF_MIGHT = {
|
||||||
"desc": "The one who holds this amulet can call upon its power to gain great strength.",
|
"desc": "The one who holds this amulet can call upon its power to gain great strength.",
|
||||||
"item_func": "add_condition",
|
"item_func": "add_condition",
|
||||||
"item_selfonly": True,
|
"item_selfonly": True,
|
||||||
"item_kwargs": {"conditions": [("Damage Up", 3), ("Accuracy Up", 3), ("Defense Up", 3)]},
|
"item_kwargs": {
|
||||||
|
"conditions": [("Damage Up", 3), ("Accuracy Up", 3), ("Defense Up", 3)]
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
AMULET_OF_WEAKNESS = {
|
AMULET_OF_WEAKNESS = {
|
||||||
|
|
@ -1453,5 +1506,7 @@ AMULET_OF_WEAKNESS = {
|
||||||
"desc": "The one who holds this amulet can call upon its power to gain great weakness. It's not a terribly useful artifact.",
|
"desc": "The one who holds this amulet can call upon its power to gain great weakness. It's not a terribly useful artifact.",
|
||||||
"item_func": "add_condition",
|
"item_func": "add_condition",
|
||||||
"item_selfonly": True,
|
"item_selfonly": True,
|
||||||
"item_kwargs": {"conditions": [("Damage Down", 3), ("Accuracy Down", 3), ("Defense Down", 3)]},
|
"item_kwargs": {
|
||||||
|
"conditions": [("Damage Down", 3), ("Accuracy Down", 3), ("Defense Down", 3)]
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,13 @@ in your game and using it as-is.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from random import randint
|
from random import randint
|
||||||
from evennia import DefaultCharacter, Command, default_cmds, DefaultScript, create_object
|
from evennia import (
|
||||||
|
DefaultCharacter,
|
||||||
|
Command,
|
||||||
|
default_cmds,
|
||||||
|
DefaultScript,
|
||||||
|
create_object,
|
||||||
|
)
|
||||||
from evennia.commands.default.muxcommand import MuxCommand
|
from evennia.commands.default.muxcommand import MuxCommand
|
||||||
from evennia.commands.default.help import CmdHelp
|
from evennia.commands.default.help import CmdHelp
|
||||||
|
|
||||||
|
|
@ -312,7 +318,9 @@ def spend_action(character, actions, action_name=None):
|
||||||
character.db.combat_actionsleft -= actions # Use up actions.
|
character.db.combat_actionsleft -= actions # Use up actions.
|
||||||
if character.db.combat_actionsleft < 0:
|
if character.db.combat_actionsleft < 0:
|
||||||
character.db.combat_actionsleft = 0 # Can't have fewer than 0 actions
|
character.db.combat_actionsleft = 0 # Can't have fewer than 0 actions
|
||||||
character.db.combat_turnhandler.turn_end_check(character) # Signal potential end of turn.
|
character.db.combat_turnhandler.turn_end_check(
|
||||||
|
character
|
||||||
|
) # Signal potential end of turn.
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
@ -417,7 +425,9 @@ class TBMagicTurnHandler(DefaultScript):
|
||||||
self.db.fighters = ordered_by_roll
|
self.db.fighters = ordered_by_roll
|
||||||
|
|
||||||
# Announce the turn order.
|
# Announce the turn order.
|
||||||
self.obj.msg_contents("Turn order is: %s " % ", ".join(obj.key for obj in self.db.fighters))
|
self.obj.msg_contents(
|
||||||
|
"Turn order is: %s " % ", ".join(obj.key for obj in self.db.fighters)
|
||||||
|
)
|
||||||
|
|
||||||
# Start first fighter's turn.
|
# Start first fighter's turn.
|
||||||
self.start_turn(self.db.fighters[0])
|
self.start_turn(self.db.fighters[0])
|
||||||
|
|
@ -432,7 +442,9 @@ class TBMagicTurnHandler(DefaultScript):
|
||||||
"""
|
"""
|
||||||
for fighter in self.db.fighters:
|
for fighter in self.db.fighters:
|
||||||
combat_cleanup(fighter) # Clean up the combat attributes for every fighter.
|
combat_cleanup(fighter) # Clean up the combat attributes for every fighter.
|
||||||
self.obj.db.combat_turnhandler = None # Remove reference to turn handler in location
|
self.obj.db.combat_turnhandler = (
|
||||||
|
None
|
||||||
|
) # Remove reference to turn handler in location
|
||||||
|
|
||||||
def at_repeat(self):
|
def at_repeat(self):
|
||||||
"""
|
"""
|
||||||
|
|
@ -450,7 +462,9 @@ class TBMagicTurnHandler(DefaultScript):
|
||||||
currentchar, "all", action_name="disengage"
|
currentchar, "all", action_name="disengage"
|
||||||
) # Spend all remaining actions.
|
) # Spend all remaining actions.
|
||||||
return
|
return
|
||||||
elif self.db.timer <= 10 and not self.db.timeout_warning_given: # 10 seconds left
|
elif (
|
||||||
|
self.db.timer <= 10 and not self.db.timeout_warning_given
|
||||||
|
): # 10 seconds left
|
||||||
# Warn the current character if they're about to time out.
|
# Warn the current character if they're about to time out.
|
||||||
currentchar.msg("WARNING: About to time out!")
|
currentchar.msg("WARNING: About to time out!")
|
||||||
self.db.timeout_warning_given = True
|
self.db.timeout_warning_given = True
|
||||||
|
|
@ -462,7 +476,9 @@ class TBMagicTurnHandler(DefaultScript):
|
||||||
Args:
|
Args:
|
||||||
character (obj): Character to initialize for combat.
|
character (obj): Character to initialize for combat.
|
||||||
"""
|
"""
|
||||||
combat_cleanup(character) # Clean up leftover combat attributes beforehand, just in case.
|
combat_cleanup(
|
||||||
|
character
|
||||||
|
) # Clean up leftover combat attributes beforehand, just in case.
|
||||||
character.db.combat_actionsleft = (
|
character.db.combat_actionsleft = (
|
||||||
0
|
0
|
||||||
) # Actions remaining - start of turn adds to this, turn ends when it reaches 0
|
) # Actions remaining - start of turn adds to this, turn ends when it reaches 0
|
||||||
|
|
@ -511,13 +527,17 @@ class TBMagicTurnHandler(DefaultScript):
|
||||||
defeated_characters = 0
|
defeated_characters = 0
|
||||||
for fighter in self.db.fighters:
|
for fighter in self.db.fighters:
|
||||||
if fighter.db.HP == 0:
|
if fighter.db.HP == 0:
|
||||||
defeated_characters += 1 # Add 1 for every fighter with 0 HP left (defeated)
|
defeated_characters += (
|
||||||
|
1
|
||||||
|
) # Add 1 for every fighter with 0 HP left (defeated)
|
||||||
if defeated_characters == (
|
if defeated_characters == (
|
||||||
len(self.db.fighters) - 1
|
len(self.db.fighters) - 1
|
||||||
): # If only one character isn't defeated
|
): # If only one character isn't defeated
|
||||||
for fighter in self.db.fighters:
|
for fighter in self.db.fighters:
|
||||||
if fighter.db.HP != 0:
|
if fighter.db.HP != 0:
|
||||||
LastStanding = fighter # Pick the one fighter left with HP remaining
|
LastStanding = (
|
||||||
|
fighter
|
||||||
|
) # Pick the one fighter left with HP remaining
|
||||||
self.obj.msg_contents("Only %s remains! Combat is over!" % LastStanding)
|
self.obj.msg_contents("Only %s remains! Combat is over!" % LastStanding)
|
||||||
self.stop() # Stop this script and end combat.
|
self.stop() # Stop this script and end combat.
|
||||||
return
|
return
|
||||||
|
|
@ -526,11 +546,15 @@ class TBMagicTurnHandler(DefaultScript):
|
||||||
currentchar = self.db.fighters[self.db.turn]
|
currentchar = self.db.fighters[self.db.turn]
|
||||||
self.db.turn += 1 # Go to the next in the turn order.
|
self.db.turn += 1 # Go to the next in the turn order.
|
||||||
if self.db.turn > len(self.db.fighters) - 1:
|
if self.db.turn > len(self.db.fighters) - 1:
|
||||||
self.db.turn = 0 # Go back to the first in the turn order once you reach the end.
|
self.db.turn = (
|
||||||
|
0
|
||||||
|
) # Go back to the first in the turn order once you reach the end.
|
||||||
newchar = self.db.fighters[self.db.turn] # Note the new character
|
newchar = self.db.fighters[self.db.turn] # Note the new character
|
||||||
self.db.timer = TURN_TIMEOUT + self.time_until_next_repeat() # Reset the timer.
|
self.db.timer = TURN_TIMEOUT + self.time_until_next_repeat() # Reset the timer.
|
||||||
self.db.timeout_warning_given = False # Reset the timeout warning.
|
self.db.timeout_warning_given = False # Reset the timeout warning.
|
||||||
self.obj.msg_contents("%s's turn ends - %s's turn begins!" % (currentchar, newchar))
|
self.obj.msg_contents(
|
||||||
|
"%s's turn ends - %s's turn begins!" % (currentchar, newchar)
|
||||||
|
)
|
||||||
self.start_turn(newchar) # Start the new character's turn.
|
self.start_turn(newchar) # Start the new character's turn.
|
||||||
|
|
||||||
def turn_end_check(self, character):
|
def turn_end_check(self, character):
|
||||||
|
|
@ -594,7 +618,9 @@ class CmdFight(Command):
|
||||||
if is_in_combat(self.caller): # Already in a fight
|
if is_in_combat(self.caller): # Already in a fight
|
||||||
self.caller.msg("You're already in a fight!")
|
self.caller.msg("You're already in a fight!")
|
||||||
return
|
return
|
||||||
for thing in here.contents: # Test everything in the room to add it to the fight.
|
for (
|
||||||
|
thing
|
||||||
|
) in here.contents: # Test everything in the room to add it to the fight.
|
||||||
if thing.db.HP: # If the object has HP...
|
if thing.db.HP: # If the object has HP...
|
||||||
fighters.append(thing) # ...then add it to the fight.
|
fighters.append(thing) # ...then add it to the fight.
|
||||||
if len(fighters) <= 1: # If you're the only able fighter in the room
|
if len(fighters) <= 1: # If you're the only able fighter in the room
|
||||||
|
|
@ -689,7 +715,9 @@ class CmdPass(Command):
|
||||||
self.caller.location.msg_contents(
|
self.caller.location.msg_contents(
|
||||||
"%s takes no further action, passing the turn." % self.caller
|
"%s takes no further action, passing the turn." % self.caller
|
||||||
)
|
)
|
||||||
spend_action(self.caller, "all", action_name="pass") # Spend all remaining actions.
|
spend_action(
|
||||||
|
self.caller, "all", action_name="pass"
|
||||||
|
) # Spend all remaining actions.
|
||||||
|
|
||||||
|
|
||||||
class CmdDisengage(Command):
|
class CmdDisengage(Command):
|
||||||
|
|
@ -720,8 +748,12 @@ class CmdDisengage(Command):
|
||||||
self.caller.msg("You can only do that on your turn.")
|
self.caller.msg("You can only do that on your turn.")
|
||||||
return
|
return
|
||||||
|
|
||||||
self.caller.location.msg_contents("%s disengages, ready to stop fighting." % self.caller)
|
self.caller.location.msg_contents(
|
||||||
spend_action(self.caller, "all", action_name="disengage") # Spend all remaining actions.
|
"%s disengages, ready to stop fighting." % self.caller
|
||||||
|
)
|
||||||
|
spend_action(
|
||||||
|
self.caller, "all", action_name="disengage"
|
||||||
|
) # Spend all remaining actions.
|
||||||
"""
|
"""
|
||||||
The action_name kwarg sets the character's last action to "disengage", which is checked by
|
The action_name kwarg sets the character's last action to "disengage", which is checked by
|
||||||
the turn handler script to see if all fighters have disengaged.
|
the turn handler script to see if all fighters have disengaged.
|
||||||
|
|
@ -786,11 +818,17 @@ class CmdLearnSpell(Command):
|
||||||
if len(spell_to_learn) == 1: # If one match, extract the string
|
if len(spell_to_learn) == 1: # If one match, extract the string
|
||||||
spell_to_learn = spell_to_learn[0]
|
spell_to_learn = spell_to_learn[0]
|
||||||
|
|
||||||
if spell_to_learn not in self.caller.db.spells_known: # If the spell isn't known...
|
if (
|
||||||
caller.db.spells_known.append(spell_to_learn) # ...then add the spell to the character
|
spell_to_learn not in self.caller.db.spells_known
|
||||||
|
): # If the spell isn't known...
|
||||||
|
caller.db.spells_known.append(
|
||||||
|
spell_to_learn
|
||||||
|
) # ...then add the spell to the character
|
||||||
caller.msg("You learn the spell '%s'!" % spell_to_learn)
|
caller.msg("You learn the spell '%s'!" % spell_to_learn)
|
||||||
return
|
return
|
||||||
if spell_to_learn in self.caller.db.spells_known: # Already has the spell specified
|
if (
|
||||||
|
spell_to_learn in self.caller.db.spells_known
|
||||||
|
): # Already has the spell specified
|
||||||
caller.msg("You already know the spell '%s'!" % spell_to_learn)
|
caller.msg("You already know the spell '%s'!" % spell_to_learn)
|
||||||
"""
|
"""
|
||||||
You will almost definitely want to replace this with your own system
|
You will almost definitely want to replace this with your own system
|
||||||
|
|
@ -908,7 +946,9 @@ class CmdCast(MuxCommand):
|
||||||
|
|
||||||
# If not in combat and the spell isn't a non-combat spell, error ms and return.
|
# If not in combat and the spell isn't a non-combat spell, error ms and return.
|
||||||
if spelldata["noncombat_spell"] == False and is_in_combat(caller) == False:
|
if spelldata["noncombat_spell"] == False and is_in_combat(caller) == False:
|
||||||
caller.msg("You can't use the spell '%s' outside of combat." % spell_to_cast)
|
caller.msg(
|
||||||
|
"You can't use the spell '%s' outside of combat." % spell_to_cast
|
||||||
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
# If spell takes no targets and one is given, give error message and return
|
# If spell takes no targets and one is given, give error message and return
|
||||||
|
|
@ -1014,7 +1054,9 @@ class CmdRest(Command):
|
||||||
|
|
||||||
self.caller.db.hp = self.caller.db.max_hp # Set current HP to maximum
|
self.caller.db.hp = self.caller.db.max_hp # Set current HP to maximum
|
||||||
self.caller.db.mp = self.caller.db.max_mp # Set current MP to maximum
|
self.caller.db.mp = self.caller.db.max_mp # Set current MP to maximum
|
||||||
self.caller.location.msg_contents("%s rests to recover HP and MP." % self.caller)
|
self.caller.location.msg_contents(
|
||||||
|
"%s rests to recover HP and MP." % self.caller
|
||||||
|
)
|
||||||
# You'll probably want to replace this with your own system for recovering HP and MP.
|
# You'll probably want to replace this with your own system for recovering HP and MP.
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1066,7 +1108,9 @@ class CmdCombatHelp(CmdHelp):
|
||||||
# tips on combat when used in a fight with no arguments.
|
# tips on combat when used in a fight with no arguments.
|
||||||
|
|
||||||
def func(self):
|
def func(self):
|
||||||
if is_in_combat(self.caller) and not self.args: # In combat and entered 'help' alone
|
if (
|
||||||
|
is_in_combat(self.caller) and not self.args
|
||||||
|
): # In combat and entered 'help' alone
|
||||||
self.caller.msg(
|
self.caller.msg(
|
||||||
"Available combat commands:|/"
|
"Available combat commands:|/"
|
||||||
+ "|wAttack:|n Attack a target, attempting to deal damage.|/"
|
+ "|wAttack:|n Attack a target, attempting to deal damage.|/"
|
||||||
|
|
|
||||||
|
|
@ -101,7 +101,13 @@ in your game and using it as-is.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from random import randint
|
from random import randint
|
||||||
from evennia import DefaultCharacter, DefaultObject, Command, default_cmds, DefaultScript
|
from evennia import (
|
||||||
|
DefaultCharacter,
|
||||||
|
DefaultObject,
|
||||||
|
Command,
|
||||||
|
default_cmds,
|
||||||
|
DefaultScript,
|
||||||
|
)
|
||||||
from evennia.commands.default.help import CmdHelp
|
from evennia.commands.default.help import CmdHelp
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
@ -259,7 +265,9 @@ def at_defeat(defeated):
|
||||||
defeated.location.msg_contents("%s has been defeated!" % defeated)
|
defeated.location.msg_contents("%s has been defeated!" % defeated)
|
||||||
|
|
||||||
|
|
||||||
def resolve_attack(attacker, defender, attack_type, attack_value=None, defense_value=None):
|
def resolve_attack(
|
||||||
|
attacker, defender, attack_type, attack_value=None, defense_value=None
|
||||||
|
):
|
||||||
"""
|
"""
|
||||||
Resolves an attack and outputs the result.
|
Resolves an attack and outputs the result.
|
||||||
|
|
||||||
|
|
@ -482,7 +490,9 @@ def spend_action(character, actions, action_name=None):
|
||||||
character.db.combat_actionsleft -= actions # Use up actions.
|
character.db.combat_actionsleft -= actions # Use up actions.
|
||||||
if character.db.combat_actionsleft < 0:
|
if character.db.combat_actionsleft < 0:
|
||||||
character.db.combat_actionsleft = 0 # Can't have fewer than 0 actions
|
character.db.combat_actionsleft = 0 # Can't have fewer than 0 actions
|
||||||
character.db.combat_turnhandler.turn_end_check(character) # Signal potential end of turn.
|
character.db.combat_turnhandler.turn_end_check(
|
||||||
|
character
|
||||||
|
) # Signal potential end of turn.
|
||||||
|
|
||||||
|
|
||||||
def combat_status_message(fighter):
|
def combat_status_message(fighter):
|
||||||
|
|
@ -515,7 +525,9 @@ def combat_status_message(fighter):
|
||||||
range_obj.append(thing)
|
range_obj.append(thing)
|
||||||
|
|
||||||
if engaged_obj:
|
if engaged_obj:
|
||||||
status_msg += "|/Engaged targets: %s" % ", ".join(obj.key for obj in engaged_obj)
|
status_msg += "|/Engaged targets: %s" % ", ".join(
|
||||||
|
obj.key for obj in engaged_obj
|
||||||
|
)
|
||||||
if reach_obj:
|
if reach_obj:
|
||||||
status_msg += "|/Reach targets: %s" % ", ".join(obj.key for obj in reach_obj)
|
status_msg += "|/Reach targets: %s" % ", ".join(obj.key for obj in reach_obj)
|
||||||
if range_obj:
|
if range_obj:
|
||||||
|
|
@ -574,7 +586,9 @@ class TBRangeTurnHandler(DefaultScript):
|
||||||
self.db.fighters = ordered_by_roll
|
self.db.fighters = ordered_by_roll
|
||||||
|
|
||||||
# Announce the turn order.
|
# Announce the turn order.
|
||||||
self.obj.msg_contents("Turn order is: %s " % ", ".join(obj.key for obj in self.db.fighters))
|
self.obj.msg_contents(
|
||||||
|
"Turn order is: %s " % ", ".join(obj.key for obj in self.db.fighters)
|
||||||
|
)
|
||||||
|
|
||||||
# Start first fighter's turn.
|
# Start first fighter's turn.
|
||||||
self.start_turn(self.db.fighters[0])
|
self.start_turn(self.db.fighters[0])
|
||||||
|
|
@ -588,8 +602,12 @@ class TBRangeTurnHandler(DefaultScript):
|
||||||
Called at script termination.
|
Called at script termination.
|
||||||
"""
|
"""
|
||||||
for thing in self.obj.contents:
|
for thing in self.obj.contents:
|
||||||
combat_cleanup(thing) # Clean up the combat attributes for every object in the room.
|
combat_cleanup(
|
||||||
self.obj.db.combat_turnhandler = None # Remove reference to turn handler in location
|
thing
|
||||||
|
) # Clean up the combat attributes for every object in the room.
|
||||||
|
self.obj.db.combat_turnhandler = (
|
||||||
|
None
|
||||||
|
) # Remove reference to turn handler in location
|
||||||
|
|
||||||
def at_repeat(self):
|
def at_repeat(self):
|
||||||
"""
|
"""
|
||||||
|
|
@ -607,7 +625,9 @@ class TBRangeTurnHandler(DefaultScript):
|
||||||
currentchar, "all", action_name="disengage"
|
currentchar, "all", action_name="disengage"
|
||||||
) # Spend all remaining actions.
|
) # Spend all remaining actions.
|
||||||
return
|
return
|
||||||
elif self.db.timer <= 10 and not self.db.timeout_warning_given: # 10 seconds left
|
elif (
|
||||||
|
self.db.timer <= 10 and not self.db.timeout_warning_given
|
||||||
|
): # 10 seconds left
|
||||||
# Warn the current character if they're about to time out.
|
# Warn the current character if they're about to time out.
|
||||||
currentchar.msg("WARNING: About to time out!")
|
currentchar.msg("WARNING: About to time out!")
|
||||||
self.db.timeout_warning_given = True
|
self.db.timeout_warning_given = True
|
||||||
|
|
@ -672,7 +692,9 @@ class TBRangeTurnHandler(DefaultScript):
|
||||||
Args:
|
Args:
|
||||||
character (obj): Character to initialize for combat.
|
character (obj): Character to initialize for combat.
|
||||||
"""
|
"""
|
||||||
combat_cleanup(character) # Clean up leftover combat attributes beforehand, just in case.
|
combat_cleanup(
|
||||||
|
character
|
||||||
|
) # Clean up leftover combat attributes beforehand, just in case.
|
||||||
character.db.combat_actionsleft = (
|
character.db.combat_actionsleft = (
|
||||||
0
|
0
|
||||||
) # Actions remaining - start of turn adds to this, turn ends when it reaches 0
|
) # Actions remaining - start of turn adds to this, turn ends when it reaches 0
|
||||||
|
|
@ -720,13 +742,17 @@ class TBRangeTurnHandler(DefaultScript):
|
||||||
defeated_characters = 0
|
defeated_characters = 0
|
||||||
for fighter in self.db.fighters:
|
for fighter in self.db.fighters:
|
||||||
if fighter.db.HP == 0:
|
if fighter.db.HP == 0:
|
||||||
defeated_characters += 1 # Add 1 for every fighter with 0 HP left (defeated)
|
defeated_characters += (
|
||||||
|
1
|
||||||
|
) # Add 1 for every fighter with 0 HP left (defeated)
|
||||||
if defeated_characters == (
|
if defeated_characters == (
|
||||||
len(self.db.fighters) - 1
|
len(self.db.fighters) - 1
|
||||||
): # If only one character isn't defeated
|
): # If only one character isn't defeated
|
||||||
for fighter in self.db.fighters:
|
for fighter in self.db.fighters:
|
||||||
if fighter.db.HP != 0:
|
if fighter.db.HP != 0:
|
||||||
LastStanding = fighter # Pick the one fighter left with HP remaining
|
LastStanding = (
|
||||||
|
fighter
|
||||||
|
) # Pick the one fighter left with HP remaining
|
||||||
self.obj.msg_contents("Only %s remains! Combat is over!" % LastStanding)
|
self.obj.msg_contents("Only %s remains! Combat is over!" % LastStanding)
|
||||||
self.stop() # Stop this script and end combat.
|
self.stop() # Stop this script and end combat.
|
||||||
return
|
return
|
||||||
|
|
@ -735,11 +761,15 @@ class TBRangeTurnHandler(DefaultScript):
|
||||||
currentchar = self.db.fighters[self.db.turn]
|
currentchar = self.db.fighters[self.db.turn]
|
||||||
self.db.turn += 1 # Go to the next in the turn order.
|
self.db.turn += 1 # Go to the next in the turn order.
|
||||||
if self.db.turn > len(self.db.fighters) - 1:
|
if self.db.turn > len(self.db.fighters) - 1:
|
||||||
self.db.turn = 0 # Go back to the first in the turn order once you reach the end.
|
self.db.turn = (
|
||||||
|
0
|
||||||
|
) # Go back to the first in the turn order once you reach the end.
|
||||||
newchar = self.db.fighters[self.db.turn] # Note the new character
|
newchar = self.db.fighters[self.db.turn] # Note the new character
|
||||||
self.db.timer = TURN_TIMEOUT + self.time_until_next_repeat() # Reset the timer.
|
self.db.timer = TURN_TIMEOUT + self.time_until_next_repeat() # Reset the timer.
|
||||||
self.db.timeout_warning_given = False # Reset the timeout warning.
|
self.db.timeout_warning_given = False # Reset the timeout warning.
|
||||||
self.obj.msg_contents("%s's turn ends - %s's turn begins!" % (currentchar, newchar))
|
self.obj.msg_contents(
|
||||||
|
"%s's turn ends - %s's turn begins!" % (currentchar, newchar)
|
||||||
|
)
|
||||||
self.start_turn(newchar) # Start the new character's turn.
|
self.start_turn(newchar) # Start the new character's turn.
|
||||||
|
|
||||||
def turn_end_check(self, character):
|
def turn_end_check(self, character):
|
||||||
|
|
@ -876,7 +906,9 @@ class TBRangeObject(DefaultObject):
|
||||||
if dropper.location.db.combat_turnhandler:
|
if dropper.location.db.combat_turnhandler:
|
||||||
# Object joins the range field
|
# Object joins the range field
|
||||||
self.db.combat_range = {}
|
self.db.combat_range = {}
|
||||||
dropper.location.db.combat_turnhandler.join_rangefield(self, anchor_obj=dropper)
|
dropper.location.db.combat_turnhandler.join_rangefield(
|
||||||
|
self, anchor_obj=dropper
|
||||||
|
)
|
||||||
|
|
||||||
def at_before_get(self, getter):
|
def at_before_get(self, getter):
|
||||||
"""
|
"""
|
||||||
|
|
@ -958,7 +990,8 @@ class TBRangeObject(DefaultObject):
|
||||||
return False
|
return False
|
||||||
if get_range(giver, getter) > 0: # Too far away from target
|
if get_range(giver, getter) > 0: # Too far away from target
|
||||||
giver.msg(
|
giver.msg(
|
||||||
"You aren't close enough to give things to %s! (see: help approach)" % getter
|
"You aren't close enough to give things to %s! (see: help approach)"
|
||||||
|
% getter
|
||||||
)
|
)
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
@ -1019,7 +1052,9 @@ class CmdFight(Command):
|
||||||
if is_in_combat(self.caller): # Already in a fight
|
if is_in_combat(self.caller): # Already in a fight
|
||||||
self.caller.msg("You're already in a fight!")
|
self.caller.msg("You're already in a fight!")
|
||||||
return
|
return
|
||||||
for thing in here.contents: # Test everything in the room to add it to the fight.
|
for (
|
||||||
|
thing
|
||||||
|
) in here.contents: # Test everything in the room to add it to the fight.
|
||||||
if thing.db.HP: # If the object has HP...
|
if thing.db.HP: # If the object has HP...
|
||||||
fighters.append(thing) # ...then add it to the fight.
|
fighters.append(thing) # ...then add it to the fight.
|
||||||
if len(fighters) <= 1: # If you're the only able fighter in the room
|
if len(fighters) <= 1: # If you're the only able fighter in the room
|
||||||
|
|
@ -1144,7 +1179,11 @@ class CmdShoot(Command):
|
||||||
in_melee = []
|
in_melee = []
|
||||||
for target in attacker.db.combat_range:
|
for target in attacker.db.combat_range:
|
||||||
# Object is engaged and has HP
|
# Object is engaged and has HP
|
||||||
if get_range(attacker, defender) == 0 and target.db.hp and target != self.caller:
|
if (
|
||||||
|
get_range(attacker, defender) == 0
|
||||||
|
and target.db.hp
|
||||||
|
and target != self.caller
|
||||||
|
):
|
||||||
in_melee.append(target) # Add to list of targets in melee
|
in_melee.append(target) # Add to list of targets in melee
|
||||||
|
|
||||||
if len(in_melee) > 0:
|
if len(in_melee) > 0:
|
||||||
|
|
@ -1294,7 +1333,9 @@ class CmdPass(Command):
|
||||||
self.caller.location.msg_contents(
|
self.caller.location.msg_contents(
|
||||||
"%s takes no further action, passing the turn." % self.caller
|
"%s takes no further action, passing the turn." % self.caller
|
||||||
)
|
)
|
||||||
spend_action(self.caller, "all", action_name="pass") # Spend all remaining actions.
|
spend_action(
|
||||||
|
self.caller, "all", action_name="pass"
|
||||||
|
) # Spend all remaining actions.
|
||||||
|
|
||||||
|
|
||||||
class CmdDisengage(Command):
|
class CmdDisengage(Command):
|
||||||
|
|
@ -1325,8 +1366,12 @@ class CmdDisengage(Command):
|
||||||
self.caller.msg("You can only do that on your turn.")
|
self.caller.msg("You can only do that on your turn.")
|
||||||
return
|
return
|
||||||
|
|
||||||
self.caller.location.msg_contents("%s disengages, ready to stop fighting." % self.caller)
|
self.caller.location.msg_contents(
|
||||||
spend_action(self.caller, "all", action_name="disengage") # Spend all remaining actions.
|
"%s disengages, ready to stop fighting." % self.caller
|
||||||
|
)
|
||||||
|
spend_action(
|
||||||
|
self.caller, "all", action_name="disengage"
|
||||||
|
) # Spend all remaining actions.
|
||||||
"""
|
"""
|
||||||
The action_name kwarg sets the character's last action to "disengage", which is checked by
|
The action_name kwarg sets the character's last action to "disengage", which is checked by
|
||||||
the turn handler script to see if all fighters have disengaged.
|
the turn handler script to see if all fighters have disengaged.
|
||||||
|
|
@ -1397,7 +1442,9 @@ class CmdCombatHelp(CmdHelp):
|
||||||
# tips on combat when used in a fight with no arguments.
|
# tips on combat when used in a fight with no arguments.
|
||||||
|
|
||||||
def func(self):
|
def func(self):
|
||||||
if is_in_combat(self.caller) and not self.args: # In combat and entered 'help' alone
|
if (
|
||||||
|
is_in_combat(self.caller) and not self.args
|
||||||
|
): # In combat and entered 'help' alone
|
||||||
self.caller.msg(
|
self.caller.msg(
|
||||||
"Available combat commands:|/"
|
"Available combat commands:|/"
|
||||||
+ "|wAttack:|n Attack an engaged target, attempting to deal damage.|/"
|
+ "|wAttack:|n Attack an engaged target, attempting to deal damage.|/"
|
||||||
|
|
|
||||||
|
|
@ -44,9 +44,7 @@ class BodyFunctions(DefaultScript):
|
||||||
elif rand < 0.2:
|
elif rand < 0.2:
|
||||||
string = "You have an itch. Hard to reach too."
|
string = "You have an itch. Hard to reach too."
|
||||||
elif rand < 0.3:
|
elif rand < 0.3:
|
||||||
string = (
|
string = "You think you hear someone behind you. ... but when you look there's noone there."
|
||||||
"You think you hear someone behind you. ... but when you look there's noone there."
|
|
||||||
)
|
|
||||||
elif rand < 0.4:
|
elif rand < 0.4:
|
||||||
string = "You inspect your fingernails. Nothing to report."
|
string = "You inspect your fingernails. Nothing to report."
|
||||||
elif rand < 0.5:
|
elif rand < 0.5:
|
||||||
|
|
|
||||||
|
|
@ -113,7 +113,9 @@ class CmdSmashGlass(Command):
|
||||||
string = "You smash your hand against the glass"
|
string = "You smash your hand against the glass"
|
||||||
string += " with all your might. The lid won't budge"
|
string += " with all your might. The lid won't budge"
|
||||||
string += " but you cause quite the tremor through the button's mount."
|
string += " but you cause quite the tremor through the button's mount."
|
||||||
string += "\nIt looks like the button's lamp stopped working for the time being."
|
string += (
|
||||||
|
"\nIt looks like the button's lamp stopped working for the time being."
|
||||||
|
)
|
||||||
self.obj.lamp_works = False
|
self.obj.lamp_works = False
|
||||||
elif rand < 0.6:
|
elif rand < 0.6:
|
||||||
string = "You hit the lid hard. It doesn't move an inch."
|
string = "You hit the lid hard. It doesn't move an inch."
|
||||||
|
|
@ -123,7 +125,8 @@ class CmdSmashGlass(Command):
|
||||||
string += " you should just try to open the lid instead?"
|
string += " you should just try to open the lid instead?"
|
||||||
self.caller.msg(string)
|
self.caller.msg(string)
|
||||||
self.caller.location.msg_contents(
|
self.caller.location.msg_contents(
|
||||||
"%s tries to smash the glass of the button." % (self.caller.name), exclude=self.caller
|
"%s tries to smash the glass of the button." % (self.caller.name),
|
||||||
|
exclude=self.caller,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -121,7 +121,9 @@ class RedButton(DefaultObject):
|
||||||
self.db.lamp_works = False
|
self.db.lamp_works = False
|
||||||
desc = self.db.desc_lamp_broken
|
desc = self.db.desc_lamp_broken
|
||||||
if not desc:
|
if not desc:
|
||||||
self.db.desc += "\nThe big red button has stopped blinking for the time being."
|
self.db.desc += (
|
||||||
|
"\nThe big red button has stopped blinking for the time being."
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
self.db.desc = desc
|
self.db.desc = desc
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -142,7 +142,8 @@ class BlindedState(DefaultScript):
|
||||||
"""
|
"""
|
||||||
self.obj.msg("You blink feverishly as your eyesight slowly returns.")
|
self.obj.msg("You blink feverishly as your eyesight slowly returns.")
|
||||||
self.obj.location.msg_contents(
|
self.obj.location.msg_contents(
|
||||||
"%s seems to be recovering their eyesight." % self.obj.name, exclude=self.obj
|
"%s seems to be recovering their eyesight." % self.obj.name,
|
||||||
|
exclude=self.obj,
|
||||||
)
|
)
|
||||||
self.obj.cmdset.delete() # this will clear the latest added cmdset,
|
self.obj.cmdset.delete() # this will clear the latest added cmdset,
|
||||||
# (which is the blinded one).
|
# (which is the blinded one).
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue