Make scripts/objects lists use EvMore. Change EvMore to not justify by default.

This commit is contained in:
Griatch 2020-01-11 15:49:12 +01:00
parent b5aee2c41e
commit 69d85bd184
221 changed files with 2190 additions and 6810 deletions

View file

@ -36,6 +36,9 @@ without arguments starts a full interactive Python console.
the `TickerHandler.remove` method. This makes it easier to manage tickers.
- EvMore `text` argument can now also be a list - each entry in the list is run
through str(eval()) and ends up on its own line. Good for paginated object lists.
- EvMore auto-justify now defaults to False since this works better with all types
of texts (such as tables). New `justify` bool. Old `justify_kwargs` remains
but is now only used to pass extra kwargs into the justify function.
## Evennia 0.9 (2018-2019)

View file

@ -142,9 +142,7 @@ def _create_version():
print(err)
try:
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()
.decode()
)
@ -264,9 +262,7 @@ def _init():
def _help(self):
"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("_")]
print(self.__doc__ + "-" * 60 + "\n" + ", ".join(names))

View file

@ -26,13 +26,7 @@ from evennia.commands import cmdhandler
from evennia.server.models import ServerConfig
from evennia.server.throttle import Throttle
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 (
SIGNAL_ACCOUNT_POST_CREATE,
SIGNAL_OBJECT_POST_PUPPET,
@ -57,10 +51,12 @@ _CMDSET_ACCOUNT = settings.CMDSET_ACCOUNT
_MUDINFO_CHANNEL = None
# Create throttles for too many account-creations and login attempts
CREATION_THROTTLE = Throttle(limit=settings.CREATION_THROTTLE_LIMIT,
timeout=settings.CREATION_THROTTLE_TIMEOUT)
LOGIN_THROTTLE = Throttle(limit=settings.LOGIN_THROTTLE_LIMIT,
timeout=settings.LOGIN_THROTTLE_TIMEOUT)
CREATION_THROTTLE = Throttle(
limit=settings.CREATION_THROTTLE_LIMIT, timeout=settings.CREATION_THROTTLE_TIMEOUT
)
LOGIN_THROTTLE = Throttle(
limit=settings.LOGIN_THROTTLE_LIMIT, timeout=settings.LOGIN_THROTTLE_TIMEOUT
)
class AccountSessionHandler(object):
@ -297,9 +293,7 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase):
self.msg(txt1, session=session)
self.msg(txt2, session=obj.sessions.all())
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"
self.msg(txt1, session=session)
self.msg(txt2, session=obj.sessions.all())
@ -354,9 +348,7 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase):
if not obj.sessions.count():
del obj.account
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.
session.puppet = None
session.puid = None
@ -392,9 +384,7 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase):
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):
"""
@ -737,11 +727,7 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase):
try:
try:
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}).")
@ -762,13 +748,9 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase):
account.db.creator_ip = ip
# 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):
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)
logger.log_err(string)
@ -803,9 +785,7 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase):
# We are in the middle between logged in and -not, so we have
# to handle tracebacks ourselves at this point. If we don't,
# 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()
# Update the throttle to indicate a new account was created from this IP
@ -832,9 +812,7 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase):
except RuntimeError:
# no puppet to disconnect from
pass
session.sessionhandler.disconnect(
session, reason=_("Account being deleted.")
)
session.sessionhandler.disconnect(session, reason=_("Account being deleted."))
self.scripts.stop()
self.attributes.clear()
self.nicks.clear()
@ -994,12 +972,7 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase):
return matches
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
@ -1079,9 +1052,7 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase):
"""
# 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("_saved_protocol_flags", {}, lockstring=lockstring)
@ -1236,19 +1207,13 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase):
global _MUDINFO_CHANNEL
if not _MUDINFO_CHANNEL:
try:
_MUDINFO_CHANNEL = ChannelDB.objects.filter(
db_key=settings.CHANNEL_MUDINFO["key"]
)[0]
_MUDINFO_CHANNEL = ChannelDB.objects.filter(db_key=settings.CHANNEL_MUDINFO["key"])[
0
]
except Exception:
logger.log_trace()
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:
_MUDINFO_CHANNEL.tempmsg(f"[{_MUDINFO_CHANNEL.key}, {now}]: {message}")
else:
@ -1300,12 +1265,9 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase):
# screen. We execute look on the account.
# we make sure to clean up the _playable_characters list in case
# 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.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):
@ -1463,9 +1425,7 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase):
csessid = sess.sessid
addr = "%s (%s)" % (
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(
"\n %s %s"
@ -1488,18 +1448,14 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase):
"\n\n You don't have any characters yet. See |whelp @charcreate|n for creating one."
)
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(
"\n |w@chardelete <name>|n - delete a character (cannot be undone!)"
)
if characters:
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:
result.append(
f"\n\nAvailable character{string_s_ending} ({len(characters)}/unlimited):"
@ -1509,9 +1465,7 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase):
"\n\nAvailable character%s%s:"
% (
string_s_ending,
charmax > 1
and " (%i/%i)" % (len(characters), charmax)
or "",
charmax > 1 and " (%i/%i)" % (len(characters), charmax) or "",
)
)
@ -1531,9 +1485,7 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase):
)
else:
# 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)
return look_string
@ -1611,9 +1563,7 @@ class DefaultGuest(DefaultAccount):
# We are in the middle between logged in and -not, so we have
# to handle tracebacks ourselves at this point. If we don't,
# 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()
return None, errors

View file

@ -32,8 +32,7 @@ class AccountDBChangeForm(UserChangeForm):
"invalid": "This value may contain only letters, spaces, numbers "
"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):
@ -67,8 +66,7 @@ class AccountDBCreationForm(UserCreationForm):
"invalid": "This value may contain only letters, spaces, numbers "
"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):
@ -230,13 +228,7 @@ class AccountDBAdmin(BaseUserAdmin):
(
"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 "
"accessing the admin site. They are unrelated to "
"in-game access rights.</i>",
@ -246,8 +238,7 @@ class AccountDBAdmin(BaseUserAdmin):
"Game Options",
{
"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>",
},
),
)
@ -290,9 +281,7 @@ class AccountDBAdmin(BaseUserAdmin):
from django.http import HttpResponseRedirect
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)

View file

@ -124,9 +124,7 @@ class Bot(DefaultAccount):
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):
"""
@ -327,12 +325,8 @@ class IRCBot(Bot):
if kwargs["type"] == "nicklist":
# the return of a nicklist request
if hasattr(self, "_nicklist_callers") and self._nicklist_callers:
chstr = (
f"{self.db.irc_channel} ({self.db.irc_network}:{self.db.irc_port})"
)
nicklist = ", ".join(
sorted(kwargs["nicklist"], key=lambda n: n.lower())
)
chstr = 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:
obj.msg(f"Nicks at {chstr}:\n {nicklist}")
self._nicklist_callers = []
@ -341,9 +335,7 @@ class IRCBot(Bot):
elif kwargs["type"] == "ping":
# the return of a ping
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:
obj.msg(f"IRC ping return from {chstr} took {kwargs['timing']}s.")
self._ping_callers = []
@ -442,14 +434,8 @@ class RSSBot(Bot):
self.db.rss_rate = rss_rate
# instruct the server and portal to create a new session with
# the stored configuration
configdict = {
"uid": self.dbid,
"url": self.db.rss_url,
"rate": self.db.rss_rate,
}
_SESSIONS.start_bot_session(
"evennia.server.portal.rss.RSSBotFactory", configdict
)
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):
"""

View file

@ -92,9 +92,7 @@ class AccountDBManager(TypedObjectManager, UserManager):
end_date = timezone.now()
tdelta = datetime.timedelta(days)
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):
"""
@ -179,11 +177,7 @@ class AccountDBManager(TypedObjectManager, UserManager):
# try alias match
matches = self.filter(
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

View file

@ -17,10 +17,7 @@ class Migration(migrations.Migration):
(
"id",
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")),
@ -54,21 +51,15 @@ class Migration(migrations.Migration):
),
(
"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",
models.CharField(
max_length=30, verbose_name="last name", blank=True
),
models.CharField(max_length=30, verbose_name="last name", blank=True),
),
(
"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",
@ -92,10 +83,7 @@ class Migration(migrations.Migration):
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",
models.CharField(
@ -107,9 +95,7 @@ class Migration(migrations.Migration):
),
(
"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",

View file

@ -6,9 +6,7 @@ from django.db import models, migrations
def convert_defaults(apps, schema_editor):
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.save()

View file

@ -10,10 +10,7 @@ class Migration(migrations.Migration):
operations = [
migrations.CreateModel(
name="DefaultAccount",
fields=[],
options={"proxy": True},
bases=("accounts.accountdb",),
name="DefaultAccount", fields=[], options={"proxy": True}, bases=("accounts.accountdb",)
),
migrations.CreateModel(
name="DefaultGuest",
@ -21,7 +18,5 @@ class Migration(migrations.Migration):
options={"proxy": True},
bases=("accounts.defaultaccount",),
),
migrations.AlterModelOptions(
name="accountdb", options={"verbose_name": "Account"}
),
migrations.AlterModelOptions(name="accountdb", options={"verbose_name": "Account"}),
]

View file

@ -14,15 +14,12 @@ class Migration(migrations.Migration):
migrations.DeleteModel(name="DefaultGuest"),
migrations.DeleteModel(name="DefaultAccount"),
migrations.AlterModelManagers(
name="accountdb",
managers=[("objects", evennia.accounts.manager.AccountDBManager())],
name="accountdb", managers=[("objects", evennia.accounts.manager.AccountDBManager())]
),
migrations.AlterField(
model_name="accountdb",
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(
model_name="accountdb",
@ -39,9 +36,7 @@ class Migration(migrations.Migration):
migrations.AlterField(
model_name="accountdb",
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(
model_name="accountdb",

View file

@ -12,8 +12,7 @@ class Migration(migrations.Migration):
operations = [
migrations.AlterModelManagers(
name="accountdb",
managers=[("objects", evennia.accounts.manager.AccountDBManager())],
name="accountdb", managers=[("objects", evennia.accounts.manager.AccountDBManager())]
),
migrations.AlterField(
model_name="accountdb",
@ -42,9 +41,7 @@ class Migration(migrations.Migration):
model_name="accountdb",
name="db_is_bot",
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(

View file

@ -22,8 +22,6 @@ class Migration(migrations.Migration):
migrations.AlterField(
model_name="accountdb",
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"),
),
]

View file

@ -129,11 +129,7 @@ class AccountDB(TypedObject, AbstractUser):
Setter. Allows for self.name = value. Stores as a comma-separated
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")()
# @cmdset_storage.deleter
@ -142,9 +138,7 @@ class AccountDB(TypedObject, AbstractUser):
_SA(self, "db_cmdset_storage", None)
_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

View file

@ -54,9 +54,7 @@ class TestAccountSessionHandler(TestCase):
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(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)], [])
def test_all(self):
@ -88,8 +86,7 @@ class TestDefaultGuest(EvenniaTest):
# Create a second guest account
account, errors = DefaultGuest.authenticate(ip=self.ip)
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")
@ -150,17 +147,13 @@ class TestDefaultAccountAuth(EvenniaTest):
# Try creating a duplicate account
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()
def test_throttle(self):
"Confirm throttle activates on too many failures."
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(
obj,
"Authentication was provided a bogus password; this should NOT have returned an account!",
@ -183,9 +176,7 @@ class TestDefaultAccountAuth(EvenniaTest):
# Should not allow duplicate username
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
result, error = DefaultAccount.validate_username("xx")
@ -301,9 +292,7 @@ class TestDefaultAccount(TestCase):
account.puppet_object(self.s1, obj)
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)
@ -334,9 +323,7 @@ class TestDefaultAccount(TestCase):
account.puppet_object(self.s1, obj)
# works because django.conf.settings.MULTISESSION_MODE is not in (1, 3)
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] == {})
@ -378,15 +365,12 @@ class TestAccountPuppetDeletion(EvenniaTest):
def test_puppet_deletion(self):
# Check for existing chars
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
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.
self.char1.delete()
@ -414,9 +398,7 @@ class TestDefaultAccountEv(EvenniaTest):
self.account.msg = MagicMock()
with patch("evennia.accounts.accounts._MULTISESSION_MODE", 2):
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)
def test_idle_time(self, mock_time):
@ -450,15 +432,8 @@ class TestDefaultAccountEv(EvenniaTest):
"test@test.com",
"testpassword123",
locks="test:all()",
tags=[
("tag1", "category1"),
("tag2", "category2", "data1"),
("tag3", None),
],
attributes=[
("key1", "value1", "category1", "edit:false()", True),
("key2", "value2"),
],
tags=[("tag1", "category1"), ("tag2", "category2", "data1"), ("tag3", None)],
attributes=[("key1", "value1", "category1", "edit:false()", True), ("key2", "value2")],
)
acct.save()
self.assertTrue(acct.pk)

View file

@ -82,9 +82,7 @@ CMD_CHANNEL = "__send_to_channel_command"
CMD_LOGINSTART = "__unloggedin_look_command"
# 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
# is the normal "production message to echo to the account.
@ -134,8 +132,7 @@ likely file a bug report with the Evennia project.
)
_ERROR_RECURSION_LIMIT = (
"Command recursion limit ({recursion_limit}) "
"reached for '{raw_cmdname}' ({cmdclass})."
"Command recursion limit ({recursion_limit}) " "reached for '{raw_cmdname}' ({cmdclass})."
)
@ -164,9 +161,7 @@ def _msg_err(receiver, stringtuple):
if _IN_GAME_ERRORS:
receiver.msg(
string.format(
traceback=tracestring,
errmsg=stringtuple[0].strip(),
timestamp=timestamp,
traceback=tracestring, errmsg=stringtuple[0].strip(), timestamp=timestamp
).strip()
)
else:
@ -218,9 +213,7 @@ def _progressive_cmd_run(cmd, generator, response=None):
elif isinstance(value, str):
_GET_INPUT(cmd.caller, value, _process_input, cmd=cmd, generator=generator)
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):
@ -331,9 +324,7 @@ def get_and_merge_cmdsets(caller, session, account, obj, callertype, raw_string)
# Gather all cmdsets stored on objects in the room and
# also in the caller's inventory and the location itself
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]
for lobj in local_objlist:
@ -363,9 +354,7 @@ def get_and_merge_cmdsets(caller, session, account, obj, callertype, raw_string)
# only keep the setting if duplicates were set to False/True
# explicitly.
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)
except Exception:
_msg_err(caller, _ERROR_CMDSETS)
@ -405,9 +394,7 @@ def get_and_merge_cmdsets(caller, session, account, obj, callertype, raw_string)
if current.no_exits:
# filter out all exits
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
if not current.no_channels:
@ -431,9 +418,7 @@ def get_and_merge_cmdsets(caller, session, account, obj, callertype, raw_string)
if current.no_exits:
# filter out all exits
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
if not current.no_channels:
@ -451,28 +436,20 @@ def get_and_merge_cmdsets(caller, session, account, obj, callertype, raw_string)
if current.no_exits:
# filter out all exits
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
if not current.no_channels:
# also objs may have channels
cmdsets += yield _get_channel_cmdset(obj)
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
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)
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:
@ -495,9 +472,7 @@ def get_and_merge_cmdsets(caller, session, account, obj, callertype, raw_string)
tempmergers[prio] = cmdset
# 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
cmdset = cmdsets[0]
@ -758,12 +733,7 @@ def cmdhandler(
if len(matches) == 1:
# We have a unique command match. But it may still be invalid.
match = matches[0]
cmdname, args, cmd, raw_cmdname = (
match[0],
match[1],
match[2],
match[5],
)
cmdname, args, cmd, raw_cmdname = (match[0], match[1], match[2], match[5])
if not matches:
# No commands match our entered command
@ -801,9 +771,7 @@ def cmdhandler(
raise ExecSystemCommand(cmd, sysarg)
# 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)
except ErrorReported as exc:
@ -819,13 +787,7 @@ def cmdhandler(
if syscmd:
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)
elif sysarg:

View file

@ -71,18 +71,13 @@ def build_matches(raw_string, cmdset, include_prefixes=False):
for cmdname in [cmd.key] + cmd.aliases
if cmdname
and l_raw_string.startswith(cmdname.lower())
and (
not cmd.arg_regex
or cmd.arg_regex.match(l_raw_string[len(cmdname) :])
)
and (not cmd.arg_regex or cmd.arg_regex.match(l_raw_string[len(cmdname) :]))
]
)
else:
# strip prefixes set in settings
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()
for cmd in cmdset:
@ -95,14 +90,9 @@ def build_matches(raw_string, cmdset, include_prefixes=False):
if (
cmdname
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:
log_trace("cmdhandler error. raw_input:%s" % raw_string)
return matches
@ -135,10 +125,7 @@ def try_num_prefixes(raw_string):
# the user might be trying to identify the command
# with a #num-command style syntax. We expect the regex to
# contain the groups "number" and "name".
mindex, new_raw_string = (
num_ref_match.group("number"),
num_ref_match.group("name"),
)
mindex, new_raw_string = (num_ref_match.group("number"), num_ref_match.group("name"))
return mindex, new_raw_string
else:
return None, None
@ -193,9 +180,7 @@ def cmdparser(raw_string, cmdset, caller, match_index=None):
if _CMD_IGNORE_PREFIXES:
# still no match. Try to strip prefixes
raw_string = (
raw_string.lstrip(_CMD_IGNORE_PREFIXES)
if len(raw_string) > 1
else raw_string
raw_string.lstrip(_CMD_IGNORE_PREFIXES) if len(raw_string) > 1 else raw_string
)
matches = build_matches(raw_string, cmdset, include_prefixes=False)

View file

@ -334,9 +334,7 @@ class CmdSet(object, metaclass=_CmdSetMeta):
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):
"""
@ -405,16 +403,10 @@ class CmdSet(object, metaclass=_CmdSetMeta):
# set changes the setting (i.e. has a non-None value). We don't pass through
# the duplicates setting; that is per-merge
cmdset_c.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
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
else:
# B higher priority than A
@ -440,12 +432,8 @@ class CmdSet(object, metaclass=_CmdSetMeta):
cmdset_c.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_objs = (
cmdset_a.no_objs if self.no_objs is None else self.no_objs
)
cmdset_c.no_exits = 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
# might be different from the main mergetype.
@ -629,11 +617,7 @@ class CmdSet(object, metaclass=_CmdSetMeta):
"""
names = []
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:
[names.extend(cmd._keyaliases) for cmd in self.commands]
return names

View file

@ -114,9 +114,7 @@ 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):
@ -162,9 +160,7 @@ def import_cmdset(path, cmdsetobj, emit_to_obj=None, no_logging=False):
"""
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 = ""
for python_path in python_paths:
@ -172,9 +168,7 @@ def import_cmdset(path, cmdsetobj, emit_to_obj=None, no_logging=False):
if "." in path:
modpath, classname = python_path.rsplit(".", 1)
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:
# first try to get from cache
@ -213,9 +207,7 @@ def import_cmdset(path, cmdsetobj, emit_to_obj=None, no_logging=False):
errstring += _ERROR_CMDSET_IMPORT
if _IN_GAME_ERRORS:
errstring = errstring.format(
path=python_path,
traceback=format_exc(),
timestamp=logger.timeformat(),
path=python_path, traceback=format_exc(), timestamp=logger.timeformat()
)
else:
errstring = errstring.format(
@ -234,9 +226,7 @@ def import_cmdset(path, cmdsetobj, emit_to_obj=None, no_logging=False):
errstring += _ERROR_CMDSET_SYNTAXERROR
if _IN_GAME_ERRORS:
errstring = errstring.format(
path=python_path,
traceback=format_exc(),
timestamp=logger.timeformat(),
path=python_path, traceback=format_exc(), timestamp=logger.timeformat()
)
else:
errstring = errstring.format(
@ -248,9 +238,7 @@ def import_cmdset(path, cmdsetobj, emit_to_obj=None, no_logging=False):
errstring += _ERROR_CMDSET_EXCEPTION
if _IN_GAME_ERRORS:
errstring = errstring.format(
path=python_path,
traceback=format_exc(),
timestamp=logger.timeformat(),
path=python_path, traceback=format_exc(), timestamp=logger.timeformat()
)
else:
errstring = errstring.format(
@ -359,17 +347,13 @@ class CmdSetHandler(object):
permstring = "non-perm"
if self.current.permanent:
permstring = "perm"
tmpstring = _(
" <{key} ({mergetype}, prio {prio}, {permstring})>:\n {keylist}"
)
tmpstring = _(" <{key} ({mergetype}, prio {prio}, {permstring})>:\n {keylist}")
string += tmpstring.format(
key=self.current.key,
mergetype=mergetype,
prio=self.current.priority,
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()
@ -507,9 +491,7 @@ class CmdSetHandler(object):
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):
"""
@ -553,9 +535,7 @@ class CmdSetHandler(object):
else:
# try it as a callable
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:
# try it as a path or key
delcmdsets = [
@ -647,15 +627,12 @@ class CmdSetHandler(object):
if must_be_default:
return self.cmdset_stack and (self.cmdset_stack[0].path == cmdset.path)
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:
# try it as a path or key
if must_be_default:
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:
return any(

View file

@ -37,14 +37,10 @@ def _init_command(cls, **kwargs):
cls.key = cls.key.lower()
if cls.aliases and not is_iter(cls.aliases):
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:
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
cls._matchset = set([cls.key] + cls.aliases)
@ -414,8 +410,7 @@ class Command(object, metaclass=CommandMeta):
"""
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"""
Command {self} has no defined `func()` - showing on-command variables:
@ -431,10 +426,7 @@ Command {self} has no defined `func()` - showing on-command variables:
string += "\nname of cmd (self.key): |w%s|n\n" % self.key
string += "cmd aliases (self.aliases): |w%s|n\n" % self.aliases
string += "cmd locks (self.locks): |w%s|n\n" % self.locks
string += (
"help category (self.help_category): |w%s|n\n"
% self.help_category.capitalize()
)
string += "help category (self.help_category): |w%s|n\n" % self.help_category.capitalize()
string += "object calling (self.caller): |w%s|n\n" % self.caller
string += "object storing cmdset (self.obj): |w%s|n\n" % self.obj
string += "command string given (self.cmdstring): |w%s|n\n" % self.cmdstring
@ -585,21 +577,15 @@ Command {self} has no defined `func()` - showing on-command variables:
if header_text:
if color_header:
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":
begin_center = ANSIString(
"|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)
else:
center_string = ANSIString(
"|n |%s%s |n" % (colors["headertext"], header_text)
)
center_string = ANSIString("|n |%s%s |n" % (colors["headertext"], header_text))
else:
center_string = ""
@ -613,22 +599,14 @@ Command {self} has no defined `func()` - showing on-command variables:
right_width = math.floor(remain_fill / 2)
left_width = math.ceil(remain_fill / 2)
right_fill = ANSIString(
"|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))
)
right_fill = ANSIString("|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:
edge_fill = ANSIString("|n|%s%s|n" % (colors["border"], edge_character))
main_string = ANSIString(center_string)
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:
final_send = left_fill + ANSIString(center_string) + right_fill

View file

@ -72,9 +72,9 @@ class MuxAccountLookCommand(COMMAND_DEFAULT_CLASS):
self.account.db._playable_characters = playable
# store playable property
if self.args:
self.playable = dict(
(utils.to_str(char.key.lower()), char) for char in playable
).get(self.args.lower(), None)
self.playable = dict((utils.to_str(char.key.lower()), char) for char in playable).get(
self.args.lower(), None
)
else:
self.playable = playable
@ -113,9 +113,7 @@ class CmdOOCLook(MuxAccountLookCommand):
if _MULTISESSION_MODE < 2:
# 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
# call on-account look helper method
@ -154,8 +152,7 @@ class CmdCharCreate(COMMAND_DEFAULT_CLASS):
charmax = _MAX_NR_CHARACTERS
if not account.is_superuser and (
account.db._playable_characters
and len(account.db._playable_characters) >= charmax
account.db._playable_characters and len(account.db._playable_characters) >= charmax
):
self.msg("You may only create a maximum of %i characters." % charmax)
return
@ -175,11 +172,7 @@ class CmdCharCreate(COMMAND_DEFAULT_CLASS):
default_home = ObjectDB.objects.get_id(settings.DEFAULT_HOME)
permissions = settings.PERMISSION_ACCOUNT_DEFAULT
new_character = create.create_object(
typeclass,
key=key,
location=start_location,
home=default_home,
permissions=permissions,
typeclass, key=key, location=start_location, home=default_home, permissions=permissions
)
# only allow creator (and developers) to puppet this char
new_character.locks.add(
@ -266,7 +259,9 @@ class CmdCharDelete(COMMAND_DEFAULT_CLASS):
self.msg("You do not have permission to delete this character.")
return
prompt = "|rThis will permanently destroy '%s'. This cannot be undone.|n Continue yes/[no]?"
prompt = (
"|rThis will permanently destroy '%s'. This cannot be undone.|n Continue yes/[no]?"
)
get_input(account, prompt % match.key, _callback)
@ -313,9 +308,7 @@ class CmdIC(COMMAND_DEFAULT_CLASS):
if not new_character:
# search for a matching character
new_character = [
char
for char in search.object_search(self.args)
if char.access(account, "puppet")
char for char in search.object_search(self.args) if char.access(account, "puppet")
]
if not new_character:
self.msg("That is not a valid character choice.")
@ -386,9 +379,7 @@ class CmdOOC(MuxAccountLookCommand):
if _MULTISESSION_MODE < 2:
# 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
self.msg(account.at_look(target=self.playable, session=session))
@ -466,9 +457,9 @@ class CmdWho(COMMAND_DEFAULT_CLASS):
if self.cmdstring == "doing":
show_session_data = False
else:
show_session_data = account.check_permstring(
"Developer"
) or account.check_permstring("Admins")
show_session_data = account.check_permstring("Developer") or account.check_permstring(
"Admins"
)
naccounts = SESSIONS.account_count()
if show_session_data:
@ -495,15 +486,11 @@ class CmdWho(COMMAND_DEFAULT_CLASS):
utils.crop(account.get_display_name(account), width=25),
utils.time_format(delta_conn, 0),
utils.time_format(delta_cmd, 1),
utils.crop(
puppet.get_display_name(account) if puppet else "None", width=25
),
utils.crop(puppet.get_display_name(account) if puppet else "None", width=25),
utils.crop(location, width=25),
session.cmd_total,
session.protocol_key,
isinstance(session.address, tuple)
and session.address[0]
or session.address,
isinstance(session.address, tuple) and session.address[0] or session.address,
)
else:
# unprivileged
@ -575,9 +562,7 @@ class CmdOption(COMMAND_DEFAULT_CLASS):
self.msg("|gCleared all saved options.")
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 len(options["SCREENWIDTH"]) == 1:
@ -604,15 +589,11 @@ class CmdOption(COMMAND_DEFAULT_CLASS):
if saved_options:
saved = " |YYes|n" if key in saved_options else ""
changed = (
"|y*|n"
if key in saved_options and flags[key] != saved_options[key]
else ""
"|y*|n" if key in saved_options and flags[key] != saved_options[key] else ""
)
row.append("%s%s" % (saved, changed))
table.add_row(*row)
self.msg(
"|wClient settings (%s):|n\n%s|n" % (self.session.protocol_key, table)
)
self.msg("|wClient settings (%s):|n\n%s|n" % (self.session.protocol_key, table))
return
@ -642,9 +623,7 @@ class CmdOption(COMMAND_DEFAULT_CLASS):
old_val = flags.get(new_name, False)
new_val = validator(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:
flags[new_name] = new_val
self.msg(
@ -688,9 +667,7 @@ class CmdOption(COMMAND_DEFAULT_CLASS):
# a valid setting
if "save" in self.switches:
# 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)
self.account.attributes.add("_saved_protocol_flags", saved_options)
for key in optiondict:
@ -698,9 +675,7 @@ class CmdOption(COMMAND_DEFAULT_CLASS):
if "clear" in self.switches:
# clear this save
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.session.update_flags(**optiondict)
@ -777,8 +752,7 @@ class CmdQuit(COMMAND_DEFAULT_CLASS):
if "all" in self.switches:
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"
for session in account.sessions.all():
@ -787,10 +761,7 @@ class CmdQuit(COMMAND_DEFAULT_CLASS):
nsess = len(account.sessions.all())
reason = "quit"
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:
account.msg(
"|RQuitting|n. %i sessions are still connected." % (nsess - 1),
@ -798,9 +769,7 @@ class CmdQuit(COMMAND_DEFAULT_CLASS):
)
else:
# 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)
@ -872,13 +841,11 @@ class CmdColorTest(COMMAND_DEFAULT_CLASS):
for code, _ in ap.ansi_map[self.slice_dark_fg]
]
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]
]
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]
]
dark_fg.extend(["" for _ in range(len(bright_fg) - len(dark_fg))])
@ -900,21 +867,11 @@ class CmdColorTest(COMMAND_DEFAULT_CLASS):
for ig in range(6):
for ib in range(6):
# 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
table[6 + ir].append(
"|%i%i%i|[%i%i%i%s|n"
% (
5 - ir,
5 - ig,
5 - ib,
ir,
ig,
ib,
"||[%i%i%i" % (ir, ig, ib),
)
% (5 - ir, 5 - ig, 5 - ib, ir, ig, ib, "||[%i%i%i" % (ir, ig, ib))
)
table = self.table_format(table)
string = "Xterm256 colors (if not all hues show, your client might not report that it can handle xterm256):"
@ -925,9 +882,7 @@ class CmdColorTest(COMMAND_DEFAULT_CLASS):
letter = chr(97 + (ibatch * 6 + igray))
inverse = chr(122 - (ibatch * 6 + igray))
table[0 + igray].append("|=%s%s |n" % (letter, "||=%s" % letter))
table[6 + igray].append(
"|=%s|[=%s%s |n" % (inverse, letter, "||[=%s" % letter)
)
table[6 + igray].append("|=%s|[=%s%s |n" % (inverse, letter, "||[=%s" % letter))
for igray in range(6):
# the last row (y, z) has empty columns
if igray < 2:
@ -1013,10 +968,7 @@ class CmdQuell(COMMAND_DEFAULT_CLASS):
cpermstr += "\nUse unquell to return to normal permission usage."
self.msg(cpermstr)
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)
@ -1047,10 +999,7 @@ class CmdStyle(COMMAND_DEFAULT_CLASS):
for op_key in self.account.options.options_dict.keys():
op_found = self.account.options.get(op_key, return_obj=True)
table.add_row(
op_key,
op_found.description,
op_found.__class__.__name__,
op_found.display(),
op_key, op_found.description, op_found.__class__.__name__, op_found.display()
)
self.msg(str(table))

View file

@ -89,9 +89,7 @@ class CmdBoot(COMMAND_DEFAULT_CLASS):
boot_list.append(match)
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
# Carry out the booting of the sessions in the boot list.
@ -192,8 +190,7 @@ class CmdBan(COMMAND_DEFAULT_CLASS):
banlist = []
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))
return
@ -402,12 +399,9 @@ class CmdNewPassword(COMMAND_DEFAULT_CLASS):
account.save()
self.msg("%s - new password set to '%s'." % (account.name, newpass))
if account.character != caller:
account.msg(
"%s has changed your password to '%s'." % (caller.name, newpass)
)
account.msg("%s has changed your password to '%s'." % (caller.name, newpass))
logger.log_sec(
"Password Changed: %s (Caller: %s, IP: %s)."
% (account, caller, self.session.address)
"Password Changed: %s (Caller: %s, IP: %s)." % (account, caller, self.session.address)
)
@ -492,17 +486,14 @@ class CmdPerm(COMMAND_DEFAULT_CLASS):
obj.permissions.remove(perm)
if obj.permissions.get(perm):
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:
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(
"\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(
"Permissions Deleted: %s, %s (Caller: %s, IP: %s)."
@ -532,8 +523,7 @@ class CmdPerm(COMMAND_DEFAULT_CLASS):
obj.permissions.add(perm)
plystring = "the Account" if accountmode else "the Object/Character"
caller_result.append(
"\nPermission '%s' given to %s (%s)."
% (perm, obj.name, plystring)
"\nPermission '%s' given to %s (%s)." % (perm, obj.name, plystring)
)
target_result.append(
"\n%s gives you (%s, %s) the permission '%s'."
@ -593,17 +583,13 @@ class CmdForce(COMMAND_DEFAULT_CLASS):
def func(self):
"""Implements the force command"""
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
targ = self.caller.search(self.lhs)
if not targ:
return
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
targ.execute_cmd(self.rhs)
self.caller.msg("You have forced %s to: %s" % (targ, self.rhs))

View file

@ -269,9 +269,7 @@ class CmdBatchCommands(_COMMAND_DEFAULT_CLASS):
"%s'%s' could not load. You have to supply python paths "
"from one of the defined batch-file directories\n (%s)."
)
caller.msg(
string % (err, python_path, ", ".join(settings.BASE_BATCHPROCESS_PATHS))
)
caller.msg(string % (err, python_path, ", ".join(settings.BASE_BATCHPROCESS_PATHS)))
return
if not commands:
caller.msg("File %s seems empty of valid commands." % python_path)
@ -294,9 +292,7 @@ class CmdBatchCommands(_COMMAND_DEFAULT_CLASS):
# Set interactive state directly
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)
else:
caller.msg(
@ -395,9 +391,7 @@ class CmdBatchCode(_COMMAND_DEFAULT_CLASS):
"%s'%s' could not load. You have to supply python paths "
"from one of the defined batch-file directories\n (%s)."
)
caller.msg(
string % (err, python_path, ", ".join(settings.BASE_BATCHPROCESS_PATHS))
)
caller.msg(string % (err, python_path, ", ".join(settings.BASE_BATCHPROCESS_PATHS)))
return
if not codes:
caller.msg("File %s seems empty of functional code." % python_path)
@ -421,14 +415,10 @@ class CmdBatchCode(_COMMAND_DEFAULT_CLASS):
# Set interactive state directly
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)
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
if "PythonProcPool" in utils.server_services():
@ -489,9 +479,7 @@ class CmdStateAbort(_COMMAND_DEFAULT_CLASS):
def func(self):
"""Exit back to default."""
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):

View file

@ -108,20 +108,12 @@ class ObjManipCommand(COMMAND_DEFAULT_CLASS):
objdef, option = [part.strip() for part in objdef.rsplit(":", 1)]
if ";" in objdef:
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:
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
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})
# store for future access
@ -185,12 +177,7 @@ class CmdSetObjAlias(COMMAND_DEFAULT_CLASS):
obj.get_display_name(caller),
", ".join(
"'%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
),
)
@ -231,9 +218,7 @@ class CmdSetObjAlias(COMMAND_DEFAULT_CLASS):
# merge the old and new aliases (if any)
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
old_aliases.extend(new_aliases)
@ -339,10 +324,7 @@ class CmdCopy(ObjManipCommand):
to_obj_aliases,
)
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
caller.msg(string)
@ -565,9 +547,7 @@ class CmdCreate(ObjManipCommand):
# lockstring of newly created objects, for easy overloading.
# Will be formatted with the {id} of the creating object.
new_obj_lockstring = (
"control:id({id}) or perm(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):
"""
@ -660,9 +640,7 @@ class CmdDesc(COMMAND_DEFAULT_CLASS):
def edit_handler(self):
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
if self.args:
obj = self.caller.search(self.args)
@ -672,9 +650,7 @@ class CmdDesc(COMMAND_DEFAULT_CLASS):
return
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
# launch the editor
@ -715,9 +691,7 @@ class CmdDesc(COMMAND_DEFAULT_CLASS):
obj.db.desc = desc
caller.msg("The description was set on %s." % obj.get_display_name(caller))
else:
caller.msg(
"You don't have permission to edit the description of %s." % obj.key
)
caller.msg("You don't have permission to edit the description of %s." % obj.key)
class CmdDestroy(COMMAND_DEFAULT_CLASS):
@ -798,13 +772,9 @@ class CmdDestroy(COMMAND_DEFAULT_CLASS):
else:
string += "\n%s was destroyed." % objname
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:
string += (
" Objects inside %s were moved to their homes." % objname
)
string += " Objects inside %s were moved to their homes." % objname
return string
objs = []
@ -814,9 +784,7 @@ class CmdDestroy(COMMAND_DEFAULT_CLASS):
if "-" in objname:
# 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:
for dbref in range(int(dmin), int(dmax + 1)):
obj = caller.search("#" + str(dbref))
@ -909,10 +877,7 @@ class CmdDig(ObjManipCommand):
caller = self.caller
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 += "[, <exit_back_here>[;alias;alias..][:parent]]"
caller.msg(string)
@ -992,9 +957,7 @@ class CmdDig(ObjManipCommand):
if not back_exit["name"]:
exit_back_string = "\nNo back exit created."
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:
typeclass = back_exit["option"]
if not typeclass:
@ -1088,9 +1051,8 @@ class CmdTunnel(COMMAND_DEFAULT_CLASS):
exitshort = self.lhs.split(":")[0]
if exitshort not in self.directions:
string = (
"tunnel can only understand the following directions: %s."
% ",".join(sorted(self.directions.keys()))
string = "tunnel can only understand the following directions: %s." % ",".join(
sorted(self.directions.keys())
)
string += "\n(use dig for more freedom)"
self.caller.msg(string)
@ -1121,13 +1083,7 @@ class CmdTunnel(COMMAND_DEFAULT_CLASS):
backstring = ", %s;%s" % (backname, backshort)
# 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)
@ -1168,12 +1124,8 @@ class CmdLink(COMMAND_DEFAULT_CLASS):
# try to search locally first
results = caller.search(object_name, quiet=True)
if (
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)
)
if 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)
elif len(results) == 1: # A unique local match
obj = results[0]
@ -1198,9 +1150,9 @@ class CmdLink(COMMAND_DEFAULT_CLASS):
string = note % (obj.name, obj.dbref)
if "twoway" in self.switches:
if not (target.location and obj.location):
string = (
"To create a two-way link, %s and %s must both have a location"
% (obj, target)
string = "To create a two-way link, %s and %s must both have a location" % (
obj,
target,
)
string += " (i.e. they cannot be rooms, but should be exits)."
self.caller.msg(string)
@ -1227,10 +1179,7 @@ class CmdLink(COMMAND_DEFAULT_CLASS):
if dest:
string = "%s is an exit to %s." % (obj.name, dest.name)
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:
# We gave the command link 'obj = ' which means we want to
@ -1333,11 +1282,7 @@ class CmdSetHome(CmdLink):
new_home.dbref,
)
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)
@ -1410,12 +1355,8 @@ class CmdName(ObjManipCommand):
if not newname:
caller.msg("No name defined!")
return
if not (
obj.access(caller, "control") or obj.access(caller, "edit")
):
caller.msg(
"You don't have right to edit this account %s." % obj
)
if not (obj.access(caller, "control") or obj.access(caller, "edit")):
caller.msg("You don't have right to edit this account %s." % obj)
return
obj.username = newname
obj.save()
@ -1470,9 +1411,7 @@ class CmdOpen(ObjManipCommand):
help_category = "Building"
# 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.
At this point we know destination is a valid location
@ -1493,7 +1432,9 @@ class CmdOpen(ObjManipCommand):
if not exit_obj.destination:
# we are trying to link a non-exit
string = "'%s' already exists and is not an exit!\nIf you want to convert it "
string += "to an exit, you must assign an object to the 'destination' property first."
string += (
"to an exit, you must assign an object to the 'destination' property first."
)
caller.msg(string % exit_name)
return None
# we are re-linking an old exit.
@ -1505,9 +1446,9 @@ class CmdOpen(ObjManipCommand):
exit_obj.destination = destination
if exit_aliases:
[exit_obj.aliases.add(alias) for alias in exit_aliases]
string += (
" Rerouted its old destination '%s' to '%s' and changed aliases."
% (old_destination.name, destination.name)
string += " Rerouted its old destination '%s' to '%s' and changed aliases." % (
old_destination.name,
destination.name,
)
else:
string += " It already points to the correct place."
@ -1517,11 +1458,7 @@ class CmdOpen(ObjManipCommand):
if not typeclass:
typeclass = settings.BASE_EXIT_TYPECLASS
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:
# storing a destination is what makes it an exit!
@ -1576,9 +1513,7 @@ class CmdOpen(ObjManipCommand):
return
# 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:
# an error; the exit was not created, so we quit.
return
@ -1588,11 +1523,7 @@ class CmdOpen(ObjManipCommand):
back_exit_aliases = self.lhs_objs[1]["aliases"]
back_exit_typeclass = self.lhs_objs[1]["option"]
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
)
@ -1787,18 +1718,11 @@ class CmdSetAttribute(ObjManipCommand):
del deep[del_key]
except (IndexError, KeyError, TypeError):
continue
return "\nDeleted attribute '%s' (= nested) from %s." % (
attr,
obj.name,
)
return "\nDeleted attribute '%s' (= nested) from %s." % (attr, obj.name)
else:
exists = obj.attributes.has(key)
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)
if nested:
error += " (Nested lookups attempted)"
@ -1892,9 +1816,7 @@ class CmdSetAttribute(ObjManipCommand):
"""
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
if objname.startswith("*") or "account" in self.switches:
found_obj = caller.search_account(objname.lstrip("*"))
@ -1913,9 +1835,7 @@ class CmdSetAttribute(ObjManipCommand):
else:
global_search = False
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
def func(self):
@ -1941,16 +1861,12 @@ class CmdSetAttribute(ObjManipCommand):
result = []
if "edit" in self.switches:
# 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)
return
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
self.edit_handler(obj, attrs[0])
return
@ -1968,10 +1884,7 @@ class CmdSetAttribute(ObjManipCommand):
return
else:
# 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)
return
for attr in attrs:
@ -1980,9 +1893,7 @@ class CmdSetAttribute(ObjManipCommand):
result.append(self.rm_attr(obj, attr))
else:
# 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)
return
for attr in attrs:
@ -2053,17 +1964,15 @@ class CmdTypeclass(COMMAND_DEFAULT_CLASS):
if "list" in self.switches:
tclasses = get_all_typeclasses()
contribs = [
key for key in sorted(tclasses) if key.startswith("evennia.contrib")
] or ["<None loaded>"]
contribs = [key for key in sorted(tclasses) if key.startswith("evennia.contrib")] or [
"<None loaded>"
]
core = [
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")
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>"
]
string = (
"|wCore typeclasses|n\n"
" {core}\n"
@ -2072,9 +1981,7 @@ class CmdTypeclass(COMMAND_DEFAULT_CLASS):
"|wGame-dir typeclasses|n\n"
" {game}"
).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)
return
@ -2090,9 +1997,7 @@ class CmdTypeclass(COMMAND_DEFAULT_CLASS):
# no object found to examine, see if it's a typeclass-path instead
tclasses = get_all_typeclasses()
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)
if nmatches > 1:
@ -2102,15 +2007,11 @@ class CmdTypeclass(COMMAND_DEFAULT_CLASS):
)
)
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:
# one match found
caller.msg(
"Docstring for typeclass '{}':\n{}".format(
oquery, matches[0][1].__doc__
)
"Docstring for typeclass '{}':\n{}".format(oquery, matches[0][1].__doc__)
)
else:
# do the search again to get the error handling in case of multi-match
@ -2170,17 +2071,11 @@ class CmdTypeclass(COMMAND_DEFAULT_CLASS):
# we let this raise exception if needed
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:
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:
string = "%s changed typeclass from %s to %s.\n" % (
obj.name,
@ -2294,8 +2189,7 @@ class CmdLock(ObjManipCommand):
caller = self.caller
if not self.args:
string = (
"Usage: lock <object>[ = <lockstring>] or lock[/switch] "
"<object>/<access_type>"
"Usage: lock <object>[ = <lockstring>] or lock[/switch] " "<object>/<access_type>"
)
caller.msg(string)
return
@ -2441,10 +2335,7 @@ class CmdExamine(ObjManipCommand):
except Exception:
ndb_attr = None
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:
ndb_attr = obj.nattributes.all(return_tuples=True)
except Exception:
@ -2468,9 +2359,7 @@ class CmdExamine(ObjManipCommand):
"""
string = "\n|wName/key|n: |c%s|n (%s)" % (obj.name, obj.dbref)
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():
string += "\n|wSession id(s)|n: %s" % (
", ".join("#%i" % sess.sessid for sess in obj.sessions.all())
@ -2512,20 +2401,14 @@ class CmdExamine(ObjManipCommand):
locks = str(obj.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:
locks_string = " Default"
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.
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" % (
"\n ".join(
"%s [%s] (%s, prio %s)"
@ -2540,9 +2423,7 @@ class CmdExamine(ObjManipCommand):
# we always at least try to add account- and session sets since these are ignored
# if we merge on the object level.
if hasattr(obj, "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 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
@ -2560,9 +2441,7 @@ class CmdExamine(ObjManipCommand):
all_cmdsets.extend(
[
(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):
@ -2579,21 +2458,15 @@ class CmdExamine(ObjManipCommand):
)
# 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)
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()
):
if hasattr(obj, "scripts") and hasattr(obj.scripts, "all") and obj.scripts.all():
string += "\n|wScripts|n:\n %s" % obj.scripts
# add the attributes
string += self.format_attributes(obj)
@ -2772,9 +2645,7 @@ class CmdFind(COMMAND_DEFAULT_CLASS):
caller.msg("Usage: find <string> [= low [-high]]")
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")
searchstring = self.lhs
@ -2822,16 +2693,10 @@ class CmdFind(COMMAND_DEFAULT_CLASS):
if not result:
string += "\n |RNo match found.|n"
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:
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:
string += " (|wlocation|n: |g{}|n)".format(
result.location.get_display_name(caller)
@ -2848,9 +2713,7 @@ class CmdFind(COMMAND_DEFAULT_CLASS):
id__lte=high,
)
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(
db_tags__db_key__istartswith=searchstring,
db_tags__db_tagtype__iexact="alias",
@ -2873,33 +2736,19 @@ class CmdFind(COMMAND_DEFAULT_CLASS):
# convert result to typeclasses.
results = [result for result in results]
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:
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:
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)
# still results after type filtering?
if nresults:
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:
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:
string = "|wOne Match|n(#%i-#%i%s):" % (low, high, restrictions)
string += "\n |g%s - %s|n" % (
@ -2985,8 +2834,7 @@ class CmdTeleport(COMMAND_DEFAULT_CLASS):
caller.msg("Teleported %s -> None-location." % obj_to_teleport)
if obj_to_teleport.location and not tel_quietly:
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
return
@ -3029,10 +2877,7 @@ class CmdTeleport(COMMAND_DEFAULT_CLASS):
# try the teleport
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:
caller.msg("Teleported to %s." % destination)
@ -3077,9 +2922,7 @@ class CmdScript(COMMAND_DEFAULT_CLASS):
return
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
obj = caller.search(self.lhs)
@ -3091,9 +2934,7 @@ class CmdScript(COMMAND_DEFAULT_CLASS):
# no rhs means we want to operate on all scripts
scripts = obj.scripts.all()
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:
# view all scripts
from evennia.commands.default.system import format_script_list
@ -3101,17 +2942,12 @@ class CmdScript(COMMAND_DEFAULT_CLASS):
result.append(format_script_list(scripts))
elif "start" in self.switches:
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:
for script in scripts:
result.append(
"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()
obj.scripts.validate()
@ -3139,10 +2975,7 @@ class CmdScript(COMMAND_DEFAULT_CLASS):
for path in paths:
ok = obj.scripts.stop(path)
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:
result = ["Script stopped and removed from object."]
break
@ -3151,13 +2984,12 @@ class CmdScript(COMMAND_DEFAULT_CLASS):
for path in paths:
ok = obj.scripts.start(path)
if not ok:
result.append(
"\nScript %s could not be (re)started." % path
)
result.append("\nScript %s could not be (re)started." % path)
else:
result = ["Script started successfully."]
break
caller.msg("".join(result).strip())
EvMore(caller, "".join(result).strip())
class CmdTag(COMMAND_DEFAULT_CLASS):
@ -3257,10 +3089,7 @@ class CmdTag(COMMAND_DEFAULT_CLASS):
]
if old_tags:
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:
string = "No Tags to clear on %s." % obj
self.caller.msg(string)
@ -3291,18 +3120,12 @@ class CmdTag(COMMAND_DEFAULT_CLASS):
tagtuples = obj.tags.all(return_key_and_category=True)
ntags = len(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:
string = "Tag%s on %s: %s" % (
"s" if ntags > 1 else "",
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:
string = "No tags attached to %s." % obj
@ -3417,12 +3240,9 @@ class CmdSpawn(COMMAND_DEFAULT_CLASS):
return None
if expect == dict:
# 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(
"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
try:
@ -3458,10 +3278,7 @@ class CmdSpawn(COMMAND_DEFAULT_CLASS):
if len(prototype) > 1:
caller.msg(
"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
@ -3482,9 +3299,7 @@ class CmdSpawn(COMMAND_DEFAULT_CLASS):
else:
key, tags = self.args.strip(), None
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
EvMore(
caller,
@ -3537,18 +3352,14 @@ class CmdSpawn(COMMAND_DEFAULT_CLASS):
prototype_key = prototype.get("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
# check for existing prototype,
old_matchstring = _search_show_prototype(prototype_key)
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"
answer = yield (string + question)
@ -3586,9 +3397,7 @@ class CmdSpawn(COMMAND_DEFAULT_CLASS):
"Use spawn/update <key> to apply later as needed.|n"
)
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))
return
@ -3616,9 +3425,7 @@ class CmdSpawn(COMMAND_DEFAULT_CLASS):
caller.msg("|rError deleting:|R {}|n".format(err))
caller.msg(
"Deletion {}.".format(
"successful"
if success
else "failed (does the prototype exist?)"
"successful" if success else "failed (does the prototype exist?)"
)
)
return
@ -3642,9 +3449,7 @@ class CmdSpawn(COMMAND_DEFAULT_CLASS):
if answer.lower() in ["n", "no"]:
caller.msg("|rUpdate cancelled.")
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))
# A direct creation of an object from a given prototype
@ -3670,19 +3475,14 @@ class CmdSpawn(COMMAND_DEFAULT_CLASS):
"Found {} prototypes matching '{}':\n {}".format(
nprots,
prototype,
", ".join(
proto.get("prototype_key", "") for proto in prototypes
),
", ".join(proto.get("prototype_key", "") for proto in prototypes),
)
)
return
# we have a prototype, check access
prototype = prototypes[0]
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.")
return

View file

@ -188,18 +188,14 @@ class CmdDelCom(COMMAND_DEFAULT_CLASS):
if delnicks:
for nick in [
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
]:
nick.delete()
disconnect = channel.disconnect(account)
if disconnect:
wipednicks = " Eventual aliases were removed." if delnicks else ""
self.msg(
"You stop listening to channel '%s'.%s" % (channel.key, wipednicks)
)
self.msg("You stop listening to channel '%s'.%s" % (channel.key, wipednicks))
return
else:
# we are removing a channel nick
@ -210,10 +206,7 @@ class CmdDelCom(COMMAND_DEFAULT_CLASS):
else:
if caller.nicks.get(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:
self.msg("You had no such alias defined for this channel.")
@ -347,9 +340,7 @@ class CmdChannels(COMMAND_DEFAULT_CLASS):
"%s%s"
% (
chan.key,
chan.aliases.all()
and "(%s)" % ",".join(chan.aliases.all())
or "",
chan.aliases.all() and "(%s)" % ",".join(chan.aliases.all()) or "",
),
"%s"
% ",".join(
@ -390,9 +381,7 @@ class CmdChannels(COMMAND_DEFAULT_CLASS):
"%s%s"
% (
chan.key,
chan.aliases.all()
and "(%s)" % ",".join(chan.aliases.all())
or "",
chan.aliases.all() and "(%s)" % ",".join(chan.aliases.all()) or "",
),
"%s"
% ",".join(
@ -444,9 +433,7 @@ class CmdCdestroy(COMMAND_DEFAULT_CLASS):
self.msg("You are not allowed to do that.")
return
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)
channel.msg(msgobj)
channel.delete()
@ -507,10 +494,7 @@ class CmdCBoot(COMMAND_DEFAULT_CLASS):
self.msg(string)
return
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)
return
if "quiet" not in self.switches:
@ -661,9 +645,7 @@ class CmdChannelCreate(COMMAND_DEFAULT_CLASS):
return
# Create and set the channel up
lockstring = "send:all();listen:all();control:id(%s)" % caller.id
new_chan = create.create_channel(
channame.strip(), aliases, description, locks=lockstring
)
new_chan = create.create_channel(channame.strip(), aliases, description, locks=lockstring)
new_chan.connect(caller)
CHANNELHANDLER.update()
self.msg("Created channel %s and connected to it." % new_chan.key)
@ -795,9 +777,7 @@ class CmdPage(COMMAND_DEFAULT_CLASS):
caller = self.caller
# 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
pages_we_got = Msg.objects.get_messages_by_receiver(caller)
@ -915,10 +895,7 @@ def _list_bots(cmd):
"""
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:
table = cmd.styled_table(
@ -987,9 +964,7 @@ class CmdIRC2Chan(COMMAND_DEFAULT_CLASS):
"""Setup the irc-channel mapping"""
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)
return
@ -998,11 +973,7 @@ class CmdIRC2Chan(COMMAND_DEFAULT_CLASS):
self.msg(_list_bots(self))
return
if (
"disconnect" in self.switches
or "remove" in self.switches
or "delete" in self.switches
):
if "disconnect" in self.switches or "remove" in self.switches or "delete" in self.switches:
botname = "ircbot-%s" % self.lhs
matches = AccountDB.objects.filter(db_is_bot=True, username=botname)
dbref = utils.dbref(self.lhs)
@ -1132,9 +1103,7 @@ class CmdIRCStatus(COMMAND_DEFAULT_CLASS):
elif option in ("users", "nicklist", "who"):
# retrieve user list. The bot must handles the echo since it's
# 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)
elif self.caller.locks.check_lockstring(
self.caller, "dummy:perm(ircstatus) or perm(Developer)"
@ -1182,9 +1151,7 @@ class CmdRSS2Chan(COMMAND_DEFAULT_CLASS):
# checking we have all we need
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)
return
try:
@ -1203,9 +1170,7 @@ class CmdRSS2Chan(COMMAND_DEFAULT_CLASS):
# show all connections
rssbots = [
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:
table = self.styled_table(
@ -1218,28 +1183,19 @@ class CmdRSS2Chan(COMMAND_DEFAULT_CLASS):
)
for rssbot in rssbots:
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)
else:
self.msg("No rss bots found.")
return
if (
"disconnect" in self.switches
or "remove" in self.switches
or "delete" in self.switches
):
if "disconnect" in self.switches or "remove" in self.switches or "delete" in self.switches:
botname = "rssbot-%s" % self.lhs
matches = AccountDB.objects.filter(db_is_bot=True, db_key=botname)
if not matches:
# 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:
matches[0].delete()
self.msg("RSS connection destroyed.")
@ -1321,34 +1277,24 @@ class CmdGrapevine2Chan(COMMAND_DEFAULT_CLASS):
maxwidth=_DEFAULT_WIDTH,
)
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)
else:
self.msg("No grapevine bots found.")
return
if (
"disconnect" in self.switches
or "remove" in self.switches
or "delete" in self.switches
):
if "disconnect" in self.switches or "remove" in self.switches or "delete" in self.switches:
botname = "grapevinebot-%s" % self.lhs
matches = AccountDB.objects.filter(db_is_bot=True, db_key=botname)
if not matches:
# 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:
matches[0].delete()
self.msg("Grapevine connection destroyed.")
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
if not self.args or not self.rhs:
@ -1371,9 +1317,7 @@ class CmdGrapevine2Chan(COMMAND_DEFAULT_CLASS):
self.msg("Reusing bot '%s' (%s)" % (botname, bot.dbref))
else:
# 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)
self.msg(f"Grapevine connection created {channel} <-> {grapevine_channel}.")

View file

@ -157,24 +157,14 @@ class CmdNick(COMMAND_DEFAULT_CLASS):
caller = self.caller
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)
nicktypes = nicktypes if specified_nicktype else ["inputline"]
nicklist = (
utils.make_iter(
caller.nicks.get(category="inputline", return_obj=True) or []
)
+ utils.make_iter(
caller.nicks.get(category="object", return_obj=True) or []
)
+ utils.make_iter(
caller.nicks.get(category="account", return_obj=True) or []
)
utils.make_iter(caller.nicks.get(category="inputline", return_obj=True) or [])
+ utils.make_iter(caller.nicks.get(category="object", return_obj=True) or [])
+ utils.make_iter(caller.nicks.get(category="account", return_obj=True) or [])
)
if "list" in switches or self.cmdstring in ("nicks",):
@ -186,10 +176,7 @@ class CmdNick(COMMAND_DEFAULT_CLASS):
for inum, nickobj in enumerate(nicklist):
_, _, nickvalue, replacement = nickobj.value
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
caller.msg(string)
@ -220,9 +207,7 @@ class CmdNick(COMMAND_DEFAULT_CLASS):
if not specified_nicktype:
nicktypes = ("object", "account", "inputline")
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]
if oldnicks:
@ -256,9 +241,7 @@ class CmdNick(COMMAND_DEFAULT_CLASS):
_, _, nick, repl = nick.value
if nick.startswith(self.lhs):
strings.append(
"{}-nick: '{}' -> '{}'".format(
nicktype.capitalize(), nick, repl
)
"{}-nick: '{}' -> '{}'".format(nicktype.capitalize(), nick, repl)
)
if strings:
caller.msg("\n".join(strings))
@ -276,16 +259,12 @@ class CmdNick(COMMAND_DEFAULT_CLASS):
obj = account
else:
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:
_, _, nick, repl = nick.value
if nick.startswith(self.lhs):
strings.append(
"{}-nick: '{}' -> '{}'".format(
nicktype.capitalize(), nick, repl
)
"{}-nick: '{}' -> '{}'".format(nicktype.capitalize(), nick, repl)
)
if strings:
caller.msg("\n".join(strings))
@ -303,16 +282,12 @@ class CmdNick(COMMAND_DEFAULT_CLASS):
obj = account
else:
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:
_, _, nick, repl = nick.value
if nick.startswith(self.lhs):
strings.append(
"{}-nick: '{}' -> '{}'".format(
nicktype.capitalize(), nick, repl
)
"{}-nick: '{}' -> '{}'".format(nicktype.capitalize(), nick, repl)
)
if strings:
caller.msg("\n".join(strings))
@ -341,9 +316,7 @@ class CmdNick(COMMAND_DEFAULT_CLASS):
old_nickstring = 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:
_, _, old_nickstring, old_replstring = oldnick.value
if replstring:
@ -455,9 +428,7 @@ class CmdGet(COMMAND_DEFAULT_CLASS):
obj.move_to(caller, quiet=True)
caller.msg("You pick up %s." % obj.name)
caller.location.msg_contents(
"%s picks up %s." % (caller.name, obj.name), exclude=caller
)
caller.location.msg_contents("%s picks up %s." % (caller.name, obj.name), exclude=caller)
# calling at_get hook method
obj.at_get(caller)
@ -502,9 +473,7 @@ class CmdDrop(COMMAND_DEFAULT_CLASS):
obj.move_to(caller.location, quiet=True)
caller.msg("You drop %s." % (obj.name,))
caller.location.msg_contents(
"%s drops %s." % (caller.name, obj.name), exclude=caller
)
caller.location.msg_contents("%s drops %s." % (caller.name, obj.name), exclude=caller)
# Call the object script's at_drop() method.
obj.at_drop(caller)
@ -706,9 +675,7 @@ class CmdPose(COMMAND_DEFAULT_CLASS):
self.caller.msg(msg)
else:
msg = "%s%s" % (self.caller.name, self.args)
self.caller.location.msg_contents(
text=(msg, {"type": "pose"}), from_obj=self.caller
)
self.caller.location.msg_contents(text=(msg, {"type": "pose"}), from_obj=self.caller)
class CmdAccess(COMMAND_DEFAULT_CLASS):
@ -732,9 +699,7 @@ class CmdAccess(COMMAND_DEFAULT_CLASS):
caller = self.caller
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:
cperms = "<Superuser>"

View file

@ -67,10 +67,7 @@ class CmdHelp(Command):
if type(self).help_more:
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:
options = self.account.db._saved_webclient_options
if options and options["helppopup"]:
@ -104,9 +101,7 @@ class CmdHelp(Command):
if title:
string += "|CHelp for |w%s|n" % title
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:
string += "\n%s" % dedent(help_text.rstrip())
if suggested:
@ -129,18 +124,14 @@ class CmdHelp(Command):
string += "\n" + _SEP + "\n |CCommand help entries|n\n" + _SEP
for category in sorted(hdict_cmds.keys()):
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()):
string += "\n\n" + _SEP + "\n\r |COther help entries|n\n" + _SEP
for category in sorted(hdict_db.keys()):
string += "\n\r |w%s|n:\n" % (str(category).title())
string += (
"|G"
+ fill(
", ".join(sorted([str(topic) for topic in hdict_db[category]]))
)
+ fill(", ".join(sorted([str(topic) for topic in hdict_db[category]])))
+ "|n"
)
return string
@ -213,9 +204,7 @@ class CmdHelp(Command):
# retrieve all available commands and database topics
all_cmds = [cmd for cmd in cmdset if self.check_show_help(cmd, caller)]
all_topics = [
topic
for topic in HelpEntry.objects.all()
if topic.access(caller, "view", default=True)
topic for topic in HelpEntry.objects.all() if topic.access(caller, "view", default=True)
]
all_categories = list(
set(
@ -253,18 +242,13 @@ class CmdHelp(Command):
suggestions = [
sugg
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 not 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
@ -307,18 +291,8 @@ class CmdHelp(Command):
if query in all_categories:
self.msg_help(
self.format_help_list(
{
query: [
cmd.key for cmd in all_cmds if cmd.help_category == query
]
},
{
query: [
topic.key
for topic in all_topics
if topic.help_category == query
]
},
{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
@ -402,19 +376,14 @@ class CmdSetHelp(COMMAND_DEFAULT_CLASS):
self.msg("You have to define a topic!")
return
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 ""
old_entry = None
# check if we have an old entry with the same name
try:
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:
old_entry = list(old_entry)[0]
break
@ -436,11 +405,7 @@ class CmdSetHelp(COMMAND_DEFAULT_CLASS):
helpentry = old_entry
else:
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
@ -457,9 +422,7 @@ class CmdSetHelp(COMMAND_DEFAULT_CLASS):
if "append" in switches or "merge" in switches or "extend" in switches:
# merge/append operations
if not old_entry:
self.msg(
"Could not find topic '%s'. You must give an exact name." % topicstr
)
self.msg("Could not find topic '%s'. You must give an exact name." % topicstr)
return
if not self.rhs:
self.msg("You must supply text to append/merge.")
@ -506,9 +469,7 @@ class CmdSetHelp(COMMAND_DEFAULT_CLASS):
topicstr, self.rhs, category=category, locks=lockstring, aliases=aliases
)
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:
# open the line editor to edit the helptext
self.caller.db._editing_help = new_entry
@ -523,6 +484,5 @@ class CmdSetHelp(COMMAND_DEFAULT_CLASS):
return
else:
self.msg(
"Error when creating topic '%s'%s! Contact an admin."
% (topicstr, aliastxt)
"Error when creating topic '%s'%s! Contact an admin." % (topicstr, aliastxt)
)

View file

@ -129,14 +129,10 @@ class MuxCommand(Command):
if switches and self.switch_options:
valid_switches, unused_switches, extra_switches = [], [], []
for element in switches:
option_check = [
opt for opt in self.switch_options if opt == element
]
option_check = [opt for opt in self.switch_options if opt == element]
if not option_check:
option_check = [
opt
for opt in self.switch_options
if opt.startswith(element)
opt for opt in self.switch_options if opt.startswith(element)
]
match_count = len(option_check)
if match_count > 1:
@ -144,13 +140,9 @@ class MuxCommand(Command):
option_check
) # Either the option provided is ambiguous,
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:
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
self.msg(
"|g%s|n: |wAmbiguous switch supplied: Did you mean /|C%s|w?"
@ -162,17 +154,13 @@ class MuxCommand(Command):
'|g%s|n: |wExtra switch%s "/|C%s|w" ignored.'
% (self.cmdstring, plural, "|n, /|C".join(unused_switches))
)
switches = (
valid_switches
) # Only include valid_switches in command function call
switches = valid_switches # Only include valid_switches in command function call
arglist = [arg.strip() for arg in args.split()]
# check for arg1, arg2, ... = argA, argB, ... constructs
lhs, rhs = args.strip(), None
if lhs:
if delimiters and hasattr(
delimiters, "__iter__"
): # If delimiter is iterable,
if delimiters and hasattr(delimiters, "__iter__"): # If delimiter is iterable,
best_split = delimiters[0] # (default to first delimiter)
for this_split in delimiters: # try each delimiter
if this_split in lhs: # to find first successful split
@ -204,15 +192,11 @@ class MuxCommand(Command):
# a special property "character" for the puppeted object, if any. This
# is convenient for commands defined on the Account only.
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
self.character = self.caller
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
self.character = self.caller.get_puppet(self.session)
else:
@ -225,8 +209,7 @@ class MuxCommand(Command):
to all the variables defined therein.
"""
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"""
Command {self} has no defined `func()` - showing on-command variables: No child func() defined for {self} - available variables:
@ -253,9 +236,7 @@ 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 switches (self.switches): |w%s|n\n" % self.switches
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 += "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
@ -280,6 +261,4 @@ class MuxAccountCommand(MuxCommand):
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

View file

@ -103,9 +103,7 @@ class SystemMultimatch(COMMAND_DEFAULT_CLASS):
# evennia.commands.cmdparse.create_match for more details.
matches = self.matches
# at_search_result will itself msg the multimatch options to the caller.
at_search_result(
[match[2] for match in matches], self.caller, query=matches[0][0]
)
at_search_result([match[2] for match in matches], self.caller, query=matches[0][0])
# Command called when the command given at the command line

View file

@ -23,6 +23,7 @@ from evennia.accounts.models import AccountDB
from evennia.utils import logger, utils, gametime, create, search
from evennia.utils.eveditor import EvEditor
from evennia.utils.evtable import EvTable
from evennia.utils.evmore import EvMore
from evennia.utils.utils import crop, class_from_module
COMMAND_DEFAULT_CLASS = class_from_module(settings.COMMAND_DEFAULT_CLASS)
@ -150,12 +151,7 @@ def _py_code(caller, buf):
string = "Executing code%s ..." % (" (measure timing)" if measure_time else "")
caller.msg(string)
_run_code_snippet(
caller,
buf,
mode="exec",
measure_time=measure_time,
client_raw=client_raw,
show_input=False,
caller, buf, mode="exec", measure_time=measure_time, client_raw=client_raw, show_input=False
)
return True
@ -240,9 +236,7 @@ def _run_code_snippet(
for session in sessions:
try:
caller.msg(
ret, session=session, options={"raw": True, "client_raw": client_raw}
)
caller.msg(ret, session=session, options={"raw": True, "client_raw": client_raw})
except TypeError:
caller.msg(ret, options={"raw": True, "client_raw": client_raw})
@ -416,7 +410,9 @@ def format_script_list(scripts):
align="r",
border="tablecols",
)
for script in scripts:
nextrep = script.time_until_next_repeat()
if nextrep is None:
nextrep = "PAUS" if script.db._paused_time else "--"
@ -440,6 +436,7 @@ def format_script_list(scripts):
script.typeclass_path.rsplit(".", 1)[-1],
crop(script.desc, width=20),
)
return "%s" % table
@ -484,9 +481,7 @@ class CmdScripts(COMMAND_DEFAULT_CLASS):
if new_script:
caller.msg("Global script %s was started successfully." % args)
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
# test first if this is a script match
@ -507,10 +502,7 @@ class CmdScripts(COMMAND_DEFAULT_CLASS):
return
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)
return
@ -539,7 +531,7 @@ class CmdScripts(COMMAND_DEFAULT_CLASS):
else:
# No stopping or validation. We just want to view things.
string = format_script_list(scripts)
caller.msg(string)
EvMore(caller, string)
class CmdObjects(COMMAND_DEFAULT_CLASS):
@ -597,9 +589,7 @@ class CmdObjects(COMMAND_DEFAULT_CLASS):
nexits,
"%.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
typetable = self.styled_table(
@ -611,16 +601,9 @@ class CmdObjects(COMMAND_DEFAULT_CLASS):
typetable.add_row(path, count, "%.2f" % ((float(count) / nobjs) * 100))
# last N table
objs = ObjectDB.objects.all().order_by("db_date_created")[
max(0, nobjs - nlim) :
]
objs = ObjectDB.objects.all().order_by("db_date_created")[max(0, nobjs - nlim) :]
latesttable = self.styled_table(
"|wcreated|n",
"|wdbref|n",
"|wname|n",
"|wtypeclass|n",
align="l",
border="table",
"|wcreated|n", "|wdbref|n", "|wname|n", "|wtypeclass|n", align="l", border="table"
)
latesttable.align = "l"
for obj in objs:
@ -628,10 +611,7 @@ class CmdObjects(COMMAND_DEFAULT_CLASS):
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|wLast %s Objects created:|n\n%s" % (min(nobjs, nlim), latesttable)
caller.msg(string)
@ -684,9 +664,7 @@ class CmdAccounts(COMMAND_DEFAULT_CLASS):
return
if len(accounts) > 1:
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)
return
account = accounts.first()
@ -735,16 +713,9 @@ class CmdAccounts(COMMAND_DEFAULT_CLASS):
for path, count in dbtotals.items():
typetable.add_row(path, count, "%.2f" % ((float(count) / naccounts) * 100))
# last N table
plyrs = AccountDB.objects.all().order_by("db_date_created")[
max(0, naccounts - nlim) :
]
plyrs = AccountDB.objects.all().order_by("db_date_created")[max(0, naccounts - nlim) :]
latesttable = self.styled_table(
"|wcreated|n",
"|wdbref|n",
"|wname|n",
"|wtypeclass|n",
border="cells",
align="l",
"|wcreated|n", "|wdbref|n", "|wname|n", "|wtypeclass|n", border="cells", align="l"
)
for ply in plyrs:
latesttable.add_row(
@ -752,10 +723,7 @@ class CmdAccounts(COMMAND_DEFAULT_CLASS):
)
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)
@ -805,9 +773,7 @@ class CmdService(COMMAND_DEFAULT_CLASS):
"|wService|n (use services/start|stop|delete)", "|wstatus", align="l"
)
for service in service_collection.services:
table.add_row(
service.name, service.running and "|gRunning" or "|rNot Running"
)
table.add_row(service.name, service.running and "|gRunning" or "|rNot Running")
caller.msg(str(table))
return
@ -817,9 +783,7 @@ class CmdService(COMMAND_DEFAULT_CLASS):
service = service_collection.getServiceNamed(self.args)
except Exception:
string = "Invalid service name. This command is case-sensitive. "
string += (
"See service/list for valid service name (enter the full name exactly)."
)
string += "See service/list for valid service name (enter the full name exactly)."
caller.msg(string)
return
@ -833,9 +797,7 @@ class CmdService(COMMAND_DEFAULT_CLASS):
return
if service.name[:7] == "Evennia":
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
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*"
@ -927,9 +889,7 @@ class CmdTime(COMMAND_DEFAULT_CLASS):
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("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.reformat_column(0, width=30)
table2 = self.styled_table(
@ -939,14 +899,11 @@ class CmdTime(COMMAND_DEFAULT_CLASS):
width=77,
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("Total time passed:", utils.time_format(gametime.gametime(), 2))
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)
self.caller.msg(str(table1) + "\n" + str(table2))
@ -1043,9 +1000,7 @@ class CmdServerLoad(COMMAND_DEFAULT_CLASS):
# Display table
loadtable = self.styled_table("property", "statistic", align="l")
loadtable.add_row("Total CPU load", "%g %%" % loadavg)
loadtable.add_row(
"Total computer memory usage", "%g MB (%g%%)" % (rmem, pmem)
)
loadtable.add_row("Total computer memory usage", "%g MB (%g%%)" % (rmem, pmem))
loadtable.add_row("Process ID", "%g" % pid),
else:
loadtable = (
@ -1062,12 +1017,10 @@ class CmdServerLoad(COMMAND_DEFAULT_CLASS):
loadavg = os.getloadavg()[0]
rmem = (
float(os.popen("ps -p %d -o %s | tail -1" % (pid, "rss")).read())
/ 1000.0
float(os.popen("ps -p %d -o %s | tail -1" % (pid, "rss")).read()) / 1000.0
) # resident memory
vmem = (
float(os.popen("ps -p %d -o %s | tail -1" % (pid, "vsz")).read())
/ 1000.0
float(os.popen("ps -p %d -o %s | tail -1" % (pid, "vsz")).read()) / 1000.0
) # virtual memory
pmem = float(
os.popen("ps -p %d -o %s | tail -1" % (pid, "%mem")).read()
@ -1099,12 +1052,9 @@ class CmdServerLoad(COMMAND_DEFAULT_CLASS):
% (rusage.ru_majflt, rusage.ru_minflt, rusage.ru_nswap),
)
loadtable.add_row(
"Disk I/O",
"%g reads, %g writes" % (rusage.ru_inblock, rusage.ru_oublock),
)
loadtable.add_row(
"Network I/O", "%g in, %g out" % (rusage.ru_msgrcv, rusage.ru_msgsnd)
"Disk I/O", "%g reads, %g writes" % (rusage.ru_inblock, rusage.ru_oublock)
)
loadtable.add_row("Network I/O", "%g in, %g out" % (rusage.ru_msgrcv, rusage.ru_msgsnd))
loadtable.add_row(
"Context switching",
"%g vol, %g forced, %g signals"
@ -1124,9 +1074,7 @@ class CmdServerLoad(COMMAND_DEFAULT_CLASS):
)
memtable = self.styled_table("entity name", "number", "idmapper %", align="l")
for tup in sorted_cache:
memtable.add_row(
tup[0], "%i" % tup[1], "%.2f" % (float(tup[1]) / total_num * 100)
)
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)
@ -1158,18 +1106,14 @@ class CmdTickers(COMMAND_DEFAULT_CLASS):
if not all_subs:
self.caller.msg("No tickers are currently active.")
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:
table.add_row(
sub[3],
"%s%s"
% (
sub[0] or "[None]",
sub[0]
and " (#%s)" % (sub[0].id if hasattr(sub[0], "id") else "")
or "",
sub[0] and " (#%s)" % (sub[0].id if hasattr(sub[0], "id") else "") or "",
),
sub[1] if sub[1] else sub[2],
sub[4] or "[Unset]",

View file

@ -99,9 +99,7 @@ class CommandTest(EvenniaTest):
cmdobj.cmdset = cmdset
cmdobj.session = SESSIONS.session_from_sessid(1)
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)
# test
old_msg = receiver.msg
@ -142,18 +140,14 @@ class CommandTest(EvenniaTest):
for name, args, kwargs in receiver.msg.mock_calls
]
# Get the first element of a tuple if msg received a tuple instead of a string
stored_msg = [
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:
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
msg_sep = "|" if noansi else "||"
# Have to strip ansi for each returned message for the regex to handle it correctly
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()
if msg == "" and returned_msg or not returned_msg.startswith(msg.strip()):
sep1 = "\n" + "=" * 30 + "Wanted message" + "=" * 34 + "\n"
@ -208,12 +202,8 @@ class TestGeneral(CommandTest):
self.assertEqual(
"testaliasedstring2", self.char1.nicks.get("testalias", category="account")
)
self.assertEqual(
None, self.char1.account.nicks.get("testalias", category="account")
)
self.assertEqual(
"testaliasedstring3", self.char1.nicks.get("testalias", category="object")
)
self.assertEqual(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):
self.call(general.CmdGet(), "Obj", "You pick up Obj.")
@ -240,13 +230,9 @@ class TestGeneral(CommandTest):
"Switches matched: ['test', 'testswitch', 'testswitch2']",
)
self.call(CmdTest(), "/test", "Switches matched: ['test']")
self.call(CmdTest(), "/test/testswitch", "Switches matched: ['test', 'testswitch']")
self.call(
CmdTest(), "/test/testswitch", "Switches matched: ['test', 'testswitch']"
)
self.call(
CmdTest(),
"/testswitch/testswitch2",
"Switches matched: ['testswitch', 'testswitch2']",
CmdTest(), "/testswitch/testswitch2", "Switches matched: ['testswitch', 'testswitch2']"
)
self.call(CmdTest(), "/testswitch", "Switches matched: ['testswitch']")
self.call(CmdTest(), "/testswitch2", "Switches matched: ['testswitch2']")
@ -288,9 +274,7 @@ class TestHelp(CommandTest):
"testhelp, General = This is a test",
"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):
@ -348,10 +332,7 @@ class TestAccount(CommandTest):
def test_ooc_look(self):
if settings.MULTISESSION_MODE < 2:
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:
self.call(
@ -367,11 +348,7 @@ class TestAccount(CommandTest):
def test_ic(self):
self.account.unpuppet_object(self.session)
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):
@ -390,16 +367,11 @@ class TestAccount(CommandTest):
def test_quit(self):
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):
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):
self.call(account.CmdColorTest(), "ansi", "ANSI colors:", caller=self.account)
@ -484,11 +456,7 @@ class TestBuilding(CommandTest):
self.call(building.CmdExamine(), "*TestAccount", "Name/key: TestAccount")
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(), "out", "Name/key: out")
@ -508,11 +476,7 @@ class TestBuilding(CommandTest):
self.call(building.CmdSetObjAlias(), "", "Usage: ")
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 =", "No aliases to clear.")
@ -523,11 +487,7 @@ class TestBuilding(CommandTest):
"Copied Obj to 'TestObj3' (aliases: ['TestObj3b']",
)
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'.")
def test_attribute_commands(self):
@ -542,14 +502,8 @@ class TestBuilding(CommandTest):
'Obj2/test2="value2"',
"Created attribute Obj2/test2 = 'value2'",
)
self.call(
building.CmdSetAttribute(), "Obj2/test2", "Attribute Obj2/test2 = value2"
)
self.call(
building.CmdSetAttribute(),
"Obj2/NotFound",
"Obj2 has no attribute 'notfound'.",
)
self.call(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:
self.call(building.CmdSetAttribute(), "/edit Obj2/test3")
@ -573,59 +527,35 @@ class TestBuilding(CommandTest):
"(value: 'value2')",
)
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(),
"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(),
"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.")
def test_nested_attribute_commands(self):
# list - adding white space proves real parsing
self.call(
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"
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[0] = 99",
"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
self.call(
building.CmdSetAttribute(),
"Obj/test1[0] =",
"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(
building.CmdSetAttribute(),
"Obj/test1[1]",
@ -656,35 +586,17 @@ class TestBuilding(CommandTest):
"Created attribute Obj/test2 = {'one': 1, 'two': 2}",
)
self.call(
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",
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']=99",
"Modified attribute Obj/test2 = {'one': 99, 'two': 2}",
)
self.call(
building.CmdSetAttribute(),
"Obj/test2['one']",
"Attribute Obj/test2['one'] = 99",
)
self.call(
building.CmdSetAttribute(),
"Obj/test2['two']",
"Attribute Obj/test2['two'] = 2",
)
self.call(building.CmdSetAttribute(), "Obj/test2['one']", "Attribute Obj/test2['one'] = 99")
self.call(building.CmdSetAttribute(), "Obj/test2['two']", "Attribute Obj/test2['two'] = 2")
self.call(
building.CmdSetAttribute(),
"Obj/test2[+'three']",
@ -717,9 +629,7 @@ class TestBuilding(CommandTest):
"Obj has no attribute 'test2['two']'. (Nested lookups attempted)",
)
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(
building.CmdSetAttribute(),
@ -744,9 +654,7 @@ class TestBuilding(CommandTest):
# tuple
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(
building.CmdSetAttribute(),
@ -777,23 +685,15 @@ class TestBuilding(CommandTest):
"Created attribute Obj/test3 = [{'one': 1}]",
)
self.call(
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}",
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]['one'] =",
"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 = [{}]")
# Naughty keys
@ -802,35 +702,23 @@ class TestBuilding(CommandTest):
"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(
building.CmdSetAttribute(),
"Obj/test4=[{'one': 1}]",
"Created attribute Obj/test4 = [{'one': 1}]",
)
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
self.call(building.CmdSetAttribute(), "Obj/test4[0]", "Attribute Obj/test4[0] = {'one': 1}")
self.call(
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",
building.CmdSetAttribute(), "Obj/test4[0]['one']", "Attribute Obj/test4[0]['one'] = 1"
)
# Restored access
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(
building.CmdSetAttribute(),
"Obj/test4[0]['one']",
@ -848,11 +736,7 @@ class TestBuilding(CommandTest):
# duplicate keys don't cause issues
"test5[0][0]": [("test5", [0, 0]), ("test5[0]", [0]), ("test5[0][0]", [])],
# 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 []
"test7[dict": [("test7[dict", [])],
}
@ -892,24 +776,16 @@ class TestBuilding(CommandTest):
"*TestAccount=TestAccountRenamed",
"Account's name changed to 'TestAccountRenamed'.",
)
self.call(building.CmdName(), "*NotFound=TestAccountRenamed", "Could not find '*NotFound'")
self.call(
building.CmdName(),
"*NotFound=TestAccountRenamed",
"Could not find '*NotFound'",
)
self.call(
building.CmdName(),
"Obj3=Obj4;foo;bar",
"Object's name changed to 'Obj4' (foo, bar).",
building.CmdName(), "Obj3=Obj4;foo;bar", "Object's name changed to 'Obj4' (foo, bar)."
)
self.call(building.CmdName(), "Obj4=", "No names or aliases defined!")
def test_desc(self):
oid = self.obj2.id
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: ")
@ -931,11 +807,7 @@ class TestBuilding(CommandTest):
oid = self.obj2.id
o2d = self.obj2.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.room1.db.desc == r1d
@ -944,11 +816,7 @@ class TestBuilding(CommandTest):
rid = self.room1.id
o2d = self.obj2.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.room1.db.desc == "Obj2" and self.room1.db.desc != r1d
@ -990,22 +858,14 @@ class TestBuilding(CommandTest):
)
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: ")
def test_tunnel(self):
self.call(building.CmdTunnel(), "n = TestRoom2;test2", "Created room TestRoom2")
self.call(building.CmdTunnel(), "", "Usage: ")
self.call(
building.CmdTunnel(),
"foo = TestRoom2;test2",
"tunnel can only understand the",
)
self.call(
building.CmdTunnel(), "/tel e = TestRoom3;test3", "Created room TestRoom3"
)
self.call(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")
exits = DefaultExit.objects.filter_family(db_key__in=("east", "west"))
self.assertEqual(len(exits), 2)
@ -1019,32 +879,20 @@ class TestBuilding(CommandTest):
def test_exit_commands(self):
self.call(
building.CmdOpen(),
"TestExit1=Room2",
"Created new Exit 'TestExit1' from Room to Room2",
)
self.call(
building.CmdLink(),
"TestExit1=Room",
"Link created TestExit1 -> Room (one way).",
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.CmdUnLink(), "", "Usage: ")
self.call(building.CmdLink(), "NotFound", "Could not find 'NotFound'.")
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(
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.",
building.CmdUnLink(), "TestExit1", "Former exit TestExit1 no longer links anywhere."
)
self.char1.location = self.room2
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(
building.CmdOpen(),
@ -1054,9 +902,7 @@ class TestBuilding(CommandTest):
# ensure it matches locally first
self.call(
building.CmdLink(),
"TestExit=Room2",
"Link created TestExit2 -> Room2 (one way).",
building.CmdLink(), "TestExit=Room2", "Link created TestExit2 -> Room2 (one way)."
)
self.call(
building.CmdLink(),
@ -1077,29 +923,21 @@ class TestBuilding(CommandTest):
# ensure can still match globally when not a local name
self.call(building.CmdLink(), "TestExit1=Room2", "Note: TestExit1")
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):
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(), "self", "Char's current home is Room")
self.call(building.CmdSetHome(), "Obj", "Obj's current home is Room2")
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):
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'")
def test_typeclass(self):
@ -1133,9 +971,7 @@ class TestBuilding(CommandTest):
"/force Obj = evennia.objects.objects.DefaultExit",
"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(
building.CmdTypeclass(),
"/show Obj",
@ -1157,19 +993,13 @@ class TestBuilding(CommandTest):
def test_lock(self):
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(
building.CmdLock(),
"*TestAccount = test:all()",
"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(),
@ -1190,9 +1020,7 @@ class TestBuilding(CommandTest):
self.call(building.CmdFind(), "", "Usage: ")
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"
) # 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(),
@ -1218,9 +1046,7 @@ class TestBuilding(CommandTest):
def test_script(self):
self.call(building.CmdScript(), "Obj = ", "No scripts defined on Obj")
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(
@ -1236,9 +1062,7 @@ class TestBuilding(CommandTest):
self.call(building.CmdScript(), "/stop Obj", "Stopping script")
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(),
@ -1269,18 +1093,12 @@ class TestBuilding(CommandTest):
oid, rid, rid2
),
)
self.call(building.CmdTeleport(), "NotFound = Room", "Could not find 'NotFound'.")
self.call(
building.CmdTeleport(), "NotFound = Room", "Could not find 'NotFound'."
)
self.call(
building.CmdTeleport(),
"Obj = Obj",
"You can't teleport an object inside of itself!",
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(),
@ -1309,30 +1127,19 @@ class TestBuilding(CommandTest):
self.call(
building.CmdTag(),
"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(
building.CmdTag(), "/search testtag", "Found 1 object with tag 'testtag':"
)
self.call(
building.CmdTag(), "/search testtag2", "Found 1 object with tag 'testtag2':"
)
self.call(building.CmdTag(), "/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(
building.CmdTag(),
"/search testtag2: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(
building.CmdTag(),
"/del Obj",
@ -1368,8 +1175,7 @@ class TestBuilding(CommandTest):
self.call(
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.",
)
@ -1479,9 +1285,7 @@ class TestBuilding(CommandTest):
# spawn/edit with invalid prototype
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)
@ -1496,11 +1300,7 @@ class TestBuilding(CommandTest):
# spawn/examine with invalid prototype
# 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):

View file

@ -202,11 +202,11 @@ class CmdUnconnectedCreate(COMMAND_DEFAULT_CLASS):
# tell the caller everything went well.
string = "A new account '%s' was created. Welcome!"
if " " in username:
string += "\n\nYou can now log in with the command 'connect \"%s\" <your password>'."
else:
string += (
"\n\nYou can now log with the command 'connect %s <your password>'."
"\n\nYou can now log in with the command 'connect \"%s\" <your password>'."
)
else:
string += "\n\nYou can now log with the command 'connect %s <your password>'."
session.msg(string % (username, username))
else:
session.msg("|R%s|n" % "\n".join(errors))
@ -258,13 +258,9 @@ class CmdUnconnectedLook(COMMAND_DEFAULT_CLASS):
if "connection_screen" in callables:
connection_screen = callables["connection_screen"]()
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:
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)
@ -361,8 +357,7 @@ class CmdUnconnectedEncoding(COMMAND_DEFAULT_CLASS):
string = ""
if pencoding:
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
if encodings:
@ -385,9 +380,9 @@ class CmdUnconnectedEncoding(COMMAND_DEFAULT_CLASS):
)
else:
self.session.protocol_flags["ENCODING"] = encoding
string = (
"Your custom text encoding was changed from '|w%s|n' to '|w%s|n'."
% (old_encoding, encoding)
string = "Your custom text encoding was changed from '|w%s|n' to '|w%s|n'." % (
old_encoding,
encoding,
)
sync = True
if sync:
@ -441,9 +436,7 @@ 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.
"""
@ -468,9 +461,7 @@ def _create_account(
# join the new account to the public channel
pchannel = ChannelDB.objects.get_channel(settings.DEFAULT_CHANNELS[0]["key"])
if not pchannel or not pchannel.connect(new_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)
return new_account

View file

@ -99,116 +99,68 @@ class TestCmdSetMergers(TestCase):
a, c = self.cmdset_a, self.cmdset_c
cmdset_f = a + c # same-prio
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(
sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "C"), 2
)
self.assertEqual(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
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(
sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "C"), 0
)
self.assertEqual(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
cmdset_f = a + c # high prio A
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(
sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "C"), 0
)
self.assertEqual(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):
a, c = self.cmdset_a, self.cmdset_c
a.mergetype = "Intersect"
cmdset_f = a + c # same-prio - c's Union kicks in
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(
sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "C"), 2
)
self.assertEqual(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
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(
sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "C"), 0
)
self.assertEqual(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
cmdset_f = a + c # high prio A, intersect kicks in
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(
sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "C"), 0
)
self.assertEqual(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):
a, c = self.cmdset_a, self.cmdset_c
c.mergetype = "Replace"
cmdset_f = a + c # same-prio. C's Replace kicks in
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(
sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "C"), 2
)
self.assertEqual(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
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(
sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "C"), 0
)
self.assertEqual(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
cmdset_f = c + a # c higher prio. C's Replace kicks in
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(
sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "C"), 2
)
self.assertEqual(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):
a, c = self.cmdset_a, self.cmdset_c
c.mergetype = "Remove"
cmdset_f = a + c # same-prio. C's Remove kicks in
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(
sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "C"), 0
)
self.assertEqual(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
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(
sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "C"), 0
)
self.assertEqual(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
cmdset_f = c + a # c higher prio. C's Remove kicks in
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(
sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "C"), 0
)
self.assertEqual(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):
"Merge in reverse- and forward orders, same priorities"
@ -217,18 +169,12 @@ class TestCmdSetMergers(TestCase):
self.assertEqual(cmdset_f.priority, 0)
self.assertEqual(cmdset_f.mergetype, "Union")
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
self.assertEqual(cmdset_f.priority, 0)
self.assertEqual(cmdset_f.mergetype, "Union")
self.assertEqual(
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")
)
self.assertEqual(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):
"Merge in reverse- and forward order with well-defined prioritities"
@ -241,16 +187,12 @@ class TestCmdSetMergers(TestCase):
self.assertEqual(cmdset_f.priority, 2)
self.assertEqual(cmdset_f.mergetype, "Union")
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
self.assertEqual(cmdset_f.priority, 2)
self.assertEqual(cmdset_f.mergetype, "Union")
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):
"Test transfer of cmdset options"
@ -283,9 +225,7 @@ class TestCmdSetMergers(TestCase):
self.assertTrue(cmdset_f.no_channels)
self.assertTrue(cmdset_f.duplicates)
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_objs)
self.assertTrue(cmdset_f.no_channels)
@ -391,9 +331,7 @@ class TestGetAndMergeCmdSets(TwistedTestCase, EvenniaTest):
def test_from_object(self):
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.
def _callback(cmdset):
@ -410,9 +348,7 @@ class TestGetAndMergeCmdSets(TwistedTestCase, EvenniaTest):
a.no_channels = True
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):
self.assertTrue(cmdset.no_exits)
@ -427,9 +363,7 @@ class TestGetAndMergeCmdSets(TwistedTestCase, EvenniaTest):
from evennia.commands.default.cmdset_account import AccountCmdSet
from evennia.comms.channelhandler import CHANNEL_HANDLER
testchannel = evennia.create_channel(
"channeltest", locks="listen:all();send:all()"
)
testchannel = evennia.create_channel("channeltest", locks="listen:all();send:all()")
CHANNEL_HANDLER.add(testchannel)
CHANNEL_HANDLER.update()
self.assertTrue(testchannel.connect(self.account))
@ -443,14 +377,9 @@ class TestGetAndMergeCmdSets(TwistedTestCase, EvenniaTest):
def _callback(cmdset):
pcmdset = AccountCmdSet()
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(
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))
@ -464,9 +393,7 @@ class TestGetAndMergeCmdSets(TwistedTestCase, EvenniaTest):
b.duplicates = True
d.duplicates = True
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):
self.assertEqual(len(cmdset.commands), 9)
@ -539,9 +466,7 @@ class TestCmdParser(TestCase):
# test prefix exclusion on the cmd class
bcmd = [cmd for cmd in a_cmdset.commands if cmd.key == "&the third command"][0]
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")],
)
@ -552,8 +477,7 @@ class TestCmdParser(TestCase):
self.assertEqual(cmdparser.try_num_prefixes("567-look me"), ("567", "look me"))
@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):
a_cmdset = _CmdSetTest()

View file

@ -117,9 +117,7 @@ class ChannelAdmin(admin.ModelAdmin):
from django.http import HttpResponseRedirect
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)

View file

@ -129,16 +129,11 @@ class ChannelCommand(command.Command):
return
if self.history_start is not None:
# 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):
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)

View file

@ -301,13 +301,7 @@ class DefaultChannel(ChannelDB, metaclass=TypeclassBase):
CHANNELHANDLER.update()
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.
@ -361,9 +355,7 @@ class DefaultChannel(ChannelDB, metaclass=TypeclassBase):
# note our addition of the from_channel keyword here. This could be checked
# by a custom account.msg() to treat channel-receives differently.
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:
logger.log_trace("%s\nCannot send msg to '%s'." % (e, entity))
@ -371,8 +363,7 @@ class DefaultChannel(ChannelDB, metaclass=TypeclassBase):
if msgobj.keep_log:
# log to 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(
@ -426,9 +417,7 @@ class DefaultChannel(ChannelDB, metaclass=TypeclassBase):
senders = make_iter(senders) if senders else []
if isinstance(msgobj, str):
# 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()
msgobj.keep_log = keep_log if keep_log is not None else self.db.keep_log
@ -689,8 +678,7 @@ class DefaultChannel(ChannelDB, metaclass=TypeclassBase):
"""
content_type = ContentType.objects.get_for_model(self.__class__)
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

View file

@ -205,30 +205,24 @@ class MsgManager(TypedObjectManager):
# explicitly exclude channel recipients
if typ == "account":
return list(
self.filter(
db_sender_accounts=obj, db_receivers_channels__isnull=True
).exclude(db_hide_from_accounts=obj)
self.filter(db_sender_accounts=obj, db_receivers_channels__isnull=True).exclude(
db_hide_from_accounts=obj
)
)
elif typ == "object":
return list(
self.filter(
db_sender_objects=obj, db_receivers_channels__isnull=True
).exclude(db_hide_from_objects=obj)
self.filter(db_sender_objects=obj, db_receivers_channels__isnull=True).exclude(
db_hide_from_objects=obj
)
)
else:
raise CommError
else:
# get everything, channel or not
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":
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:
raise CommError
@ -248,21 +242,11 @@ class MsgManager(TypedObjectManager):
"""
obj, typ = identify_object(recipient)
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":
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":
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:
raise CommError
@ -277,9 +261,7 @@ class MsgManager(TypedObjectManager):
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):
"""
@ -315,13 +297,9 @@ class MsgManager(TypedObjectManager):
# filter by sender
sender, styp = identify_object(sender)
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":
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:
sender_restrict = Q()
# filter by receiver
@ -331,9 +309,7 @@ class MsgManager(TypedObjectManager):
db_hide_from_accounts=receiver
)
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":
receiver_restrict = Q(db_receivers_channels=receiver) & ~Q(
db_hide_from_channels=receiver
@ -342,15 +318,11 @@ class MsgManager(TypedObjectManager):
receiver_restrict = Q()
# filter by full text
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:
fulltext_restrict = Q()
# 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
message_search = search_message
@ -447,17 +419,12 @@ class ChannelDBManager(TypedObjectManager):
if exact:
channels = self.filter(
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()
else:
channels = self.filter(
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()
return channels

View file

@ -15,16 +15,10 @@ class Migration(migrations.Migration):
(
"id",
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",
models.CharField(
@ -36,9 +30,7 @@ class Migration(migrations.Migration):
),
(
"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",
@ -58,10 +50,7 @@ class Migration(migrations.Migration):
(
"id",
models.AutoField(
verbose_name="ID",
serialize=False,
auto_created=True,
primary_key=True,
verbose_name="ID", serialize=False, auto_created=True, primary_key=True
),
),
(
@ -74,10 +63,7 @@ class Migration(migrations.Migration):
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_date_sent",
@ -88,17 +74,13 @@ class Migration(migrations.Migration):
(
"db_lock_storage",
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",
models.ManyToManyField(
related_name="hide_from_channels_set",
null=True,
to="comms.ChannelDB",
related_name="hide_from_channels_set", null=True, to="comms.ChannelDB"
),
),
],

View file

@ -19,9 +19,7 @@ class Migration(migrations.Migration):
model_name="msg",
name="db_hide_from_accounts",
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,
),

View file

@ -6,9 +6,7 @@ from django.db import models, migrations
def convert_defaults(apps, schema_editor):
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.save()

View file

@ -6,10 +6,7 @@ from django.db import models, migrations
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 = [
migrations.AddField(

View file

@ -15,20 +15,14 @@ class Migration(migrations.Migration):
model_name="msg",
name="db_hide_from_channels",
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(
model_name="msg",
name="db_hide_from_objects",
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(

View file

@ -7,10 +7,7 @@ from django.db import migrations, models
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 = [
migrations.AddField(

View file

@ -67,9 +67,7 @@ class Migration(migrations.Migration):
model_name="msg",
name="db_hide_from_accounts",
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(

View file

@ -7,9 +7,6 @@ from django.db import migrations
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 = []

View file

@ -116,9 +116,7 @@ class Migration(migrations.Migration):
model_name="msg",
name="db_hide_from_accounts",
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(

View file

@ -12,8 +12,6 @@ class Migration(migrations.Migration):
operations = [
migrations.RemoveField(model_name="channeldb", name="db_subscriptions"),
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")
),
]

View file

@ -80,9 +80,7 @@ class Migration(migrations.Migration):
migrations.AlterField(
model_name="msg",
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(
model_name="msg",
@ -93,15 +91,11 @@ class Migration(migrations.Migration):
model_name="msg",
name="db_lock_storage",
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(
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(
model_name="msg",

View file

@ -134,10 +134,7 @@ class Msg(SharedMemoryModel):
help_text="script_receivers",
)
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
@ -487,8 +484,7 @@ class TempMsg(object):
"""
senders = ",".join(obj.key for obj in self.senders)
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))

View file

@ -414,13 +414,9 @@ class CmdTradeBase(Command):
self.args, self.emote = [part.strip() for part in self.args.rsplit(":", 1)]
self.str_caller = 'You say, "' + self.emote + '"\n [%s]'
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:
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
@ -570,9 +566,7 @@ class CmdAccept(CmdTradeBase):
)
self.msg_other(
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,
)
@ -608,10 +602,7 @@ class CmdDecline(CmdTradeBase):
return
if self.tradehandler.decline(self.caller):
# 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(
caller,
self.str_other
@ -621,9 +612,7 @@ class CmdDecline(CmdTradeBase):
else:
# no acceptance to change
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
@ -757,8 +746,7 @@ class CmdFinish(CmdTradeBase):
self.tradehandler.finish(force=True)
caller.msg(self.str_caller % "You |raborted|n trade. No deal was made.")
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
)
@ -814,13 +802,8 @@ class CmdTrade(Command):
"""Initiate trade"""
if not self.args:
if (
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."
)
if 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:
self.caller.msg("Usage: trade <other party> [accept|decline] [:emote]")
return
@ -869,9 +852,7 @@ class CmdTrade(Command):
if self.caller.ndb.tradehandler:
# trying to start trade without stopping a previous one
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:
string = "You are already trying to initiate trade with %s. You need to decline that trade first."
self.caller.msg(string % part_b.key)
@ -884,9 +865,7 @@ class CmdTrade(Command):
# initiate a new trade
TradeHandler(part_a, part_b)
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)
return
elif accept:
@ -894,8 +873,7 @@ class CmdTrade(Command):
if part_a.ndb.tradehandler:
# already in a trade
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
if part_b.ndb.tradehandler.join(part_a):
@ -910,9 +888,7 @@ class CmdTrade(Command):
# stopping an invite
part_a.ndb.tradehandler.finish(force=True)
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):
part_b.msg(theiremote + str_noinit_a % part_a.key)
part_a.msg(selfemote + str_noinit_b % part_b.key)

View file

@ -162,9 +162,7 @@ def _menu_savefunc(caller, buf):
def _menu_quitfunc(caller):
caller.cmdset.add(
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:
caller.ndb._building_menu.move(back=True)
@ -211,9 +209,7 @@ def _call_or_get(value, menu=None, choice=None, string=None, obj=None, caller=No
spec = getargspec(value)
args = spec.args
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:
if "menu" in args:
kwargs["menu"] = menu
@ -347,9 +343,7 @@ class CmdNoInput(Command):
self.menu.display()
else:
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)
@ -369,9 +363,7 @@ class CmdNoMatch(Command):
raw_string = self.args.rstrip()
if self.menu is None:
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)
return
@ -493,12 +485,7 @@ class Choice(object):
text = ""
if self.text:
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 = text.format(obj=self.obj, caller=self.caller)
@ -862,9 +849,7 @@ class BuildingMenu(object):
Current value: |c{{{obj_attr}}}|n
""".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(
@ -923,18 +908,10 @@ class BuildingMenu(object):
"""
on_enter = on_enter or menu_edit
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.
@ -998,9 +975,7 @@ class BuildingMenu(object):
menu_class = class_from_module(parent_class)
except Exception:
log_trace(
"BuildingMenu: attempting to load class {} failed".format(
repr(parent_class)
)
"BuildingMenu: attempting to load class {} failed".format(repr(parent_class))
)
return
@ -1011,9 +986,7 @@ class BuildingMenu(object):
)
except Exception:
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
else:
@ -1041,9 +1014,7 @@ class BuildingMenu(object):
"""
parent_keys = parent_keys or []
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):
self.caller.cmdset.remove(BuildingMenuCmdSet)
@ -1052,9 +1023,7 @@ class BuildingMenu(object):
menu_class = class_from_module(submenu_class)
except Exception:
log_trace(
"BuildingMenu: attempting to load class {} failed".format(
repr(submenu_class)
)
"BuildingMenu: attempting to load class {} failed".format(repr(submenu_class))
)
return
@ -1063,9 +1032,7 @@ class BuildingMenu(object):
building_menu = menu_class(self.caller, submenu_obj, parents=parents)
except Exception:
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
else:
@ -1101,9 +1068,7 @@ class BuildingMenu(object):
if not back: # Move forward
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)
else: # Move backward
@ -1134,9 +1099,9 @@ class BuildingMenu(object):
# Display methods. Override for customization
def display_title(self):
"""Return the menu title to be displayed."""
return _call_or_get(
self.title, menu=self, obj=self.obj, caller=self.caller
).format(obj=self.obj)
return _call_or_get(self.title, menu=self, obj=self.obj, caller=self.caller).format(
obj=self.obj
)
def display_choice(self, choice):
"""Display the specified choice.
@ -1152,24 +1117,13 @@ class BuildingMenu(object):
pos = clear_title.find(choice.key.lower())
ret = " "
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:
ret += "[|y" + choice.key.title() + "|n] " + title
if choice.glance:
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)
@ -1207,9 +1161,7 @@ class BuildingMenu(object):
if not class_name:
log_err(
"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
@ -1217,9 +1169,7 @@ class BuildingMenu(object):
menu_class = class_from_module(class_name)
except Exception:
log_trace(
"BuildingMenu: attempting to load class {} failed".format(
repr(class_name)
)
"BuildingMenu: attempting to load class {} failed".format(repr(class_name))
)
return
@ -1231,18 +1181,11 @@ class BuildingMenu(object):
persistent = menu.get("persistent", False)
try:
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:
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
@ -1313,9 +1256,7 @@ class GenericBuildingCmd(Command):
def func(self):
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
obj = self.caller.search(self.args.strip(), global_search=True)

View file

@ -79,9 +79,7 @@ class CmdOOCLook(default_cmds.CmdLook):
if self.args:
# Maybe the caller wants to look at a character
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
objs = managers.objects.get_objs_with_key_and_typeclass(
self.args.strip(), CHARACTER_TYPECLASS
@ -101,12 +99,8 @@ class CmdOOCLook(default_cmds.CmdLook):
charnames = [charobj.key for charobj in charobjs if charobj]
if charnames:
charlist = "The following Character(s) are available:\n\n"
charlist += "\n\r".join(
["|w %s|n" % charname for charname in charnames]
)
charlist += (
"\n\n Use |w@ic <character name>|n to switch to that Character."
)
charlist += "\n\r".join(["|w %s|n" % charname for charname in charnames])
charlist += "\n\n Use |w@ic <character name>|n to switch to that Character."
else:
charlist = "You have no Characters."
string = """ You, %s, are an |wOOC ghost|n without form. The world is hidden
@ -161,9 +155,7 @@ class CmdOOCCharacterCreate(Command):
self.caller.msg("Usage: create <character name>")
return
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:
self.caller.msg("Character |c%s|n already exists." % charname)
return

View file

@ -254,8 +254,7 @@ class Clothing(DefaultObject):
for garment in get_worn_clothes(wearer):
if (
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)
garment.db.covered_by = self
@ -395,18 +394,13 @@ class CmdWear(MuxCommand):
return
# 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.")
return
# Apply individual clothing type limits.
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 type_count >= CLOTHING_TYPE_LIMIT[clothing.db.clothing_type]:
self.caller.msg(
@ -420,9 +414,7 @@ class CmdWear(MuxCommand):
return
if len(self.arglist) > 1: # If wearstyle arguments given
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(
str(e) for e in wearstyle_list
) # Join list of args back into one string
@ -465,9 +457,7 @@ class CmdRemove(MuxCommand):
self.caller.msg("You're not wearing that!")
return
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
clothing.remove(self.caller)
@ -499,17 +489,13 @@ class CmdCover(MuxCommand):
if self.arglist[1].lower() == "with" and len(self.arglist) > 2:
del self.arglist[1]
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:
return
if not to_cover.is_typeclass("evennia.contrib.clothing.Clothing", exact=False):
self.caller.msg("%s isn't clothes!" % to_cover.name)
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)
return
if cover_with.db.clothing_type:
@ -527,8 +513,7 @@ class CmdCover(MuxCommand):
return
if to_cover.db.covered_by:
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
if not cover_with.db.worn:
@ -577,13 +562,9 @@ class CmdUncover(MuxCommand):
return
covered_by = to_uncover.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
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
@ -624,9 +605,7 @@ class CmdDrop(MuxCommand):
# This part is new!
# You can't drop clothing items that are covered.
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
# Remove clothes if they're dropped.
if obj.db.worn:
@ -634,9 +613,7 @@ class CmdDrop(MuxCommand):
obj.move_to(caller.location, quiet=True)
caller.msg("You drop %s." % (obj.name,))
caller.location.msg_contents(
"%s drops %s." % (caller.name, obj.name), exclude=caller
)
caller.location.msg_contents("%s drops %s." % (caller.name, obj.name), exclude=caller)
# Call the object script's at_drop() method.
obj.at_drop(caller)
@ -681,8 +658,7 @@ class CmdGive(MuxCommand):
# This is new! Can't give away something that's worn.
if to_give.db.covered_by:
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
# Remove clothes if they're given.

View file

@ -115,10 +115,7 @@ CURLY_COLOR_ANSI_EXTRA_MAP = [
(r"{-", _ANSI_TAB), # tab
(r"{_", _ANSI_SPACE), # space
(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"{r", _ANSI_HILITE + _ANSI_RED),
(r"{g", _ANSI_HILITE + _ANSI_GREEN),
@ -159,9 +156,7 @@ CURLY_COLOR_ANSI_EXTRA_MAP = [
]
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_GBG = [r"\{\[=([a-z])"] # |[=a - greyscale background
@ -220,9 +215,7 @@ 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_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_GBG = [r"%c\[=([a-z])"] # %c[=a - greyscale background

View file

@ -117,9 +117,7 @@ def gametime_to_realtime(format=False, **kwargs):
name = name[:-1]
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 /= TIMEFACTOR
if format:
@ -127,9 +125,7 @@ def gametime_to_realtime(format=False, **kwargs):
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
interval would correspond to. This is usually a lot less

View file

@ -177,9 +177,7 @@ class CmdDice(default_cmds.MuxCommand):
ndicelimit = 10000 # Maximum number of dice
nsidelimit = 10000 # Maximum number of sides
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
ndice, nsides = parts[0], parts[2]
@ -203,11 +201,7 @@ class CmdDice(default_cmds.MuxCommand):
# do the roll
try:
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:
self.caller.msg(
@ -217,9 +211,7 @@ class CmdDice(default_cmds.MuxCommand):
return
# format output
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:
rolls = rolls[0]
if outcome is None:

View file

@ -56,9 +56,7 @@ MULTISESSION_MODE = settings.MULTISESSION_MODE
CONNECTION_SCREEN_MODULE = settings.CONNECTION_SCREEN_MODULE
CONNECTION_SCREEN = ""
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:
# malformed connection screen or no screen given
pass
@ -178,24 +176,18 @@ class CmdUnconnectedCreate(MuxCommand):
try:
accountname, email, password = self.accountinfo
except ValueError:
string = (
'\n\r Usage (without <>): create "<accountname>" <email> <password>'
)
string = '\n\r Usage (without <>): create "<accountname>" <email> <password>'
session.msg(string)
return
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
if not utils.validate_email_address(email):
# check so the email at least looks ok.
session.msg("'%s' is not a valid e-mail address." % email)
return
# 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
# module (except not allowing spaces, for convenience of
# logging in).
@ -206,9 +198,7 @@ class CmdUnconnectedCreate(MuxCommand):
accountname = re.sub(r"\s+", " ", accountname).strip()
if AccountDB.objects.filter(username__iexact=accountname):
# account already exists (we also ignore capitalization here)
session.msg(
"Sorry, there is already an account with the name '%s'." % accountname
)
session.msg("Sorry, there is already an account with the name '%s'." % accountname)
return
if AccountDB.objects.get_account_from_email(email):
# email already set on an account
@ -261,7 +251,9 @@ class CmdUnconnectedCreate(MuxCommand):
# tell the caller everything went well.
string = "A new account '%s' was created. Welcome!"
if " " in accountname:
string += "\n\nYou can now log in with the command 'connect \"%s\" <your password>'."
string += (
"\n\nYou can now log in with the command 'connect \"%s\" <your password>'."
)
else:
string += "\n\nYou can now log with the command 'connect %s <your password>'."
session.msg(string % (accountname, email))
@ -270,9 +262,7 @@ class CmdUnconnectedCreate(MuxCommand):
# We are in the middle between logged in and -not, so we have
# to handle tracebacks ourselves at this point. If we don't,
# 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()
raise

View file

@ -234,9 +234,7 @@ class CmdGiveUp(CmdEvscapeRoom):
self.room.log(f"QUIT: {self.caller.key} used the quit command")
# 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.caller.move_to(self.caller.home, quiet=True, move_hooks=False)
@ -315,9 +313,7 @@ class CmdWho(CmdEvscapeRoom, default_cmds.CmdWho):
for obj in self.room.get_all_characters()
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}"
caller.msg(txt)
@ -393,9 +389,7 @@ class CmdEmote(Command):
emote = self.args.strip()
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
speech_clr = "|c"
@ -435,9 +429,7 @@ class CmdEmote(Command):
if target == self.caller:
txt = [f"{self_clr}{self.caller.get_display_name(target)}|n "] + txt
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 "")
if not logged and hasattr(self.caller.location, "log"):
self.caller.location.log(f"emote: {txt}")
@ -539,10 +531,7 @@ class CmdRerouter(default_cmds.MuxCommand):
from evennia.commands import 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
)
@ -614,9 +603,7 @@ class CmdStand(CmdEvscapeRoom):
obj, position = pos
self.caller.attributes.remove("position", category=self.room.tagcategory)
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:
self.caller.msg("You are already standing.")
@ -692,9 +679,7 @@ class CmdCreateObj(CmdEvscapeRoom):
else:
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}).")

View file

@ -151,9 +151,7 @@ def node_set_desc(caller, raw_string, **kwargs):
current_desc = kwargs.get("desc", caller.db.desc)
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):
@ -171,10 +169,7 @@ def node_set_desc(caller, raw_string, **kwargs):
options = (
{"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"},
)
return text, options
@ -185,10 +180,7 @@ def node_create_room(caller, raw_string, **kwargs):
text = _CREATE_ROOM_TEXT
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"},
)
@ -229,10 +221,7 @@ def node_quit(caller, raw_string, **kwargs):
from evennia import default_cmds
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
@ -259,9 +248,7 @@ class EvscaperoomMenu(EvMenu):
main_options.append(key)
main_options = " | ".join(main_options)
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
@ -278,9 +265,7 @@ def run_evscaperoom_menu(caller):
"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)
# ------------------------------------------------------------
@ -300,9 +285,7 @@ def _toggle_screen_reader(caller, raw_string, **kwargs):
session = kwargs["session"]
# 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
session.sessionhandler.session_portal_sync(session)
return None, kwargs # rerun node

View file

@ -64,12 +64,7 @@ class EvscaperoomObject(DefaultObject):
# this mapping allows for prettier descriptions of our current
# 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):
"""
@ -166,9 +161,7 @@ class EvscaperoomObject(DefaultObject):
you = caller.key if caller else "they"
first_person, third_person = parse_for_perspectives(string, you=you)
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)
if char == caller:
if not skip_caller:
@ -185,9 +178,7 @@ class EvscaperoomObject(DefaultObject):
"""
# we must clean away markers
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)
txt = parse_for_things(first_person, things_style=style)
caller.msg((txt, {"type": client_type}))
@ -285,9 +276,7 @@ class EvscaperoomObject(DefaultObject):
"""
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
@ -318,8 +307,7 @@ class EvscaperoomObject(DefaultObject):
helpstr = f"It looks like {self.key} may be " "suitable to {callsigns}."
else:
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
@ -342,14 +330,10 @@ class EvscaperoomObject(DefaultObject):
# custom-created signatures. We don't sort these
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)
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)
helpstr = helpstr.format(callsigns=callsigns)
@ -537,11 +521,7 @@ class IndexReadable(Readable):
"""
# 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):
@ -820,8 +800,7 @@ class Combinable(BaseApplicable):
new_obj = create_evscaperoom_object(**create_dict)
if new_obj and self.destroy_components:
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()
self.delete()
@ -1041,8 +1020,7 @@ class BasePositionable(EvscaperoomObject):
def at_again_position(self, caller, position):
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):

View file

@ -102,9 +102,7 @@ class EvscapeRoom(EvscaperoomObject, DefaultRoom):
if achievement not in achievements:
self.log(f"achievement: {caller} earned '{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):
"""
@ -226,8 +224,7 @@ class EvscapeRoom(EvscaperoomObject, DefaultRoom):
def return_appearance(self, looker, **kwargs):
obj, pos = self.get_position(looker)
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
else ""
)
@ -235,9 +232,7 @@ class EvscapeRoom(EvscaperoomObject, DefaultRoom):
admin_only = ""
if self.check_perm(looker, "Admin"):
# 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(
[obj.get_display_name(looker) for obj in objs]
)

View file

@ -58,9 +58,7 @@ class StateHandler(object):
except Exception as err:
logger.log_trace()
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
state = mod.State(self, self.room)
@ -204,9 +202,7 @@ class BaseState(object):
if cinematic:
message = msg_cinematic(message, borders=borders)
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)
# we assume this is a char
target.msg(parse_for_things(message, things_style=style))

View file

@ -117,9 +117,7 @@ class HelpButton(objects.EvscaperoomObject):
self.msg_char(caller, "There are no more hints to be had.")
else:
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'
)

View file

@ -18,9 +18,7 @@ from . import utils
class TestEvscaperoomCommands(CommandTest):
def setUp(self):
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.obj1.location = self.room1
@ -153,24 +151,19 @@ class TestEvscaperoomCommands(CommandTest):
cmd.room = self.room1
cmd.focus = self.obj1
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):
# don't focus on a non-room object
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
myobj = utils.create_evscaperoom_object(
objects.EvscaperoomObject, "mytestobj", location=self.room1
)
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):
self.call(commands.CmdLook(), "at obj", "Obj")
@ -180,19 +173,13 @@ class TestEvscaperoomCommands(CommandTest):
def test_speech(self):
self.call(commands.CmdSpeak(), "", "What do you want to say?", 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(), "HELLO!", "You shout: HELLO!", cmdstring="shout")
self.call(
commands.CmdSpeak(), "Hello to obj", "You say: Hello", cmdstring="say"
)
self.call(
commands.CmdSpeak(), "Hello to obj", "You shout: Hello", cmdstring="shout"
)
self.call(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):
self.call(
@ -207,9 +194,7 @@ class TestEvscaperoomCommands(CommandTest):
class TestUtils(EvenniaTest):
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(
objects.EvscaperoomObject, key="testobj", location=room
)
@ -227,15 +212,11 @@ class TestUtils(EvenniaTest):
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(third, "TestGuy looks at the nice book")
# 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(third, "With a smile, TestGuy was gone")
@ -243,12 +224,8 @@ class TestUtils(EvenniaTest):
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, 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."
)
self.assertEqual(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):
@ -271,14 +248,10 @@ class TestEvScapeRoom(EvenniaTest):
self.assertEqual(list(room.get_all_characters()), [self.char1])
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")
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)
self.assertEqual(self.char1.tags.get(category=self.roomtag), None)

View file

@ -94,9 +94,7 @@ from evennia import utils
from evennia import CmdSet
# 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
RE_MORNING = re.compile(r"<morning>(.*?)</morning>", re.IGNORECASE)
@ -446,12 +444,7 @@ class CmdExtendedRoomDesc(default_cmds.CmdDesc):
string += " |wgeneral:|n %s" % location.db.general_desc
caller.msg(string)
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
if self.rhs:
caller.msg("Seasonal descs only work with rooms, not objects.")
@ -526,13 +519,9 @@ class CmdExtendedRoomDetail(default_cmds.MuxCommand):
if not self.args:
details = location.db.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:
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))
return

View file

@ -278,11 +278,7 @@ def menunode_fieldfill(caller, raw_string, **kwargs):
# Display current form data
text = (
display_formdata(
formtemplate,
formdata,
pretext=pretext,
posttext=posttext,
borderstyle=borderstyle,
formtemplate, formdata, pretext=pretext, posttext=posttext, borderstyle=borderstyle
),
formhelptext,
)
@ -296,10 +292,7 @@ def menunode_fieldfill(caller, raw_string, **kwargs):
for field in formtemplate:
if "required" in field.keys():
# 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
blank_and_required.append(field["fieldname"])
if len(blank_and_required) > 0:
@ -435,30 +428,22 @@ def menunode_fieldfill(caller, raw_string, **kwargs):
# Test for max/min
if max_value is not None:
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)
return text, options
if min_value is not None:
if newvalue < min_value:
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)
return text, options
# Field type bool verification
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(
"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)
return text, options
@ -524,9 +509,7 @@ def form_template_to_dict(formtemplate):
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.
@ -677,7 +660,9 @@ class CmdTestMenu(Command):
"""
This performs the actual command.
"""
pretext = "|cSend a delayed message to another player ---------------------------------------|n"
pretext = (
"|cSend a delayed message to another player ---------------------------------------|n"
)
posttext = (
"|c--------------------------------------------------------------------------------|n|/"
"Syntax: type |c<field> = <new value>|n to change the values of the form. Given|/"

View file

@ -101,12 +101,7 @@ class CallbackHandler(object):
if handler:
return self.format_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
)
)

View file

@ -136,9 +136,7 @@ class CmdCallback(COMMAND_DEFAULT_CLASS):
self.is_validator = validator
self.autovalid = autovalid
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
# Before the equal sign, there is an object name or nothing
@ -166,9 +164,7 @@ class CmdCallback(COMMAND_DEFAULT_CLASS):
elif switch in ["tasks", "task"]:
self.list_tasks()
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):
"""Display the list of callbacks connected to the object."""
@ -182,9 +178,7 @@ class CmdCallback(COMMAND_DEFAULT_CLASS):
# Check that the callback name can be found in this object
created = callbacks.get(callback_name)
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
if parameters:
@ -208,15 +202,11 @@ class CmdCallback(COMMAND_DEFAULT_CLASS):
updated_by = updated_by.key if updated_by else "|gUnknown|n"
created_on = callback.get("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 = (
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 += "\nCreated by {} on {}.".format(author, created_on)
@ -264,17 +254,13 @@ class CmdCallback(COMMAND_DEFAULT_CLASS):
self.msg(str(table))
else:
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(1, width=10, align="r")
table.reformat_column(2, width=48)
for name in sorted(names):
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)
description = types.get(name, (None, "Chained event."))[1]
description = description.strip("\n").splitlines()[0]
@ -335,9 +321,7 @@ class CmdCallback(COMMAND_DEFAULT_CLASS):
# Check that the callback exists
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
# If there's only one callback, just edit it
@ -409,9 +393,7 @@ class CmdCallback(COMMAND_DEFAULT_CLASS):
# Check that the callback exists
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
# If there's only one callback, just delete it
@ -450,11 +432,7 @@ class CmdCallback(COMMAND_DEFAULT_CLASS):
# Delete the callback
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):
"""Accept a callback."""
@ -464,9 +442,7 @@ class CmdCallback(COMMAND_DEFAULT_CLASS):
# If no object, display the list of callbacks to be checked
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")
now = datetime.now()
for obj, name, number in self.handler.db.to_valid:
@ -508,9 +484,7 @@ class CmdCallback(COMMAND_DEFAULT_CLASS):
# Check that the callback exists
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
if not parameters:
@ -525,9 +499,7 @@ class CmdCallback(COMMAND_DEFAULT_CLASS):
callback = callbacks[callback_name][number]
except (ValueError, AssertionError, IndexError):
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
@ -537,9 +509,7 @@ class CmdCallback(COMMAND_DEFAULT_CLASS):
else:
self.handler.accept_callback(obj, callback_name, number)
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):
@ -587,17 +557,10 @@ def _ev_save(caller, buf):
return False
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(
callback["obj"],
callback["name"],
callback["number"],
buf,
caller,
valid=autovalid,
callback["obj"], callback["name"], callback["number"], buf, caller, valid=autovalid
)
return True
@ -614,9 +577,7 @@ def _ev_quit(caller):
return False
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
caller.msg("Exited the code editor.")

View file

@ -64,17 +64,13 @@ class EventHandler(DefaultScript):
"""
self.ndb.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
self.ndb.current_locals = {}
self.ndb.fresh_locals = {}
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:
if pypath_to_realpath(address):
self.ndb.fresh_locals.update(all_from_module(address))
@ -208,9 +204,7 @@ class EventHandler(DefaultScript):
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.
@ -252,9 +246,7 @@ class EventHandler(DefaultScript):
self.db.to_valid.append((obj, callback_name, len(callbacks) - 1))
# 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:
custom_add(obj, callback_name, len(callbacks) - 1, parameters)
@ -300,12 +292,7 @@ class EventHandler(DefaultScript):
# Edit the callback
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'
@ -348,9 +335,7 @@ class EventHandler(DefaultScript):
return
else:
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]
@ -431,8 +416,7 @@ class EventHandler(DefaultScript):
allowed = ("number", "parameters", "locals")
if any(k for k in kwargs if k not in allowed):
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)
@ -452,9 +436,7 @@ class EventHandler(DefaultScript):
except IndexError:
logger.log_trace(
"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
else:
@ -507,9 +489,7 @@ class EventHandler(DefaultScript):
oid = obj.id
logger.log_err(
"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
@ -542,11 +522,8 @@ class EventHandler(DefaultScript):
if updater and updater.sessions.all():
updater.msg(err_msg)
else:
err_msg = (
"Error in {} of {} (#{})[{}], line {}:"
" {}\n {}".format(
callback_name, obj, oid, number + 1, lineno, line, exc
)
err_msg = "Error in {} of {} (#{})[{}], line {}:" " {}\n {}".format(
callback_name, obj, oid, number + 1, lineno, line, exc
)
self.ndb.channel.msg(err_msg)
@ -684,9 +661,7 @@ def complete_task(task_id):
return
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
delta, obj, callback_name, locals = script.db.tasks.pop(task_id)

View file

@ -31,21 +31,15 @@ class TestEventHandler(EvenniaTest):
def setUp(self):
"""Create the event handler."""
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
if OLD_EVENTS:
self.handler.ndb.events = dict(OLD_EVENTS)
# Alter typeclasses
self.char1.swap_typeclass(
"evennia.contrib.ingame_python.typeclasses.EventCharacter"
)
self.char2.swap_typeclass(
"evennia.contrib.ingame_python.typeclasses.EventCharacter"
)
self.char1.swap_typeclass("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.room2.swap_typeclass("evennia.contrib.ingame_python.typeclasses.EventRoom")
self.exit.swap_typeclass("evennia.contrib.ingame_python.typeclasses.EventExit")
@ -70,11 +64,7 @@ class TestEventHandler(EvenniaTest):
"""Add a callback while needing validation."""
author = self.char1
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 = callback[0]
@ -100,12 +90,7 @@ class TestEventHandler(EvenniaTest):
# Edit it right away
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
@ -131,12 +116,7 @@ class TestEventHandler(EvenniaTest):
# Edit it right away
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)
@ -149,25 +129,13 @@ class TestEventHandler(EvenniaTest):
"""Try to delete a callback."""
# Add 3 callbacks
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.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.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
@ -203,18 +171,10 @@ class TestEventHandler(EvenniaTest):
"""Accept an callback."""
# Add 2 callbacks
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.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
@ -249,18 +209,12 @@ class TestEventHandler(EvenniaTest):
"\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
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.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)
def test_handler(self):
@ -268,9 +222,7 @@ class TestEventHandler(EvenniaTest):
self.assertIsNotNone(self.char1.callbacks)
# 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.name, "dummy")
self.assertEqual(callback.code, "pass")
@ -286,9 +238,7 @@ class TestEventHandler(EvenniaTest):
self.assertNotIn([callback], list(self.room1.callbacks.all().values()))
# 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)
# Delete the callback
@ -303,21 +253,15 @@ class TestCmdCallback(CommandTest):
def setUp(self):
"""Create the callback handler."""
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
if OLD_EVENTS:
self.handler.ndb.events = dict(OLD_EVENTS)
# Alter typeclasses
self.char1.swap_typeclass(
"evennia.contrib.ingame_python.typeclasses.EventCharacter"
)
self.char2.swap_typeclass(
"evennia.contrib.ingame_python.typeclasses.EventCharacter"
)
self.char1.swap_typeclass("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.room2.swap_typeclass("evennia.contrib.ingame_python.typeclasses.EventRoom")
self.exit.swap_typeclass("evennia.contrib.ingame_python.typeclasses.EventExit")
@ -347,9 +291,7 @@ class TestCmdCallback(CommandTest):
self.assertIn(cols[2].strip(), ("0 (0)", ""))
# 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
table = self.call(CmdCallback(), "out = traverse")
@ -428,22 +370,16 @@ class TestCmdCallback(CommandTest):
def test_del(self):
"""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
# char2 shouldn't be allowed to do so (that's not HIS callback)
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
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):
"""Test the lock of multiple editing."""
@ -496,21 +432,15 @@ class TestDefaultCallbacks(CommandTest):
def setUp(self):
"""Create the callback handler."""
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
if OLD_EVENTS:
self.handler.ndb.events = dict(OLD_EVENTS)
# Alter typeclasses
self.char1.swap_typeclass(
"evennia.contrib.ingame_python.typeclasses.EventCharacter"
)
self.char2.swap_typeclass(
"evennia.contrib.ingame_python.typeclasses.EventCharacter"
)
self.char1.swap_typeclass("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.room2.swap_typeclass("evennia.contrib.ingame_python.typeclasses.EventRoom")
self.exit.swap_typeclass("evennia.contrib.ingame_python.typeclasses.EventExit")
@ -541,28 +471,20 @@ class TestDefaultCallbacks(CommandTest):
self.exit.destination = self.room2
# 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
self.call(ExitCommand(), "", "You can leave.", obj=self.exit)
self.assertIs(self.char1.location, self.room2)
# 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)
# Try the traverse callback
self.handler.del_callback(self.exit, "can_traverse", 0)
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
@ -576,9 +498,7 @@ class TestDefaultCallbacks(CommandTest):
# Test msg_arrive and msg_leave
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
old_msg = self.char2.msg
@ -586,15 +506,11 @@ class TestDefaultCallbacks(CommandTest):
self.char2.msg = Mock()
self.call(ExitCommand(), "", obj=self.exit)
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
]
# 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)
self.assertEqual(returned_msg, "char1 goes out.")
finally:
@ -608,9 +524,7 @@ class TestDefaultCallbacks(CommandTest):
destination=self.room1,
)
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
old_msg = self.char2.msg
@ -618,15 +532,11 @@ class TestDefaultCallbacks(CommandTest):
self.char2.msg = Mock()
self.call(ExitCommand(), "", obj=back)
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
]
# 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)
self.assertEqual(returned_msg, "char1 goes in.")
finally:

View file

@ -11,11 +11,7 @@ from evennia import DefaultCharacter, DefaultExit, DefaultObject, DefaultRoom
from evennia import ScriptDB
from evennia.utils.utils import delay, inherits_from, lazy_property
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_CAN_DELETE = """
@ -174,11 +170,7 @@ class EventCharacter(DefaultCharacter):
"can_delete": (["character"], CHARACTER_CAN_DELETE),
"can_move": (["character", "origin", "destination"], CHARACTER_CAN_MOVE),
"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),
"greet": (["character", "newcomer"], CHARACTER_GREET),
"move": (["character", "origin", "destination"], CHARACTER_MOVE),
@ -221,9 +213,7 @@ class EventCharacter(DefaultCharacter):
# Get the exit from location to destination
location = self.location
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.update({"character": self})
@ -265,9 +255,7 @@ class EventCharacter(DefaultCharacter):
if not source_location and self.location.has_account:
# This was created from nowhere and added to an account's
# 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)
return
@ -363,9 +351,7 @@ class EventCharacter(DefaultCharacter):
# Call the 'greet' event of characters in the location
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)
@ -450,14 +436,11 @@ class EventCharacter(DefaultCharacter):
location = getattr(self, "location", None)
location = (
location
if location
and inherits_from(location, "evennia.objects.objects.DefaultRoom")
if location and inherits_from(location, "evennia.objects.objects.DefaultRoom")
else None
)
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")
if not allow or not message:
return
@ -469,9 +452,7 @@ class EventCharacter(DefaultCharacter):
):
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")
if not allow or not message:
return
@ -524,8 +505,7 @@ class EventCharacter(DefaultCharacter):
location = getattr(self, "location", None)
location = (
location
if location
and inherits_from(location, "evennia.objects.objects.DefaultRoom")
if location and inherits_from(location, "evennia.objects.objects.DefaultRoom")
else None
)
@ -540,9 +520,7 @@ class EventCharacter(DefaultCharacter):
and inherits_from(obj, "evennia.objects.objects.DefaultCharacter")
]
for present in presents:
present.callbacks.call(
"say", self, present, message, parameters=message
)
present.callbacks.call("say", self, present, message, parameters=message)
# Exit help
@ -679,9 +657,7 @@ class EventExit(DefaultExit):
"""
is_character = inherits_from(traversing_object, DefaultCharacter)
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:
return

View file

@ -79,13 +79,9 @@ def register_events(path_or_typeclass):
variables = help_text = custom_call = custom_add = None
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:
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
@ -143,8 +139,7 @@ def get_next_wait(format):
if not piece.isdigit():
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
@ -181,9 +176,7 @@ def time_event(obj, event_name, number, parameters):
"""
seconds, usual, key = get_next_wait(parameters)
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.desc = "event on {}".format(key)

View file

@ -126,13 +126,9 @@ class CmdMail(default_cmds.MuxAccountCommand):
"""
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:
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):
"""
@ -181,9 +177,7 @@ class CmdMail(default_cmds.MuxAccountCommand):
mind = max(0, min(mind_max, int(self.lhs) - 1))
if 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)
# handle not ret, it will be None during unit testing
if not ret or ret.strip().upper() not in ("N", "No"):
@ -201,8 +195,7 @@ class CmdMail(default_cmds.MuxAccountCommand):
try:
if not self.rhs:
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
elif not self.lhs:
@ -236,8 +229,7 @@ class CmdMail(default_cmds.MuxAccountCommand):
self.send_mail(
self.search_targets(self.lhslist),
"FWD: " + old_message.header,
"\n---- Original Message ----\n"
+ old_message.message,
"\n---- Original Message ----\n" + old_message.message,
self.caller,
)
self.caller.msg("Message forwarded.")
@ -248,9 +240,7 @@ class CmdMail(default_cmds.MuxAccountCommand):
except IndexError:
self.caller.msg("Message does not exist.")
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:
try:
if not self.rhs:
@ -268,9 +258,7 @@ class CmdMail(default_cmds.MuxAccountCommand):
self.send_mail(
old_message.senders,
"RE: " + old_message.header,
self.rhs
+ "\n---- Original Message ----\n"
+ old_message.message,
self.rhs + "\n---- Original Message ----\n" + old_message.message,
self.caller,
)
old_message.tags.remove("new", category="mail")
@ -289,9 +277,7 @@ class CmdMail(default_cmds.MuxAccountCommand):
subject, body = self.rhs.split("/", 1)
else:
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:
all_mail = self.get_all_mail()
mind_max = max(0, all_mail.count() - 1)
@ -306,16 +292,13 @@ class CmdMail(default_cmds.MuxAccountCommand):
if message:
messageForm.append(_HEAD_CHAR * _WIDTH)
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
day = message.db_date_created.day
messageForm.append(
"|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(_SUB_HEAD_CHAR * _WIDTH)

View file

@ -237,19 +237,11 @@ def example2_build_verticle_exit(x, y, **kwargs):
# create exits in the rooms
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(
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)
@ -264,13 +256,9 @@ def example2_build_horizontal_exit(x, y, **kwargs):
west_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)
@ -340,11 +328,7 @@ def build_map(caller, game_map, legend, iterations=1, build_exits=True):
# obs - we must use == for strings
if game_map[y][x] == 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:
room_dict[(x, y)] = room
@ -448,10 +432,7 @@ class CmdMapBuilder(COMMAND_DEFAULT_CLASS):
# Check if arguments passed.
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
# Set up base variables.

View file

@ -24,11 +24,7 @@ from django.conf import settings
from evennia import Command, CmdSet
from evennia import syscmdkeys
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
_GUEST_ENABLED = settings.GUEST_ENABLED
@ -36,8 +32,7 @@ _ACCOUNT = class_from_module(settings.BASE_ACCOUNT_TYPECLASS)
_GUEST = class_from_module(settings.BASE_GUEST_TYPECLASS)
_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 should be a minimum of 8 characters (preferably longer) and "
@ -111,10 +106,7 @@ def node_enter_username(caller, raw_text, **kwargs):
options = (
{"key": "", "goto": "node_enter_username"},
{"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},
)
return text, options
@ -158,9 +150,7 @@ def node_enter_password(caller, raw_string, **kwargs):
if account:
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
return "node_quit_or_login", {"login": True, "account": account}
else:
@ -180,21 +170,15 @@ def node_enter_password(caller, raw_string, **kwargs):
# Attempting to fix password
text = "Enter a new password:"
else:
text = (
"Creating a new account |c{}|n. "
"Enter a password (empty to abort):".format(username)
text = "Creating a new account |c{}|n. " "Enter a password (empty to abort):".format(
username
)
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 = (
{"key": "", "goto": _restart_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)},
)
return text, options

View file

@ -71,11 +71,7 @@ def _update_store(caller, key=None, desc=None, delete=False, swapkey=None):
elif swapkey:
# swap positions
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:
iswap = swapmatch[0]
if idesc == iswap:
@ -175,8 +171,7 @@ class CmdMultiDesc(default_cmds.MuxCommand):
do_crop = "full" not in switches
if do_crop:
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:
outtext = [
@ -245,9 +240,7 @@ class CmdMultiDesc(default_cmds.MuxCommand):
new_desc.append(key)
new_desc = "".join(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:
# add text directly to a new entry or an existing one.

View file

@ -86,9 +86,7 @@ _PUZZLES_TAG_RECIPE = "puzzle_recipe"
# puzzle part and puzzle result
_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_LOCATION_MESSAGE = "|c{caller}|n performs some kind of tribal dance and |y{result_names}|n seems to appear from thin air"
@ -142,9 +140,7 @@ def _colorize_message(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)
# ------------------------------------------
@ -161,9 +157,7 @@ class PuzzleRecipe(DefaultScript):
self.db.mask = tuple()
self.tags.add(_PUZZLES_TAG_RECIPE, category=_PUZZLES_TAG_CATEGORY)
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):
@ -307,9 +301,7 @@ class CmdCreatePuzzleRecipe(MuxCommand):
caller.msg(
"You may now dispose of all parts and results. \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)
)
@ -372,9 +364,7 @@ class CmdEditPuzzle(MuxCommand):
puzzle_name_id = "%s(%s)" % (puzzle.name, puzzle.dbref)
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)
return
@ -656,9 +646,7 @@ class CmdUsePuzzleParts(MuxCommand):
# Create lookup dict of puzzles by dbref
puzzles_dict = dict((puzzle.dbref, puzzle) for puzzle in puzzles)
# 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:
# TODO: we could use part.fail_message instead, if there was one
@ -667,9 +655,7 @@ class CmdUsePuzzleParts(MuxCommand):
caller.msg(_PUZZLE_DEFAULT_FAIL_USE_MESSAGE % (many))
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))
@ -677,9 +663,7 @@ class CmdUsePuzzleParts(MuxCommand):
puzzledbref, matched_dbrefparts = puzzletuples[0]
nparts = len(matched_dbrefparts)
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.
# we could show the names of all those that can be resolved
@ -710,9 +694,7 @@ class CmdUsePuzzleParts(MuxCommand):
result_names = ", ".join(result_names)
caller.msg(puzzle.db.use_success_message)
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,),
)
@ -732,25 +714,17 @@ class CmdListPuzzleRecipes(MuxCommand):
def func(self):
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
text = [div]
msgf_recipe = "Puzzle |y'%s' %s(%s)|n"
msgf_item = "%2s|c%15s|n: |w%s|n"
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(
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"
"Success Location message:\n" + recipe.db.use_success_location_message + "\n"
)
text.append("Mask:\n" + str(recipe.db.mask) + "\n")
text.append("Parts")
@ -787,13 +761,10 @@ class CmdListArmedPuzzles(MuxCommand):
def func(self):
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(
(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
@ -804,8 +775,7 @@ class CmdListArmedPuzzles(MuxCommand):
text.append(msgf_pznm % (pzname))
for item in items:
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:
text.append(div)

View file

@ -168,9 +168,7 @@ class RandomStringGenerator(object):
try:
script = ScriptDB.objects.get(db_key="generator_script")
except ScriptDB.DoesNotExist:
script = create_script(
"contrib.random_string_generator.RandomStringGeneratorScript"
)
script = create_script("contrib.random_string_generator.RandomStringGeneratorScript")
type(self).script = script
return script
@ -202,9 +200,7 @@ class RandomStringGenerator(object):
# Either the beginning or end, we ignore it
continue
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":
desc["min"] = element[1][0]
desc["max"] = element[1][1]

View file

@ -112,9 +112,7 @@ _VOWELS = "eaoiuy"
# 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
# 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_GRAMMAR = re.compile(r"vv|cc|v|c", _RE_FLAGS)
@ -248,9 +246,7 @@ class LanguageHandler(DefaultScript):
grammar2phonemes = defaultdict(list)
for phoneme in phonemes.split():
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])
grammar2phonemes[gram].append(phoneme)
@ -276,9 +272,7 @@ class LanguageHandler(DefaultScript):
word = word.strip()
lword = len(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:
# always create a translation, use random length
structure = choice(grammar[choice(list(grammar))])
@ -292,10 +286,7 @@ class LanguageHandler(DefaultScript):
if manual_translations:
# update with manual translations
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
@ -347,10 +338,7 @@ class LanguageHandler(DefaultScript):
wlen = max(
0,
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"]
if wlen not in grammar:
@ -380,9 +368,7 @@ class LanguageHandler(DefaultScript):
if word.istitle():
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)
title_word = word
elif new_word:
@ -525,9 +511,7 @@ _RE_WHISPER_OBSCURE = [
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"[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-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

View file

@ -137,9 +137,7 @@ _RE_PREFIX = re.compile(r"^%s" % _PREFIX, re.UNICODE)
# separate multimatches from one another and word is the first word in the
# marker. So entering "/tall man" will return groups ("", "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_RIGHT_BRACKETS = re.compile(r"\}+", _RE_FLAGS)
@ -234,8 +232,7 @@ def ordered_permutation_regex(sentence):
if comb:
solution.append(
_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
@ -261,10 +258,7 @@ def regex_tuple_from_key_alias(obj):
"""
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.key,
)
@ -366,11 +360,7 @@ def parse_sdescs_and_recogs(sender, candidates, string, search_mode=False):
"""
# Load all candidate regex tuples [(regex, obj, sdesc/recog),...]
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]
if hasattr(sender, "recog")
@ -405,28 +395,19 @@ def parse_sdescs_and_recogs(sender, candidates, string, search_mode=False):
# start index forward for all candidates.
# 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()
istart = istart0
# 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
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)
# 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)
if not nmatches:
@ -445,11 +426,7 @@ def parse_sdescs_and_recogs(sender, candidates, string, search_mode=False):
else:
# 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:
# A valid inum is given. Use this to separate data.
obj = bestmatches[inum][0]
@ -571,8 +548,7 @@ def send_emote(sender, receivers, emote, anonymous_add="first"):
try:
recog_get = receiver.recog.get
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:
receiver_sdesc_mapping = dict(
@ -656,9 +632,7 @@ class SdescHandler(object):
r"\1",
_RE_REF_LANG.sub(
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))),
),
)
@ -740,9 +714,7 @@ class RecogHandler(object):
obj2regex = self.obj.attributes.get("_recog_obj2regex", default={})
obj2recog = self.obj.attributes.get("_recog_obj2recog", default={})
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)
@ -774,9 +746,7 @@ class RecogHandler(object):
r"\1",
_RE_REF_LANG.sub(
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))),
),
)
@ -823,9 +793,7 @@ class RecogHandler(object):
# check an eventual recog_masked lock on the object
# to avoid revealing masked characters. If lock
# 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:
# recog_mask log not passed, disable recog
return obj.sdesc.get() if hasattr(obj, "sdesc") else obj.key
@ -1052,9 +1020,7 @@ class CmdPose(RPCommand): # set current pose and default pose
return
else:
# 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(
(ref, obj.sdesc.get() if hasattr(obj, "sdesc") else obj.key)
for ref, obj in mapping.items()
@ -1093,15 +1059,11 @@ class CmdRecog(RPCommand): # assign personal alias to object in room
def parse(self):
"Parse for the sdesc as alias structure"
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:
# try to split by space instead
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:
self.sdesc, self.alias = self.args.strip(), ""
@ -1115,9 +1077,7 @@ class CmdRecog(RPCommand): # assign personal alias to object in room
alias = self.alias.rstrip(".?!")
prefixed_sdesc = sdesc if sdesc.startswith(_PREFIX) else _PREFIX + sdesc
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)
# handle 0, 1 and >1 matches
if nmatches == 0:
@ -1134,11 +1094,7 @@ class CmdRecog(RPCommand): # assign personal alias to object in room
)
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:
obj = matches[0]
if not obj.access(self.obj, "enable_recog", default=True):
@ -1148,9 +1104,7 @@ class CmdRecog(RPCommand): # assign personal alias to object in room
if self.cmdstring == "forget":
# remove existing recog
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:
sdesc = obj.sdesc.get() if hasattr(obj, "sdesc") else obj.key
try:
@ -1158,10 +1112,7 @@ class CmdRecog(RPCommand): # assign personal alias to object in room
except RecogError as err:
caller.msg(err)
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):
@ -1398,9 +1349,7 @@ class ContribRPObject(DefaultObject):
# in eventual error reporting later (not their keys). Doing
# it like this e.g. allows for use of the typeclass kwarg
# 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:
# builders get a chance to search only by key+alias
@ -1465,9 +1414,7 @@ class ContribRPObject(DefaultObject):
if not looker:
return ""
# 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 = [], [], []
for con in visible:
key = con.get_display_name(looker, pose=True)

View file

@ -26,9 +26,7 @@ AUDIT_MASKS = [
{"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+(?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"^.* has changed your password to '(?P<secret>[^']+)'\."},
{"password": r"^[@\s]*[password]{6,9}\s+(?P<secret>.*)"},
@ -38,8 +36,7 @@ AUDIT_MASKS = [
if AUDIT_CALLBACK:
try:
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(
@ -185,9 +182,7 @@ class AuditedServerSession(ServerSession):
# Check to see if the command is embedded within server output
_msg = msg
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:
msg = match.group(1).replace("\\", "")
submsg = msg
@ -208,10 +203,7 @@ class AuditedServerSession(ServerSession):
if is_embedded:
msg = re.sub(
submsg,
"%s <Masked: %s>" % (masked, command),
_msg,
flags=re.IGNORECASE,
submsg, "%s <Masked: %s>" % (masked, command), _msg, flags=re.IGNORECASE
)
else:
msg = masked

View file

@ -15,9 +15,7 @@ settings.AUDIT_OUT = True
settings.AUDIT_ALLOW_SPARSE = True
# 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):
@ -57,28 +55,13 @@ class AuditingTest(EvenniaTest):
("connect johnny password123", "connect johnny ***********"),
("concnct johnny password123", "concnct johnny ***********"),
("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 **************"),
("create johnny password123", "create johnny ***********"),
(
"@password password1234 = password2345",
"@password ***************************",
),
(
"@password password1234 password2345",
"@password *************************",
),
(
"@passwd password1234 = password2345",
"@passwd ***************************",
),
(
"@userpassword johnny = password234",
"@userpassword johnny = ***********",
),
("@password password1234 = password2345", "@password ***************************"),
("@password password1234 password2345", "@password *************************"),
("@passwd password1234 = password2345", "@passwd ***************************"),
("@userpassword johnny = password234", "@userpassword johnny = ***********"),
("craete johnnypassword123", "craete *****************"),
(
"Command 'conncect teddy teddy' is not available. Maybe you meant \"@encode\"?",
@ -91,9 +74,7 @@ class AuditingTest(EvenniaTest):
)
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
secrets = [
@ -112,9 +93,7 @@ class AuditingTest(EvenniaTest):
"""
log = self.session.audit(src="client", text=[["hello"]])
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(
obj,
@ -128,10 +107,7 @@ class AuditingTest(EvenniaTest):
# Make sure OOB data is being recorded
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["data"]["prompt"], "hp=20|st=10|ma=15")

View file

@ -97,19 +97,13 @@ class CmdOpen(default_cmds.CmdOpen):
__doc__ = default_cmds.CmdOpen.__doc__
# 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
"""
# create a new exit as normal
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"):
# we don't create a return exit if it was already created (because
@ -124,11 +118,7 @@ class CmdOpen(default_cmds.CmdOpen):
)
self.return_exit_already_created = True
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
back_exit.db.return_exit = new_exit

View file

@ -81,12 +81,7 @@ class SlowExit(DefaultExit):
# 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):

View file

@ -30,10 +30,7 @@ def menu_start_node(caller):
text = "'Hello there, how can I help you?'"
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"},
)
@ -44,10 +41,7 @@ def info1(caller):
text = "'Oh, Evennia is where you are right now! Don't you feel the power?'"
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": "Ok, bye for now then.", "goto": "END"},
)

File diff suppressed because it is too large Load diff

View file

@ -422,10 +422,7 @@ def optlist_to_menuoptions(treestr, optlist, index, mark_category, go_back):
gobackitem = {
"key": ["<< Go Back", "go back", "back"],
"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)
return menuoptions
@ -464,9 +461,7 @@ def menunode_treeselect(caller, raw_string, **kwargs):
# Otherwise, convert optlist to a list of menu options.
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:
# Use start_text for the menu text on the top level
text = start_text
@ -530,10 +525,7 @@ class CmdNameColor(Command):
def func(self):
# This is all you have to do to initialize a menu!
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:"
)
@ -581,7 +573,5 @@ def change_name_color(caller, treestr, index, selection):
caller.msg("Name color removed.")
elif selection in colordict:
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")

View file

@ -291,9 +291,7 @@ def spend_action(character, actions, action_name=None):
character.db.combat_actionsleft -= actions # Use up actions.
if character.db.combat_actionsleft < 0:
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.
"""
@ -396,9 +394,7 @@ class TBBasicTurnHandler(DefaultScript):
self.db.fighters = ordered_by_roll
# 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.
self.start_turn(self.db.fighters[0])
@ -413,9 +409,7 @@ class TBBasicTurnHandler(DefaultScript):
"""
for fighter in self.db.fighters:
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):
"""
@ -433,9 +427,7 @@ class TBBasicTurnHandler(DefaultScript):
currentchar, "all", action_name="disengage"
) # Spend all remaining actions.
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.
currentchar.msg("WARNING: About to time out!")
self.db.timeout_warning_given = True
@ -447,9 +439,7 @@ class TBBasicTurnHandler(DefaultScript):
Args:
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 = (
0
) # Actions remaining - start of turn adds to this, turn ends when it reaches 0
@ -498,17 +488,13 @@ class TBBasicTurnHandler(DefaultScript):
defeated_characters = 0
for fighter in self.db.fighters:
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 == (
len(self.db.fighters) - 1
): # If only one character isn't defeated
for fighter in self.db.fighters:
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.stop() # Stop this script and end combat.
return
@ -517,15 +503,11 @@ class TBBasicTurnHandler(DefaultScript):
currentchar = self.db.fighters[self.db.turn]
self.db.turn += 1 # Go to the next in the turn order.
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
self.db.timer = TURN_TIMEOUT + self.time_until_next_repeat() # Reset the timer.
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.
def turn_end_check(self, character):
@ -589,9 +571,7 @@ class CmdFight(Command):
if is_in_combat(self.caller): # Already in a fight
self.caller.msg("You're already in a fight!")
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...
fighters.append(thing) # ...then add it to the fight.
if len(fighters) <= 1: # If you're the only able fighter in the room
@ -686,9 +666,7 @@ class CmdPass(Command):
self.caller.location.msg_contents(
"%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):
@ -719,12 +697,8 @@ class CmdDisengage(Command):
self.caller.msg("You can only do that on your turn.")
return
self.caller.location.msg_contents(
"%s disengages, ready to stop fighting." % self.caller
)
spend_action(
self.caller, "all", action_name="disengage"
) # Spend all remaining actions.
self.caller.location.msg_contents("%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 turn handler script to see if all fighters have disengaged.
@ -776,9 +750,7 @@ class CmdCombatHelp(CmdHelp):
# tips on combat when used in a fight with no arguments.
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(
"Available combat commands:|/"
+ "|wAttack:|n Attack a target, attempting to deal damage.|/"

View file

@ -55,13 +55,7 @@ in your game and using it as-is.
"""
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
"""
@ -276,8 +270,7 @@ def resolve_attack(attacker, defender, attack_value=None, defense_value=None):
)
else:
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)
# If defender HP is reduced to 0 or less, call at_defeat.
@ -349,9 +342,7 @@ def spend_action(character, actions, action_name=None):
character.db.combat_actionsleft -= actions # Use up actions.
if character.db.combat_actionsleft < 0:
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.
"""
@ -400,9 +391,7 @@ class TBEquipTurnHandler(DefaultScript):
self.db.fighters = ordered_by_roll
# 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.
self.start_turn(self.db.fighters[0])
@ -417,9 +406,7 @@ class TBEquipTurnHandler(DefaultScript):
"""
for fighter in self.db.fighters:
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):
"""
@ -437,9 +424,7 @@ class TBEquipTurnHandler(DefaultScript):
currentchar, "all", action_name="disengage"
) # Spend all remaining actions.
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.
currentchar.msg("WARNING: About to time out!")
self.db.timeout_warning_given = True
@ -451,9 +436,7 @@ class TBEquipTurnHandler(DefaultScript):
Args:
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 = (
0
) # Actions remaining - start of turn adds to this, turn ends when it reaches 0
@ -502,17 +485,13 @@ class TBEquipTurnHandler(DefaultScript):
defeated_characters = 0
for fighter in self.db.fighters:
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 == (
len(self.db.fighters) - 1
): # If only one character isn't defeated
for fighter in self.db.fighters:
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.stop() # Stop this script and end combat.
return
@ -521,15 +500,11 @@ class TBEquipTurnHandler(DefaultScript):
currentchar = self.db.fighters[self.db.turn]
self.db.turn += 1 # Go to the next in the turn order.
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
self.db.timer = TURN_TIMEOUT + self.time_until_next_repeat() # Reset the timer.
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.
def turn_end_check(self, character):
@ -735,9 +710,7 @@ class CmdFight(Command):
if is_in_combat(self.caller): # Already in a fight
self.caller.msg("You're already in a fight!")
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...
fighters.append(thing) # ...then add it to the fight.
if len(fighters) <= 1: # If you're the only able fighter in the room
@ -832,9 +805,7 @@ class CmdPass(Command):
self.caller.location.msg_contents(
"%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):
@ -865,12 +836,8 @@ class CmdDisengage(Command):
self.caller.msg("You can only do that on your turn.")
return
self.caller.location.msg_contents(
"%s disengages, ready to stop fighting." % self.caller
)
spend_action(
self.caller, "all", action_name="disengage"
) # Spend all remaining actions.
self.caller.location.msg_contents("%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 turn handler script to see if all fighters have disengaged.
@ -922,9 +889,7 @@ class CmdCombatHelp(CmdHelp):
# tips on combat when used in a fight with no arguments.
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(
"Available combat commands:|/"
+ "|wAttack:|n Attack a target, attempting to deal damage.|/"
@ -1015,9 +980,7 @@ class CmdUnwield(Command):
else:
old_weapon = self.caller.db.wielded_weapon
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):
@ -1093,9 +1056,7 @@ class CmdDoff(Command):
else:
old_armor = self.caller.db.worn_armor
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):

View file

@ -360,9 +360,7 @@ def spend_action(character, actions, action_name=None):
character.db.combat_actionsleft -= actions # Use up actions.
if character.db.combat_actionsleft < 0:
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):
@ -383,9 +381,7 @@ def spend_item_use(item, user):
if item.db.item_uses > 0: # Has uses remaining
# 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
@ -394,19 +390,13 @@ def spend_item_use(item, user):
user.msg("%s has no uses remaining." % item.key.capitalize())
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())
item.delete() # Delete the spent item
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.location = (
item.location
) # Move the residue to the same place as the item
residue = spawn({"prototype": item.db.item_consumable})[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))
item.delete() # Delete the spent item
@ -501,9 +491,7 @@ def add_condition(character, turnchar, condition, duration):
# The first value is the remaining turns - the second value is whose turn to count down on.
character.db.conditions.update({condition: [duration, turnchar]})
# Tell everyone!
character.location.msg_contents(
"%s gains the '%s' condition." % (character, condition)
)
character.location.msg_contents("%s gains the '%s' condition." % (character, condition))
"""
@ -589,17 +577,13 @@ class TBItemsCharacter(DefaultCharacter):
if self.db.hp + to_heal > self.db.max_hp:
to_heal = self.db.max_hp - self.db.hp # Cap healing to max HP
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
if "Poisoned" in self.db.conditions:
to_hurt = randint(POISON_RATE[0], POISON_RATE[1]) # Deal damage
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:
# Call at_defeat if poison defeats the character
at_defeat(self)
@ -612,9 +596,7 @@ class TBItemsCharacter(DefaultCharacter):
# Paralyzed: Have no actions in combat.
if is_in_combat(self) and "Paralyzed" in self.db.conditions:
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)
def at_update(self):
@ -689,9 +671,7 @@ class TBItemsTurnHandler(DefaultScript):
self.db.fighters = ordered_by_roll
# 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.
self.start_turn(self.db.fighters[0])
@ -706,9 +686,7 @@ class TBItemsTurnHandler(DefaultScript):
"""
for fighter in self.db.fighters:
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):
"""
@ -726,9 +704,7 @@ class TBItemsTurnHandler(DefaultScript):
currentchar, "all", action_name="disengage"
) # Spend all remaining actions.
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.
currentchar.msg("WARNING: About to time out!")
self.db.timeout_warning_given = True
@ -740,9 +716,7 @@ class TBItemsTurnHandler(DefaultScript):
Args:
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 = (
0
) # Actions remaining - start of turn adds to this, turn ends when it reaches 0
@ -791,17 +765,13 @@ class TBItemsTurnHandler(DefaultScript):
defeated_characters = 0
for fighter in self.db.fighters:
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 == (
len(self.db.fighters) - 1
): # If only one character isn't defeated
for fighter in self.db.fighters:
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.stop() # Stop this script and end combat.
return
@ -810,17 +780,13 @@ class TBItemsTurnHandler(DefaultScript):
currentchar = self.db.fighters[self.db.turn]
self.db.turn += 1 # Go to the next in the turn order.
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
self.db.timer = TURN_TIMEOUT + self.time_until_next_repeat() # Reset the timer.
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.
# Count down condition timers.
@ -888,9 +854,7 @@ class CmdFight(Command):
if is_in_combat(self.caller): # Already in a fight
self.caller.msg("You're already in a fight!")
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...
fighters.append(thing) # ...then add it to the fight.
if len(fighters) <= 1: # If you're the only able fighter in the room
@ -989,9 +953,7 @@ class CmdPass(Command):
self.caller.location.msg_contents(
"%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):
@ -1022,12 +984,8 @@ class CmdDisengage(Command):
self.caller.msg("You can only do that on your turn.")
return
self.caller.location.msg_contents(
"%s disengages, ready to stop fighting." % self.caller
)
spend_action(
self.caller, "all", action_name="disengage"
) # Spend all remaining actions.
self.caller.location.msg_contents("%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 turn handler script to see if all fighters have disengaged.
@ -1079,9 +1037,7 @@ class CmdCombatHelp(CmdHelp):
# tips on combat when used in a fight with no arguments.
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(
"Available combat commands:|/"
+ "|wAttack:|n Attack a target, attempting to deal damage.|/"
@ -1219,9 +1175,7 @@ def itemfunc_heal(item, user, target, **kwargs):
to_heal = target.db.max_hp - target.db.hp # Cap healing to max HP
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):
@ -1281,10 +1235,7 @@ def itemfunc_cure_condition(item, user, target, **kwargs):
for key in target.db.conditions:
if key in to_cure:
# 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]
user.location.msg_contents(item_msg)
@ -1310,9 +1261,7 @@ def itemfunc_attack(item, user, target, **kwargs):
return False # Returning false aborts the item use
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
if target == user:
@ -1496,9 +1445,7 @@ AMULET_OF_MIGHT = {
"desc": "The one who holds this amulet can call upon its power to gain great strength.",
"item_func": "add_condition",
"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 = {
@ -1506,7 +1453,5 @@ 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.",
"item_func": "add_condition",
"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)]},
}

View file

@ -61,13 +61,7 @@ in your game and using it as-is.
"""
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.help import CmdHelp
@ -318,9 +312,7 @@ def spend_action(character, actions, action_name=None):
character.db.combat_actionsleft -= actions # Use up actions.
if character.db.combat_actionsleft < 0:
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.
"""
@ -425,9 +417,7 @@ class TBMagicTurnHandler(DefaultScript):
self.db.fighters = ordered_by_roll
# 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.
self.start_turn(self.db.fighters[0])
@ -442,9 +432,7 @@ class TBMagicTurnHandler(DefaultScript):
"""
for fighter in self.db.fighters:
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):
"""
@ -462,9 +450,7 @@ class TBMagicTurnHandler(DefaultScript):
currentchar, "all", action_name="disengage"
) # Spend all remaining actions.
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.
currentchar.msg("WARNING: About to time out!")
self.db.timeout_warning_given = True
@ -476,9 +462,7 @@ class TBMagicTurnHandler(DefaultScript):
Args:
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 = (
0
) # Actions remaining - start of turn adds to this, turn ends when it reaches 0
@ -527,17 +511,13 @@ class TBMagicTurnHandler(DefaultScript):
defeated_characters = 0
for fighter in self.db.fighters:
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 == (
len(self.db.fighters) - 1
): # If only one character isn't defeated
for fighter in self.db.fighters:
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.stop() # Stop this script and end combat.
return
@ -546,15 +526,11 @@ class TBMagicTurnHandler(DefaultScript):
currentchar = self.db.fighters[self.db.turn]
self.db.turn += 1 # Go to the next in the turn order.
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
self.db.timer = TURN_TIMEOUT + self.time_until_next_repeat() # Reset the timer.
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.
def turn_end_check(self, character):
@ -618,9 +594,7 @@ class CmdFight(Command):
if is_in_combat(self.caller): # Already in a fight
self.caller.msg("You're already in a fight!")
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...
fighters.append(thing) # ...then add it to the fight.
if len(fighters) <= 1: # If you're the only able fighter in the room
@ -715,9 +689,7 @@ class CmdPass(Command):
self.caller.location.msg_contents(
"%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):
@ -748,12 +720,8 @@ class CmdDisengage(Command):
self.caller.msg("You can only do that on your turn.")
return
self.caller.location.msg_contents(
"%s disengages, ready to stop fighting." % self.caller
)
spend_action(
self.caller, "all", action_name="disengage"
) # Spend all remaining actions.
self.caller.location.msg_contents("%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 turn handler script to see if all fighters have disengaged.
@ -818,17 +786,11 @@ class CmdLearnSpell(Command):
if len(spell_to_learn) == 1: # If one match, extract the string
spell_to_learn = spell_to_learn[0]
if (
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
if 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)
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)
"""
You will almost definitely want to replace this with your own system
@ -946,9 +908,7 @@ class CmdCast(MuxCommand):
# 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:
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
# If spell takes no targets and one is given, give error message and return
@ -1054,9 +1014,7 @@ class CmdRest(Command):
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.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.
@ -1108,9 +1066,7 @@ class CmdCombatHelp(CmdHelp):
# tips on combat when used in a fight with no arguments.
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(
"Available combat commands:|/"
+ "|wAttack:|n Attack a target, attempting to deal damage.|/"

View file

@ -101,13 +101,7 @@ in your game and using it as-is.
"""
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
"""
@ -265,9 +259,7 @@ def at_defeat(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.
@ -490,9 +482,7 @@ def spend_action(character, actions, action_name=None):
character.db.combat_actionsleft -= actions # Use up actions.
if character.db.combat_actionsleft < 0:
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):
@ -525,9 +515,7 @@ def combat_status_message(fighter):
range_obj.append(thing)
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:
status_msg += "|/Reach targets: %s" % ", ".join(obj.key for obj in reach_obj)
if range_obj:
@ -586,9 +574,7 @@ class TBRangeTurnHandler(DefaultScript):
self.db.fighters = ordered_by_roll
# 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.
self.start_turn(self.db.fighters[0])
@ -602,12 +588,8 @@ class TBRangeTurnHandler(DefaultScript):
Called at script termination.
"""
for thing in self.obj.contents:
combat_cleanup(
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
combat_cleanup(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):
"""
@ -625,9 +607,7 @@ class TBRangeTurnHandler(DefaultScript):
currentchar, "all", action_name="disengage"
) # Spend all remaining actions.
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.
currentchar.msg("WARNING: About to time out!")
self.db.timeout_warning_given = True
@ -692,9 +672,7 @@ class TBRangeTurnHandler(DefaultScript):
Args:
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 = (
0
) # Actions remaining - start of turn adds to this, turn ends when it reaches 0
@ -742,17 +720,13 @@ class TBRangeTurnHandler(DefaultScript):
defeated_characters = 0
for fighter in self.db.fighters:
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 == (
len(self.db.fighters) - 1
): # If only one character isn't defeated
for fighter in self.db.fighters:
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.stop() # Stop this script and end combat.
return
@ -761,15 +735,11 @@ class TBRangeTurnHandler(DefaultScript):
currentchar = self.db.fighters[self.db.turn]
self.db.turn += 1 # Go to the next in the turn order.
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
self.db.timer = TURN_TIMEOUT + self.time_until_next_repeat() # Reset the timer.
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.
def turn_end_check(self, character):
@ -906,9 +876,7 @@ class TBRangeObject(DefaultObject):
if dropper.location.db.combat_turnhandler:
# Object joins the range field
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):
"""
@ -990,8 +958,7 @@ class TBRangeObject(DefaultObject):
return False
if get_range(giver, getter) > 0: # Too far away from target
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 True
@ -1052,9 +1019,7 @@ class CmdFight(Command):
if is_in_combat(self.caller): # Already in a fight
self.caller.msg("You're already in a fight!")
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...
fighters.append(thing) # ...then add it to the fight.
if len(fighters) <= 1: # If you're the only able fighter in the room
@ -1179,11 +1144,7 @@ class CmdShoot(Command):
in_melee = []
for target in attacker.db.combat_range:
# 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
if len(in_melee) > 0:
@ -1333,9 +1294,7 @@ class CmdPass(Command):
self.caller.location.msg_contents(
"%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):
@ -1366,12 +1325,8 @@ class CmdDisengage(Command):
self.caller.msg("You can only do that on your turn.")
return
self.caller.location.msg_contents(
"%s disengages, ready to stop fighting." % self.caller
)
spend_action(
self.caller, "all", action_name="disengage"
) # Spend all remaining actions.
self.caller.location.msg_contents("%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 turn handler script to see if all fighters have disengaged.
@ -1442,9 +1397,7 @@ class CmdCombatHelp(CmdHelp):
# tips on combat when used in a fight with no arguments.
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(
"Available combat commands:|/"
+ "|wAttack:|n Attack an engaged target, attempting to deal damage.|/"

View file

@ -44,7 +44,9 @@ class BodyFunctions(DefaultScript):
elif rand < 0.2:
string = "You have an itch. Hard to reach too."
elif rand < 0.3:
string = "You think you hear someone behind you. ... but when you look there's noone there."
string = (
"You think you hear someone behind you. ... but when you look there's noone there."
)
elif rand < 0.4:
string = "You inspect your fingernails. Nothing to report."
elif rand < 0.5:

View file

@ -113,9 +113,7 @@ class CmdSmashGlass(Command):
string = "You smash your hand against the glass"
string += " with all your might. The lid won't budge"
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
elif rand < 0.6:
string = "You hit the lid hard. It doesn't move an inch."
@ -125,8 +123,7 @@ class CmdSmashGlass(Command):
string += " you should just try to open the lid instead?"
self.caller.msg(string)
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
)

View file

@ -121,9 +121,7 @@ class RedButton(DefaultObject):
self.db.lamp_works = False
desc = self.db.desc_lamp_broken
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:
self.db.desc = desc

View file

@ -142,8 +142,7 @@ class BlindedState(DefaultScript):
"""
self.obj.msg("You blink feverishly as your eyesight slowly returns.")
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,
# (which is the blinded one).

View file

@ -45,14 +45,11 @@ class TestBodyFunctions(EvenniaTest):
mock_random.random = Mock(return_value=0.25)
self.script.send_random_message()
self.char1.msg.assert_called_with(
"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."
)
mock_random.random = Mock(return_value=0.35)
self.script.send_random_message()
self.char1.msg.assert_called_with(
"You inspect your fingernails. Nothing to report."
)
self.char1.msg.assert_called_with("You inspect your fingernails. Nothing to report.")
mock_random.random = Mock(return_value=0.45)
self.script.send_random_message()
self.char1.msg.assert_called_with("You cough discreetly into your hand.")
@ -61,20 +58,14 @@ class TestBodyFunctions(EvenniaTest):
self.char1.msg.assert_called_with("You scratch your head, looking around.")
mock_random.random = Mock(return_value=0.65)
self.script.send_random_message()
self.char1.msg.assert_called_with(
"You blink, forgetting what it was you were going to do."
)
self.char1.msg.assert_called_with("You blink, forgetting what it was you were going to do.")
mock_random.random = Mock(return_value=0.75)
self.script.send_random_message()
self.char1.msg.assert_called_with("You feel lonely all of a sudden.")
mock_random.random = Mock(return_value=0.85)
self.script.send_random_message()
self.char1.msg.assert_called_with(
"You get a great idea. Of course you won't tell anyone."
)
self.char1.msg.assert_called_with("You get a great idea. Of course you won't tell anyone.")
mock_random.random = Mock(return_value=0.95)
self.script.send_random_message()
self.char1.msg.assert_called_with(
"You suddenly realize how much you love Evennia!"
)
self.char1.msg.assert_called_with("You suddenly realize how much you love Evennia!")
self.char1.msg = old_func

View file

@ -160,9 +160,7 @@ class Mob(tut_objects.TutorialObject):
self.db.hit_msg = "%s wails, shudders and writhes." % self.key
self.db.irregular_msgs = ["the enemy looks about.", "the enemy changes stance."]
self.db.tutorial_info = (
"This is an object with simple state AI, using a ticker to move."
)
self.db.tutorial_info = "This is an object with simple state AI, using a ticker to move."
def _set_ticker(self, interval, hook_key, stop=False):
"""
@ -194,9 +192,7 @@ class Mob(tut_objects.TutorialObject):
if last_interval and last_hook_key:
# we have a previous subscription, kill this first.
TICKER_HANDLER.remove(
interval=last_interval,
callback=getattr(self, last_hook_key),
idstring=idstring,
interval=last_interval, callback=getattr(self, last_hook_key), idstring=idstring
)
self.db.last_ticker_interval = interval
self.db.last_hook_key = hook_key
@ -386,16 +382,13 @@ class Mob(tut_objects.TutorialObject):
# we reduced the target to <= 0 health. Move them to the
# defeated room
target.msg(self.db.defeat_msg)
self.location.msg_contents(
self.db.defeat_msg_room % target.key, exclude=target
)
self.location.msg_contents(self.db.defeat_msg_room % target.key, exclude=target)
send_defeated_to = search_object(self.db.send_defeated_to)
if send_defeated_to:
target.move_to(send_defeated_to[0], quiet=True)
else:
logger.log_err(
"Mob: mob.db.send_defeated_to not found: %s"
% self.db.send_defeated_to
"Mob: mob.db.send_defeated_to not found: %s" % self.db.send_defeated_to
)
# response methods - called by other objects

View file

@ -124,7 +124,9 @@ class TutorialReadable(TutorialObject):
Attribute and add the readable cmdset.
"""
super().at_object_creation()
self.db.tutorial_info = "This is an object with a 'read' command defined in a command set on itself."
self.db.tutorial_info = (
"This is an object with a 'read' command defined in a command set on itself."
)
self.db.readable_text = "There is no text written on %s." % self.key
# define a command on the object.
self.cmdset.add_default(CmdSetReadable, permanent=True)
@ -171,10 +173,7 @@ class CmdClimb(Command):
return
ostring = self.obj.db.climb_text
if not ostring:
ostring = (
"You climb %s. Having looked around, you climb down again."
% self.obj.name
)
ostring = "You climb %s. Having looked around, you climb down again." % self.obj.name
self.caller.msg(ostring)
# set a tag on the caller to remember that we climbed.
self.caller.tags.add("tutorial_climbed_tree", category="tutorial_world")
@ -228,7 +227,9 @@ class Obelisk(TutorialObject):
def at_object_creation(self):
"""Called when object is created."""
super().at_object_creation()
self.db.tutorial_info = "This object changes its desc randomly, and makes sure to remember which one you saw."
self.db.tutorial_info = (
"This object changes its desc randomly, and makes sure to remember which one you saw."
)
self.db.puzzle_descs = ["You see a normal stone slab"]
# make sure this can never be picked up
self.locks.add("get:false()")
@ -333,14 +334,14 @@ class LightSource(TutorialObject):
def at_object_creation(self):
"""Called when object is first created."""
super().at_object_creation()
self.db.tutorial_info = "This object can be lit to create light. It has a timeout for how long it burns."
self.db.tutorial_info = (
"This object can be lit to create light. It has a timeout for how long it burns."
)
self.db.is_giving_light = False
self.db.burntime = 60 * 3 # 3 minutes
# this is the default desc, it can of course be customized
# when created.
self.db.desc = (
"A splinter of wood with remnants of resin on it, enough for burning."
)
self.db.desc = "A splinter of wood with remnants of resin on it, enough for burning."
# add the Light command
self.cmdset.add_default(CmdSetLight, permanent=True)
@ -353,16 +354,13 @@ class LightSource(TutorialObject):
self.db.is_giving_light = False
try:
self.location.location.msg_contents(
"%s's %s flickers and dies." % (self.location, self.key),
exclude=self.location,
"%s's %s flickers and dies." % (self.location, self.key), exclude=self.location
)
self.location.msg("Your %s flickers and dies." % self.key)
self.location.location.check_light_state()
except AttributeError:
try:
self.location.msg_contents(
"A %s on the floor flickers and dies." % self.key
)
self.location.msg_contents("A %s on the floor flickers and dies." % self.key)
self.location.location.check_light_state()
except AttributeError:
# Mainly happens if we happen to be in a None location
@ -508,9 +506,7 @@ class CmdShiftRoot(Command):
elif color == "blue":
if direction == "left":
root_pos[color] = max(-1, root_pos[color] - 1)
self.caller.msg(
"You shift the root with small blue flowers to the left."
)
self.caller.msg("You shift the root with small blue flowers to the left.")
if root_pos[color] != 0 and root_pos[color] == root_pos["red"]:
root_pos["red"] += 1
self.caller.msg(
@ -518,9 +514,7 @@ class CmdShiftRoot(Command):
)
elif direction == "right":
root_pos[color] = min(1, root_pos[color] + 1)
self.caller.msg(
"You shove the root adorned with small blue flowers to the right."
)
self.caller.msg("You shove the root adorned with small blue flowers to the right.")
if root_pos[color] != 0 and root_pos[color] == root_pos["red"]:
root_pos["red"] -= 1
self.caller.msg(
@ -541,18 +535,12 @@ class CmdShiftRoot(Command):
self.caller.msg("The green weedy root falls down.")
elif direction == "down":
root_pos[color] = min(1, root_pos[color] + 1)
self.caller.msg(
"You shove the root adorned with small yellow flowers downwards."
)
self.caller.msg("You shove the root adorned with small yellow flowers downwards.")
if root_pos[color] != 0 and root_pos[color] == root_pos["green"]:
root_pos["green"] -= 1
self.caller.msg(
"The weedy green root is shifted upwards to make room."
)
self.caller.msg("The weedy green root is shifted upwards to make room.")
else:
self.caller.msg(
"The root hangs across the wall - you can only move it up or down."
)
self.caller.msg("The root hangs across the wall - you can only move it up or down.")
elif color == "green":
if direction == "up":
root_pos[color] = max(-1, root_pos[color] - 1)
@ -569,9 +557,7 @@ class CmdShiftRoot(Command):
"The root with yellow flowers gets in the way and is pushed upwards."
)
else:
self.caller.msg(
"The root hangs across the wall - you can only move it up or down."
)
self.caller.msg("The root hangs across the wall - you can only move it up or down.")
# we have moved the root. Store new position
self.obj.db.root_pos = root_pos
@ -580,9 +566,7 @@ class CmdShiftRoot(Command):
if list(root_pos.values()).count(0) == 0: # no roots in middle position
# This will affect the cmd: lock of CmdPressButton
self.obj.db.button_exposed = True
self.caller.msg(
"Holding aside the root you think you notice something behind it ..."
)
self.caller.msg("Holding aside the root you think you notice something behind it ...")
class CmdPressButton(Command):
@ -623,9 +607,7 @@ class CmdPressButton(Command):
)
self.caller.location.msg_contents(string % self.caller.key, exclude=self.caller)
if not self.obj.open_wall():
self.caller.msg(
"The exit leads nowhere, there's just more stone behind it ..."
)
self.caller.msg("The exit leads nowhere, there's just more stone behind it ...")
class CmdSetCrumblingWall(CmdSet):
@ -665,9 +647,7 @@ class CrumblingWall(TutorialObject, DefaultExit):
"""called when the object is first created."""
super().at_object_creation()
self.aliases.add(
["secret passage", "passage", "crack", "opening", "secret door"]
)
self.aliases.add(["secret passage", "passage", "crack", "opening", "secret door"])
# starting root positions. H1/H2 are the horizontally hanging roots,
# V1/V2 the vertically hanging ones. Each can have three positions:
@ -781,9 +761,7 @@ class CrumblingWall(TutorialObject, DefaultExit):
def at_failed_traverse(self, traverser):
"""This is called if the account fails to pass the Exit."""
traverser.msg(
"No matter how you try, you cannot force yourself through %s." % self.key
)
traverser.msg("No matter how you try, you cannot force yourself through %s." % self.key)
def reset(self):
"""
@ -867,15 +845,15 @@ class CmdAttack(Command):
cmdstring = self.cmdstring
if cmdstring in ("attack", "fight"):
string = (
"How do you want to fight? Choose one of 'stab', 'slash' or 'defend'."
)
string = "How do you want to fight? Choose one of 'stab', 'slash' or 'defend'."
self.caller.msg(string)
return
# parry mode
if cmdstring in ("parry", "defend"):
string = "You raise your weapon in a defensive pose, ready to block the next enemy attack."
string = (
"You raise your weapon in a defensive pose, ready to block the next enemy attack."
)
self.caller.msg(string)
self.caller.db.combat_parry_mode = True
self.caller.location.msg_contents(
@ -895,22 +873,14 @@ class CmdAttack(Command):
damage = self.obj.db.damage * 2 # modified due to stab
string = "You stab with %s. " % self.obj.key
tstring = "%s stabs at you with %s. " % (self.caller.key, self.obj.key)
ostring = "%s stabs at %s with %s. " % (
self.caller.key,
target.key,
self.obj.key,
)
ostring = "%s stabs at %s with %s. " % (self.caller.key, target.key, self.obj.key)
self.caller.db.combat_parry_mode = False
elif cmdstring in ("slash", "chop"):
hit = float(self.obj.db.hit) # un modified due to slash
damage = self.obj.db.damage # un modified due to slash
string = "You slash with %s. " % self.obj.key
tstring = "%s slash at you with %s. " % (self.caller.key, self.obj.key)
ostring = "%s slash at %s with %s. " % (
self.caller.key,
target.key,
self.obj.key,
)
ostring = "%s slash at %s with %s. " % (self.caller.key, target.key, self.obj.key)
self.caller.db.combat_parry_mode = False
else:
self.caller.msg(
@ -948,9 +918,7 @@ class CmdAttack(Command):
else:
self.caller.msg(string + "|rYou miss.|n")
target.msg(tstring + "|gThey miss you.|n")
self.caller.location.msg_contents(
ostring + "They miss.", exclude=[target, self.caller]
)
self.caller.location.msg_contents(ostring + "They miss.", exclude=[target, self.caller])
class CmdSetWeapon(CmdSet):
@ -1201,9 +1169,7 @@ class WeaponRack(TutorialObject):
prototype = random.choice(self.db.available_weapons)
# use the spawner to create a new Weapon from the
# spawner dictionary, tag the caller
wpn = spawn(
WEAPON_PROTOTYPES[prototype], prototype_parents=WEAPON_PROTOTYPES
)[0]
wpn = spawn(WEAPON_PROTOTYPES[prototype], prototype_parents=WEAPON_PROTOTYPES)[0]
caller.tags.add(rack_id, category="tutorial_world")
wpn.location = caller
caller.msg(self.db.get_weapon_msg % wpn.key)

View file

@ -396,9 +396,7 @@ class IntroRoom(TutorialRoom):
if character.is_superuser:
string = "-" * 78 + SUPERUSER_WARNING + "-" * 78
character.msg(
"|r%s|n" % string.format(name=character.key, quell="|w@quell|r")
)
character.msg("|r%s|n" % string.format(name=character.key, quell="|w@quell|r"))
# -------------------------------------------------------------
@ -573,23 +571,15 @@ class CmdLookBridge(Command):
random.choice(BRIDGE_MOODS),
)
chars = [
obj for obj in self.obj.contents_get(exclude=caller) if obj.has_account
]
chars = [obj for obj in self.obj.contents_get(exclude=caller) if obj.has_account]
if chars:
# we create the You see: message manually here
message += "\n You see: %s" % ", ".join(
"|c%s|n" % char.key for char in chars
)
message += "\n You see: %s" % ", ".join("|c%s|n" % char.key for char in chars)
self.caller.msg(message)
# there is a chance that we fall if we are on the western or central
# part of the bridge.
if (
bridge_position < 3
and random.random() < 0.05
and not self.caller.is_superuser
):
if bridge_position < 3 and random.random() < 0.05 and not self.caller.is_superuser:
# we fall 5% of time.
fall_exit = search_object(self.obj.db.fall_exit)
if fall_exit:
@ -816,9 +806,7 @@ class CmdLookDark(Command):
caller.ndb.dark_searches += 1
else:
# we could have found something!
if any(
obj for obj in caller.contents if utils.inherits_from(obj, LightSource)
):
if any(obj for obj in caller.contents if utils.inherits_from(obj, LightSource)):
# we already carry a LightSource object.
caller.msg(ALREADY_LIGHTSOURCE)
else:
@ -971,9 +959,7 @@ class DarkRoom(TutorialRoom):
self.cmdset.add(DarkCmdSet, permanent=True)
for char in (obj for obj in self.contents if obj.has_account):
if char.is_superuser:
char.msg(
"You are Superuser, so you are not affected by the dark state."
)
char.msg("You are Superuser, so you are not affected by the dark state.")
else:
# put players in darkness
char.msg("The room is completely dark.")
@ -1053,9 +1039,7 @@ class TeleportRoom(TutorialRoom):
return
# determine if the puzzle is a success or not
is_success = str(character.db.puzzle_clue) == str(self.db.puzzle_value)
teleport_to = (
self.db.success_teleport_to if is_success else self.db.failure_teleport_to
)
teleport_to = self.db.success_teleport_to if is_success else self.db.failure_teleport_to
# note that this returns a list
results = search_object(teleport_to)
if not results or len(results) > 1:
@ -1064,9 +1048,7 @@ class TeleportRoom(TutorialRoom):
return
if character.is_superuser:
# superusers don't get teleported
character.msg(
"Superuser block: You would have been teleported to %s." % results[0]
)
character.msg("Superuser block: You would have been teleported to %s." % results[0])
return
# perform the teleport
if is_success:

View file

@ -111,11 +111,7 @@ class UnixCommandParser(argparse.ArgumentParser):
"""
prog = prog or command.key
super().__init__(
prog=prog,
description=description,
conflict_handler="resolve",
add_help=False,
**kwargs
prog=prog, description=description, conflict_handler="resolve", add_help=False, **kwargs
)
self.command = command
self.post_help = epilog

Some files were not shown because too many files have changed in this diff Show more