Make PEP8 cleanup of line spaces and character distances as well as indents

This commit is contained in:
Griatch 2017-08-19 23:16:36 +02:00
parent 7ff783fea1
commit b278337172
189 changed files with 2039 additions and 1583 deletions

View file

@ -47,6 +47,7 @@ manually later.
# Helper functions
def _green(string):
if USE_COLOR:
return "%s%s%s" % (ANSI_GREEN, string, ANSI_NORMAL)
@ -98,12 +99,12 @@ def _case_sensitive_replace(string, old, new):
all_upper = False
# special cases - keep remaing case)
if new_word.lower() in CASE_WORD_EXCEPTIONS:
result.append(new_word[ind+1:])
result.append(new_word[ind + 1:])
# append any remaining characters from new
elif all_upper:
result.append(new_word[ind+1:].upper())
result.append(new_word[ind + 1:].upper())
else:
result.append(new_word[ind+1:].lower())
result.append(new_word[ind + 1:].lower())
out.append("".join(result))
# if we have more new words than old ones, just add them verbatim
out.extend([new_word for ind, new_word in enumerate(new_words) if ind >= len(old_words)])
@ -278,7 +279,7 @@ def rename_in_file(path, in_list, out_list, is_interactive):
raw_input(_HELP_TEXT.format(sources=in_list, targets=out_list))
elif ret.startswith("i"):
# ignore one or more lines
ignores = [int(ind)-1 for ind in ret[1:].split(',') if ind.strip().isdigit()]
ignores = [int(ind) - 1 for ind in ret[1:].split(',') if ind.strip().isdigit()]
if not ignores:
raw_input("Ignore example: i 2,7,34,133\n (return to continue)")
continue
@ -287,7 +288,6 @@ def rename_in_file(path, in_list, out_list, is_interactive):
continue
if __name__ == "__main__":
import argparse

View file

@ -5,7 +5,8 @@ the python bin directory and makes the 'evennia' program available on
the command %path%.
"""
import os, sys
import os
import sys
# for pip install -e
sys.path.insert(0, os.path.abspath(os.getcwd()))

View file

@ -109,9 +109,11 @@ def _create_version():
pass
return version
__version__ = _create_version()
del _create_version
def _init():
"""
This function is called automatically by the launcher only after
@ -124,7 +126,7 @@ def _init():
global Command, CmdSet, default_cmds, syscmdkeys, InterruptCommand
global search_object, search_script, search_account, search_channel, search_help, search_tag
global create_object, create_script, create_account, create_channel, create_message, create_help_entry
global settings,lockfuncs, logger, utils, gametime, ansi, spawn, managers
global settings, lockfuncs, logger, utils, gametime, ansi, spawn, managers
global contrib, TICKER_HANDLER, MONITOR_HANDLER, SESSION_HANDLER, CHANNEL_HANDLER, TASK_HANDLER
from .accounts.accounts import DefaultAccount
@ -191,6 +193,7 @@ def _init():
Parent for other containers
"""
def _help(self):
"Returns list of contents"
names = [name for name in self.__class__.__dict__ if not name.startswith('_')]
@ -198,7 +201,6 @@ def _init():
print(self.__doc__ + "-" * 60 + "\n" + ", ".join(names))
help = property(_help)
class DBmanagers(_EvContainer):
"""
Links to instantiated database managers.
@ -241,7 +243,6 @@ def _init():
managers = DBmanagers()
del DBmanagers
class DefaultCmds(_EvContainer):
"""
This container holds direct shortcuts to all default commands in Evennia.
@ -282,7 +283,6 @@ def _init():
default_cmds = DefaultCmds()
del DefaultCmds
class SystemCmds(_EvContainer):
"""
Creating commands with keys set to these constants will make
@ -313,6 +313,7 @@ def _init():
del SystemCmds
del _EvContainer
del object
del absolute_import
del print_function

View file

@ -879,10 +879,10 @@ class DefaultAccount(with_metaclass(TypeclassBase, AccountDB)):
result.append(nsess == 1 and "\n\n|wConnected session:|n" or "\n\n|wConnected sessions (%i):|n" % nsess)
for isess, sess in enumerate(sessions):
csessid = sess.sessid
addr = "%s (%s)" % (sess.protocol_key, isinstance(sess.address, tuple)
and str(sess.address[0]) or str(sess.address))
result.append("\n %s %s" % (session.sessid == csessid and "|w* %s|n" % (isess + 1)
or " %s" % (isess + 1), addr))
addr = "%s (%s)" % (sess.protocol_key, isinstance(sess.address, tuple) and
str(sess.address[0]) or str(sess.address))
result.append("\n %s %s" % (session.sessid == csessid and "|w* %s|n" % (isess + 1) or
" %s" % (isess + 1), addr))
result.append("\n\n |whelp|n - more commands")
result.append("\n |wooc <Text>|n - talk on public channel")
@ -928,6 +928,7 @@ class DefaultGuest(DefaultAccount):
This class is used for guest logins. Unlike Accounts, Guests and
their characters are deleted after disconnection.
"""
def at_post_login(self, session=None, **kwargs):
"""
In theory, guests only have one character regardless of which

View file

@ -240,7 +240,7 @@ class AccountDBAdmin(BaseUserAdmin):
"""
obj.save()
if not change:
#calling hooks for new account
# calling hooks for new account
obj.set_class_from_typeclass(typeclass_path=settings.BASE_ACCOUNT_TYPECLASS)
obj.basetype_setup()
obj.at_account_creation()
@ -252,4 +252,5 @@ class AccountDBAdmin(BaseUserAdmin):
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

@ -28,6 +28,7 @@ class BotStarter(DefaultScript):
into gear when it is initialized.
"""
def at_script_creation(self):
"""
Called once, when script is created.
@ -148,6 +149,7 @@ class IRCBot(Bot):
Bot for handling IRC connections.
"""
def start(self, ev_channel=None, irc_botname=None, irc_channel=None, irc_network=None, irc_port=None, irc_ssl=None):
"""
Start by telling the portal to start a new session.
@ -359,6 +361,7 @@ class RSSBot(Bot):
its feed at regular intervals.
"""
def start(self, ev_channel=None, rss_url=None, rss_rate=None):
"""
Start by telling the portal to start a new RSS session

View file

@ -38,6 +38,7 @@ class AccountDBManager(TypedObjectManager, UserManager):
#swap_character
"""
def num_total_accounts(self):
"""
Get total number of accounts.

View file

@ -3,12 +3,14 @@ from __future__ import unicode_literals
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"):
account.db_typeclass_path = "typeclasses.accounts.Account"
account.save()
class Migration(migrations.Migration):
dependencies = [

View file

@ -88,41 +88,41 @@ _SEARCH_AT_RESULT = utils.variable_from_module(*settings.SEARCH_AT_RESULT.rsplit
# is the normal "production message to echo to the account.
_ERROR_UNTRAPPED = (
"""
"""
An untrapped error occurred.
""",
"""
"""
An untrapped error occurred. Please file a bug report detailing the steps to reproduce.
""")
_ERROR_CMDSETS = (
"""
"""
A cmdset merger-error occurred. This is often due to a syntax
error in one of the cmdsets to merge.
""",
"""
"""
A cmdset merger-error occurred. Please file a bug report detailing the
steps to reproduce.
""")
_ERROR_NOCMDSETS = (
"""
"""
No command sets found! This is a critical bug that can have
multiple causes.
""",
"""
"""
No command sets found! This is a sign of a critical bug. If
disconnecting/reconnecting doesn't" solve the problem, try to contact
the server admin through" some other means for assistance.
""")
_ERROR_CMDHANDLER = (
"""
"""
A command handler bug occurred. If this is not due to a local change,
please file a bug report with the Evennia project, including the
traceback and steps to reproduce.
""",
"""
"""
A command handler bug occurred. Please notify staff - they should
likely file a bug report with the Evennia project.
""")
@ -234,19 +234,23 @@ class NoCmdSets(Exception):
class ExecSystemCommand(Exception):
"Run a system command"
def __init__(self, syscmd, sysarg):
self.args = (syscmd, sysarg) # needed by exception error handling
self.syscmd = syscmd
self.sysarg = sysarg
class ErrorReported(Exception):
"Re-raised when a subsructure already reported the error"
def __init__(self, raw_string):
self.args = (raw_string,)
self.raw_string = raw_string
# Helper function
@inlineCallbacks
def get_and_merge_cmdsets(caller, session, account, obj, callertype, raw_string):
"""
@ -322,7 +326,7 @@ def get_and_merge_cmdsets(caller, session, account, obj, callertype, raw_string)
if (lobj.cmdset.current and
lobj.access(caller, access_type='call', no_superuser_bypass=True))))
for cset in local_obj_cmdsets:
#This is necessary for object sets, or we won't be able to
# This is necessary for object sets, or we won't be able to
# separate the command sets from each other in a busy room. We
# only keep the setting if duplicates were set to False/True
# explicitly.
@ -333,7 +337,6 @@ def get_and_merge_cmdsets(caller, session, account, obj, callertype, raw_string)
_msg_err(caller, _ERROR_CMDSETS)
raise ErrorReported(raw_string)
@inlineCallbacks
def _get_cmdsets(obj):
"""
@ -550,7 +553,7 @@ def cmdhandler(called_by, raw_string, _testing=False, callertype="session", sess
cmd.session = session
cmd.account = account
cmd.raw_string = unformatted_raw_string
#cmd.obj # set via on-object cmdset handler for each command,
# cmd.obj # set via on-object cmdset handler for each command,
# since this may be different for every command when
# merging multuple cmdsets
@ -615,7 +618,6 @@ def cmdhandler(called_by, raw_string, _testing=False, callertype="session", sess
finally:
_COMMAND_NESTING[called_by] -= 1
raw_string = to_unicode(raw_string, force_string=True)
session, account, obj = session, None, None

View file

@ -14,6 +14,7 @@ from evennia.utils.logger import log_trace
_MULTIMATCH_REGEX = re.compile(settings.SEARCH_MULTIMATCH_REGEX, re.I + re.U)
_CMD_IGNORE_PREFIXES = settings.CMD_IGNORE_PREFIXES
def cmdparser(raw_string, cmdset, caller, match_index=None):
"""
This function is called by the cmdhandler once it has
@ -83,8 +84,8 @@ def cmdparser(raw_string, cmdset, caller, match_index=None):
for cmd in cmdset:
matches.extend([create_match(cmdname, raw_string, cmd, cmdname)
for cmdname in [cmd.key] + cmd.aliases
if cmdname and l_raw_string.startswith(cmdname.lower())
and (not cmd.arg_regex or
if cmdname and l_raw_string.startswith(cmdname.lower()) and
(not cmd.arg_regex or
cmd.arg_regex.match(l_raw_string[len(cmdname):]))])
else:
# strip prefixes set in settings
@ -151,10 +152,10 @@ def cmdparser(raw_string, cmdset, caller, match_index=None):
quality = [mat[4] for mat in matches]
matches = matches[-quality.count(quality[-1]):]
if len(matches) > 1 and match_index != None and 0 < match_index <= len(matches):
if len(matches) > 1 and match_index is not None and 0 < match_index <= len(matches):
# We couldn't separate match by quality, but we have an
# index argument to tell us which match to use.
matches = [matches[match_index-1]]
matches = [matches[match_index - 1]]
# no matter what we have at this point, we have to return it.
return matches

View file

@ -51,7 +51,7 @@ class _CmdSetMeta(type):
cls.key = cls.__name__
cls.path = "%s.%s" % (cls.__module__, cls.__name__)
if not type(cls.key_mergetypes) == dict:
if not isinstance(cls.key_mergetypes, dict):
cls.key_mergetypes = {}
super(_CmdSetMeta, cls).__init__(*args, **kwargs)
@ -188,7 +188,7 @@ class CmdSet(with_metaclass(_CmdSetMeta, object)):
# initialize system
self.at_cmdset_creation()
self._contains_cache = WeakKeyDictionary()#{}
self._contains_cache = WeakKeyDictionary() # {}
# Priority-sensitive merge operations for cmdsets
@ -214,7 +214,7 @@ class CmdSet(with_metaclass(_CmdSetMeta, object)):
cmdset_c.commands.extend(cmdset_b.commands)
else:
cmdset_c.commands.extend([cmd for cmd in cmdset_b
if not cmd in cmdset_a])
if cmd not in cmdset_a])
return cmdset_c
def _intersect(self, cmdset_a, cmdset_b):
@ -280,7 +280,7 @@ class CmdSet(with_metaclass(_CmdSetMeta, object)):
"""
cmdset_c = cmdset_a._duplicate()
cmdset_c.commands = [cmd for cmd in cmdset_b if not cmd in cmdset_a]
cmdset_c.commands = [cmd for cmd in cmdset_b if cmd not in cmdset_a]
return cmdset_c
def _instantiate(self, cmd):
@ -426,7 +426,7 @@ class CmdSet(with_metaclass(_CmdSetMeta, object)):
# This is used for diagnosis.
cmdset_c.actual_mergetype = mergetype
#print "__add__ for %s (prio %i) called with %s (prio %i)." % (self.key, self.priority, cmdset_a.key, cmdset_a.priority)
# print "__add__ for %s (prio %i) called with %s (prio %i)." % (self.key, self.priority, cmdset_a.key, cmdset_a.priority)
# return the system commands to the cmdset
cmdset_c.add(sys_commands)

View file

@ -86,32 +86,32 @@ _CMDSET_FALLBACKS = settings.CMDSET_FALLBACKS
# Output strings
_ERROR_CMDSET_IMPORT = _(
"""{traceback}
"""{traceback}
Error loading cmdset '{path}'
(Traceback was logged {timestamp})""")
_ERROR_CMDSET_KEYERROR = _(
"""Error loading cmdset: No cmdset class '{classname}' in '{path}'.
"""Error loading cmdset: No cmdset class '{classname}' in '{path}'.
(Traceback was logged {timestamp})""")
_ERROR_CMDSET_SYNTAXERROR = _(
"""{traceback}
"""{traceback}
SyntaxError encountered when loading cmdset '{path}'.
(Traceback was logged {timestamp})""")
_ERROR_CMDSET_EXCEPTION = _(
"""{traceback}
"""{traceback}
Compile/Run error when loading cmdset '{path}'.",
(Traceback was logged {timestamp})""")
_ERROR_CMDSET_FALLBACK = _(
"""
"""
Error encountered for cmdset at path '{path}'.
Replacing with fallback '{fallback_path}'.
""")
_ERROR_CMDSET_NO_FALLBACK = _(
"""Fallback path '{fallback_path}' failed to generate a cmdset."""
"""Fallback path '{fallback_path}' failed to generate a cmdset."""
)
@ -122,6 +122,7 @@ class _ErrorCmdSet(CmdSet):
key = "_CMDSET_ERROR"
errmessage = "Error when loading cmdset."
class _EmptyCmdSet(CmdSet):
"""
This cmdset represents an empty cmdset
@ -130,6 +131,7 @@ class _EmptyCmdSet(CmdSet):
priority = -101
mergetype = "Union"
def import_cmdset(path, cmdsetobj, emit_to_obj=None, no_logging=False):
"""
This helper function is used by the cmdsethandler to load a cmdset
@ -191,7 +193,7 @@ def import_cmdset(path, cmdsetobj, emit_to_obj=None, no_logging=False):
continue
_CACHED_CMDSETS[python_path] = cmdsetclass
#instantiate the cmdset (and catch its errors)
# instantiate the cmdset (and catch its errors)
if callable(cmdsetclass):
cmdsetclass = cmdsetclass(cmdsetobj)
return cmdsetclass
@ -278,7 +280,7 @@ class CmdSetHandler(object):
self.permanent_paths = [""]
if init_true:
self.update(init_mode=True) #is then called from the object __init__.
self.update(init_mode=True) # is then called from the object __init__.
def __str__(self):
"""
@ -542,7 +544,6 @@ class CmdSetHandler(object):
# legacy alias
delete_default = remove_default
def all(self):
"""
Show all cmdsets.

View file

@ -60,7 +60,7 @@ def _init_command(cls, **kwargs):
if "cmd:" not in cls.locks:
cls.locks = "cmd:all();" + cls.locks
for lockstring in cls.locks.split(';'):
if lockstring and not ':' in lockstring:
if lockstring and ':' not in lockstring:
lockstring = "cmd:%s" % lockstring
temp.append(lockstring)
cls.lock_storage = ";".join(temp)

View file

@ -364,7 +364,7 @@ class CmdSessions(COMMAND_DEFAULT_CLASS):
for sess in sorted(sessions, key=lambda x: x.sessid):
char = account.get_puppet(sess)
table.add_row(str(sess.sessid), str(sess.protocol_key),
type(sess.address) == tuple and sess.address[0] or sess.address,
isinstance(sess.address, tuple) and sess.address[0] or sess.address,
char and str(char) or "None",
char and str(char.location) or "N/A")
self.msg("|wYour current session(s):|n\n%s" % table)
@ -552,7 +552,7 @@ class CmdOption(COMMAND_DEFAULT_CLASS):
flags[new_name] = new_val
self.msg("Option |w%s|n was changed from '|w%s|n' to '|w%s|n'." % (new_name, old_val, new_val))
return {new_name: new_val}
except Exception, err:
except Exception as err:
self.msg("|rCould not set option |w%s|r:|n %s" % (new_name, err))
return False
@ -664,7 +664,7 @@ class CmdQuit(COMMAND_DEFAULT_CLASS):
if nsess == 2:
account.msg("|RQuitting|n. One session is still connected.", session=self.session)
elif nsess > 2:
account.msg("|RQuitting|n. %i sessions are still connected." % (nsess-1), session=self.session)
account.msg("|RQuitting|n. %i sessions are still connected." % (nsess - 1), session=self.session)
else:
# we are quitting the last available session
account.msg("|RQuitting|n. Hope to see you again, soon.", session=self.session)
@ -732,7 +732,7 @@ class CmdColorTest(COMMAND_DEFAULT_CLASS):
for code, _ in ap.ansi_map[self.slice_dark_bg]]
bright_bg = ["%s%s|n" % (code.replace("\\", ""), code.replace("|", "||").replace("\\", ""))
for code, _ in ap.ansi_xterm256_bright_bg_map[self.slice_bright_bg]]
dark_fg.extend(["" for _ in range(len(bright_fg)-len(dark_fg))])
dark_fg.extend(["" for _ in range(len(bright_fg) - len(dark_fg))])
table = utils.format_table([bright_fg, dark_fg, bright_bg, dark_bg])
string = "ANSI colors:"
for row in table:
@ -751,7 +751,7 @@ class CmdColorTest(COMMAND_DEFAULT_CLASS):
# foreground table
table[ir].append("|%i%i%i%s|n" % (ir, ig, ib, "||%i%i%i" % (ir, ig, ib)))
# background table
table[6+ir].append("|%i%i%i|[%i%i%i%s|n"
table[6 + ir].append("|%i%i%i|[%i%i%i%s|n"
% (5 - ir, 5 - ig, 5 - ib, ir, ig, ib, "||[%i%i%i" % (ir, ig, ib)))
table = self.table_format(table)
string = "Xterm256 colors (if not all hues show, your client might not report that it can handle xterm256):"
@ -759,8 +759,8 @@ class CmdColorTest(COMMAND_DEFAULT_CLASS):
table = [[], [], [], [], [], [], [], [], [], [], [], []]
for ibatch in range(4):
for igray in range(6):
letter = chr(97 + (ibatch*6 + igray))
inverse = chr(122 - (ibatch*6 + igray))
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))
for igray in range(6):

View file

@ -171,8 +171,8 @@ class CmdBan(COMMAND_DEFAULT_CLASS):
if not banlist:
banlist = []
if not self.args or (self.switches
and not any(switch in ('ip', 'name')
if not self.args or (self.switches and
not any(switch in ('ip', 'name')
for switch in self.switches)):
self.caller.msg(list_bans(banlist))
return

View file

@ -41,6 +41,7 @@ _DEFAULT_WIDTH = settings.CLIENT_DEFAULT_WIDTH
_PROTOTYPE_PARENTS = None
class ObjManipCommand(COMMAND_DEFAULT_CLASS):
"""
This is a parent class for some of the defining objmanip commands
@ -88,8 +89,8 @@ class ObjManipCommand(COMMAND_DEFAULT_CLASS):
objdef, attrs = [part.strip() for part in objdef.split('/', 1)]
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_attrs[iside].append({"name":objdef, 'attrs':attrs})
obj_defs[iside].append({"name": objdef, 'option': option, 'aliases': aliases})
obj_attrs[iside].append({"name": objdef, 'attrs': attrs})
# store for future access
self.lhs_objs = obj_defs[0]
@ -350,7 +351,7 @@ class CmdCpAttr(ObjManipCommand):
if not from_obj or not to_objs:
caller.msg("You have to supply both source object and target(s).")
return
#copy to all to_obj:ects
# copy to all to_obj:ects
if "move" in self.switches:
clear = True
else:
@ -522,6 +523,7 @@ class CmdCreate(ObjManipCommand):
def _desc_load(caller):
return caller.db.evmenu_target.db.desc or ""
def _desc_save(caller, buf):
"""
Save line buffer to the desc prop. This should
@ -531,10 +533,12 @@ def _desc_save(caller, buf):
caller.msg("Saved.")
return True
def _desc_quit(caller):
caller.attributes.remove("evmenu_target")
caller.msg("Exited editor.")
class CmdDesc(COMMAND_DEFAULT_CLASS):
"""
describe an object or the current room.
@ -642,7 +646,7 @@ class CmdDestroy(COMMAND_DEFAULT_CLASS):
objname = obj.name
if not (obj.access(caller, "control") or obj.access(caller, 'delete')):
return "\nYou don't have permission to delete %s." % objname
if obj.account and not 'override' in self.switches:
if obj.account and 'override' not in self.switches:
return "\nObject %s is controlled by an active account. Use /override to delete anyway." % objname
if obj.dbid == int(settings.DEFAULT_HOME.lstrip("#")):
return "\nYou are trying to delete |c%s|n, which is set as DEFAULT_HOME. " \
@ -821,6 +825,7 @@ class CmdDig(ObjManipCommand):
if new_room and ('teleport' in self.switches or "tel" in self.switches):
caller.move_to(new_room)
class CmdTunnel(COMMAND_DEFAULT_CLASS):
"""
create new rooms in cardinal directions only
@ -893,7 +898,7 @@ class CmdTunnel(COMMAND_DEFAULT_CLASS):
if "tel" in self.switches:
telswitch = "/teleport"
backstring = ""
if not "oneway" in self.switches:
if "oneway" not in self.switches:
backstring = ", %s;%s" % (backname, backshort)
# build the string we will use to call @dig
@ -951,7 +956,7 @@ class CmdLink(COMMAND_DEFAULT_CLASS):
string = ""
if not obj.destination:
string += "Note: %s(%s) did not have a destination set before. Make sure you linked the right thing." % (obj.name,obj.dbref)
string += "Note: %s(%s) did not have a destination set before. Make sure you linked the right thing." % (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)
@ -1484,10 +1489,11 @@ class CmdSetAttribute(ObjManipCommand):
old_value = obj.attributes.get(attr)
if old_value is not None and not isinstance(old_value, basestring):
typ = type(old_value).__name__
self.caller.msg("|RWARNING! Saving this buffer will overwrite the "\
self.caller.msg("|RWARNING! Saving this buffer will overwrite the "
"current attribute (of type %s) with a string!|n" % typ)
return str(old_value)
return old_value
def save(caller, buf):
"Called when editor saves its buffer."
obj.attributes.add(attr, buf)
@ -1495,7 +1501,6 @@ class CmdSetAttribute(ObjManipCommand):
# start the editor
EvEditor(self.caller, load, save, key="%s/%s" % (obj, attr))
def func(self):
"Implement the set attribute - a limited form of @py."
@ -1523,7 +1528,7 @@ class CmdSetAttribute(ObjManipCommand):
if "edit" in self.switches:
# edit in the line editor
if len(attrs) > 1:
caller.msg("The Line editor can only be applied " \
caller.msg("The Line editor can only be applied "
"to one attribute at a time.")
return
self.edit_handler(obj, attrs[0])
@ -1538,7 +1543,7 @@ class CmdSetAttribute(ObjManipCommand):
continue
result.append(self.view_attr(obj, attr))
# we view it without parsing markup.
self.caller.msg("".join(result).strip(), options={"raw":True})
self.caller.msg("".join(result).strip(), options={"raw": True})
return
else:
# deleting the attribute(s)
@ -1644,7 +1649,7 @@ class CmdTypeclass(COMMAND_DEFAULT_CLASS):
return
is_same = obj.is_typeclass(new_typeclass, exact=True)
if is_same and not 'force' in self.switches:
if is_same and 'force' not in self.switches:
string = "%s already has the typeclass '%s'. Use /force to override." % (obj.name, new_typeclass)
else:
update = "update" in self.switches
@ -1797,8 +1802,8 @@ class CmdLock(ObjManipCommand):
# we have a = separator, so we are assigning a new lock
if self.switches:
swi = ", ".join(self.switches)
caller.msg("Switch(es) |w%s|n can not be used with a "\
"lock assignment. Use e.g. " \
caller.msg("Switch(es) |w%s|n can not be used with a "
"lock assignment. Use e.g. "
"|w@lock/del objname/locktype|n instead." % swi)
return
@ -1851,7 +1856,7 @@ class CmdExamine(ObjManipCommand):
"""
key = "@examine"
aliases = ["@ex","exam"]
aliases = ["@ex", "exam"]
locks = "cmd:perm(examine) or perm(Builder)"
help_category = "Building"
arg_regex = r"(/\w+?(\s|$))|\s|$"
@ -1957,11 +1962,10 @@ class CmdExamine(ObjManipCommand):
locks_string = " Default"
string += "\n|wLocks|n:%s" % locks_string
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)
string += "\n|wStored Cmdset(s)|n:\n %s" % ("\n ".join("%s [%s] (%s, prio %s)" % \
string += "\n|wStored Cmdset(s)|n:\n %s" % ("\n ".join("%s [%s] (%s, prio %s)" %
(cmdset.path, cmdset.key, cmdset.mergetype, cmdset.priority)
for cmdset in stored_cmdsets if cmdset.key != "_EMPTY_CMDSET"))
@ -1986,11 +1990,10 @@ class CmdExamine(ObjManipCommand):
pass
all_cmdsets = [cmdset for cmdset in dict(all_cmdsets).values()]
all_cmdsets.sort(key=lambda x: x.priority, reverse=True)
string += "\n|wMerged Cmdset(s)|n:\n %s" % ("\n ".join("%s [%s] (%s, prio %s)" % \
string += "\n|wMerged Cmdset(s)|n:\n %s" % ("\n ".join("%s [%s] (%s, prio %s)" %
(cmdset.path, cmdset.key, cmdset.mergetype, cmdset.priority)
for cmdset in all_cmdsets))
# list the commands available to this object
avail_cmdset = sorted([cmd.key for cmd in avail_cmdset
if cmd.access(obj, "cmd")])
@ -2029,7 +2032,7 @@ class CmdExamine(ObjManipCommand):
string += "\n|wContents|n: %s" % ", ".join(["%s(%s)" % (cont.name, cont.dbref) for cont in obj.contents
if cont not in exits and cont not in pobjs])
separator = "-" * _DEFAULT_WIDTH
#output info
# output info
return '%s\n%s\n%s' % (separator, string.strip(), separator)
def func(self):
@ -2053,7 +2056,7 @@ class CmdExamine(ObjManipCommand):
if hasattr(caller, "location"):
obj = caller.location
if not obj.access(caller, 'examine'):
#If we don't have special info access, just look at the object instead.
# If we don't have special info access, just look at the object instead.
self.msg(caller.at_look(obj))
return
# using callback for printing result whenever function returns.
@ -2076,14 +2079,14 @@ class CmdExamine(ObjManipCommand):
obj = caller.search_account(obj_name.lstrip('*'))
except AttributeError:
# this means we are calling examine from an account object
obj = caller.search(obj_name.lstrip('*'), search_object = 'object' in self.switches)
obj = caller.search(obj_name.lstrip('*'), search_object='object' in self.switches)
else:
obj = caller.search(obj_name)
if not obj:
continue
if not obj.access(caller, 'examine'):
#If we don't have special info access, just look
# If we don't have special info access, just look
# at the object instead.
self.msg(caller.at_look(obj))
continue
@ -2184,7 +2187,7 @@ class CmdFind(COMMAND_DEFAULT_CLASS):
elif not low <= int(result[0].id) <= high:
string += "\n |RNo match found for '%s' in #dbref interval.|n" % (searchstring)
else:
result=result[0]
result = result[0]
string += "\n|g %s - %s|n" % (result.get_display_name(caller), result.path)
else:
# Not an account/dbref search but a wider search; build a queryset.
@ -2192,7 +2195,7 @@ class CmdFind(COMMAND_DEFAULT_CLASS):
if "exact" in switches:
keyquery = Q(db_key__iexact=searchstring, id__gte=low, id__lte=high)
aliasquery = Q(db_tags__db_key__iexact=searchstring,
db_tags__db_tagtype__iexact="alias",id__gte=low, id__lte=high)
db_tags__db_tagtype__iexact="alias", id__gte=low, id__lte=high)
else:
keyquery = Q(db_key__istartswith=searchstring, id__gte=low, id__lte=high)
aliasquery = Q(db_tags__db_key__istartswith=searchstring,
@ -2290,7 +2293,7 @@ class CmdTeleport(COMMAND_DEFAULT_CLASS):
obj_to_teleport.location.msg_contents("%s teleported %s into nothingness."
% (caller, obj_to_teleport),
exclude=caller)
obj_to_teleport.location=None
obj_to_teleport.location = None
return
# not teleporting to None location
@ -2561,6 +2564,7 @@ class CmdTag(COMMAND_DEFAULT_CLASS):
# Reload the server and the prototypes should be available.
#
class CmdSpawn(COMMAND_DEFAULT_CLASS):
"""
spawn objects from prototype
@ -2628,7 +2632,6 @@ class CmdSpawn(COMMAND_DEFAULT_CLASS):
self.caller.msg(string)
return
if isinstance(prototype, basestring):
# A prototype key
keystr = prototype
@ -2647,9 +2650,8 @@ class CmdSpawn(COMMAND_DEFAULT_CLASS):
self.caller.msg("The prototype must be a prototype key or a Python dictionary.")
return
if not "noloc" in self.switches and not "location" in prototype:
if "noloc" in self.switches and not "location" not in prototype:
prototype["location"] = self.caller.location
for obj in spawn(prototype):
self.caller.msg("Spawned %s." % obj.get_display_name(self.caller))

View file

@ -31,7 +31,7 @@ class AccountCmdSet(CmdSet):
self.add(account.CmdOOC())
self.add(account.CmdCharCreate())
self.add(account.CmdCharDelete())
#self.add(account.CmdSessions())
# self.add(account.CmdSessions())
self.add(account.CmdWho())
self.add(account.CmdOption())
self.add(account.CmdQuit())

View file

@ -9,6 +9,7 @@ from evennia.commands.default import general, help, admin, system
from evennia.commands.default import building
from evennia.commands.default import batchprocess
class CharacterCmdSet(CmdSet):
"""
Implements the default command set.
@ -46,7 +47,7 @@ class CharacterCmdSet(CmdSet):
self.add(system.CmdAbout())
self.add(system.CmdTime())
self.add(system.CmdServerLoad())
#self.add(system.CmdPs())
# self.add(system.CmdPs())
self.add(system.CmdTickers())
# Admin commands

View file

@ -4,6 +4,7 @@ This module stores session-level commands.
from evennia.commands.cmdset import CmdSet
from evennia.commands.default import account
class SessionCmdSet(CmdSet):
"""
Sets up the unlogged cmdset.

View file

@ -614,7 +614,7 @@ class CmdClock(COMMAND_DEFAULT_CLASS):
# Try to add the lock
try:
channel.locks.add(self.rhs)
except LockException, err:
except LockException as err:
self.msg(err)
return
string = "Lock(s) applied. "

View file

@ -170,7 +170,7 @@ class CmdNick(COMMAND_DEFAULT_CLASS):
# we are given a index in nicklist
delindex = int(arg)
if 0 < delindex <= len(nicklist):
oldnick = nicklist[delindex-1]
oldnick = nicklist[delindex - 1]
_, _, old_nickstring, old_replstring = oldnick.value
else:
errstring += "Not a valid nick index."
@ -419,6 +419,7 @@ class CmdSay(COMMAND_DEFAULT_CLASS):
# Call the at_after_say hook on the character
caller.at_say(speech)
class CmdWhisper(COMMAND_DEFAULT_CLASS):
"""
Speak privately as your character to another

View file

@ -22,6 +22,7 @@ class MuxCommand(Command):
used by Evennia to create the automatic help entry for
the command, so make sure to document consistently here.
"""
def has_perm(self, srcobj):
"""
This is called by the cmdhandler to determine
@ -191,6 +192,7 @@ class MuxAccountCommand(MuxCommand):
creating a new property "character" that is set only if a
character is actually attached to this Account and Session.
"""
def parse(self):
"""
We run the parent parser as usual, then fix the result

View file

@ -719,7 +719,7 @@ class CmdServerLoad(COMMAND_DEFAULT_CLASS):
now, _ = _IDMAPPER.cache_size()
string = "The Idmapper cache freed |w{idmapper}|n database objects.\n" \
"The Python garbage collector freed |w{gc}|n Python instances total."
self.caller.msg(string.format(idmapper=(prev-now), gc=nflushed))
self.caller.msg(string.format(idmapper=(prev - now), gc=nflushed))
return
# display active processes

View file

@ -79,7 +79,7 @@ class CommandTest(EvenniaTest):
pass
finally:
# clean out evtable sugar. We only operate on text-type
stored_msg = [args[0] if args and args[0] else kwargs.get("text",utils.to_str(kwargs, force_string=True))
stored_msg = [args[0] if args and args[0] else kwargs.get("text", utils.to_str(kwargs, force_string=True))
for name, args, kwargs in receiver.msg.mock_calls]
# Get the first element of a tuple if msg received a tuple instead of a string
stored_msg = [smsg[0] if isinstance(smsg, tuple) else smsg for smsg in stored_msg]
@ -87,9 +87,9 @@ class CommandTest(EvenniaTest):
returned_msg = "||".join(_RE.sub("", mess) for mess in stored_msg)
returned_msg = ansi.parse_ansi(returned_msg, strip_ansi=noansi).strip()
if msg == "" and returned_msg or not returned_msg.startswith(msg.strip()):
sep1 = "\n" + "="*30 + "Wanted message" + "="*34 + "\n"
sep2 = "\n" + "="*30 + "Returned message" + "="*32 + "\n"
sep3 = "\n" + "="*78
sep1 = "\n" + "=" * 30 + "Wanted message" + "=" * 34 + "\n"
sep2 = "\n" + "=" * 30 + "Returned message" + "=" * 32 + "\n"
sep3 = "\n" + "=" * 78
retval = sep1 + msg.strip() + sep2 + returned_msg + sep3
raise AssertionError(retval)
else:
@ -297,7 +297,7 @@ class TestComms(CommandTest):
self.call(comms.CmdDelCom(), "tc", "Your alias 'tc' for channel testchan was cleared.", receiver=self.account)
def test_channels(self):
self.call(comms.CmdChannels(), "" ,"Available channels (use comlist,addcom and delcom to manage", receiver=self.account)
self.call(comms.CmdChannels(), "", "Available channels (use comlist,addcom and delcom to manage", receiver=self.account)
def test_all_com(self):
self.call(comms.CmdAllCom(), "", "Available channels (use comlist,addcom and delcom to manage", receiver=self.account)
@ -322,7 +322,7 @@ class TestComms(CommandTest):
self.call(comms.CmdCBoot(), "", "Usage: @cboot[/quiet] <channel> = <account> [:reason]", receiver=self.account)
def test_cdestroy(self):
self.call(comms.CmdCdestroy(), "testchan" ,"[testchan] TestAccount: testchan is being destroyed. Make sure to change your aliases.|Channel 'testchan' was destroyed.", receiver=self.account)
self.call(comms.CmdCdestroy(), "testchan", "[testchan] TestAccount: testchan is being destroyed. Make sure to change your aliases.|Channel 'testchan' was destroyed.", receiver=self.account)
class TestBatchProcess(CommandTest):
@ -332,6 +332,7 @@ class TestBatchProcess(CommandTest):
# we make sure to delete the button again here to stop the running reactor
self.call(building.CmdDestroy(), "button", "button was destroyed.")
class CmdInterrupt(Command):
key = "interrupt"

View file

@ -147,7 +147,7 @@ def create_normal_account(session, name, password):
account (Account): the account which was created from the name and password.
"""
# check for too many login errors too quick.
if _throttle(session, maxlim=5, timeout=5*60):
if _throttle(session, maxlim=5, timeout=5 * 60):
# timeout is 5 minutes.
session.msg("|RYou made too many connection attempts. Try again in a few minutes.|n")
return None
@ -168,8 +168,8 @@ def create_normal_account(session, name, password):
# Check IP and/or name bans
bans = ServerConfig.objects.conf("server_bans")
if bans and (any(tup[0] == account.name.lower() for tup in bans)
or
if bans and (any(tup[0] == account.name.lower() for tup in bans) or
any(tup[2].match(session.address) for tup in bans if tup[2])):
# this is a banned IP or name!
string = "|rYou have been banned and cannot continue from here." \
@ -209,7 +209,7 @@ class CmdUnconnectedConnect(COMMAND_DEFAULT_CLASS):
session = self.caller
# check for too many login errors too quick.
if _throttle(session, maxlim=5, timeout=5*60, storage=_LATEST_FAILED_LOGINS):
if _throttle(session, maxlim=5, timeout=5 * 60, storage=_LATEST_FAILED_LOGINS):
# timeout is 5 minutes.
session.msg("|RYou made too many connection attempts. Try again in a few minutes.|n")
return
@ -301,8 +301,8 @@ class CmdUnconnectedCreate(COMMAND_DEFAULT_CLASS):
# Check IP and/or name bans
bans = ServerConfig.objects.conf("server_bans")
if bans and (any(tup[0] == accountname.lower() for tup in bans)
or
if bans and (any(tup[0] == accountname.lower() for tup in bans) or
any(tup[2].match(session.address) for tup in bans if tup[2])):
# this is a banned IP or name!
string = "|rYou have been banned and cannot continue from here." \

View file

@ -12,45 +12,66 @@ from evennia.commands.command import Command
class _CmdA(Command):
key = "A"
def __init__(self, cmdset, *args, **kwargs):
super(_CmdA, self).__init__(*args, **kwargs)
self.from_cmdset = cmdset
class _CmdB(Command):
key = "B"
def __init__(self, cmdset, *args, **kwargs):
super(_CmdB, self).__init__(*args, **kwargs)
self.from_cmdset = cmdset
class _CmdC(Command):
key = "C"
def __init__(self, cmdset, *args, **kwargs):
super(_CmdC, self).__init__(*args, **kwargs)
self.from_cmdset = cmdset
class _CmdD(Command):
key = "D"
def __init__(self, cmdset, *args, **kwargs):
super(_CmdD, self).__init__(*args, **kwargs)
self.from_cmdset = cmdset
class _CmdSetA(CmdSet):
key = "A"
def at_cmdset_creation(self):
self.add(_CmdA("A"))
self.add(_CmdB("A"))
self.add(_CmdC("A"))
self.add(_CmdD("A"))
class _CmdSetB(CmdSet):
key = "B"
def at_cmdset_creation(self):
self.add(_CmdA("B"))
self.add(_CmdB("B"))
self.add(_CmdC("B"))
class _CmdSetC(CmdSet):
key = "C"
def at_cmdset_creation(self):
self.add(_CmdA("C"))
self.add(_CmdB("C"))
class _CmdSetD(CmdSet):
key = "D"
def at_cmdset_creation(self):
self.add(_CmdA("D"))
self.add(_CmdB("D"))
@ -59,8 +80,10 @@ class _CmdSetD(CmdSet):
# testing Command Sets
class TestCmdSetMergers(TestCase):
"Test merging of cmdsets"
def setUp(self):
super(TestCmdSetMergers, self).setUp()
self.cmdset_a = _CmdSetA()
@ -240,10 +263,14 @@ class TestCmdSetMergers(TestCase):
# test cmdhandler functions
from evennia.commands import cmdhandler
from twisted.trial.unittest import TestCase as TwistedTestCase
class TestGetAndMergeCmdSets(TwistedTestCase, EvenniaTest):
"Test the cmdhandler.get_and_merge_cmdsets function."
def setUp(self):
super(TestGetAndMergeCmdSets, self).setUp()
self.cmdset_a = _CmdSetA()
@ -261,6 +288,7 @@ class TestGetAndMergeCmdSets(TwistedTestCase, EvenniaTest):
a.no_channels = True
self.set_cmdsets(self.session, a)
deferred = cmdhandler.get_and_merge_cmdsets(self.session, self.session, None, None, "session", "")
def _callback(cmdset):
self.assertEqual(cmdset.key, "A")
deferred.addCallback(_callback)
@ -273,6 +301,7 @@ class TestGetAndMergeCmdSets(TwistedTestCase, EvenniaTest):
self.set_cmdsets(self.account, a)
deferred = cmdhandler.get_and_merge_cmdsets(self.account, None, self.account, None, "account", "")
# get_and_merge_cmdsets converts to lower-case internally.
def _callback(cmdset):
pcmdset = AccountCmdSet()
pcmdset.at_cmdset_creation()
@ -286,7 +315,8 @@ class TestGetAndMergeCmdSets(TwistedTestCase, EvenniaTest):
self.set_cmdsets(self.obj1, self.cmdset_a)
deferred = cmdhandler.get_and_merge_cmdsets(self.obj1, None, None, self.obj1, "object", "")
# get_and_merge_cmdsets converts to lower-case internally.
_callback = lambda cmdset: self.assertEqual(sum(1 for cmd in cmdset.commands if cmd.key in ("a", "b", "c", "d")), 4)
def _callback(cmdset): return self.assertEqual(sum(1 for cmd in cmdset.commands if cmd.key in ("a", "b", "c", "d")), 4)
deferred.addCallback(_callback)
return deferred
@ -296,6 +326,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", "")
def _callback(cmdset):
self.assertTrue(cmdset.no_exits)
self.assertTrue(cmdset.no_channels)
@ -315,6 +346,7 @@ class TestGetAndMergeCmdSets(TwistedTestCase, EvenniaTest):
a, b, c, d = self.cmdset_a, self.cmdset_b, self.cmdset_c, self.cmdset_d
self.set_cmdsets(self.account, a, b, c, d)
deferred = cmdhandler.get_and_merge_cmdsets(self.session, self.session, self.account, self.char1, "session", "")
def _callback(cmdset):
pcmdset = AccountCmdSet()
pcmdset.at_cmdset_creation()
@ -332,6 +364,7 @@ class TestGetAndMergeCmdSets(TwistedTestCase, EvenniaTest):
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", "")
def _callback(cmdset):
self.assertEqual(len(cmdset.commands), 9)
deferred.addCallback(_callback)

View file

@ -34,6 +34,7 @@ from django.utils.translation import ugettext as _
_CHANNEL_COMMAND_CLASS = None
_CHANNELDB = None
class ChannelCommand(command.Command):
"""
{channelkey} channel
@ -130,7 +131,8 @@ class ChannelCommand(command.Command):
if self.history_start is not None:
# Try to view history
log_file = channel.attributes.get("log_file", default="channel_%s.log" % channel.key)
send_msg = lambda lines: self.msg("".join(line.split("[-]", 1)[1]
def send_msg(lines): return self.msg("".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)
else:
@ -164,6 +166,7 @@ class ChannelHandler(object):
evennia.create_channel())
"""
def __init__(self):
"""
Initializes the channel handler's internal state.
@ -281,5 +284,6 @@ class ChannelHandler(object):
self.cached_cmdsets[source_object] = chan_cmdset
return chan_cmdset
CHANNEL_HANDLER = ChannelHandler()
CHANNELHANDLER = CHANNEL_HANDLER # legacy

View file

@ -357,7 +357,6 @@ class DefaultChannel(with_metaclass(TypeclassBase, ChannelDB)):
# hooks
def channel_prefix(self, msg=None, emit=False, **kwargs):
"""
Hook method. How the channel should prefix itself for users.

View file

@ -74,7 +74,7 @@ def identify_object(inp):
if clsname == "AccountDB":
return inp, "account"
elif clsname == "ObjectDB":
return inp ,"object"
return inp, "object"
elif clsname == "ChannelDB":
return inp, "channel"
if isinstance(inp, basestring):
@ -332,6 +332,7 @@ class ChannelDBManager(TypedObjectManager):
subscribed to the Channel.
"""
def get_all_channels(self):
"""
Get all channels.

View file

@ -3,12 +3,14 @@ from __future__ import unicode_literals
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"):
channel.db_typeclass_path = "typeclasses.channels.Channel"
channel.save()
class Migration(migrations.Migration):
dependencies = [

View file

@ -3,6 +3,7 @@ from __future__ import unicode_literals
from django.db import migrations
def convert_channelnames(apps, schema_editor):
ChannelDB = apps.get_model("comms", "ChannelDB")
for chan in ChannelDB.objects.filter(db_key="MUDinfo"):
@ -13,6 +14,7 @@ def convert_channelnames(apps, schema_editor):
chan.db_key = "MudInfo"
chan.save()
class Migration(migrations.Migration):
dependencies = [

View file

@ -250,7 +250,6 @@ class Msg(SharedMemoryModel):
elif clsname == "ChannelDB":
self.db_receivers_channels.add(receiver)
#@receivers.deleter
def __receivers_del(self):
"Deleter. Clears all receivers"
@ -370,6 +369,7 @@ class Msg(SharedMemoryModel):
#
#------------------------------------------------------------
class TempMsg(object):
"""
This is a non-persistent object for sending temporary messages
@ -377,6 +377,7 @@ class TempMsg(object):
doesn't require sender to be given.
"""
def __init__(self, senders=None, receivers=None, channels=None, message="", header="", type="", lockstring="", hide_from=None):
"""
Creates the temp message.
@ -471,6 +472,7 @@ class SubscriptionHandler(object):
channel and hides away which type of entity is
subscribing (Account or Object)
"""
def __init__(self, obj):
"""
Initialize the handler

View file

@ -14,7 +14,7 @@ See README.md for more info.
# own code, so somthing needs to be done here. See issue #766. /Griatch
#import evennia
#evennia._init()
# evennia._init()
#import barter, dice, extended_room, menu_login, talking_npc
#import chargen, email_login, gendersub, menusystem, slow_exit
#import tutorial_world, tutorial_examples

View file

@ -105,6 +105,7 @@ class TradeTimeout(DefaultScript):
"""
This times out the trade request, in case player B did not reply in time.
"""
def at_script_creation(self):
"""
Called when script is first created
@ -136,6 +137,7 @@ class TradeHandler(object):
Objects of this class handles the ongoing trade, notably storing the current
offers from each side and wether both have accepted or not.
"""
def __init__(self, part_a, part_b):
"""
Initializes the trade. This is called when part A tries to
@ -391,6 +393,7 @@ class CmdTradeBase(Command):
Base command for Trade commands to inherit from. Implements the
custom parsing.
"""
def parse(self):
"""
Parse the relevant parts and make it easily

View file

@ -102,7 +102,7 @@ class CmdOOCLook(default_cmds.CmdLook):
else:
charlist = "You have no Characters."
string = \
""" You, %s, are an |wOOC ghost|n without form. The world is hidden
""" You, %s, are an |wOOC ghost|n without form. The world is hidden
from you and besides chatting on channels your options are limited.
You need to have a Character in order to interact with the world.
@ -179,6 +179,7 @@ class OOCCmdSetCharGen(default_cmds.AccountCmdSet):
"""
Extends the default OOC cmdset.
"""
def at_cmdset_creation(self):
"""Install everything from the default set, then overload"""
self.add(CmdOOCLook())

View file

@ -92,7 +92,7 @@ CLOTHING_TYPE_LIMIT = {
'gloves': 1,
'socks': 1,
'shoes': 1
}
}
# The maximum number of clothing items that can be worn, or None for unlimited.
CLOTHING_OVERALL_LIMIT = 20
# What types of clothes will automatically cover what other types of clothes when worn.
@ -104,7 +104,7 @@ CLOTHING_TYPE_AUTOCOVER = {
'bottom': ['underpants'],
'fullbody': ['undershirt', 'underpants'],
'shoes': ['socks']
}
}
# Types of clothes that can't be used to cover other clothes.
CLOTHING_TYPE_CANT_COVER_WITH = ['jewelry']
@ -295,6 +295,7 @@ class ClothedCharacter(DefaultCharacter):
just copy the return_appearance hook defined below to your own game's
character typeclass.
"""
def return_appearance(self, looker):
"""
This formats a description. It is the hook a 'look' command

View file

@ -111,7 +111,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 " \
raise ValueError("the unit {} isn't defined as a valid "
"game time unit".format(name))
rtime += value * UNITS[name]
rtime /= TIMEFACTOR
@ -149,6 +149,7 @@ def realtime_to_gametime(secs=0, mins=0, hrs=0, days=0, weeks=0,
return time_to_tuple(gtime, *units)
return gtime
def custom_gametime(absolute=False):
"""
Return the custom game time as a tuple of units, as defined in settings.
@ -168,6 +169,7 @@ def custom_gametime(absolute=False):
del units[-1]
return time_to_tuple(current, *units)
def real_seconds_until(**kwargs):
"""
Return the real seconds until game time.
@ -228,6 +230,7 @@ def real_seconds_until(**kwargs):
return (projected - current) / TIMEFACTOR
def schedule(callback, repeat=False, **kwargs):
"""
Call the callback when the game time is up.
@ -264,6 +267,8 @@ def schedule(callback, repeat=False, **kwargs):
return script
# Scripts dealing in gametime (use `schedule` to create it)
class GametimeScript(DefaultScript):
"""Gametime-sensitive script."""

View file

@ -118,6 +118,7 @@ def roll_dice(dicenum, dicetype, modifier=None, conditional=None, return_tuple=F
else:
return result
RE_PARTS = re.compile(r"(d|\+|-|/|\*|<|>|<=|>=|!=|==)")
RE_MOD = re.compile(r"(\+|-|/|\*)")
RE_COND = re.compile(r"(<|>|<=|>=|!=|==)")
@ -255,6 +256,7 @@ class DiceCmdSet(CmdSet):
a small cmdset for testing purposes.
Add with @py self.cmdset.add("contrib.dice.DiceCmdSet")
"""
def at_cmdset_creation(self):
"""Called when set is created"""
self.add(CmdDice())

View file

@ -24,6 +24,7 @@ class EvenniaGameIndexClient(object):
Evennia Game Index. Since EGI is in the early goings, this isn't
incredibly configurable as far as what is being sent.
"""
def __init__(self, on_bad_request=None):
"""
:param on_bad_request: Optional callable to trigger when a bad request
@ -131,6 +132,7 @@ class SimpleResponseReceiver(protocol.Protocol):
"""
Used for pulling the response body out of an HTTP response.
"""
def __init__(self, status_code, d):
self.status_code = status_code
self.buf = ''

View file

@ -108,6 +108,7 @@ class ExtendedRoom(DefaultRoom):
time. It also allows for "details", together with a slightly modified
look command.
"""
def at_object_creation(self):
"""Called when room is first created only."""
self.db.spring_desc = ""
@ -281,6 +282,7 @@ class CmdExtendedLook(default_cmds.CmdLook):
Observes your location, details at your location or objects in your vicinity.
"""
def func(self):
"""
Handle the looking - add fallback to details.

View file

@ -54,6 +54,7 @@ _RE_GENDER_PRONOUN = re.compile(r'(?<!\|)\|(?!\|)[sSoOpPaA]')
# in-game command for setting the gender
class SetGender(Command):
"""
Sets gender on yourself
@ -72,7 +73,7 @@ class SetGender(Command):
"""
caller = self.caller
arg = self.args.strip().lower()
if not arg in ("male", "female", "neutral", "ambiguous"):
if arg not in ("male", "female", "neutral", "ambiguous"):
caller.msg("Usage: @gender male||female||neutral||ambiguous")
return
caller.db.gender = arg

View file

@ -4,6 +4,7 @@ Module containing the CallbackHandler for individual objects.
from collections import namedtuple
class CallbackHandler(object):
"""
@ -200,5 +201,6 @@ class CallbackHandler(object):
return Callback(**callback)
Callback = namedtuple("Callback", ("obj", "name", "number", "code", "author",
"valid", "parameters", "created_on", "updated_by", "updated_on"))

View file

@ -73,6 +73,7 @@ them and when. You can then accept a specific callback:
Use the /del switch to remove callbacks that should not be connected.
"""
class CmdCallback(COMMAND_DEFAULT_CLASS):
"""
@ -141,7 +142,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 " \
caller.msg("The event handler is not running, can't "
"access the event system.")
return
@ -170,7 +171,7 @@ class CmdCallback(COMMAND_DEFAULT_CLASS):
elif switch in ["tasks", "task"]:
self.list_tasks()
else:
caller.msg("Mutually exclusive or invalid switches were " \
caller.msg("Mutually exclusive or invalid switches were "
"used, cannot proceed.")
def list_callbacks(self):
@ -277,8 +278,8 @@ class CmdCallback(COMMAND_DEFAULT_CLASS):
types = self.handler.get_events(obj)
# Check that the callback exists
if not callback_name.startswith("chain_") and not callback_name in types:
self.msg("The callback name {} can't be found in {} of " \
if not callback_name.startswith("chain_") and callback_name not in types:
self.msg("The callback name {} can't be found in {} of "
"typeclass {}.".format(callback_name, obj, type(obj)))
return
@ -313,7 +314,7 @@ class CmdCallback(COMMAND_DEFAULT_CLASS):
return
# Check that the callback exists
if not callback_name in callbacks:
if callback_name not in callbacks:
self.msg("The callback name {} can't be found in {}.".format(
callback_name, obj))
return
@ -377,7 +378,7 @@ class CmdCallback(COMMAND_DEFAULT_CLASS):
return
# Check that the callback exists
if not callback_name in callbacks:
if callback_name not in callbacks:
self.msg("The callback name {} can't be found in {}.".format(
callback_name, obj))
return
@ -388,7 +389,7 @@ class CmdCallback(COMMAND_DEFAULT_CLASS):
callback = callbacks[callback_name][0]
else:
if not parameters:
self.msg("Which callback do you wish to delete? Specify " \
self.msg("Which callback do you wish to delete? Specify "
"a number.")
self.list_callbacks()
return
@ -469,7 +470,7 @@ class CmdCallback(COMMAND_DEFAULT_CLASS):
return
# Check that the callback exists
if not callback_name in callbacks:
if callback_name not in callbacks:
self.msg("The callback name {} can't be found in {}.".format(
callback_name, obj))
return
@ -520,9 +521,12 @@ class CmdCallback(COMMAND_DEFAULT_CLASS):
self.msg(unicode(table))
# Private functions to handle editing
def _ev_load(caller):
return caller.db._callback and caller.db._callback.get("code", "") or ""
def _ev_save(caller, buf):
"""Save and add the callback."""
lock = "perm({}) or perm(events_without_validation)".format(
@ -530,7 +534,7 @@ def _ev_save(caller, buf):
autovalid = caller.locks.check_lockstring(caller, lock)
callback = caller.db._callback
handler = get_event_handler()
if not handler or not callback or not all(key in callback for key in \
if not handler or not callback or not all(key in callback for key in
("obj", "name", "number", "valid")):
caller.msg("Couldn't save this callback.")
return False
@ -543,10 +547,11 @@ def _ev_save(caller, buf):
caller, valid=autovalid)
return True
def _ev_quit(caller):
callback = caller.db._callback
handler = get_event_handler()
if not handler or not callback or not all(key in callback for key in \
if not handler or not callback or not all(key in callback for key in
("obj", "name", "number", "valid")):
caller.msg("Couldn't save this callback.")
return False

View file

@ -8,6 +8,7 @@ Eventfuncs are just Python functions that can be used inside of calllbacks.
from evennia import ObjectDB, ScriptDB
from evennia.contrib.ingame_python.utils import InterruptEvent
def deny():
"""
Deny, that is stop, the callback here.
@ -22,6 +23,7 @@ def deny():
"""
raise InterruptEvent
def get(**kwargs):
"""
Return an object with the given search option or None if None is found.
@ -53,6 +55,7 @@ def get(**kwargs):
return object
def call_event(obj, event_name, seconds=0):
"""
Call the specified event in X seconds.

View file

@ -21,6 +21,7 @@ from evennia.contrib.ingame_python.utils import get_next_wait, EVENTS, Interrupt
# Constants
RE_LINE_ERROR = re.compile(r'^ File "\<string\>", line (\d+)')
class EventHandler(DefaultScript):
"""
@ -414,12 +415,12 @@ class EventHandler(DefaultScript):
# Errors should not pass silently
allowed = ("number", "parameters", "locals")
if any(k for k in kwargs if k not in allowed):
raise TypeError("Unknown keyword arguments were specified " \
raise TypeError("Unknown keyword arguments were specified "
"to call callbacks: {}".format(kwargs))
event = self.get_events(obj).get(callback_name)
if locals is None and not event:
logger.log_err("The callback {} for the object {} (typeclass " \
logger.log_err("The callback {} for the object {} (typeclass "
"{}) can't be found".format(callback_name, obj, type(obj)))
return False
@ -430,7 +431,7 @@ class EventHandler(DefaultScript):
try:
locals[variable] = args[i]
except IndexError:
logger.log_trace("callback {} of {} ({}): need variable " \
logger.log_trace("callback {} of {} ({}): need variable "
"{} in position {}".format(callback_name, obj,
type(obj), variable, i))
return False
@ -482,7 +483,7 @@ class EventHandler(DefaultScript):
number = callback["number"]
obj = callback["obj"]
oid = obj.id
logger.log_err("An error occurred during the callback {} of " \
logger.log_err("An error occurred during the callback {} of "
"{} (#{}), number {}\n{}".format(callback_name, obj,
oid, number + 1, "\n".join(trace)))
@ -655,7 +656,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 " \
logger.log_err("The task #{} was scheduled, but it cannot be "
"found".format(task_id))
return

View file

@ -21,6 +21,7 @@ settings.EVENTS_CALENDAR = "standard"
# Constants
OLD_EVENTS = {}
class TestEventHandler(EvenniaTest):
"""
@ -485,7 +486,7 @@ class TestDefaultCallbacks(CommandTest):
try:
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, force_string=True))
stored_msg = [args[0] if args and args[0] else kwargs.get("text", utils.to_str(kwargs, force_string=True))
for name, args, kwargs in 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]
@ -506,7 +507,7 @@ class TestDefaultCallbacks(CommandTest):
try:
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, force_string=True))
stored_msg = [args[0] if args and args[0] else kwargs.get("text", utils.to_str(kwargs, force_string=True))
for name, args, kwargs in 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]

View file

@ -159,6 +159,7 @@ Variables you can use in this event:
character: the character connected to this event.
"""
@register_events
class EventCharacter(DefaultCharacter):
@ -489,6 +490,7 @@ Variables you can use in this event:
destination: the character's location after moving.
"""
@register_events
class EventExit(DefaultExit):
@ -573,6 +575,7 @@ Variables you can use in this event:
object: the object connected to this event.
"""
@register_events
class EventObject(DefaultObject):
@ -621,6 +624,7 @@ class EventObject(DefaultObject):
super(EventObject, self).at_drop(dropper)
self.callbacks.call("drop", dropper, self)
# Room help
ROOM_CAN_DELETE = """
Can the room be deleted?
@ -742,6 +746,7 @@ Variables you can use in this event:
room: the room connected to this event.
"""
@register_events
class EventRoom(DefaultRoom):

View file

@ -20,6 +20,7 @@ from evennia.contrib.custom_gametime import real_seconds_until as custom_rsu
# Temporary storage for events waiting for the script to be started
EVENTS = []
def get_event_handler():
"""Return the event handler or None."""
try:
@ -30,6 +31,7 @@ def get_event_handler():
return script
def register_events(path_or_typeclass):
"""
Register the events in this typeclass.
@ -84,6 +86,8 @@ def register_events(path_or_typeclass):
return typeclass
# Custom callbacks for specific event types
def get_next_wait(format):
"""
Get the length of time in seconds before format.
@ -104,7 +108,7 @@ def get_next_wait(format):
"""
calendar = getattr(settings, "EVENTS_CALENDAR", None)
if calendar is None:
logger.log_err("A time-related event has been set whereas " \
logger.log_err("A time-related event has been set whereas "
"the gametime calendar has not been set in the settings.")
return
elif calendar == "standard":
@ -131,7 +135,7 @@ def get_next_wait(format):
break
if not piece.isdigit():
logger.log_trace("The time specified '{}' in {} isn't " \
logger.log_trace("The time specified '{}' in {} isn't "
"a valid number".format(piece, format))
return
@ -154,6 +158,7 @@ def get_next_wait(format):
usual = gametime_to_realtime(**kwargs)
return until, usual, details
def time_event(obj, event_name, number, parameters):
"""
Create a time-related event.
@ -173,6 +178,7 @@ def time_event(obj, event_name, number, parameters):
script.db.number = number
script.ndb.usual = usual
def keyword_event(callbacks, parameters):
"""
Custom call for events with keywords (like push, or pull, or turn...).
@ -201,6 +207,7 @@ def keyword_event(callbacks, parameters):
return to_call
def phrase_event(callbacks, parameters):
"""
Custom call for events with keywords in sentences (like say or whisper).
@ -236,6 +243,7 @@ def phrase_event(callbacks, parameters):
return to_call
class InterruptEvent(RuntimeError):
"""

View file

@ -22,6 +22,7 @@ _HEAD_CHAR = "|015-|n"
_SUB_HEAD_CHAR = "-"
_WIDTH = 78
class CmdMail(default_cmds.MuxCommand):
"""
Commands that allow either IC or OOC communications
@ -253,4 +254,3 @@ class CmdMail(default_cmds.MuxCommand):
self.caller.msg(_HEAD_CHAR * _WIDTH)
else:
self.caller.msg("There are no messages in your inbox.")

View file

@ -173,6 +173,7 @@ def example1_build_temple(x, y, **kwargs):
# This is generally mandatory.
return room
# Include your trigger characters and build functions in a legend dict.
EXAMPLE1_LEGEND = {("", ""): example1_build_forest,
("", "n"): example1_build_mountains,
@ -225,8 +226,8 @@ def example2_build_verticle_exit(x, y, **kwargs):
if kwargs["iteration"] == 0:
return
north_room = kwargs["room_dict"][(x, y-1)]
south_room = kwargs["room_dict"][(x, y+1)]
north_room = kwargs["room_dict"][(x, y - 1)]
south_room = kwargs["room_dict"][(x, y + 1)]
# create exits in the rooms
create_object(exits.Exit, key="south",
@ -247,8 +248,8 @@ def example2_build_horizontal_exit(x, y, **kwargs):
if kwargs["iteration"] == 0:
return
west_room = kwargs["room_dict"][(x-1, y)]
east_room = kwargs["room_dict"][(x+1, y)]
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,
@ -261,6 +262,7 @@ def example2_build_horizontal_exit(x, y, **kwargs):
kwargs["caller"].msg("Connected: " + west_room.key +
" & " + east_room.key)
# Include your trigger characters and build functions in a legend dict.
EXAMPLE2_LEGEND = {("", ""): example2_build_forest,
("|"): example2_build_verticle_exit,
@ -339,37 +341,38 @@ def build_map(caller, game_map, legend, iterations=1, build_exits=True):
y = loc_key[1]
# north
if (x, y-1) in room_dict:
if room_dict[(x, y-1)]:
if (x, y - 1) in room_dict:
if room_dict[(x, y - 1)]:
create_object(exits.Exit, key="north",
aliases=["n"], location=location,
destination=room_dict[(x, y-1)])
destination=room_dict[(x, y - 1)])
# east
if (x+1, y) in room_dict:
if room_dict[(x+1, y)]:
if (x + 1, y) in room_dict:
if room_dict[(x + 1, y)]:
create_object(exits.Exit, key="east",
aliases=["e"], location=location,
destination=room_dict[(x+1, y)])
destination=room_dict[(x + 1, y)])
# south
if (x, y+1) in room_dict:
if room_dict[(x, y+1)]:
if (x, y + 1) in room_dict:
if room_dict[(x, y + 1)]:
create_object(exits.Exit, key="south",
aliases=["s"], location=location,
destination=room_dict[(x, y+1)])
destination=room_dict[(x, y + 1)])
# west
if (x-1, y) in room_dict:
if room_dict[(x-1, y)]:
if (x - 1, y) in room_dict:
if room_dict[(x - 1, y)]:
create_object(exits.Exit, key="west",
aliases=["w"], location=location,
destination=room_dict[(x-1, y)])
destination=room_dict[(x - 1, y)])
caller.msg("Map Created.")
# access command
class CmdMapBuilder(COMMAND_DEFAULT_CLASS):
"""
Build a map from a 2D ASCII map.
@ -478,4 +481,3 @@ class CmdMapBuilder(COMMAND_DEFAULT_CLASS):
# Pass map and legend to the build function.
build_map(caller, game_map, legend, iterations, build_exits)

View file

@ -97,6 +97,7 @@ def _update_store(caller, key=None, desc=None, delete=False, swapkey=None):
# eveditor save/load/quit functions
def _save_editor(caller, buffer):
"Called when the editor saves its contents"
key = caller.db._multidesc_editkey
@ -104,6 +105,7 @@ def _save_editor(caller, buffer):
caller.msg("Saved description to key '%s'." % key)
return True
def _load_editor(caller):
"Called when the editor loads contents"
key = caller.db._multidesc_editkey
@ -112,6 +114,7 @@ def _load_editor(caller):
return caller.db.multidesc[match[0]][1]
return ""
def _quit_editor(caller):
"Called when the editor quits"
del caller.db._multidesc_editkey
@ -161,7 +164,7 @@ class CmdMultiDesc(default_cmds.MuxCommand):
# list all stored descriptions, either in full or cropped.
# Note that we list starting from 1, not from 0.
_update_store(caller)
do_crop = not "full" in switches
do_crop = "full" not in switches
if do_crop:
outtext = ["|w%s:|n %s" % (key, crop(desc))
for key, desc in caller.db.multidesc]
@ -249,6 +252,6 @@ class CmdMultiDesc(default_cmds.MuxCommand):
else:
caller.msg("|wCurrent desc:|n\n%s" % caller.db.desc)
except DescValidateError, err:
except DescValidateError as err:
# This is triggered by _key_to_index
caller.msg(err)

View file

@ -57,6 +57,7 @@ import time
from evennia import DefaultScript, ScriptDB
from evennia.utils.create import create_script
class RejectedRegex(RuntimeError):
"""The provided regular expression has been rejected.

View file

@ -148,13 +148,13 @@ class LanguageHandler(DefaultScript):
don't know the language well enough).
"""
def at_script_creation(self):
"Called when script is first started"
self.key = "language_handler"
self.persistent = True
self.db.language_storage = {}
def add(self, key="default", phonemes=_PHONEMES,
grammar=_GRAMMAR, word_length_variance=0, noun_prefix="",
noun_postfix="", vowels=_VOWELS, manual_translations=None,
@ -240,7 +240,7 @@ class LanguageHandler(DefaultScript):
word = word.strip()
lword = len(word)
new_word = ""
wlen = max(0, lword + sum(randint(-1,1) for i
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
@ -257,7 +257,7 @@ class LanguageHandler(DefaultScript):
translation.update(dict((key.lower(), value.lower()) for key, value in manual_translations.items()))
# store data
storage = {"translation" : translation,
storage = {"translation": translation,
"grammar": grammar,
"grammar2phonemes": dict(grammar2phonemes),
"word_length_variance": word_length_variance,
@ -296,7 +296,7 @@ class LanguageHandler(DefaultScript):
else:
# make up translation on the fly. Length can
# vary from un-translated word.
wlen = max(0, lword + sum(randint(-1,1) for i
wlen = max(0, lword + sum(randint(-1, 1) for i
in range(self.language["word_length_variance"])))
grammar = self.language["grammar"]
if wlen not in grammar:
@ -347,6 +347,8 @@ class LanguageHandler(DefaultScript):
# Language access functions
_LANGUAGE_HANDLER = None
def obfuscate_language(text, level=0.0, language="default"):
"""
Main access method for the language parser.
@ -412,7 +414,6 @@ def available_languages():
return list(_LANGUAGE_HANDLER.attributes.get("language_storage", {}))
#------------------------------------------------------------
#
# Whisper obscuration
@ -427,6 +428,7 @@ def available_languages():
#
#------------------------------------------------------------
_RE_WHISPER_OBSCURE = [
re.compile(r"^$", _RE_FLAGS), # This is a Test! #0 full whisper
re.compile(r"[ae]", _RE_FLAGS), # This -s - Test! #1 add uy
@ -460,4 +462,3 @@ def obfuscate_whisper(whisper, level=0.0):
level = min(max(0.0, level), 1.0)
olevel = int(13.0 * level)
return _RE_WHISPER_OBSCURE[olevel].sub('...' if olevel == 13.0 else '-', whisper)

View file

@ -127,10 +127,10 @@ _NUM_SEP = "-"
# Texts
_EMOTE_NOMATCH_ERROR = \
"""|RNo match for |r{ref}|R.|n"""
"""|RNo match for |r{ref}|R.|n"""
_EMOTE_MULTIMATCH_ERROR = \
"""|RMultiple possibilities for {ref}:
"""|RMultiple possibilities for {ref}:
|r{reflist}|n"""
_RE_FLAGS = re.MULTILINE + re.IGNORECASE + re.UNICODE
@ -168,6 +168,7 @@ _RE_LANGUAGE = re.compile(r"(?:\((\w+)\))*(\".+?\")")
# 2) for every person seeing the emote, parse this
# intermediary form into the one valid for that char.
class EmoteError(Exception):
pass
@ -240,6 +241,7 @@ def ordered_permutation_regex(sentence):
regex = r"|".join(sorted(set(solution), key=len, reverse=True))
return regex
def regex_tuple_from_key_alias(obj):
"""
This will build a regex tuple for any object, not just from those
@ -358,7 +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") else []) + \
[obj.sdesc.get_regex_tuple()
for obj in candidates if hasattr(obj, "sdesc")] + \
@ -418,7 +420,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]
@ -438,7 +440,7 @@ def parse_sdescs_and_recogs(sender, candidates, string, search_mode=False):
mapping[key] = obj
else:
refname = marker_match.group()
reflist = ["%s%s%s (%s%s)" % (inum+1, _NUM_SEP,
reflist = ["%s%s%s (%s%s)" % (inum + 1, _NUM_SEP,
_RE_PREFIX.sub("", refname), text,
" (%s)" % sender.key if sender == ob else "")
for inum, (ob, text) in enumerate(obj)]
@ -546,6 +548,7 @@ def send_emote(sender, receivers, emote, anonymous_add="first"):
# Handlers for sdesc and recog
#------------------------------------------------------------
class SdescHandler(object):
"""
This Handler wraps all operations with sdescs. We
@ -559,6 +562,7 @@ class SdescHandler(object):
_regex - an empty dictionary
"""
def __init__(self, obj):
"""
Initialize the handler
@ -656,6 +660,7 @@ class RecogHandler(object):
_recog_obj2regex
"""
def __init__(self, obj):
"""
Initialize the handler
@ -785,6 +790,7 @@ class RecogHandler(object):
class RPCommand(Command):
"simple parent"
def parse(self):
"strip extra whitespace"
self.args = self.args.strip()
@ -843,7 +849,6 @@ class CmdSay(RPCommand): # replaces standard say
locks = "cmd:all()"
def func(self):
"Run the say command"
caller = self.caller
@ -884,7 +889,7 @@ class CmdSdesc(RPCommand): # set/look at own sdesc
sdesc = _RE_CHAREND.sub("", self.args)
try:
sdesc = caller.sdesc.add(sdesc)
except SdescError, err:
except SdescError as err:
caller.msg(err)
return
caller.msg("%s's sdesc was set to '%s'." % (caller.key, sdesc))
@ -1034,11 +1039,11 @@ class CmdRecog(RPCommand): # assign personal alias to object in room
if nmatches == 0:
caller.msg(_EMOTE_NOMATCH_ERROR.format(ref=sdesc))
elif nmatches > 1:
reflist = ["%s%s%s (%s%s)" % (inum+1, _NUM_SEP,
reflist = ["%s%s%s (%s%s)" % (inum + 1, _NUM_SEP,
_RE_PREFIX.sub("", sdesc), caller.recog.get(obj),
" (%s)" % caller.key if caller == obj else "")
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):
@ -1053,7 +1058,7 @@ class CmdRecog(RPCommand): # assign personal alias to object in room
sdesc = obj.sdesc.get() if hasattr(obj, "sdesc") else obj.key
try:
alias = caller.recog.add(obj, alias)
except RecogError, err:
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))
@ -1095,7 +1100,7 @@ class CmdMask(RPCommand):
caller.sdesc.add(sdesc)
caller.msg("You wear a mask as '%s'." % sdesc)
else:
#unmask
# unmask
old_sdesc = caller.db.unmasked_sdesc
if not old_sdesc:
caller.msg("You are not wearing a mask.")
@ -1110,6 +1115,7 @@ class RPSystemCmdSet(CmdSet):
"""
Mix-in for adding rp-commands to default cmdset.
"""
def at_cmdset_creation(self):
self.add(CmdEmote())
self.add(CmdSay())
@ -1258,7 +1264,8 @@ class ContribRPObject(DefaultObject):
# the sdesc-related substitution
is_builder = self.locks.check_lockstring(self, "perm(Builder)")
use_dbref = is_builder if use_dbref is None else use_dbref
search_obj = lambda string: ObjectDB.objects.object_search(string,
def search_obj(string): return ObjectDB.objects.object_search(string,
attribute_name=attribute_name,
typeclass=typeclass,
candidates=candidates,
@ -1488,4 +1495,4 @@ class ContribRPCharacter(DefaultCharacter, ContribRPObject):
return "%s|w%s|n" % ("|W(%s)" % language if language else "", text)
#from evennia.contrib import rplanguage
#return "|w%s|n" % rplanguage.obfuscate_language(text, level=1.0)
# return "|w%s|n" % rplanguage.obfuscate_language(text, level=1.0)

View file

@ -40,6 +40,7 @@ class SimpleDoor(DefaultExit):
sides using `exitname.setlock("traverse:false())`
"""
def at_object_creation(self):
"""
Called the very first time the door is created.
@ -165,4 +166,3 @@ class CmdOpenCloseDoor(default_cmds.MuxCommand):
else:
door.setlock("traverse:false()")
self.caller.msg("You close %s." % door.key)

View file

@ -42,10 +42,12 @@ MOVE_DELAY = {"stroll": 6,
"run": 2,
"sprint": 1}
class SlowExit(DefaultExit):
"""
This overloads the way moving happens.
"""
def at_traverse(self, traversing_object, target_location):
"""
Implements the actual traversal, using utils.delay to delay the move_to.
@ -87,6 +89,7 @@ SPEED_DESCS = {"stroll": "strolling",
"run": "running",
"sprint": "sprinting"}
class CmdSetSpeed(Command):
"""
set your movement speed

View file

@ -48,6 +48,7 @@ def info1(caller):
return text, options
def info2(caller):
text = "'My name is not really important ... I'm just an NPC after all.'"
@ -67,7 +68,6 @@ def info3(caller):
{"desc": "Wait, why don't you tell me your name first?",
"goto": "info2"})
return text, options
@ -82,6 +82,7 @@ def END(caller):
# The talk command (sits on the NPC)
#
class CmdTalk(default_cmds.MuxCommand):
"""
Talks to an npc
@ -112,6 +113,7 @@ class CmdTalk(default_cmds.MuxCommand):
class TalkingCmdSet(CmdSet):
"Stores the talk command."
key = "talkingcmdset"
def at_cmdset_creation(self):
"populates the cmdset"
self.add(CmdTalk())
@ -122,6 +124,7 @@ class TalkingNPC(DefaultObject):
This implements a simple Object using the talk command and using
the conversation defined above.
"""
def at_object_creation(self):
"This is called when object is first created."
self.db.desc = "This is a talkative NPC."

View file

@ -64,6 +64,7 @@ class TestLanguage(EvenniaTest):
# Testing of emoting / sdesc / recog system
from evennia import create_object
from evennia.contrib import rpsystem
@ -176,6 +177,7 @@ from evennia.contrib import extended_room
from evennia import gametime
from evennia.objects.objects import DefaultRoom
class ForceUTCDatetime(datetime.datetime):
"""Force UTC datetime."""
@ -185,6 +187,7 @@ class ForceUTCDatetime(datetime.datetime):
"""Force fromtimestamp to run with naive datetimes."""
return datetime.datetime.utcfromtimestamp(timestamp)
@patch('evennia.contrib.extended_room.datetime.datetime', ForceUTCDatetime)
class TestExtendedRoom(CommandTest):
room_typeclass = extended_room.ExtendedRoom
@ -237,6 +240,7 @@ class TestExtendedRoom(CommandTest):
from evennia.contrib import barter
class TestBarter(CommandTest):
def setUp(self):
@ -295,7 +299,7 @@ class TestBarter(CommandTest):
self.call(barter.CmdTrade(), "Char decline : Nope!", "You say, \"Nope!\"", caller=self.char2)
self.call(barter.CmdTrade(), "Char2 : Hey wanna trade?", "You say, \"Hey wanna trade?\"", caller=self.char1)
self.call(barter.CmdTrade(), "Char accept : Sure!", "You say, \"Sure!\"", caller=self.char2)
self.call(barter.CmdOffer(), "TradeItem3", "Your trade action: You offer TradeItem3",caller=self.char2)
self.call(barter.CmdOffer(), "TradeItem3", "Your trade action: You offer TradeItem3", caller=self.char2)
self.call(barter.CmdOffer(), "TradeItem1 : Here's my offer.", "You say, \"Here's my offer.\"\n [You offer TradeItem1]")
self.call(barter.CmdAccept(), "", "Your trade action: You accept the offer. Char2 must now also accept")
self.call(barter.CmdDecline(), "", "Your trade action: You change your mind, declining the current offer.")
@ -319,9 +323,11 @@ class TestBarter(CommandTest):
# Test wilderness
from evennia.contrib import wilderness
from evennia import DefaultCharacter
class TestWilderness(EvenniaTest):
def setUp(self):
@ -438,9 +444,11 @@ class TestWilderness(EvenniaTest):
new_loc = wilderness.get_new_coordinates(loc, direction)
self.assertEquals(new_loc, correct_loc, direction)
# Testing chargen contrib
from evennia.contrib import chargen
class TestChargen(CommandTest):
def test_ooclook(self):
@ -451,13 +459,15 @@ class TestChargen(CommandTest):
self.call(chargen.CmdOOCCharacterCreate(), "testchar", "The character testchar was successfully created!", caller=self.account)
self.call(chargen.CmdOOCCharacterCreate(), "testchar", "Character testchar already exists.", caller=self.account)
self.assertTrue(self.account.db._character_dbrefs)
self.call(chargen.CmdOOCLook(), "", "You, TestAccount, are an OOC ghost without form.",caller=self.account)
self.call(chargen.CmdOOCLook(), "", "You, TestAccount, are an OOC ghost without form.", caller=self.account)
self.call(chargen.CmdOOCLook(), "testchar", "testchar(", caller=self.account)
# Testing clothing contrib
from evennia.contrib import clothing
from evennia.objects.objects import DefaultRoom
class TestClothingCmd(CommandTest):
def test_clothingcommands(self):
@ -501,6 +511,7 @@ class TestClothingCmd(CommandTest):
# Test inventory command.
self.call(clothing.CmdInventory(), "", "You are not carrying or wearing anything.", caller=wearer)
class TestClothingFunc(EvenniaTest):
def test_clothingfunctions(self):
@ -537,42 +548,50 @@ class TestClothingFunc(EvenniaTest):
test_pants.wear(wearer, True)
self.assertEqual(clothing.get_worn_clothes(wearer), [test_hat, test_pants])
self.assertEqual(clothing.clothing_type_count(clothes_list), {'hat':1, 'top':1, 'bottom':1})
self.assertEqual(clothing.clothing_type_count(clothes_list), {'hat': 1, 'top': 1, 'bottom': 1})
self.assertEqual(clothing.single_type_count(clothes_list, 'hat'), 1)
# Testing custom_gametime
from evennia.contrib import custom_gametime
def _testcallback():
pass
class TestCustomGameTime(EvenniaTest):
def setUp(self):
super(TestCustomGameTime, self).setUp()
gametime.gametime = Mock(return_value=2975000898.46) # does not seem to work
def tearDown(self):
if hasattr(self, "timescript"):
self.timescript.stop()
def test_time_to_tuple(self):
self.assertEqual(custom_gametime.time_to_tuple(10000, 34,2,4,6,1), (294, 2, 0, 0, 0, 0))
self.assertEqual(custom_gametime.time_to_tuple(10000, 3,3,4), (3333, 0, 0, 1))
self.assertEqual(custom_gametime.time_to_tuple(100000, 239,24,3), (418, 4, 0, 2))
self.assertEqual(custom_gametime.time_to_tuple(10000, 34, 2, 4, 6, 1), (294, 2, 0, 0, 0, 0))
self.assertEqual(custom_gametime.time_to_tuple(10000, 3, 3, 4), (3333, 0, 0, 1))
self.assertEqual(custom_gametime.time_to_tuple(100000, 239, 24, 3), (418, 4, 0, 2))
def test_gametime_to_realtime(self):
self.assertEqual(custom_gametime.gametime_to_realtime(days=2, mins=4), 86520.0)
self.assertEqual(custom_gametime.gametime_to_realtime(format=True, days=2), (0,0,0,1,0,0,0))
self.assertEqual(custom_gametime.gametime_to_realtime(format=True, days=2), (0, 0, 0, 1, 0, 0, 0))
def test_realtime_to_gametime(self):
self.assertEqual(custom_gametime.realtime_to_gametime(days=2, mins=34), 349680.0)
self.assertEqual(custom_gametime.realtime_to_gametime(days=2, mins=34, format=True), (0, 0, 0, 4, 1, 8, 0))
self.assertEqual(custom_gametime.realtime_to_gametime(format=True, days=2, mins=4), (0, 0, 0, 4, 0, 8, 0))
def test_custom_gametime(self):
self.assertEqual(custom_gametime.custom_gametime(), (102, 5, 2, 6, 21, 8, 18))
self.assertEqual(custom_gametime.custom_gametime(absolute=True), (102, 5, 2, 6, 21, 8, 18))
def test_real_seconds_until(self):
self.assertEqual(custom_gametime.real_seconds_until(year=2300, month=11, day=6), 31911667199.77)
def test_schedule(self):
self.timescript = custom_gametime.schedule(_testcallback, repeat=True, min=5, sec=0)
self.assertEqual(self.timescript.interval, 1700.7699999809265)
@ -585,9 +604,10 @@ class TestDice(CommandTest):
def test_roll_dice(self, mocked_randint):
# we must import dice here for the mocked randint to apply correctly.
from evennia.contrib import dice
self.assertEqual(dice.roll_dice(6, 6, modifier=('+', 4)), mocked_randint()*6 + 4)
self.assertEqual(dice.roll_dice(6, 6, modifier=('+', 4)), mocked_randint() * 6 + 4)
self.assertEqual(dice.roll_dice(6, 6, conditional=('<', 35)), True)
self.assertEqual(dice.roll_dice(6, 6, conditional=('>', 33)), False)
def test_cmddice(self, mocked_randint):
from evennia.contrib import dice
self.call(dice.CmdDice(), "3d6 + 4", "You roll 3d6 + 4.| Roll(s): 5, 5 and 5. Total result is 19.")
@ -596,29 +616,37 @@ class TestDice(CommandTest):
# Test email-login
from evennia.contrib import email_login
class TestEmailLogin(CommandTest):
def test_connect(self):
self.call(email_login.CmdUnconnectedConnect(), "mytest@test.com test", "The email 'mytest@test.com' does not match any accounts.")
self.call(email_login.CmdUnconnectedCreate(), '"mytest" mytest@test.com test11111', "A new account 'mytest' was created. Welcome!")
self.call(email_login.CmdUnconnectedConnect(), "mytest@test.com test11111", "", caller=self.account.sessions.get()[0])
def test_quit(self):
self.call(email_login.CmdUnconnectedQuit(), "", "", caller=self.account.sessions.get()[0])
def test_unconnectedlook(self):
self.call(email_login.CmdUnconnectedLook(), "", "==========")
def test_unconnectedhelp(self):
self.call(email_login.CmdUnconnectedHelp(), "", "You are not yet logged into the game.")
# test gendersub contrib
from evennia.contrib import gendersub
class TestGenderSub(CommandTest):
def test_setgender(self):
self.call(gendersub.SetGender(), "male", "Your gender was set to male.")
self.call(gendersub.SetGender(), "ambiguous", "Your gender was set to ambiguous.")
self.call(gendersub.SetGender(), "Foo", "Usage: @gender")
def test_gendercharacter(self):
char = create_object(gendersub.GenderCharacter, key="Gendered", location=self.room1)
txt = "Test |p gender"
@ -626,8 +654,10 @@ class TestGenderSub(CommandTest):
# test mail contrib
from evennia.contrib import mail
class TestMail(CommandTest):
def test_mail(self):
self.call(mail.CmdMail(), "2", "'2' is not a valid mail id.", caller=self.account)
@ -646,13 +676,15 @@ class TestMail(CommandTest):
# test map builder contrib
from evennia.contrib import mapbuilder
class TestMapBuilder(CommandTest):
def test_cmdmapbuilder(self):
self.call(mapbuilder.CmdMapBuilder(),
"evennia.contrib.mapbuilder.EXAMPLE1_MAP evennia.contrib.mapbuilder.EXAMPLE1_LEGEND",
"""Creating Map...|≈≈≈≈≈
"""Creating Map...|≈≈≈≈≈
n
n
@ -660,7 +692,7 @@ class TestMapBuilder(CommandTest):
|Creating Landmass...|""")
self.call(mapbuilder.CmdMapBuilder(),
"evennia.contrib.mapbuilder.EXAMPLE2_MAP evennia.contrib.mapbuilder.EXAMPLE2_LEGEND",
"""Creating Map...|≈ ≈ ≈ ≈ ≈
"""Creating Map...|≈ ≈ ≈ ≈ ≈
@ -674,6 +706,7 @@ class TestMapBuilder(CommandTest):
from evennia.contrib import menu_login
class TestMenuLogin(CommandTest):
def test_cmdunloggedlook(self):
self.call(menu_login.CmdUnloggedinLook(), "", "======")
@ -683,23 +716,26 @@ class TestMenuLogin(CommandTest):
from evennia.contrib import multidescer
class TestMultidescer(CommandTest):
def test_cmdmultidesc(self):
self.call(multidescer.CmdMultiDesc(),"/list", "Stored descs:\ncaller:")
self.call(multidescer.CmdMultiDesc(),"test = Desc 1", "Stored description 'test': \"Desc 1\"")
self.call(multidescer.CmdMultiDesc(),"test2 = Desc 2", "Stored description 'test2': \"Desc 2\"")
self.call(multidescer.CmdMultiDesc(),"/swap test-test2", "Swapped descs 'test' and 'test2'.")
self.call(multidescer.CmdMultiDesc(),"test3 = Desc 3init", "Stored description 'test3': \"Desc 3init\"")
self.call(multidescer.CmdMultiDesc(),"/list", "Stored descs:\ntest3: Desc 3init\ntest: Desc 1\ntest2: Desc 2\ncaller:")
self.call(multidescer.CmdMultiDesc(),"test3 = Desc 3", "Stored description 'test3': \"Desc 3\"")
self.call(multidescer.CmdMultiDesc(),"/set test1 + test2 + + test3", "test1 Desc 2 Desc 3\n\n"
self.call(multidescer.CmdMultiDesc(), "/list", "Stored descs:\ncaller:")
self.call(multidescer.CmdMultiDesc(), "test = Desc 1", "Stored description 'test': \"Desc 1\"")
self.call(multidescer.CmdMultiDesc(), "test2 = Desc 2", "Stored description 'test2': \"Desc 2\"")
self.call(multidescer.CmdMultiDesc(), "/swap test-test2", "Swapped descs 'test' and 'test2'.")
self.call(multidescer.CmdMultiDesc(), "test3 = Desc 3init", "Stored description 'test3': \"Desc 3init\"")
self.call(multidescer.CmdMultiDesc(), "/list", "Stored descs:\ntest3: Desc 3init\ntest: Desc 1\ntest2: Desc 2\ncaller:")
self.call(multidescer.CmdMultiDesc(), "test3 = Desc 3", "Stored description 'test3': \"Desc 3\"")
self.call(multidescer.CmdMultiDesc(), "/set test1 + test2 + + test3", "test1 Desc 2 Desc 3\n\n"
"The above was set as the current description.")
self.assertEqual(self.char1.db.desc, "test1 Desc 2 Desc 3")
# test simpledoor contrib
from evennia.contrib import simpledoor
class TestSimpleDoor(CommandTest):
def test_cmdopen(self):
self.call(simpledoor.CmdOpen(), "newdoor;door:contrib.simpledoor.SimpleDoor,backdoor;door = Room2",
@ -712,8 +748,10 @@ class TestSimpleDoor(CommandTest):
# test slow_exit contrib
from evennia.contrib import slow_exit
slow_exit.MOVE_DELAY = {"stroll":0, "walk": 0, "run": 0, "sprint": 0}
slow_exit.MOVE_DELAY = {"stroll": 0, "walk": 0, "run": 0, "sprint": 0}
class TestSlowExit(CommandTest):
def test_exit(self):
@ -724,12 +762,14 @@ class TestSlowExit(CommandTest):
# test talking npc contrib
from evennia.contrib import talking_npc
class TestTalkingNPC(CommandTest):
def test_talkingnpc(self):
npc = create_object(talking_npc.TalkingNPC, key="npctalker", location=self.room1)
self.call(talking_npc.CmdTalk(), "","(You walk up and talk to Char.)|")
self.call(talking_npc.CmdTalk(), "", "(You walk up and talk to Char.)|")
npc.delete()
@ -739,6 +779,7 @@ class TestTalkingNPC(CommandTest):
from evennia.contrib.tutorial_world import mob
class TestTutorialWorldMob(EvenniaTest):
def test_mob(self):
mobobj = create_object(mob.Mob, key="mob")
@ -748,28 +789,34 @@ class TestTutorialWorldMob(EvenniaTest):
mobobj.set_dead()
self.assertEqual(mobobj.db.is_dead, True)
mobobj._set_ticker(0, "foo", stop=True)
#TODO should be expanded with further tests of the modes and damage etc.
# TODO should be expanded with further tests of the modes and damage etc.
# test tutorial_world/objects
from evennia.contrib.tutorial_world import objects as tutobjects
class TestTutorialWorldObjects(CommandTest):
def test_tutorialobj(self):
obj1 = create_object(tutobjects.TutorialObject, key="tutobj")
obj1.reset()
self.assertEqual(obj1.location, obj1.home)
def test_readable(self):
readable = create_object(tutobjects.Readable, key="book", location=self.room1)
readable.db.readable_text = "Text to read"
self.call(tutobjects.CmdRead(), "book","You read book:\n Text to read", obj=readable)
self.call(tutobjects.CmdRead(), "book", "You read book:\n Text to read", obj=readable)
def test_climbable(self):
climbable = create_object(tutobjects.Climbable, key="tree", location=self.room1)
self.call(tutobjects.CmdClimb(), "tree", "You climb tree. Having looked around, you climb down again.", obj=climbable)
self.assertEqual(self.char1.tags.get("tutorial_climbed_tree", category="tutorial_world"), "tutorial_climbed_tree")
def test_obelisk(self):
obelisk = create_object(tutobjects.Obelisk, key="obelisk", location=self.room1)
self.assertEqual(obelisk.return_appearance(self.char1).startswith("|cobelisk("), True)
def test_lightsource(self):
light = create_object(tutobjects.LightSource, key="torch", location=self.room1)
self.call(tutobjects.CmdLight(), "", "You light torch.", obj=light)
@ -777,11 +824,12 @@ class TestTutorialWorldObjects(CommandTest):
if hasattr(light, "deferred"):
light.deferred.cancel()
self.assertFalse(light.pk)
def test_crumblingwall(self):
wall = create_object(tutobjects.CrumblingWall, key="wall", location=self.room1)
self.assertFalse(wall.db.button_exposed)
self.assertFalse(wall.db.exit_open)
wall.db.root_pos = {"yellow":0, "green":0,"red":0,"blue":0}
wall.db.root_pos = {"yellow": 0, "green": 0, "red": 0, "blue": 0}
self.call(tutobjects.CmdShiftRoot(), "blue root right",
"You shove the root adorned with small blue flowers to the right.", obj=wall)
self.call(tutobjects.CmdShiftRoot(), "red root left",
@ -798,18 +846,22 @@ class TestTutorialWorldObjects(CommandTest):
if hasattr(wall, "deferred"):
wall.deferred.cancel()
wall.delete()
def test_weapon(self):
weapon = create_object(tutobjects.Weapon, key="sword", location=self.char1)
self.call(tutobjects.CmdAttack(), "Char", "You stab with sword.", obj=weapon, cmdstring="stab")
self.call(tutobjects.CmdAttack(), "Char", "You slash with sword.", obj=weapon, cmdstring="slash")
def test_weaponrack(self):
rack = create_object(tutobjects.WeaponRack, key="rack", location=self.room1)
rack.db.available_weapons = ["sword"]
self.call(tutobjects.CmdGetWeapon(), "", "You find Rusty sword.", obj=rack)
# test tutorial_world/
from evennia.contrib.tutorial_world import rooms as tutrooms
class TestTutorialWorldRooms(CommandTest):
def test_cmdtutorial(self):
room = create_object(tutrooms.TutorialRoom, key="tutroom")
@ -820,14 +872,17 @@ class TestTutorialWorldRooms(CommandTest):
self.call(tutrooms.CmdTutorialLook(), "detail", "A detail", obj=room)
self.call(tutrooms.CmdTutorialLook(), "foo", "A detail", obj=room)
room.delete()
def test_weatherroom(self):
room = create_object(tutrooms.WeatherRoom, key="weatherroom")
room.update_weather()
tutrooms.TICKER_HANDLER.remove(interval=room.db.interval, callback=room.update_weather, idstring="tutorial")
room.delete()
def test_introroom(self):
room = create_object(tutrooms.IntroRoom, key="introroom")
room.at_object_receive(self.char1, self.room1)
def test_bridgeroom(self):
room = create_object(tutrooms.BridgeRoom, key="bridgeroom")
room.update_weather()
@ -837,19 +892,24 @@ class TestTutorialWorldRooms(CommandTest):
room.at_object_leave(self.char1, self.room1)
tutrooms.TICKER_HANDLER.remove(interval=room.db.interval, callback=room.update_weather, idstring="tutorial")
room.delete()
def test_darkroom(self):
room = create_object(tutrooms.DarkRoom, key="darkroom")
self.char1.move_to(room)
self.call(tutrooms.CmdDarkHelp(), "", "Can't help you until")
def test_teleportroom(self):
create_object(tutrooms.TeleportRoom, key="teleportroom")
def test_outroroom(self):
create_object(tutrooms.OutroRoom, key="outroroom")
# test turnbattle
from evennia.contrib import turnbattle
from evennia.objects.objects import DefaultRoom
class TestTurnBattleCmd(CommandTest):
# Test combat commands
@ -860,6 +920,7 @@ class TestTurnBattleCmd(CommandTest):
self.call(turnbattle.CmdDisengage(), "", "You can only do that in combat. (see: help fight)")
self.call(turnbattle.CmdRest(), "", "Char rests to recover HP.")
class TestTurnBattleFunc(EvenniaTest):
# Test combat functions
@ -944,6 +1005,7 @@ class TestTurnBattleFunc(EvenniaTest):
from evennia.contrib.unixcommand import UnixCommand
class CmdDummy(UnixCommand):
"""A dummy UnixCommand."""
@ -991,6 +1053,7 @@ class TestUnixCommand(CommandTest):
import re
from evennia.contrib import color_markups
class TestColorMarkup(EvenniaTest):
"""
Note: Normally this would be tested by importing the ansi parser and run
@ -999,6 +1062,7 @@ class TestColorMarkup(EvenniaTest):
many other modules it appears that trying to overload
settings to test it causes issues with unrelated tests.
"""
def test_curly_markup(self):
ansi_map = color_markups.CURLY_COLOR_ANSI_EXTRA_MAP
self.assertIsNotNone(re.match(re.escape(ansi_map[7][0]), '{r'))
@ -1047,10 +1111,12 @@ class TestColorMarkup(EvenniaTest):
self.assertEqual(bright_map[0][1], '%c[500')
self.assertEqual(bright_map[-1][1], '%c[222')
from evennia.contrib import random_string_generator
SIMPLE_GENERATOR = random_string_generator.RandomStringGenerator("simple", "[01]{2}")
class TestRandomStringGenerator(EvenniaTest):
def test_generate(self):

View file

@ -12,6 +12,7 @@ make sure to put it on yourself or you won't see any messages!
import random
from evennia import DefaultScript
class BodyFunctions(DefaultScript):
"""
This class defines the script itself
@ -21,7 +22,7 @@ class BodyFunctions(DefaultScript):
self.key = "bodyfunction"
self.desc = "Adds various timed events to a character."
self.interval = 20 # seconds
#self.repeats = 5 # repeat only a certain number of times
# self.repeats = 5 # repeat only a certain number of times
self.start_delay = True # wait self.interval until first call
#self.persistent = True

View file

@ -39,7 +39,7 @@
#
#HEADER
# HEADER
# everything in this block will be appended to the beginning of
# all other #CODE blocks when they are executed.
@ -51,7 +51,7 @@ from evennia import DefaultObject
limbo = search_object('Limbo')[0]
#CODE
# CODE
# This is the first code block. Within each block, Python
# code works as normal. Note how we make use if imports and
@ -66,7 +66,7 @@ red_button = create_object(red_button.RedButton, key="Red button",
# we take a look at what we created
caller.msg("A %s was created." % red_button.key)
#CODE
# CODE
# this code block has 'table' and 'chair' set as deletable
# objects. This means that when the batchcode processor runs in

View file

@ -33,6 +33,7 @@ class RedButton(DefaultObject):
desc_lamp_broken - description when lamp is broken
"""
def at_object_creation(self):
"""
This function is called when object is created. Use this

View file

@ -26,12 +26,14 @@ from evennia.contrib.tutorial_examples import cmdset_red_button as cmdsetexample
# a bright light. The last one also has a timer component that allows it
# to remove itself after a while (and the player recovers their eyesight).
class ClosedLidState(DefaultScript):
"""
This manages the cmdset for the "closed" button state. What this
means is that while this script is valid, we add the RedButtonClosed
cmdset to it (with commands like open, nudge lid etc)
"""
def at_script_creation(self):
"Called when script first created."
self.desc = "Script that manages the closed-state cmdsets for red button."
@ -44,7 +46,7 @@ class ClosedLidState(DefaultScript):
checked so we don't need to worry about adding the script to an
open lid.
"""
#All we do is add the cmdset for the closed state.
# All we do is add the cmdset for the closed state.
self.obj.cmdset.add(cmdsetexamples.LidClosedCmdSet)
def is_valid(self):
@ -67,6 +69,7 @@ class OpenLidState(DefaultScript):
This manages the cmdset for the "open" button state. This will add
the RedButtonOpen
"""
def at_script_creation(self):
"Called when script first created."
self.desc = "Script that manages the opened-state cmdsets for red button."
@ -105,6 +108,7 @@ class BlindedState(DefaultScript):
restored. It's up to the function starting the script to actually
set it on the right account object.
"""
def at_script_creation(self):
"""
We set up the script here.
@ -158,6 +162,7 @@ class CloseLidEvent(DefaultScript):
script that should be started/created when the
lid is opened.
"""
def at_script_creation(self):
"""
Called when script object is first created. Sets things up.
@ -194,10 +199,12 @@ class CloseLidEvent(DefaultScript):
"""
self.obj.close_lid()
class BlinkButtonEvent(DefaultScript):
"""
This timed script lets the button flash at regular intervals.
"""
def at_script_creation(self):
"""
Sets things up. We want the button's lamp to blink at
@ -206,9 +213,9 @@ class BlinkButtonEvent(DefaultScript):
"""
self.key = "blink_button"
self.desc = "Blinks red buttons"
self.interval = 35 #seconds
self.start_delay = False #blink right away
self.persistent = True #keep blinking also after server reboot
self.interval = 35 # seconds
self.start_delay = False # blink right away
self.persistent = True # keep blinking also after server reboot
def is_valid(self):
"""
@ -223,6 +230,7 @@ class BlinkButtonEvent(DefaultScript):
"""
self.obj.blink()
class DeactivateButtonEvent(DefaultScript):
"""
This deactivates the button for a short while (it won't blink, won't
@ -231,13 +239,14 @@ class DeactivateButtonEvent(DefaultScript):
in the AddBlindedCmdSet script since that script is defined on the *account*
whereas this one must be defined on the *button*.
"""
def at_script_creation(self):
"""
Sets things up.
"""
self.key = "deactivate_button"
self.desc = "Deactivate red button temporarily"
self.interval = 21 #seconds
self.interval = 21 # seconds
self.start_delay = True # wait with the first repeat for self.interval seconds.
self.persistent = True
self.repeats = 1 # only do this once

View file

@ -5,4 +5,3 @@ This package holds the demo game of Evennia.
from __future__ import absolute_import
from . import mob, objects, rooms

View file

@ -13,6 +13,7 @@ from evennia import Command, CmdSet
from evennia import logger
from evennia.contrib.tutorial_world import objects as tut_objects
class CmdMobOnOff(Command):
"""
Activates/deactivates Mob
@ -51,9 +52,11 @@ class MobCmdSet(CmdSet):
"""
Holds the admin command controlling the mob
"""
def at_cmdset_creation(self):
self.add(CmdMobOnOff())
class Mob(tut_objects.TutorialObject):
"""
This is a state-machine AI mobile. It has several states which are
@ -91,6 +94,7 @@ class Mob(tut_objects.TutorialObject):
happen to roam into a room with no exits.
"""
def at_init(self):
"""
When initialized from cache (after a server reboot), set up
@ -379,7 +383,6 @@ class Mob(tut_objects.TutorialObject):
else:
logger.log_err("Mob: mob.db.send_defeated_to not found: %s" % self.db.send_defeated_to)
# response methods - called by other objects
def at_hit(self, weapon, attacker, damage):

View file

@ -106,6 +106,7 @@ class CmdSetReadable(CmdSet):
"""
A CmdSet for readables.
"""
def at_cmdset_creation(self):
"""
Called when the cmdset is created.
@ -117,6 +118,7 @@ class Readable(TutorialObject):
"""
This simple object defines some attributes and
"""
def at_object_creation(self):
"""
Called when object is created. We make sure to set the needed
@ -176,6 +178,7 @@ class CmdClimb(Command):
class CmdSetClimbable(CmdSet):
"""Climbing cmdset"""
def at_cmdset_creation(self):
"""populate set"""
self.add(CmdClimb())
@ -303,6 +306,7 @@ class LightSource(TutorialObject):
When burned out, the object will be deleted.
"""
def at_init(self):
"""
If this is called with the Attribute is_giving_light already
@ -589,6 +593,7 @@ class CrumblingWall(TutorialObject, DefaultExit):
whenever the button is pushed (this hides it as an exit
until it actually is)
"""
def at_init(self):
"""
Called when object is recalled from cache.
@ -838,6 +843,7 @@ class CmdAttack(Command):
class CmdSetWeapon(CmdSet):
"""Holds the attack command."""
def at_cmdset_creation(self):
"""called at first object creation."""
self.add(CmdAttack())
@ -854,6 +860,7 @@ class Weapon(TutorialObject):
type of attack) (0-10)
"""
def at_object_creation(self):
"""Called at first creation of the object"""
super(Weapon, self).at_object_creation()
@ -987,7 +994,7 @@ WEAPON_PROTOTYPES = {
"hit": 0.85,
"parry": 0.7,
"damage": 11}
}
}
class CmdGetWeapon(Command):
@ -1037,6 +1044,7 @@ class WeaponRack(TutorialObject):
grab another one.
"""
def at_object_creation(self):
"""
called at creation

View file

@ -215,6 +215,7 @@ class TutorialRoom(DefaultRoom):
This is the base room type for all rooms in the tutorial world.
It defines a cmdset on itself for reading tutorial info about the location.
"""
def at_object_creation(self):
"""Called when room is first created"""
self.db.tutorial_info = "This is a tutorial room. It allows you to use the 'tutorial' command."
@ -300,6 +301,7 @@ class WeatherRoom(TutorialRoom):
inherit from this.
"""
def at_object_creation(self):
"""
Called when object is first created.
@ -355,6 +357,7 @@ class IntroRoom(TutorialRoom):
properties to customize:
char_health - integer > 0 (default 20)
"""
def at_object_creation(self):
"""
Called when the room is first created.
@ -377,7 +380,7 @@ class IntroRoom(TutorialRoom):
character.db.health_max = health
if character.is_superuser:
string = "-"*78 + SUPERUSER_WARNING + "-"*78
string = "-" * 78 + SUPERUSER_WARNING + "-" * 78
character.msg("|r%s|n" % string.format(name=character.key, quell="|w@quell|r"))
@ -625,6 +628,7 @@ class BridgeRoom(WeatherRoom):
the CmdLookBridge command).
"""
def at_object_creation(self):
"""Setups the room"""
# this will start the weather room's ticker and tell
@ -827,6 +831,7 @@ class DarkRoom(TutorialRoom):
may have been beaten up by the ghostly apparition at this point.
"""
def at_object_creation(self):
"""
Called when object is first created.
@ -942,6 +947,7 @@ class TeleportRoom(TutorialRoom):
failure_teleport_msg - message to echo while teleporting to failure
"""
def at_object_creation(self):
"""Called at first creation"""
super(TeleportRoom, self).at_object_creation()

View file

@ -16,6 +16,7 @@ own cmdsets by inheriting from them or directly from `evennia.CmdSet`.
from evennia import default_cmds
class CharacterCmdSet(default_cmds.CharacterCmdSet):
"""
The `CharacterCmdSet` contains general in-game commands like `look`,

View file

@ -25,6 +25,7 @@ line to your settings file:
"""
def at_search_result(matches, caller, query="", quiet=False, **kwargs):
"""
This is a generic hook for handling all processing of a search

View file

@ -31,6 +31,7 @@ your settings file:
"""
def cmdparser(raw_string, cmdset, caller, match_index=None):
"""
This function is called by the cmdhandler once it has

View file

@ -45,7 +45,7 @@ and can be used to customize it to each session.
"""
#def capitalize(text, *args, **kwargs):
# def capitalize(text, *args, **kwargs):
# "Silly capitalize example. Used as {capitalize() ... {/capitalize"
# session = kwargs.get("session")
# return text.capitalize()

View file

@ -20,7 +20,7 @@ lock functions from evennia.locks.lockfuncs.
"""
#def myfalse(accessing_obj, accessed_obj, *args, **kwargs):
# def myfalse(accessing_obj, accessed_obj, *args, **kwargs):
# """
# called in lockstring with myfalse().
# A simple logger that always returns false. Prints to stdout

View file

@ -114,4 +114,4 @@ MSSPTable = {
"TRAINING SYSTEM": "None", # "None", "Level", "Skill", "Both"
"WORLD ORIGINALITY": "None", # "All Stock", "Mostly Stock", "Mostly Original", "All Original"
}
}

View file

@ -23,6 +23,7 @@ settings file:
from evennia.server.serversession import ServerSession as BaseServerSession
class ServerSession(BaseServerSession):
"""
This class represents a player's session and is a template for

View file

@ -26,4 +26,3 @@ def at_webserver_root_creation(web_root):
"""
return web_root

View file

@ -24,6 +24,7 @@ several more options for customizing the Guest account system.
from evennia import DefaultAccount, DefaultGuest
class Account(DefaultAccount):
"""
This class describes the actual OOC account (i.e. the user connecting

View file

@ -14,6 +14,7 @@ to be modified.
from evennia import DefaultChannel
class Channel(DefaultChannel):
"""
Working methods:

View file

@ -9,6 +9,7 @@ creation commands.
"""
from evennia import DefaultCharacter
class Character(DefaultCharacter):
"""
The Character defaults to reimplementing some of base Object's hook methods with the

View file

@ -8,6 +8,7 @@ for allowing Characters to traverse the exit to its destination.
"""
from evennia import DefaultExit
class Exit(DefaultExit):
"""
Exits are connectors between rooms. Exits are normal Objects except

View file

@ -12,6 +12,7 @@ inheritance.
"""
from evennia import DefaultObject
class Object(DefaultObject):
"""
This is the root typeclass object, implementing an in-game Evennia

View file

@ -38,7 +38,7 @@ See the `@spawn` command and `evennia.utils.spawner` for more info.
#from random import randint
#
#GOBLIN = {
# GOBLIN = {
# "key": "goblin grunt",
# "health": lambda: randint(20,30),
# "resists": ["cold", "poison"],
@ -46,13 +46,13 @@ See the `@spawn` command and `evennia.utils.spawner` for more info.
# "weaknesses": ["fire", "light"]
# }
#
#GOBLIN_WIZARD = {
# GOBLIN_WIZARD = {
# "prototype": "GOBLIN",
# "key": "goblin wizard",
# "spells": ["fire ball", "lighting bolt"]
# }
#
#GOBLIN_ARCHER = {
# GOBLIN_ARCHER = {
# "prototype": "GOBLIN",
# "key": "goblin archer",
# "attacks": ["short bow"]
@ -62,12 +62,12 @@ See the `@spawn` command and `evennia.utils.spawner` for more info.
# (nor key) of its own, so it should normally only be
# used as a mix-in, as in the example of the goblin
# archwizard below.
#ARCHWIZARD_MIXIN = {
# ARCHWIZARD_MIXIN = {
# "attacks": ["archwizard staff"],
# "spells": ["greater fire ball", "greater lighting"]
#}
#
#GOBLIN_ARCHWIZARD = {
# GOBLIN_ARCHWIZARD = {
# "key": "goblin archwizard",
# "prototype" : ("GOBLIN_WIZARD", "ARCHWIZARD_MIXIN")
#}

View file

@ -8,12 +8,12 @@ from django.contrib import admin
from evennia.help.models import HelpEntry
from evennia.typeclasses.admin import TagInline
class HelpTagInline(TagInline):
model = HelpEntry.db_tags.through
related_field = "helpentry"
class HelpEntryForm(forms.ModelForm):
"Defines how to display the help entry"
class Meta(object):
@ -22,8 +22,9 @@ class HelpEntryForm(forms.ModelForm):
db_help_category = forms.CharField(label="Help category", initial='General',
help_text="organizes help entries in lists")
db_lock_storage = forms.CharField(label="Locks", initial='view:all()',required=False,
widget=forms.TextInput(attrs={'size':'40'}),)
db_lock_storage = forms.CharField(label="Locks", initial='view:all()', required=False,
widget=forms.TextInput(attrs={'size': '40'}),)
class HelpEntryAdmin(admin.ModelAdmin):
"Sets up the admin manaager for help entries"
@ -38,9 +39,9 @@ class HelpEntryAdmin(admin.ModelAdmin):
form = HelpEntryForm
fieldsets = (
(None, {'fields':(('db_key', 'db_help_category'),
(None, {'fields': (('db_key', 'db_help_category'),
'db_entrytext', 'db_lock_storage'),
'description':"Sets a Help entry. Set lock to <i>view:all()</I> unless you want to restrict it."}),)
'description': "Sets a Help entry. Set lock to <i>view:all()</I> unless you want to restrict it."}),)
admin.site.register(HelpEntry, HelpEntryAdmin)

View file

@ -24,6 +24,7 @@ class HelpEntryManager(TypedObjectManager):
search_help (equivalent to evennia.search_helpentry)
"""
def find_topicmatch(self, topicstr, exact=False):
"""
Searches for matching topics or aliases based on player's

View file

@ -346,8 +346,8 @@ def attr(accessing_obj, accessed_obj, *args, **kwargs):
# check attributes, if they exist
if (hasattr(accessing_obj, 'attributes') and accessing_obj.attributes.has(attrname)):
if value:
return (hasattr(accessing_obj, 'attributes')
and valcompare(accessing_obj.attributes.get(attrname), value, compare))
return (hasattr(accessing_obj, 'attributes') and
valcompare(accessing_obj.attributes.get(attrname), value, compare))
# fails on False/None values
return bool(accessing_obj.attributes.get(attrname))
return False
@ -366,6 +366,7 @@ def objattr(accessing_obj, accessed_obj, *args, **kwargs):
"""
return attr(accessed_obj, accessed_obj, *args, **kwargs)
def locattr(accessing_obj, accessed_obj, *args, **kwargs):
"""
Usage:
@ -386,6 +387,7 @@ def locattr(accessing_obj, accessed_obj, *args, **kwargs):
return attr(accessing_obj.location, accessed_obj, *args, **kwargs)
return False
def objlocattr(accessing_obj, accessed_obj, *args, **kwargs):
"""
Usage:
@ -464,6 +466,7 @@ def attr_ne(accessing_obj, accessed_obj, *args, **kwargs):
"""
return attr(accessing_obj, accessed_obj, *args, **{'compare': 'ne'})
def tag(accessing_obj, accessed_obj, *args, **kwargs):
"""
Usage:
@ -481,6 +484,7 @@ def tag(accessing_obj, accessed_obj, *args, **kwargs):
category = args[1] if len(args) > 1 else None
return accessing_obj.tags.get(tagkey, category=category)
def objtag(accessing_obj, accessed_obj, *args, **kwargs):
"""
Usage:
@ -492,6 +496,7 @@ def objtag(accessing_obj, accessed_obj, *args, **kwargs):
"""
return accessed_obj.tags.get(*args)
def inside(accessing_obj, accessed_obj, *args, **kwargs):
"""
Usage:
@ -548,7 +553,7 @@ def holds(accessing_obj, accessed_obj, *args, **kwargs):
if len(args) == 1:
# command is holds(dbref/key) - check if given objname/dbref is held by accessing_ob
return check_holds(args[0])
elif len(args = 2):
elif len(args=2):
# command is holds(attrname, value) check if any held object has the given attribute and value
for obj in contents:
if obj.attributes.get(args[0]) == args[1]:
@ -566,6 +571,7 @@ def superuser(*args, **kwargs):
"""
return False
def has_account(accessing_obj, accessed_obj, *args, **kwargs):
"""
Only returns true if accessing_obj has_account is true, that is,
@ -576,6 +582,7 @@ def has_account(accessing_obj, accessed_obj, *args, **kwargs):
"""
return hasattr(accessing_obj, "has_account") and accessing_obj.has_account
def serversetting(accessing_obj, accessed_obj, *args, **kwargs):
"""
Only returns true if the Evennia settings exists, alternatively has

View file

@ -121,6 +121,7 @@ WARNING_LOG = settings.LOCKWARNING_LOG_FILE
# by errors in lock definitions.
#
class LockException(Exception):
"""
Raised during an error in a lock.
@ -133,6 +134,8 @@ class LockException(Exception):
#
_LOCKFUNCS = {}
def _cache_lockfuncs():
"""
Updates the cache.
@ -146,6 +149,7 @@ def _cache_lockfuncs():
# pre-compiled regular expressions
#
_RE_FUNCS = re.compile(r"\w+\([^)]*\)")
_RE_SEPS = re.compile(r"(?<=[ )])AND(?=\s)|(?<=[ )])OR(?=\s)|(?<=[ )])NOT(?=\s)")
_RE_OK = re.compile(r"%s|and|or|not")
@ -229,7 +233,7 @@ class LockHandler(object):
if not callable(func):
elist.append(_("Lock: lock-function '%s' is not available.") % funcstring)
continue
args = list(arg.strip() for arg in rest.split(',') if arg and not '=' in arg)
args = list(arg.strip() for arg in rest.split(',') if arg and '=' not in arg)
kwargs = dict([arg.split('=', 1) for arg in rest.split(',') if arg and '=' in arg])
lock_funcs.append((func, args, kwargs))
evalstring = evalstring.replace(funcstring, '%s')
@ -244,8 +248,8 @@ class LockHandler(object):
continue
if access_type in locks:
duplicates += 1
wlist.append(_("LockHandler on %(obj)s: access type '%(access_type)s' changed from '%(source)s' to '%(goal)s' " % \
{"obj":self.obj, "access_type":access_type, "source":locks[access_type][2], "goal":raw_lockstring}))
wlist.append(_("LockHandler on %(obj)s: access type '%(access_type)s' changed from '%(source)s' to '%(goal)s' " %
{"obj": self.obj, "access_type": access_type, "source": locks[access_type][2], "goal": raw_lockstring}))
locks[access_type] = (evalstring, tuple(lock_funcs), raw_lockstring)
if wlist and WARNING_LOG:
# a warning text was set, it's not an error, so only report
@ -300,7 +304,7 @@ class LockHandler(object):
"""
# sanity checks
for lockdef in lockstring.split(';'):
if not ':' in lockstring:
if ':' not in lockstring:
self._log_error(_("Lock: '%s' contains no colon (:).") % lockdef)
return False
access_type, rhs = [part.strip() for part in lockdef.split(':', 1)]
@ -449,9 +453,9 @@ class LockHandler(object):
return True
except AttributeError:
# happens before session is initiated.
if not no_superuser_bypass and ((hasattr(accessing_obj, 'is_superuser') and accessing_obj.is_superuser)
or (hasattr(accessing_obj, 'account') and hasattr(accessing_obj.account, 'is_superuser') and accessing_obj.account.is_superuser)
or (hasattr(accessing_obj, 'get_account') and (not accessing_obj.get_account() or accessing_obj.get_account().is_superuser))):
if not no_superuser_bypass and ((hasattr(accessing_obj, 'is_superuser') and accessing_obj.is_superuser) or
(hasattr(accessing_obj, 'account') and hasattr(accessing_obj.account, 'is_superuser') and accessing_obj.account.is_superuser) or
(hasattr(accessing_obj, 'get_account') and (not accessing_obj.get_account() or accessing_obj.get_account().is_superuser))):
return True
# no superuser or bypass -> normal lock operation
@ -510,17 +514,17 @@ class LockHandler(object):
if accessing_obj.locks.lock_bypass and not no_superuser_bypass:
return True
except AttributeError:
if no_superuser_bypass and ((hasattr(accessing_obj, 'is_superuser') and accessing_obj.is_superuser)
or (hasattr(accessing_obj, 'account') and hasattr(accessing_obj.account, 'is_superuser') and accessing_obj.account.is_superuser)
or (hasattr(accessing_obj, 'get_account') and (not accessing_obj.get_account() or accessing_obj.get_account().is_superuser))):
if no_superuser_bypass and ((hasattr(accessing_obj, 'is_superuser') and accessing_obj.is_superuser) or
(hasattr(accessing_obj, 'account') and hasattr(accessing_obj.account, 'is_superuser') and accessing_obj.account.is_superuser) or
(hasattr(accessing_obj, 'get_account') and (not accessing_obj.get_account() or accessing_obj.get_account().is_superuser))):
return True
if not ":" in lockstring:
if ":" not in lockstring:
lockstring = "%s:%s" % ("_dummy", lockstring)
locks = self._parse_lockstring(lockstring)
if access_type:
if not access_type in locks:
if access_type not in locks:
return default
else:
return self._eval_access_type(
@ -541,7 +545,7 @@ def _test():
obj1 = TestObj()
obj2 = TestObj()
#obj1.lock_storage = "owner:dbref(#4);edit:dbref(#5) or perm(Admin);examine:perm(Builder);delete:perm(Admin);get:all()"
# obj1.lock_storage = "owner:dbref(#4);edit:dbref(#5) or perm(Admin);examine:perm(Builder);delete:perm(Admin);get:all()"
#obj1.lock_storage = "cmd:all();admin:id(1);listen:all();send:all()"
obj1.lock_storage = "listen:perm(Developer)"
@ -550,7 +554,7 @@ def _test():
obj2.permissions.add("Developer")
obj2.id = 4
#obj1.locks.add("edit:attr(test)")
# obj1.locks.add("edit:attr(test)")
print("comparing obj2.permissions (%s) vs obj1.locks (%s)" % (obj2.permissions, obj1.locks))
print(obj1.locks.check(obj2, 'owner'))

View file

@ -3,12 +3,14 @@ from __future__ import unicode_literals
from django.db import models, migrations
def convert_defaults(apps, schema_editor):
ObjectDB = apps.get_model("objects", "ObjectDB")
for obj in ObjectDB.objects.filter(db_typeclass_path="src.objects.objects.Object"):
obj.db_typeclass_path = "typeclasses.objects.Object"
obj.save()
class Migration(migrations.Migration):
dependencies = [

View file

@ -21,6 +21,7 @@ def forwards(apps, schema_editor):
object.db_account = account
object.save(update_fields=['db_account'])
class Migration(migrations.Migration):
dependencies = [

View file

@ -33,6 +33,7 @@ class ContentsHandler(object):
for object-cmdsets). It is stored on the 'contents_cache' property
of the ObjectDB.
"""
def __init__(self, obj):
"""
Sets up the contents handler.

View file

@ -39,6 +39,7 @@ class ObjectSessionHandler(object):
Handles the get/setting of the sessid
comma-separated integer field
"""
def __init__(self, obj):
"""
Initializes the handler.
@ -1778,6 +1779,7 @@ class DefaultRoom(DefaultObject):
This is the base room object. It's just like any Object except its
location is always `None`.
"""
def basetype_setup(self):
"""
Simple room setup setting locks to make sure the room

View file

@ -34,6 +34,7 @@ class ScriptDBManager(TypedObjectManager):
copy_script
"""
def get_all_scripts_on_obj(self, obj, key=None):
"""
Find all Scripts related to a particular object.

View file

@ -3,6 +3,7 @@ from __future__ import unicode_literals
from django.db import models, migrations
def convert_defaults(apps, schema_editor):
ScriptDB = apps.get_model("scripts", "ScriptDB")
for script in ScriptDB.objects.filter(db_typeclass_path="src.scripts.scripts.Script"):
@ -12,6 +13,7 @@ def convert_defaults(apps, schema_editor):
script.db_typeclass_path = "evennia.utils.gametime.GameTime"
script.save()
class Migration(migrations.Migration):
dependencies = [

View file

@ -3,6 +3,7 @@ from __future__ import unicode_literals
from django.db import models, migrations
def remove_manage_scripts(apps, schema_editor):
ScriptDB = apps.get_model("scripts", "ScriptDB")
for script in ScriptDB.objects.filter(db_typeclass_path__in=(u'evennia.scripts.scripts.CheckSessions',
@ -12,6 +13,7 @@ def remove_manage_scripts(apps, schema_editor):
u'evennia.utils.gametime.GameTime')):
script.delete()
class Migration(migrations.Migration):
dependencies = [

View file

@ -3,6 +3,7 @@ from __future__ import unicode_literals
from django.db import models, migrations
def remove_manage_scripts(apps, schema_editor):
ScriptDB = apps.get_model("scripts", "ScriptDB")
for script in ScriptDB.objects.filter(db_typeclass_path__in=(u'src.scripts.scripts.CheckSessions',
@ -12,6 +13,7 @@ def remove_manage_scripts(apps, schema_editor):
u'src.utils.gametime.GameTime')):
script.delete()
class Migration(migrations.Migration):
dependencies = [

View file

@ -71,7 +71,6 @@ class ScriptDB(TypedObject):
"""
#
# ScriptDB Database Model setup
#

View file

@ -23,11 +23,13 @@ _SA = object.__setattr__
_GA = object.__getattribute__
_DA = object.__delattr__
class MonitorHandler(object):
"""
This is a resource singleton that allows for registering
callbacks for when a field or Attribute is updated (saved).
"""
def __init__(self):
"""
Initialize the handler.
@ -149,7 +151,6 @@ class MonitorHandler(object):
else:
self.monitors[obj][fieldname][idstring] = (callback, persistent, kwargs)
def remove(self, obj, fieldname, idstring=""):
"""
Remove a monitor.

View file

@ -13,11 +13,13 @@ from evennia.utils import logger
from django.utils.translation import ugettext as _
class ScriptHandler(object):
"""
Implements the handler. This sits on each game object.
"""
def __init__(self, obj):
"""
Set up internal state.

View file

@ -596,6 +596,7 @@ class DoNothing(DefaultScript):
"""
A script that does nothing. Used as default fallback.
"""
def at_script_creation(self):
"""
Setup the script
@ -608,6 +609,7 @@ class Store(DefaultScript):
"""
Simple storage script
"""
def at_script_creation(self):
"""
Setup the script

View file

@ -11,6 +11,7 @@ from evennia.utils.dbserialize import dbserialize, dbunserialize
TASK_HANDLER = None
class TaskHandler(object):
"""
@ -71,8 +72,8 @@ class TaskHandler(object):
try:
dbserialize(callback)
except (TypeError, AttributeError):
raise ValueError("the specified callback {} cannot be pickled. " \
"It must be a top-level function in a module or an " \
raise ValueError("the specified callback {} cannot be pickled. "
"It must be a top-level function in a module or an "
"instance method.".format(callback))
else:
safe_callback = callback
@ -112,8 +113,8 @@ class TaskHandler(object):
try:
dbserialize(arg)
except (TypeError, AttributeError):
logger.log_err("The positional argument {} cannot be " \
"pickled and will not be present in the arguments " \
logger.log_err("The positional argument {} cannot be "
"pickled and will not be present in the arguments "
"fed to the callback {}".format(arg, callback))
else:
safe_args.append(arg)
@ -122,8 +123,8 @@ class TaskHandler(object):
try:
dbserialize(value)
except (TypeError, AttributeError):
logger.log_err("The {} keyword argument {} cannot be " \
"pickled and will not be present in the arguments " \
logger.log_err("The {} keyword argument {} cannot be "
"pickled and will not be present in the arguments "
"fed to the callback {}".format(key, value, callback))
else:
safe_kwargs[key] = value
@ -185,4 +186,3 @@ class TaskHandler(object):
# Create the soft singleton
TASK_HANDLER = TaskHandler()

View file

@ -7,6 +7,7 @@ from evennia.scripts.scripts import DoNothing
class TestScriptDB(TestCase):
"Check the singleton/static ScriptDB object works correctly"
def setUp(self):
self.scr = create_script(DoNothing)

View file

@ -81,10 +81,11 @@ _SA = object.__setattr__
_ERROR_ADD_TICKER = \
"""TickerHandler: Tried to add an invalid ticker:
"""TickerHandler: Tried to add an invalid ticker:
{storekey}
Ticker was not added."""
class Ticker(object):
"""
Represents a repeatedly running task that calls
@ -145,7 +146,6 @@ class Ticker(object):
self._to_remove = []
self._to_add = []
def __init__(self, interval):
"""
Set up the ticker
@ -584,5 +584,6 @@ class TickerHandler(object):
store_keys.append((kwargs.get("_obj", None), callfunc, path, interval, idstring, persistent))
return store_keys
# main tickerhandler
TICKER_HANDLER = TickerHandler()

View file

@ -19,4 +19,6 @@ class ServerConfigAdmin(admin.ModelAdmin):
save_as = True
save_on_top = True
list_select_related = True
admin.site.register(ServerConfig, ServerConfigAdmin)

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