Merge branch 'develop' into master
This commit is contained in:
commit
ab1bd6415d
64 changed files with 7206 additions and 2051 deletions
|
|
@ -168,7 +168,7 @@ class CmdCharCreate(COMMAND_DEFAULT_CLASS):
|
|||
if desc:
|
||||
new_character.db.desc = desc
|
||||
elif not new_character.db.desc:
|
||||
new_character.db.desc = "This is an Account."
|
||||
new_character.db.desc = "This is a character."
|
||||
self.msg("Created new character %s. Use |w@ic %s|n to enter the game as this character."
|
||||
% (new_character.key, new_character.key))
|
||||
|
||||
|
|
@ -455,7 +455,7 @@ class CmdOption(COMMAND_DEFAULT_CLASS):
|
|||
Usage:
|
||||
@option[/save] [name = value]
|
||||
|
||||
Switch:
|
||||
Switches:
|
||||
save - Save the current option settings for future logins.
|
||||
clear - Clear the saved options.
|
||||
|
||||
|
|
@ -467,6 +467,7 @@ class CmdOption(COMMAND_DEFAULT_CLASS):
|
|||
"""
|
||||
key = "@option"
|
||||
aliases = "@options"
|
||||
switch_options = ("save", "clear")
|
||||
locks = "cmd:all()"
|
||||
|
||||
# this is used by the parent
|
||||
|
|
@ -650,6 +651,7 @@ class CmdQuit(COMMAND_DEFAULT_CLASS):
|
|||
game. Use the /all switch to disconnect from all sessions.
|
||||
"""
|
||||
key = "@quit"
|
||||
switch_options = ("all",)
|
||||
locks = "cmd:all()"
|
||||
|
||||
# this is used by the parent
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ class CmdBoot(COMMAND_DEFAULT_CLASS):
|
|||
"""
|
||||
|
||||
key = "@boot"
|
||||
switch_options = ("quiet", "sid")
|
||||
locks = "cmd:perm(boot) or perm(Admin)"
|
||||
help_category = "Admin"
|
||||
|
||||
|
|
@ -265,6 +266,7 @@ class CmdDelAccount(COMMAND_DEFAULT_CLASS):
|
|||
"""
|
||||
|
||||
key = "@delaccount"
|
||||
switch_options = ("delobj",)
|
||||
locks = "cmd:perm(delaccount) or perm(Developer)"
|
||||
help_category = "Admin"
|
||||
|
||||
|
|
@ -329,9 +331,9 @@ class CmdEmit(COMMAND_DEFAULT_CLASS):
|
|||
@pemit [<obj>, <obj>, ... =] <message>
|
||||
|
||||
Switches:
|
||||
room : limit emits to rooms only (default)
|
||||
accounts : limit emits to accounts only
|
||||
contents : send to the contents of matched objects too
|
||||
room - limit emits to rooms only (default)
|
||||
accounts - limit emits to accounts only
|
||||
contents - send to the contents of matched objects too
|
||||
|
||||
Emits a message to the selected objects or to
|
||||
your immediate surroundings. If the object is a room,
|
||||
|
|
@ -341,6 +343,7 @@ class CmdEmit(COMMAND_DEFAULT_CLASS):
|
|||
"""
|
||||
key = "@emit"
|
||||
aliases = ["@pemit", "@remit"]
|
||||
switch_options = ("room", "accounts", "contents")
|
||||
locks = "cmd:perm(emit) or perm(Builder)"
|
||||
help_category = "Admin"
|
||||
|
||||
|
|
@ -442,14 +445,15 @@ class CmdPerm(COMMAND_DEFAULT_CLASS):
|
|||
@perm[/switch] *<account> [= <permission>[,<permission>,...]]
|
||||
|
||||
Switches:
|
||||
del : delete the given permission from <object> or <account>.
|
||||
account : set permission on an account (same as adding * to name)
|
||||
del - delete the given permission from <object> or <account>.
|
||||
account - set permission on an account (same as adding * to name)
|
||||
|
||||
This command sets/clears individual permission strings on an object
|
||||
or account. If no permission is given, list all permissions on <object>.
|
||||
"""
|
||||
key = "@perm"
|
||||
aliases = "@setperm"
|
||||
switch_options = ("del", "account")
|
||||
locks = "cmd:perm(perm) or perm(Developer)"
|
||||
help_category = "Admin"
|
||||
|
||||
|
|
|
|||
|
|
@ -237,6 +237,7 @@ class CmdBatchCommands(_COMMAND_DEFAULT_CLASS):
|
|||
"""
|
||||
key = "@batchcommands"
|
||||
aliases = ["@batchcommand", "@batchcmd"]
|
||||
switch_options = ("interactive",)
|
||||
locks = "cmd:perm(batchcommands) or perm(Developer)"
|
||||
help_category = "Building"
|
||||
|
||||
|
|
@ -347,6 +348,7 @@ class CmdBatchCode(_COMMAND_DEFAULT_CLASS):
|
|||
"""
|
||||
key = "@batchcode"
|
||||
aliases = ["@batchcodes"]
|
||||
switch_options = ("interactive", "debug")
|
||||
locks = "cmd:superuser()"
|
||||
help_category = "Building"
|
||||
|
||||
|
|
|
|||
|
|
@ -106,9 +106,15 @@ class CmdSetObjAlias(COMMAND_DEFAULT_CLASS):
|
|||
Usage:
|
||||
@alias <obj> [= [alias[,alias,alias,...]]]
|
||||
@alias <obj> =
|
||||
@alias/category <obj> = [alias[,alias,...]:<category>
|
||||
|
||||
Switches:
|
||||
category - requires ending input with :category, to store the
|
||||
given aliases with the given category.
|
||||
|
||||
Assigns aliases to an object so it can be referenced by more
|
||||
than one name. Assign empty to remove all aliases from object.
|
||||
than one name. Assign empty to remove all aliases from object. If
|
||||
assigning a category, all aliases given will be using this category.
|
||||
|
||||
Observe that this is not the same thing as personal aliases
|
||||
created with the 'nick' command! Aliases set with @alias are
|
||||
|
|
@ -118,6 +124,7 @@ class CmdSetObjAlias(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
key = "@alias"
|
||||
aliases = "@setobjalias"
|
||||
switch_options = ("category",)
|
||||
locks = "cmd:perm(setobjalias) or perm(Builder)"
|
||||
help_category = "Building"
|
||||
|
||||
|
|
@ -138,9 +145,12 @@ class CmdSetObjAlias(COMMAND_DEFAULT_CLASS):
|
|||
return
|
||||
if self.rhs is None:
|
||||
# no =, so we just list aliases on object.
|
||||
aliases = obj.aliases.all()
|
||||
aliases = obj.aliases.all(return_key_and_category=True)
|
||||
if aliases:
|
||||
caller.msg("Aliases for '%s': %s" % (obj.get_display_name(caller), ", ".join(aliases)))
|
||||
caller.msg("Aliases for %s: %s" % (
|
||||
obj.get_display_name(caller),
|
||||
", ".join("'%s'%s" % (alias, "" if category is None else "[category:'%s']" % category)
|
||||
for (alias, category) in aliases)))
|
||||
else:
|
||||
caller.msg("No aliases exist for '%s'." % obj.get_display_name(caller))
|
||||
return
|
||||
|
|
@ -159,17 +169,27 @@ class CmdSetObjAlias(COMMAND_DEFAULT_CLASS):
|
|||
caller.msg("No aliases to clear.")
|
||||
return
|
||||
|
||||
category = None
|
||||
if "category" in self.switches:
|
||||
if ":" in self.rhs:
|
||||
rhs, category = self.rhs.rsplit(':', 1)
|
||||
category = category.strip()
|
||||
else:
|
||||
caller.msg("If specifying the /category switch, the category must be given "
|
||||
"as :category at the end.")
|
||||
else:
|
||||
rhs = self.rhs
|
||||
|
||||
# merge the old and new aliases (if any)
|
||||
old_aliases = obj.aliases.all()
|
||||
new_aliases = [alias.strip().lower() for alias in self.rhs.split(',')
|
||||
if alias.strip()]
|
||||
old_aliases = obj.aliases.get(category=category, return_list=True)
|
||||
new_aliases = [alias.strip().lower() for alias in rhs.split(',') if alias.strip()]
|
||||
|
||||
# make the aliases only appear once
|
||||
old_aliases.extend(new_aliases)
|
||||
aliases = list(set(old_aliases))
|
||||
|
||||
# save back to object.
|
||||
obj.aliases.add(aliases)
|
||||
obj.aliases.add(aliases, category=category)
|
||||
|
||||
# we need to trigger this here, since this will force
|
||||
# (default) Exits to rebuild their Exit commands with the new
|
||||
|
|
@ -177,7 +197,8 @@ class CmdSetObjAlias(COMMAND_DEFAULT_CLASS):
|
|||
obj.at_cmdset_get(force_init=True)
|
||||
|
||||
# report all aliases on the object
|
||||
caller.msg("Alias(es) for '%s' set to %s." % (obj.get_display_name(caller), str(obj.aliases)))
|
||||
caller.msg("Alias(es) for '%s' set to '%s'%s." % (obj.get_display_name(caller),
|
||||
str(obj.aliases), " (category: '%s')" % category if category else ""))
|
||||
|
||||
|
||||
class CmdCopy(ObjManipCommand):
|
||||
|
|
@ -198,6 +219,7 @@ class CmdCopy(ObjManipCommand):
|
|||
"""
|
||||
|
||||
key = "@copy"
|
||||
switch_options = ("reset",)
|
||||
locks = "cmd:perm(copy) or perm(Builder)"
|
||||
help_category = "Building"
|
||||
|
||||
|
|
@ -279,6 +301,7 @@ class CmdCpAttr(ObjManipCommand):
|
|||
If you don't supply a source object, yourself is used.
|
||||
"""
|
||||
key = "@cpattr"
|
||||
switch_options = ("move",)
|
||||
locks = "cmd:perm(cpattr) or perm(Builder)"
|
||||
help_category = "Building"
|
||||
|
||||
|
|
@ -420,6 +443,7 @@ class CmdMvAttr(ObjManipCommand):
|
|||
object. If you don't supply a source object, yourself is used.
|
||||
"""
|
||||
key = "@mvattr"
|
||||
switch_options = ("copy",)
|
||||
locks = "cmd:perm(mvattr) or perm(Builder)"
|
||||
help_category = "Building"
|
||||
|
||||
|
|
@ -468,6 +492,7 @@ class CmdCreate(ObjManipCommand):
|
|||
"""
|
||||
|
||||
key = "@create"
|
||||
switch_options = ("drop",)
|
||||
locks = "cmd:perm(create) or perm(Builder)"
|
||||
help_category = "Building"
|
||||
|
||||
|
|
@ -553,6 +578,7 @@ class CmdDesc(COMMAND_DEFAULT_CLASS):
|
|||
"""
|
||||
key = "@desc"
|
||||
aliases = "@describe"
|
||||
switch_options = ("edit",)
|
||||
locks = "cmd:perm(desc) or perm(Builder)"
|
||||
help_category = "Building"
|
||||
|
||||
|
|
@ -614,11 +640,11 @@ class CmdDestroy(COMMAND_DEFAULT_CLASS):
|
|||
Usage:
|
||||
@destroy[/switches] [obj, obj2, obj3, [dbref-dbref], ...]
|
||||
|
||||
switches:
|
||||
Switches:
|
||||
override - The @destroy command will usually avoid accidentally
|
||||
destroying account objects. This switch overrides this safety.
|
||||
force - destroy without confirmation.
|
||||
examples:
|
||||
Examples:
|
||||
@destroy house, roof, door, 44-78
|
||||
@destroy 5-10, flower, 45
|
||||
@destroy/force north
|
||||
|
|
@ -631,6 +657,7 @@ class CmdDestroy(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
key = "@destroy"
|
||||
aliases = ["@delete", "@del"]
|
||||
switch_options = ("override", "force")
|
||||
locks = "cmd:perm(destroy) or perm(Builder)"
|
||||
help_category = "Building"
|
||||
|
||||
|
|
@ -754,6 +781,7 @@ class CmdDig(ObjManipCommand):
|
|||
would be 'north;no;n'.
|
||||
"""
|
||||
key = "@dig"
|
||||
switch_options = ("teleport",)
|
||||
locks = "cmd:perm(dig) or perm(Builder)"
|
||||
help_category = "Building"
|
||||
|
||||
|
|
@ -863,7 +891,7 @@ class CmdDig(ObjManipCommand):
|
|||
new_back_exit.dbref,
|
||||
alias_string)
|
||||
caller.msg("%s%s%s" % (room_string, exit_to_string, exit_back_string))
|
||||
if new_room and ('teleport' in self.switches or "tel" in self.switches):
|
||||
if new_room and 'teleport' in self.switches:
|
||||
caller.move_to(new_room)
|
||||
|
||||
|
||||
|
|
@ -896,6 +924,7 @@ class CmdTunnel(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
key = "@tunnel"
|
||||
aliases = ["@tun"]
|
||||
switch_options = ("oneway", "tel")
|
||||
locks = "cmd: perm(tunnel) or perm(Builder)"
|
||||
help_category = "Building"
|
||||
|
||||
|
|
@ -1458,6 +1487,13 @@ class CmdSetAttribute(ObjManipCommand):
|
|||
|
||||
Switch:
|
||||
edit: Open the line editor (string values only)
|
||||
script: If we're trying to set an attribute on a script
|
||||
channel: If we're trying to set an attribute on a channel
|
||||
account: If we're trying to set an attribute on an account
|
||||
room: Setting an attribute on a room (global search)
|
||||
exit: Setting an attribute on an exit (global search)
|
||||
char: Setting an attribute on a character (global search)
|
||||
character: Alias for char, as above.
|
||||
|
||||
Sets attributes on objects. The second form clears
|
||||
a previously set attribute while the last form
|
||||
|
|
@ -1558,6 +1594,38 @@ class CmdSetAttribute(ObjManipCommand):
|
|||
# start the editor
|
||||
EvEditor(self.caller, load, save, key="%s/%s" % (obj, attr))
|
||||
|
||||
def search_for_obj(self, objname):
|
||||
"""
|
||||
Searches for an object matching objname. The object may be of different typeclasses.
|
||||
Args:
|
||||
objname: Name of the object we're looking for
|
||||
|
||||
Returns:
|
||||
A typeclassed object, or None if nothing is found.
|
||||
"""
|
||||
from evennia.utils.utils import variable_from_module
|
||||
_AT_SEARCH_RESULT = variable_from_module(*settings.SEARCH_AT_RESULT.rsplit('.', 1))
|
||||
caller = self.caller
|
||||
if objname.startswith('*') or "account" in self.switches:
|
||||
found_obj = caller.search_account(objname.lstrip('*'))
|
||||
elif "script" in self.switches:
|
||||
found_obj = _AT_SEARCH_RESULT(search.search_script(objname), caller)
|
||||
elif "channel" in self.switches:
|
||||
found_obj = _AT_SEARCH_RESULT(search.search_channel(objname), caller)
|
||||
else:
|
||||
global_search = True
|
||||
if "char" in self.switches or "character" in self.switches:
|
||||
typeclass = settings.BASE_CHARACTER_TYPECLASS
|
||||
elif "room" in self.switches:
|
||||
typeclass = settings.BASE_ROOM_TYPECLASS
|
||||
elif "exit" in self.switches:
|
||||
typeclass = settings.BASE_EXIT_TYPECLASS
|
||||
else:
|
||||
global_search = False
|
||||
typeclass = None
|
||||
found_obj = caller.search(objname, global_search=global_search, typeclass=typeclass)
|
||||
return found_obj
|
||||
|
||||
def func(self):
|
||||
"""Implement the set attribute - a limited form of @py."""
|
||||
|
||||
|
|
@ -1571,10 +1639,7 @@ class CmdSetAttribute(ObjManipCommand):
|
|||
objname = self.lhs_objattr[0]['name']
|
||||
attrs = self.lhs_objattr[0]['attrs']
|
||||
|
||||
if objname.startswith('*'):
|
||||
obj = caller.search_account(objname.lstrip('*'))
|
||||
else:
|
||||
obj = caller.search(objname)
|
||||
obj = self.search_for_obj(objname)
|
||||
if not obj:
|
||||
return
|
||||
|
||||
|
|
@ -2202,12 +2267,14 @@ class CmdFind(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
Usage:
|
||||
@find[/switches] <name or dbref or *account> [= dbrefmin[-dbrefmax]]
|
||||
@locate - this is a shorthand for using the /loc switch.
|
||||
|
||||
Switches:
|
||||
room - only look for rooms (location=None)
|
||||
exit - only look for exits (destination!=None)
|
||||
char - only look for characters (BASE_CHARACTER_TYPECLASS)
|
||||
exact- only exact matches are returned.
|
||||
loc - display object location if exists and match has one result
|
||||
|
||||
Searches the database for an object of a particular name or exact #dbref.
|
||||
Use *accountname to search for an account. The switches allows for
|
||||
|
|
@ -2218,6 +2285,7 @@ class CmdFind(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
key = "@find"
|
||||
aliases = "@search, @locate"
|
||||
switch_options = ("room", "exit", "char", "exact", "loc")
|
||||
locks = "cmd:perm(find) or perm(Builder)"
|
||||
help_category = "Building"
|
||||
|
||||
|
|
@ -2230,6 +2298,9 @@ class CmdFind(COMMAND_DEFAULT_CLASS):
|
|||
caller.msg("Usage: @find <string> [= low [-high]]")
|
||||
return
|
||||
|
||||
if "locate" in self.cmdstring: # Use option /loc as a default for @locate command alias
|
||||
switches.append('loc')
|
||||
|
||||
searchstring = self.lhs
|
||||
low, high = 1, ObjectDB.objects.all().order_by("-id")[0].id
|
||||
if self.rhs:
|
||||
|
|
@ -2251,7 +2322,7 @@ class CmdFind(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
restrictions = ""
|
||||
if self.switches:
|
||||
restrictions = ", %s" % (",".join(self.switches))
|
||||
restrictions = ", %s" % (", ".join(self.switches))
|
||||
|
||||
if is_dbref or is_account:
|
||||
|
||||
|
|
@ -2279,6 +2350,8 @@ class CmdFind(COMMAND_DEFAULT_CLASS):
|
|||
else:
|
||||
result = result[0]
|
||||
string += "\n|g %s - %s|n" % (result.get_display_name(caller), result.path)
|
||||
if "loc" in self.switches and not is_account and result.location:
|
||||
string += " (|wlocation|n: |g{}|n)".format(result.location.get_display_name(caller))
|
||||
else:
|
||||
# Not an account/dbref search but a wider search; build a queryset.
|
||||
# Searchs for key and aliases
|
||||
|
|
@ -2314,6 +2387,8 @@ class CmdFind(COMMAND_DEFAULT_CLASS):
|
|||
else:
|
||||
string = "|wOne Match|n(#%i-#%i%s):" % (low, high, restrictions)
|
||||
string += "\n |g%s - %s|n" % (results[0].get_display_name(caller), results[0].path)
|
||||
if "loc" in self.switches and nresults == 1 and results[0].location:
|
||||
string += " (|wlocation|n: |g{}|n)".format(results[0].location.get_display_name(caller))
|
||||
else:
|
||||
string = "|wMatch|n(#%i-#%i%s):" % (low, high, restrictions)
|
||||
string += "\n |RNo matches found for '%s'|n" % searchstring
|
||||
|
|
@ -2327,7 +2402,7 @@ class CmdTeleport(COMMAND_DEFAULT_CLASS):
|
|||
teleport object to another location
|
||||
|
||||
Usage:
|
||||
@tel/switch [<object> =] <target location>
|
||||
@tel/switch [<object> to||=] <target location>
|
||||
|
||||
Examples:
|
||||
@tel Limbo
|
||||
|
|
@ -2351,6 +2426,8 @@ class CmdTeleport(COMMAND_DEFAULT_CLASS):
|
|||
"""
|
||||
key = "@tel"
|
||||
aliases = "@teleport"
|
||||
switch_options = ("quiet", "intoexit", "tonone", "loc")
|
||||
rhs_split = ("=", " to ") # Prefer = delimiter, but allow " to " usage.
|
||||
locks = "cmd:perm(teleport) or perm(Builder)"
|
||||
help_category = "Building"
|
||||
|
||||
|
|
@ -2458,6 +2535,7 @@ class CmdScript(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
key = "@script"
|
||||
aliases = "@addscript"
|
||||
switch_options = ("start", "stop")
|
||||
locks = "cmd:perm(script) or perm(Builder)"
|
||||
help_category = "Building"
|
||||
|
||||
|
|
@ -2557,6 +2635,7 @@ class CmdTag(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
key = "@tag"
|
||||
aliases = ["@tags"]
|
||||
options = ("search", "del")
|
||||
locks = "cmd:perm(tag) or perm(Builder)"
|
||||
help_category = "Building"
|
||||
arg_regex = r"(/\w+?(\s|$))|\s|$"
|
||||
|
|
@ -2698,6 +2777,7 @@ class CmdSpawn(COMMAND_DEFAULT_CLASS):
|
|||
"""
|
||||
|
||||
key = "@spawn"
|
||||
switch_options = ("noloc", )
|
||||
locks = "cmd:perm(spawn) or perm(Builder)"
|
||||
help_category = "Building"
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ command method rather than caller.msg().
|
|||
|
||||
from evennia.commands.cmdset import CmdSet
|
||||
from evennia.commands.default import help, comms, admin, system
|
||||
from evennia.commands.default import building, account
|
||||
from evennia.commands.default import building, account, general
|
||||
|
||||
|
||||
class AccountCmdSet(CmdSet):
|
||||
|
|
@ -39,6 +39,9 @@ class AccountCmdSet(CmdSet):
|
|||
self.add(account.CmdColorTest())
|
||||
self.add(account.CmdQuell())
|
||||
|
||||
# nicks
|
||||
self.add(general.CmdNick())
|
||||
|
||||
# testing
|
||||
self.add(building.CmdExamine())
|
||||
|
||||
|
|
|
|||
|
|
@ -377,7 +377,7 @@ class CmdCBoot(COMMAND_DEFAULT_CLASS):
|
|||
Usage:
|
||||
@cboot[/quiet] <channel> = <account> [:reason]
|
||||
|
||||
Switches:
|
||||
Switch:
|
||||
quiet - don't notify the channel
|
||||
|
||||
Kicks an account or object from a channel you control.
|
||||
|
|
@ -385,6 +385,7 @@ class CmdCBoot(COMMAND_DEFAULT_CLASS):
|
|||
"""
|
||||
|
||||
key = "@cboot"
|
||||
switch_options = ("quiet",)
|
||||
locks = "cmd: not pperm(channel_banned)"
|
||||
help_category = "Comms"
|
||||
|
||||
|
|
@ -453,6 +454,7 @@ class CmdCemit(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
key = "@cemit"
|
||||
aliases = ["@cmsg"]
|
||||
switch_options = ("sendername", "quiet")
|
||||
locks = "cmd: not pperm(channel_banned) and pperm(Player)"
|
||||
help_category = "Comms"
|
||||
|
||||
|
|
@ -683,6 +685,7 @@ class CmdPage(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
key = "page"
|
||||
aliases = ['tell']
|
||||
switch_options = ("last", "list")
|
||||
locks = "cmd:not pperm(page_banned)"
|
||||
help_category = "Comms"
|
||||
|
||||
|
|
@ -850,6 +853,7 @@ class CmdIRC2Chan(COMMAND_DEFAULT_CLASS):
|
|||
"""
|
||||
|
||||
key = "@irc2chan"
|
||||
switch_options = ("delete", "remove", "disconnect", "list", "ssl")
|
||||
locks = "cmd:serversetting(IRC_ENABLED) and pperm(Developer)"
|
||||
help_category = "Comms"
|
||||
|
||||
|
|
@ -1016,6 +1020,7 @@ class CmdRSS2Chan(COMMAND_DEFAULT_CLASS):
|
|||
"""
|
||||
|
||||
key = "@rss2chan"
|
||||
switch_options = ("disconnect", "remove", "list")
|
||||
locks = "cmd:serversetting(RSS_ENABLED) and pperm(Developer)"
|
||||
help_category = "Comms"
|
||||
|
||||
|
|
|
|||
|
|
@ -88,8 +88,7 @@ class CmdNick(COMMAND_DEFAULT_CLASS):
|
|||
Switches:
|
||||
inputline - replace on the inputline (default)
|
||||
object - replace on object-lookup
|
||||
account - replace on account-lookup
|
||||
|
||||
account - replace on account-lookup
|
||||
list - show all defined aliases (also "nicks" works)
|
||||
delete - remove nick by index in /list
|
||||
clearall - clear all nicks
|
||||
|
|
@ -118,7 +117,8 @@ class CmdNick(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
"""
|
||||
key = "nick"
|
||||
aliases = ["nickname", "nicks", "alias"]
|
||||
switch_options = ("inputline", "object", "account", "list", "delete", "clearall")
|
||||
aliases = ["nickname", "nicks"]
|
||||
locks = "cmd:all()"
|
||||
|
||||
def parse(self):
|
||||
|
|
@ -143,7 +143,6 @@ class CmdNick(COMMAND_DEFAULT_CLASS):
|
|||
return re.sub(r"(\$[0-9]+|\*|\?|\[.+?\])", r"|Y\1|n", string)
|
||||
|
||||
caller = self.caller
|
||||
account = self.caller.account or caller
|
||||
switches = self.switches
|
||||
nicktypes = [switch for switch in switches if switch in ("object", "account", "inputline")]
|
||||
specified_nicktype = bool(nicktypes)
|
||||
|
|
@ -151,7 +150,7 @@ class CmdNick(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
nicklist = (utils.make_iter(caller.nicks.get(category="inputline", return_obj=True) or []) +
|
||||
utils.make_iter(caller.nicks.get(category="object", return_obj=True) or []) +
|
||||
utils.make_iter(account.nicks.get(category="account", return_obj=True) or []))
|
||||
utils.make_iter(caller.nicks.get(category="account", return_obj=True) or []))
|
||||
|
||||
if 'list' in switches or self.cmdstring in ("nicks", "@nicks"):
|
||||
|
||||
|
|
@ -174,29 +173,77 @@ class CmdNick(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
if 'delete' in switches or 'del' in switches:
|
||||
if not self.args or not self.lhs:
|
||||
caller.msg("usage nick/delete #num ('nicks' for list)")
|
||||
caller.msg("usage nick/delete <nick> or <#num> ('nicks' for list)")
|
||||
return
|
||||
# see if a number was given
|
||||
arg = self.args.lstrip("#")
|
||||
oldnicks = []
|
||||
if arg.isdigit():
|
||||
# we are given a index in nicklist
|
||||
delindex = int(arg)
|
||||
if 0 < delindex <= len(nicklist):
|
||||
oldnick = nicklist[delindex - 1]
|
||||
_, _, old_nickstring, old_replstring = oldnick.value
|
||||
oldnicks.append(nicklist[delindex - 1])
|
||||
else:
|
||||
caller.msg("Not a valid nick index. See 'nicks' for a list.")
|
||||
return
|
||||
nicktype = oldnick.category
|
||||
nicktypestr = "%s-nick" % nicktype.capitalize()
|
||||
else:
|
||||
if not specified_nicktype:
|
||||
nicktypes = ("object", "account", "inputline")
|
||||
for nicktype in nicktypes:
|
||||
oldnicks.append(caller.nicks.get(arg, category=nicktype, return_obj=True))
|
||||
|
||||
if nicktype == "account":
|
||||
account.nicks.remove(old_nickstring, category=nicktype)
|
||||
else:
|
||||
oldnicks = [oldnick for oldnick in oldnicks if oldnick]
|
||||
if oldnicks:
|
||||
for oldnick in oldnicks:
|
||||
nicktype = oldnick.category
|
||||
nicktypestr = "%s-nick" % nicktype.capitalize()
|
||||
_, _, old_nickstring, old_replstring = oldnick.value
|
||||
caller.nicks.remove(old_nickstring, category=nicktype)
|
||||
caller.msg("%s removed: '|w%s|n' -> |w%s|n." % (
|
||||
nicktypestr, old_nickstring, old_replstring))
|
||||
return
|
||||
caller.msg("%s removed: '|w%s|n' -> |w%s|n." % (
|
||||
nicktypestr, old_nickstring, old_replstring))
|
||||
else:
|
||||
caller.msg("No matching nicks to remove.")
|
||||
return
|
||||
|
||||
if not self.rhs and self.lhs:
|
||||
# check what a nick is set to
|
||||
strings = []
|
||||
if not specified_nicktype:
|
||||
nicktypes = ("object", "account", "inputline")
|
||||
for nicktype in nicktypes:
|
||||
nicks = utils.make_iter(caller.nicks.get(category=nicktype, return_obj=True))
|
||||
for nick in nicks:
|
||||
_, _, nick, repl = nick.value
|
||||
if nick.startswith(self.lhs):
|
||||
strings.append("{}-nick: '{}' -> '{}'".format(
|
||||
nicktype.capitalize(), nick, repl))
|
||||
if strings:
|
||||
caller.msg("\n".join(strings))
|
||||
else:
|
||||
caller.msg("No nicks found matching '{}'".format(self.lhs))
|
||||
return
|
||||
|
||||
if not self.rhs and self.lhs:
|
||||
# check what a nick is set to
|
||||
strings = []
|
||||
if not specified_nicktype:
|
||||
nicktypes = ("object", "account", "inputline")
|
||||
for nicktype in nicktypes:
|
||||
if nicktype == "account":
|
||||
obj = account
|
||||
else:
|
||||
obj = caller
|
||||
nicks = utils.make_iter(obj.nicks.get(category=nicktype, return_obj=True))
|
||||
for nick in nicks:
|
||||
_, _, nick, repl = nick.value
|
||||
if nick.startswith(self.lhs):
|
||||
strings.append("{}-nick: '{}' -> '{}'".format(
|
||||
nicktype.capitalize(), nick, repl))
|
||||
if strings:
|
||||
caller.msg("\n".join(strings))
|
||||
else:
|
||||
caller.msg("No nicks found matching '{}'".format(self.lhs))
|
||||
return
|
||||
|
||||
if not self.rhs and self.lhs:
|
||||
# check what a nick is set to
|
||||
|
|
@ -237,16 +284,11 @@ class CmdNick(COMMAND_DEFAULT_CLASS):
|
|||
errstring = ""
|
||||
string = ""
|
||||
for nicktype in nicktypes:
|
||||
if nicktype == "account":
|
||||
obj = account
|
||||
else:
|
||||
obj = caller
|
||||
|
||||
nicktypestr = "%s-nick" % nicktype.capitalize()
|
||||
old_nickstring = None
|
||||
old_replstring = None
|
||||
|
||||
oldnick = obj.nicks.get(key=nickstring, category=nicktype, return_obj=True)
|
||||
oldnick = caller.nicks.get(key=nickstring, category=nicktype, return_obj=True)
|
||||
if oldnick:
|
||||
_, _, old_nickstring, old_replstring = oldnick.value
|
||||
if replstring:
|
||||
|
|
@ -261,7 +303,7 @@ class CmdNick(COMMAND_DEFAULT_CLASS):
|
|||
else:
|
||||
string += "\n%s '|w%s|n' mapped to '|w%s|n'." % (nicktypestr, nickstring, replstring)
|
||||
try:
|
||||
obj.nicks.add(nickstring, replstring, category=nicktype)
|
||||
caller.nicks.add(nickstring, replstring, category=nicktype)
|
||||
except NickTemplateInvalid:
|
||||
caller.msg("You must use the same $-markers both in the nick and in the replacement.")
|
||||
return
|
||||
|
|
@ -337,13 +379,17 @@ class CmdGet(COMMAND_DEFAULT_CLASS):
|
|||
caller.msg("You can't get that.")
|
||||
return
|
||||
|
||||
# calling at_before_get hook method
|
||||
if not obj.at_before_get(caller):
|
||||
return
|
||||
|
||||
obj.move_to(caller, quiet=True)
|
||||
caller.msg("You pick up %s." % obj.name)
|
||||
caller.location.msg_contents("%s picks up %s." %
|
||||
(caller.name,
|
||||
obj.name),
|
||||
exclude=caller)
|
||||
# calling hook method
|
||||
# calling at_get hook method
|
||||
obj.at_get(caller)
|
||||
|
||||
|
||||
|
|
@ -378,6 +424,10 @@ class CmdDrop(COMMAND_DEFAULT_CLASS):
|
|||
if not obj:
|
||||
return
|
||||
|
||||
# Call the object script's at_before_drop() method.
|
||||
if not obj.at_before_drop(caller):
|
||||
return
|
||||
|
||||
obj.move_to(caller.location, quiet=True)
|
||||
caller.msg("You drop %s." % (obj.name,))
|
||||
caller.location.msg_contents("%s drops %s." %
|
||||
|
|
@ -392,12 +442,13 @@ class CmdGive(COMMAND_DEFAULT_CLASS):
|
|||
give away something to someone
|
||||
|
||||
Usage:
|
||||
give <inventory obj> = <target>
|
||||
give <inventory obj> <to||=> <target>
|
||||
|
||||
Gives an items from your inventory to another character,
|
||||
placing it in their inventory.
|
||||
"""
|
||||
key = "give"
|
||||
rhs_split = ("=", " to ") # Prefer = delimiter, but allow " to " usage.
|
||||
locks = "cmd:all()"
|
||||
arg_regex = r"\s|$"
|
||||
|
||||
|
|
@ -420,6 +471,11 @@ class CmdGive(COMMAND_DEFAULT_CLASS):
|
|||
if not to_give.location == caller:
|
||||
caller.msg("You are not holding %s." % to_give.key)
|
||||
return
|
||||
|
||||
# calling at_before_give hook method
|
||||
if not to_give.at_before_give(caller, target):
|
||||
return
|
||||
|
||||
# give object
|
||||
caller.msg("You give %s to %s." % (to_give.key, target.key))
|
||||
to_give.move_to(target, quiet=True)
|
||||
|
|
@ -496,7 +552,7 @@ class CmdWhisper(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
Usage:
|
||||
whisper <character> = <message>
|
||||
whisper <char1>, <char2> = <message?
|
||||
whisper <char1>, <char2> = <message>
|
||||
|
||||
Talk privately to one or more characters in your current location, without
|
||||
others in the room being informed.
|
||||
|
|
|
|||
|
|
@ -317,6 +317,7 @@ class CmdSetHelp(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
"""
|
||||
key = "@sethelp"
|
||||
switch_options = ("edit", "replace", "append", "extend", "delete")
|
||||
locks = "cmd:perm(Helper)"
|
||||
help_category = "Building"
|
||||
|
||||
|
|
|
|||
|
|
@ -79,6 +79,13 @@ class MuxCommand(Command):
|
|||
it here). The rest of the command is stored in self.args, which can
|
||||
start with the switch indicator /.
|
||||
|
||||
Optional variables to aid in parsing, if set:
|
||||
self.switch_options - (tuple of valid /switches expected by this
|
||||
command (without the /))
|
||||
self.rhs_split - Alternate string delimiter or tuple of strings
|
||||
to separate left/right hand sides. tuple form
|
||||
gives priority split to first string delimiter.
|
||||
|
||||
This parser breaks self.args into its constituents and stores them in the
|
||||
following variables:
|
||||
self.switches = [list of /switches (without the /)]
|
||||
|
|
@ -97,9 +104,18 @@ class MuxCommand(Command):
|
|||
"""
|
||||
raw = self.args
|
||||
args = raw.strip()
|
||||
# Without explicitly setting these attributes, they assume default values:
|
||||
if not hasattr(self, "switch_options"):
|
||||
self.switch_options = None
|
||||
if not hasattr(self, "rhs_split"):
|
||||
self.rhs_split = "="
|
||||
if not hasattr(self, "account_caller"):
|
||||
self.account_caller = False
|
||||
|
||||
# split out switches
|
||||
switches = []
|
||||
switches, delimiters = [], self.rhs_split
|
||||
if self.switch_options:
|
||||
self.switch_options = [opt.lower() for opt in self.switch_options]
|
||||
if args and len(args) > 1 and raw[0] == "/":
|
||||
# we have a switch, or a set of switches. These end with a space.
|
||||
switches = args[1:].split(None, 1)
|
||||
|
|
@ -109,16 +125,50 @@ class MuxCommand(Command):
|
|||
else:
|
||||
args = ""
|
||||
switches = switches[0].split('/')
|
||||
# If user-provides switches, parse them with parser switch options.
|
||||
if switches and self.switch_options:
|
||||
valid_switches, unused_switches, extra_switches = [], [], []
|
||||
for element in switches:
|
||||
option_check = [opt for opt in self.switch_options if opt == element]
|
||||
if not option_check:
|
||||
option_check = [opt for opt in self.switch_options if opt.startswith(element)]
|
||||
match_count = len(option_check)
|
||||
if match_count > 1:
|
||||
extra_switches.extend(option_check) # Either the option provided is ambiguous,
|
||||
elif match_count == 1:
|
||||
valid_switches.extend(option_check) # or it is a valid option abbreviation,
|
||||
elif match_count == 0:
|
||||
unused_switches.append(element) # or an extraneous option to be ignored.
|
||||
if extra_switches: # User provided switches
|
||||
self.msg('|g%s|n: |wAmbiguous switch supplied: Did you mean /|C%s|w?' %
|
||||
(self.cmdstring, ' |nor /|C'.join(extra_switches)))
|
||||
if unused_switches:
|
||||
plural = '' if len(unused_switches) == 1 else 'es'
|
||||
self.msg('|g%s|n: |wExtra switch%s "/|C%s|w" ignored.' %
|
||||
(self.cmdstring, plural, '|n, /|C'.join(unused_switches)))
|
||||
switches = valid_switches # Only include valid_switches in command function call
|
||||
arglist = [arg.strip() for arg in args.split()]
|
||||
|
||||
# check for arg1, arg2, ... = argA, argB, ... constructs
|
||||
lhs, rhs = args, None
|
||||
lhslist, rhslist = [arg.strip() for arg in args.split(',')], []
|
||||
if args and '=' in args:
|
||||
lhs, rhs = [arg.strip() for arg in args.split('=', 1)]
|
||||
lhslist = [arg.strip() for arg in lhs.split(',')]
|
||||
rhslist = [arg.strip() for arg in rhs.split(',')]
|
||||
|
||||
lhs, rhs = args.strip(), None
|
||||
if lhs:
|
||||
if delimiters and hasattr(delimiters, '__iter__'): # If delimiter is iterable,
|
||||
best_split = delimiters[0] # (default to first delimiter)
|
||||
for this_split in delimiters: # try each delimiter
|
||||
if this_split in lhs: # to find first successful split
|
||||
best_split = this_split # to be the best split.
|
||||
break
|
||||
else:
|
||||
best_split = delimiters
|
||||
# Parse to separate left into left/right sides using best_split delimiter string
|
||||
if best_split in lhs:
|
||||
lhs, rhs = lhs.split(best_split, 1)
|
||||
# Trim user-injected whitespace
|
||||
rhs = rhs.strip() if rhs is not None else None
|
||||
lhs = lhs.strip()
|
||||
# Further split left/right sides by comma delimiter
|
||||
lhslist = [arg.strip() for arg in lhs.split(',')] if lhs is not None else ""
|
||||
rhslist = [arg.strip() for arg in rhs.split(',')] if rhs is not None else ""
|
||||
# save to object properties:
|
||||
self.raw = raw
|
||||
self.switches = switches
|
||||
|
|
@ -133,7 +183,7 @@ class MuxCommand(Command):
|
|||
# sure that self.caller is always the account if possible. We also create
|
||||
# a special property "character" for the puppeted object, if any. This
|
||||
# is convenient for commands defined on the Account only.
|
||||
if hasattr(self, "account_caller") and self.account_caller:
|
||||
if self.account_caller:
|
||||
if utils.inherits_from(self.caller, "evennia.objects.objects.DefaultObject"):
|
||||
# caller is an Object/Character
|
||||
self.character = self.caller
|
||||
|
|
@ -169,6 +219,8 @@ class MuxCommand(Command):
|
|||
string += "\nraw argument (self.raw): |w%s|n \n" % self.raw
|
||||
string += "cmd args (self.args): |w%s|n\n" % self.args
|
||||
string += "cmd switches (self.switches): |w%s|n\n" % self.switches
|
||||
string += "cmd options (self.switch_options): |w%s|n\n" % self.switch_options
|
||||
string += "cmd parse left/right using (self.rhs_split): |w%s|n\n" % self.rhs_split
|
||||
string += "space-separated arg list (self.arglist): |w%s|n\n" % self.arglist
|
||||
string += "lhs, left-hand side of '=' (self.lhs): |w%s|n\n" % self.lhs
|
||||
string += "lhs, comma separated (self.lhslist): |w%s|n\n" % self.lhslist
|
||||
|
|
@ -193,18 +245,4 @@ class MuxAccountCommand(MuxCommand):
|
|||
character is actually attached to this Account and Session.
|
||||
"""
|
||||
|
||||
def parse(self):
|
||||
"""
|
||||
We run the parent parser as usual, then fix the result
|
||||
"""
|
||||
super(MuxAccountCommand, self).parse()
|
||||
|
||||
if utils.inherits_from(self.caller, "evennia.objects.objects.DefaultObject"):
|
||||
# caller is an Object/Character
|
||||
self.character = self.caller
|
||||
self.caller = self.caller.account
|
||||
elif utils.inherits_from(self.caller, "evennia.accounts.accounts.DefaultAccount"):
|
||||
# caller was already an Account
|
||||
self.character = self.caller.get_puppet(self.session)
|
||||
else:
|
||||
self.character = None
|
||||
account_caller = True # Using MuxAccountCommand explicitly defaults the caller to an account
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ class CmdReload(COMMAND_DEFAULT_CLASS):
|
|||
if self.args:
|
||||
reason = "(Reason: %s) " % self.args.rstrip(".")
|
||||
SESSIONS.announce_all(" Server restart initiated %s..." % reason)
|
||||
SESSIONS.server.shutdown(mode='reload')
|
||||
SESSIONS.portal_restart_server()
|
||||
|
||||
|
||||
class CmdReset(COMMAND_DEFAULT_CLASS):
|
||||
|
|
@ -91,7 +91,7 @@ class CmdReset(COMMAND_DEFAULT_CLASS):
|
|||
Reload the system.
|
||||
"""
|
||||
SESSIONS.announce_all(" Server resetting/restarting ...")
|
||||
SESSIONS.server.shutdown(mode='reset')
|
||||
SESSIONS.portal_reset_server()
|
||||
|
||||
|
||||
class CmdShutdown(COMMAND_DEFAULT_CLASS):
|
||||
|
|
@ -119,7 +119,6 @@ class CmdShutdown(COMMAND_DEFAULT_CLASS):
|
|||
announcement += "%s\n" % self.args
|
||||
logger.log_info('Server shutdown by %s.' % self.caller.name)
|
||||
SESSIONS.announce_all(announcement)
|
||||
SESSIONS.server.shutdown(mode='shutdown')
|
||||
SESSIONS.portal_shutdown()
|
||||
|
||||
|
||||
|
|
@ -246,6 +245,7 @@ class CmdPy(COMMAND_DEFAULT_CLASS):
|
|||
"""
|
||||
key = "@py"
|
||||
aliases = ["!"]
|
||||
switch_options = ("time", "edit")
|
||||
locks = "cmd:perm(py) or perm(Developer)"
|
||||
help_category = "System"
|
||||
|
||||
|
|
@ -329,6 +329,7 @@ class CmdScripts(COMMAND_DEFAULT_CLASS):
|
|||
"""
|
||||
key = "@scripts"
|
||||
aliases = ["@globalscript", "@listscripts"]
|
||||
switch_options = ("start", "stop", "kill", "validate")
|
||||
locks = "cmd:perm(listscripts) or perm(Admin)"
|
||||
help_category = "System"
|
||||
|
||||
|
|
@ -522,6 +523,7 @@ class CmdService(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
key = "@service"
|
||||
aliases = ["@services"]
|
||||
switch_options = ("list", "start", "stop", "delete")
|
||||
locks = "cmd:perm(service) or perm(Developer)"
|
||||
help_category = "System"
|
||||
|
||||
|
|
@ -673,7 +675,7 @@ class CmdServerLoad(COMMAND_DEFAULT_CLASS):
|
|||
Usage:
|
||||
@server[/mem]
|
||||
|
||||
Switch:
|
||||
Switches:
|
||||
mem - return only a string of the current memory usage
|
||||
flushmem - flush the idmapper cache
|
||||
|
||||
|
|
@ -704,6 +706,7 @@ class CmdServerLoad(COMMAND_DEFAULT_CLASS):
|
|||
"""
|
||||
key = "@server"
|
||||
aliases = ["@serverload", "@serverprocess"]
|
||||
switch_options = ("mem", "flushmem")
|
||||
locks = "cmd:perm(list) or perm(Developer)"
|
||||
help_category = "System"
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ from mock import Mock, mock
|
|||
from evennia.commands.default.cmdset_character import CharacterCmdSet
|
||||
from evennia.utils.test_resources import EvenniaTest
|
||||
from evennia.commands.default import help, general, system, admin, account, building, batchprocess, comms
|
||||
from evennia.commands.default.muxcommand import MuxCommand
|
||||
from evennia.commands.command import Command, InterruptCommand
|
||||
from evennia.utils import ansi, utils
|
||||
from evennia.server.sessionhandler import SESSIONS
|
||||
|
|
@ -72,7 +73,6 @@ class CommandTest(EvenniaTest):
|
|||
cmdobj.obj = obj or (caller if caller else self.char1)
|
||||
# test
|
||||
old_msg = receiver.msg
|
||||
returned_msg = ""
|
||||
try:
|
||||
receiver.msg = Mock()
|
||||
cmdobj.at_pre_cmd()
|
||||
|
|
@ -126,18 +126,48 @@ class TestGeneral(CommandTest):
|
|||
self.call(general.CmdPose(), "looks around", "Char looks around")
|
||||
|
||||
def test_nick(self):
|
||||
self.call(general.CmdNick(), "testalias = testaliasedstring1", "Inputlinenick 'testalias' mapped to 'testaliasedstring1'.")
|
||||
self.call(general.CmdNick(), "/account testalias = testaliasedstring2", "Accountnick 'testalias' mapped to 'testaliasedstring2'.")
|
||||
self.call(general.CmdNick(), "/object testalias = testaliasedstring3", "Objectnick 'testalias' mapped to 'testaliasedstring3'.")
|
||||
self.call(general.CmdNick(), "testalias = testaliasedstring1",
|
||||
"Inputlinenick 'testalias' mapped to 'testaliasedstring1'.")
|
||||
self.call(general.CmdNick(), "/account testalias = testaliasedstring2",
|
||||
"Accountnick 'testalias' mapped to 'testaliasedstring2'.")
|
||||
self.call(general.CmdNick(), "/object testalias = testaliasedstring3",
|
||||
"Objectnick 'testalias' mapped to 'testaliasedstring3'.")
|
||||
self.assertEqual(u"testaliasedstring1", self.char1.nicks.get("testalias"))
|
||||
self.assertEqual(None, self.char1.nicks.get("testalias", category="account"))
|
||||
self.assertEqual(u"testaliasedstring2", self.char1.account.nicks.get("testalias", category="account"))
|
||||
self.assertEqual(u"testaliasedstring2", self.char1.nicks.get("testalias", category="account"))
|
||||
self.assertEqual(None, self.char1.account.nicks.get("testalias", category="account"))
|
||||
self.assertEqual(u"testaliasedstring3", self.char1.nicks.get("testalias", category="object"))
|
||||
|
||||
def test_get_and_drop(self):
|
||||
self.call(general.CmdGet(), "Obj", "You pick up Obj.")
|
||||
self.call(general.CmdDrop(), "Obj", "You drop Obj.")
|
||||
|
||||
def test_give(self):
|
||||
self.call(general.CmdGive(), "Obj to Char2", "You aren't carrying Obj.")
|
||||
self.call(general.CmdGive(), "Obj = Char2", "You aren't carrying Obj.")
|
||||
self.call(general.CmdGet(), "Obj", "You pick up Obj.")
|
||||
self.call(general.CmdGive(), "Obj to Char2", "You give")
|
||||
self.call(general.CmdGive(), "Obj = Char", "You give", caller=self.char2)
|
||||
|
||||
def test_mux_command(self):
|
||||
|
||||
class CmdTest(MuxCommand):
|
||||
key = 'test'
|
||||
switch_options = ('test', 'testswitch', 'testswitch2')
|
||||
|
||||
def func(self):
|
||||
self.msg("Switches matched: {}".format(self.switches))
|
||||
|
||||
self.call(CmdTest(), "/test/testswitch/testswitch2", "Switches matched: ['test', 'testswitch', 'testswitch2']")
|
||||
self.call(CmdTest(), "/test", "Switches matched: ['test']")
|
||||
self.call(CmdTest(), "/test/testswitch", "Switches matched: ['test', 'testswitch']")
|
||||
self.call(CmdTest(), "/testswitch/testswitch2", "Switches matched: ['testswitch', 'testswitch2']")
|
||||
self.call(CmdTest(), "/testswitch", "Switches matched: ['testswitch']")
|
||||
self.call(CmdTest(), "/testswitch2", "Switches matched: ['testswitch2']")
|
||||
self.call(CmdTest(), "/t", "test: Ambiguous switch supplied: "
|
||||
"Did you mean /test or /testswitch or /testswitch2?|Switches matched: []")
|
||||
self.call(CmdTest(), "/tests", "test: Ambiguous switch supplied: "
|
||||
"Did you mean /testswitch or /testswitch2?|Switches matched: []")
|
||||
|
||||
def test_say(self):
|
||||
self.call(general.CmdSay(), "Testing", "You say, \"Testing\"")
|
||||
|
||||
|
|
@ -225,7 +255,8 @@ class TestAccount(CommandTest):
|
|||
self.call(account.CmdColorTest(), "ansi", "ANSI colors:", caller=self.account)
|
||||
|
||||
def test_char_create(self):
|
||||
self.call(account.CmdCharCreate(), "Test1=Test char", "Created new character Test1. Use @ic Test1 to enter the game", caller=self.account)
|
||||
self.call(account.CmdCharCreate(), "Test1=Test char",
|
||||
"Created new character Test1. Use @ic Test1 to enter the game", caller=self.account)
|
||||
|
||||
def test_quell(self):
|
||||
self.call(account.CmdQuell(), "", "Quelling to current puppet's permissions (developer).", caller=self.account)
|
||||
|
|
@ -234,16 +265,19 @@ class TestAccount(CommandTest):
|
|||
class TestBuilding(CommandTest):
|
||||
def test_create(self):
|
||||
name = settings.BASE_OBJECT_TYPECLASS.rsplit('.', 1)[1]
|
||||
self.call(building.CmdCreate(), "/drop TestObj1", "You create a new %s: TestObj1." % name)
|
||||
self.call(building.CmdCreate(), "/d TestObj1", # /d switch is abbreviated form of /drop
|
||||
"You create a new %s: TestObj1." % name)
|
||||
|
||||
def test_examine(self):
|
||||
self.call(building.CmdExamine(), "Obj", "Name/key: Obj")
|
||||
|
||||
def test_set_obj_alias(self):
|
||||
self.call(building.CmdSetObjAlias(), "Obj = TestObj1b", "Alias(es) for 'Obj(#4)' set to testobj1b.")
|
||||
self.call(building.CmdSetObjAlias(), "Obj =", "Cleared aliases from Obj(#4)")
|
||||
self.call(building.CmdSetObjAlias(), "Obj = TestObj1b", "Alias(es) for 'Obj(#4)' set to 'testobj1b'.")
|
||||
|
||||
def test_copy(self):
|
||||
self.call(building.CmdCopy(), "Obj = TestObj2;TestObj2b, TestObj3;TestObj3b", "Copied Obj to 'TestObj3' (aliases: ['TestObj3b']")
|
||||
self.call(building.CmdCopy(), "Obj = TestObj2;TestObj2b, TestObj3;TestObj3b",
|
||||
"Copied Obj to 'TestObj3' (aliases: ['TestObj3b']")
|
||||
|
||||
def test_attribute_commands(self):
|
||||
self.call(building.CmdSetAttribute(), "Obj/test1=\"value1\"", "Created attribute Obj/test1 = 'value1'")
|
||||
|
|
@ -286,19 +320,35 @@ class TestBuilding(CommandTest):
|
|||
|
||||
def test_typeclass(self):
|
||||
self.call(building.CmdTypeclass(), "Obj = evennia.objects.objects.DefaultExit",
|
||||
"Obj changed typeclass from evennia.objects.objects.DefaultObject to evennia.objects.objects.DefaultExit.")
|
||||
"Obj changed typeclass from evennia.objects.objects.DefaultObject "
|
||||
"to evennia.objects.objects.DefaultExit.")
|
||||
|
||||
def test_lock(self):
|
||||
self.call(building.CmdLock(), "Obj = test:perm(Developer)", "Added lock 'test:perm(Developer)' to Obj.")
|
||||
|
||||
def test_find(self):
|
||||
self.call(building.CmdFind(), "Room2", "One Match")
|
||||
expect = "One Match(#1#7, loc):\n " +\
|
||||
"Char2(#7) evennia.objects.objects.DefaultCharacter (location: Room(#1))"
|
||||
self.call(building.CmdFind(), "Char2", expect, cmdstring="locate")
|
||||
self.call(building.CmdFind(), "/ex Char2", # /ex is an ambiguous switch
|
||||
"locate: Ambiguous switch supplied: Did you mean /exit or /exact?|" + expect,
|
||||
cmdstring="locate")
|
||||
self.call(building.CmdFind(), "Char2", expect, cmdstring="@locate")
|
||||
self.call(building.CmdFind(), "/l Char2", expect, cmdstring="find") # /l switch is abbreviated form of /loc
|
||||
self.call(building.CmdFind(), "Char2", "One Match", cmdstring="@find")
|
||||
|
||||
def test_script(self):
|
||||
self.call(building.CmdScript(), "Obj = scripts.Script", "Script scripts.Script successfully added")
|
||||
|
||||
def test_teleport(self):
|
||||
self.call(building.CmdTeleport(), "Room2", "Room2(#2)\n|Teleported to Room2.")
|
||||
self.call(building.CmdTeleport(), "/quiet Room2", "Room2(#2)\n|Teleported to Room2.")
|
||||
self.call(building.CmdTeleport(), "/t", # /t switch is abbreviated form of /tonone
|
||||
"Cannot teleport a puppeted object (Char, puppeted by TestAccount(account 1)) to a Nonelocation.")
|
||||
self.call(building.CmdTeleport(), "/l Room2", # /l switch is abbreviated form of /loc
|
||||
"Destination has no location.")
|
||||
self.call(building.CmdTeleport(), "/q me to Room2", # /q switch is abbreviated form of /quiet
|
||||
"Char is already at Room2.")
|
||||
|
||||
def test_spawn(self):
|
||||
def getObject(commandTest, objKeyStr):
|
||||
|
|
@ -314,7 +364,7 @@ class TestBuilding(CommandTest):
|
|||
self.call(building.CmdSpawn(), " ", "Usage: @spawn")
|
||||
|
||||
# Tests "@spawn <prototype_dictionary>" without specifying location.
|
||||
self.call(building.CmdSpawn(), \
|
||||
self.call(building.CmdSpawn(),
|
||||
"{'key':'goblin', 'typeclass':'evennia.DefaultCharacter'}", "Spawned goblin")
|
||||
goblin = getObject(self, "goblin")
|
||||
|
||||
|
|
@ -333,8 +383,8 @@ class TestBuilding(CommandTest):
|
|||
# char1's default location in the future...
|
||||
spawnLoc = self.room1
|
||||
|
||||
self.call(building.CmdSpawn(), \
|
||||
"{'prototype':'GOBLIN', 'key':'goblin', 'location':'%s'}" \
|
||||
self.call(building.CmdSpawn(),
|
||||
"{'prototype':'GOBLIN', 'key':'goblin', 'location':'%s'}"
|
||||
% spawnLoc.dbref, "Spawned goblin")
|
||||
goblin = getObject(self, "goblin")
|
||||
self.assertEqual(goblin.location, spawnLoc)
|
||||
|
|
@ -347,70 +397,81 @@ class TestBuilding(CommandTest):
|
|||
self.assertIsInstance(ball, DefaultObject)
|
||||
ball.delete()
|
||||
|
||||
# Tests "@spawn/noloc ..." without specifying a location.
|
||||
# Tests "@spawn/n ..." without specifying a location.
|
||||
# Location should be "None".
|
||||
self.call(building.CmdSpawn(), "/noloc 'BALL'", "Spawned Ball")
|
||||
self.call(building.CmdSpawn(), "/n 'BALL'", "Spawned Ball") # /n switch is abbreviated form of /noloc
|
||||
ball = getObject(self, "Ball")
|
||||
self.assertIsNone(ball.location)
|
||||
ball.delete()
|
||||
|
||||
# Tests "@spawn/noloc ...", but DO specify a location.
|
||||
# Location should be the specified location.
|
||||
self.call(building.CmdSpawn(), \
|
||||
"/noloc {'prototype':'BALL', 'location':'%s'}" \
|
||||
self.call(building.CmdSpawn(),
|
||||
"/noloc {'prototype':'BALL', 'location':'%s'}"
|
||||
% spawnLoc.dbref, "Spawned Ball")
|
||||
ball = getObject(self, "Ball")
|
||||
self.assertEqual(ball.location, spawnLoc)
|
||||
ball.delete()
|
||||
|
||||
# test calling spawn with an invalid prototype.
|
||||
self.call(building.CmdSpawn(), \
|
||||
"'NO_EXIST'", "No prototype named 'NO_EXIST'")
|
||||
self.call(building.CmdSpawn(), "'NO_EXIST'", "No prototype named 'NO_EXIST'")
|
||||
|
||||
|
||||
class TestComms(CommandTest):
|
||||
|
||||
def setUp(self):
|
||||
super(CommandTest, self).setUp()
|
||||
self.call(comms.CmdChannelCreate(), "testchan;test=Test Channel", "Created channel testchan and connected to it.", receiver=self.account)
|
||||
self.call(comms.CmdChannelCreate(), "testchan;test=Test Channel",
|
||||
"Created channel testchan and connected to it.", receiver=self.account)
|
||||
|
||||
def test_toggle_com(self):
|
||||
self.call(comms.CmdAddCom(), "tc = testchan", "You are already connected to channel testchan. You can now", receiver=self.account)
|
||||
self.call(comms.CmdAddCom(), "tc = testchan",
|
||||
"You are already connected to channel testchan. You can now", receiver=self.account)
|
||||
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)
|
||||
self.call(comms.CmdAllCom(), "",
|
||||
"Available channels (use comlist,addcom and delcom to manage", receiver=self.account)
|
||||
|
||||
def test_clock(self):
|
||||
self.call(comms.CmdClock(), "testchan=send:all()", "Lock(s) applied. Current locks on testchan:", receiver=self.account)
|
||||
self.call(comms.CmdClock(),
|
||||
"testchan=send:all()", "Lock(s) applied. Current locks on testchan:", receiver=self.account)
|
||||
|
||||
def test_cdesc(self):
|
||||
self.call(comms.CmdCdesc(), "testchan = Test Channel", "Description of channel 'testchan' set to 'Test Channel'.", receiver=self.account)
|
||||
self.call(comms.CmdCdesc(), "testchan = Test Channel",
|
||||
"Description of channel 'testchan' set to 'Test Channel'.", receiver=self.account)
|
||||
|
||||
def test_cemit(self):
|
||||
self.call(comms.CmdCemit(), "testchan = Test Message", "[testchan] Test Message|Sent to channel testchan: Test Message", receiver=self.account)
|
||||
self.call(comms.CmdCemit(), "testchan = Test Message",
|
||||
"[testchan] Test Message|Sent to channel testchan: Test Message", receiver=self.account)
|
||||
|
||||
def test_cwho(self):
|
||||
self.call(comms.CmdCWho(), "testchan", "Channel subscriptions\ntestchan:\n TestAccount", receiver=self.account)
|
||||
|
||||
def test_page(self):
|
||||
self.call(comms.CmdPage(), "TestAccount2 = Test", "TestAccount2 is offline. They will see your message if they list their pages later.|You paged TestAccount2 with: 'Test'.", receiver=self.account)
|
||||
self.call(comms.CmdPage(), "TestAccount2 = Test",
|
||||
"TestAccount2 is offline. They will see your message if they list their pages later."
|
||||
"|You paged TestAccount2 with: 'Test'.", receiver=self.account)
|
||||
|
||||
def test_cboot(self):
|
||||
# No one else connected to boot
|
||||
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):
|
||||
def test_batch_commands(self):
|
||||
# cannot test batchcode here, it must run inside the server process
|
||||
self.call(batchprocess.CmdBatchCommands(), "example_batch_cmds", "Running Batchcommand processor Automatic mode for example_batch_cmds")
|
||||
self.call(batchprocess.CmdBatchCommands(), "example_batch_cmds",
|
||||
"Running Batchcommand processor Automatic mode for example_batch_cmds")
|
||||
# we make sure to delete the button again here to stop the running reactor
|
||||
confirm = building.CmdDestroy.confirm
|
||||
building.CmdDestroy.confirm = False
|
||||
|
|
|
|||
|
|
@ -293,7 +293,7 @@ class CmdUnconnectedCreate(COMMAND_DEFAULT_CLASS):
|
|||
session.msg(string)
|
||||
return
|
||||
if not re.findall(r"^[\w. @+\-']+$", password) or not (3 < len(password)):
|
||||
string = "\n\r Password should be longer than 3 characers. Letters, spaces, digits and @/./+/-/_/' only." \
|
||||
string = "\n\r Password should be longer than 3 characters. Letters, spaces, digits and @/./+/-/_/' only." \
|
||||
"\nFor best security, make it longer than 8 characters. You can also use a phrase of" \
|
||||
"\nmany words if you enclose the password in double quotes."
|
||||
session.msg(string)
|
||||
|
|
@ -557,7 +557,7 @@ def _create_character(session, new_account, typeclass, home, permissions):
|
|||
|
||||
# If no description is set, set a default description
|
||||
if not new_character.db.desc:
|
||||
new_character.db.desc = "This is an Account."
|
||||
new_character.db.desc = "This is a character."
|
||||
# We need to set this to have @ic auto-connect to this character
|
||||
new_account.db._last_puppet = new_character
|
||||
except Exception as e:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue