PEP8 cleanup of the entire codebase. Unchanged are many cases of too-long lines, partly because of the rewrite they would require but also because splitting many lines up would make the code harder to read. Also the third-party libraries (idmapper, prettytable etc) were not cleaned.

This commit is contained in:
Griatch 2013-11-14 19:31:17 +01:00
parent 30b7d2a405
commit 1ae17bcbe4
154 changed files with 5613 additions and 4054 deletions

View file

@ -4,7 +4,8 @@ Admin commands
"""
import time, re
import time
import re
from django.conf import settings
from django.contrib.auth.models import User
from src.server.sessionhandler import SESSIONS
@ -15,8 +16,8 @@ from src.commands.default.muxcommand import MuxCommand
PERMISSION_HIERARCHY = [p.lower() for p in settings.PERMISSION_HIERARCHY]
# limit members for API inclusion
__all__ = ("CmdBoot", "CmdBan", "CmdUnban", "CmdDelPlayer", "CmdEmit", "CmdNewPassword",
"CmdPerm", "CmdWall")
__all__ = ("CmdBoot", "CmdBan", "CmdUnban", "CmdDelPlayer",
"CmdEmit", "CmdNewPassword", "CmdPerm", "CmdWall")
class CmdBoot(MuxCommand):
@ -98,6 +99,7 @@ class CmdBoot(MuxCommand):
# regex matching IP addresses with wildcards, eg. 233.122.4.*
IPREGEX = re.compile(r"[0-9*]{1,3}\.[0-9*]{1,3}\.[0-9*]{1,3}\.[0-9*]{1,3}")
def list_bans(banlist):
"""
Helper function to display a list of active bans. Input argument
@ -108,12 +110,13 @@ def list_bans(banlist):
table = prettytable.PrettyTable(["{wid", "{wname/ip", "{wdate", "{wreason"])
for inum, ban in enumerate(banlist):
table.add_row([str(inum+1),
table.add_row([str(inum + 1),
ban[0] and ban[0] or ban[1],
ban[3], ban[4]])
string = "{wActive bans:{n\n%s" % table
return string
class CmdBan(MuxCommand):
"""
ban a player from the server
@ -152,7 +155,7 @@ class CmdBan(MuxCommand):
key = "@ban"
aliases = ["@bans"]
locks = "cmd:perm(ban) or perm(Immortals)"
help_category="Admin"
help_category = "Admin"
def func(self):
"""
@ -172,14 +175,15 @@ class CmdBan(MuxCommand):
banlist = []
if not self.args or (self.switches
and not any(switch in ('ip', 'name') for switch in self.switches)):
and not any(switch in ('ip', 'name')
for switch in self.switches)):
self.caller.msg(list_bans(banlist))
return
now = time.ctime()
reason = ""
if ':' in self.args:
ban, reason = self.args.rsplit(':',1)
ban, reason = self.args.rsplit(':', 1)
else:
ban = self.args
ban = ban.lower()
@ -193,7 +197,7 @@ class CmdBan(MuxCommand):
typ = "IP"
ban = ipban[0]
# replace * with regex form and compile it
ipregex = ban.replace('.','\.')
ipregex = ban.replace('.', '\.')
ipregex = ipregex.replace('*', '[0-9]{1,3}')
#print "regex:",ipregex
ipregex = re.compile(r"%s" % ipregex)
@ -203,6 +207,7 @@ class CmdBan(MuxCommand):
ServerConfig.objects.conf('server_bans', banlist)
self.caller.msg("%s-Ban {w%s{x was added." % (typ, ban))
class CmdUnban(MuxCommand):
"""
remove a ban
@ -218,7 +223,7 @@ class CmdUnban(MuxCommand):
"""
key = "@unban"
locks = "cmd:perm(unban) or perm(Immortals)"
help_category="Admin"
help_category = "Admin"
def func(self):
"Implement unbanning"
@ -241,10 +246,11 @@ class CmdUnban(MuxCommand):
self.caller.msg("Ban id {w%s{x was not found." % self.args)
else:
# all is ok, clear ban
ban = banlist[num-1]
del banlist[num-1]
ban = banlist[num - 1]
del banlist[num - 1]
ServerConfig.objects.conf('server_bans', banlist)
self.caller.msg("Cleared ban %s: %s" % (num, " ".join([s for s in ban[:2]])))
self.caller.msg("Cleared ban %s: %s" %
(num, " ".join([s for s in ban[:2]])))
class CmdDelPlayer(MuxCommand):
@ -408,7 +414,7 @@ class CmdEmit(MuxCommand):
obj = caller.search(objname, global_search=True)
if not obj:
return
if rooms_only and not obj.location == None:
if rooms_only and not obj.location is None:
caller.msg("%s is not a room. Ignored." % objname)
continue
if players_only and not obj.has_player:
@ -425,7 +431,6 @@ class CmdEmit(MuxCommand):
caller.msg("You are not allowed to emit to %s." % objname)
class CmdNewPassword(MuxCommand):
"""
@userpassword
@ -457,7 +462,8 @@ class CmdNewPassword(MuxCommand):
player.user.save()
self.msg("%s - new password set to '%s'." % (player.name, self.rhs))
if player.character != caller:
player.msg("%s has changed your password to '%s'." % (caller.name, self.rhs))
player.msg("%s has changed your password to '%s'." % (caller.name,
self.rhs))
class CmdPerm(MuxCommand):
@ -497,7 +503,7 @@ class CmdPerm(MuxCommand):
if playermode:
obj = caller.search_player(lhs)
else:
obj = caller.search(lhs, global_search=True)
obj = caller.search(lhs, global_search=True)
if not obj:
return
@ -511,7 +517,9 @@ class CmdPerm(MuxCommand):
string += "<None>"
else:
string += ", ".join(obj.permissions.all())
if hasattr(obj, 'player') and hasattr(obj.player, 'is_superuser') and obj.player.is_superuser:
if (hasattr(obj, 'player') and
hasattr(obj.player, 'is_superuser') and
obj.player.is_superuser):
string += "\n(... but this object is currently controlled by a SUPERUSER! "
string += "All access checks are passed automatically.)"
caller.msg(string)
@ -539,9 +547,10 @@ class CmdPerm(MuxCommand):
for perm in self.rhslist:
# don't allow to set a permission higher in the hierarchy than the one the
# caller has (to prevent self-escalation)
if perm.lower() in PERMISSION_HIERARCHY and not obj.locks.check_lockstring(caller, "dummy:perm(%s)" % perm):
# don't allow to set a permission higher in the hierarchy than
# the one the caller has (to prevent self-escalation)
if (perm.lower() in PERMISSION_HIERARCHY and not
obj.locks.check_lockstring(caller, "dummy:perm(%s)" % perm)):
caller.msg("You cannot assign a permission higher than the one you have yourself.")
return

View file

@ -95,11 +95,12 @@ def format_header(caller, entry):
stacklen = len(caller.ndb.batch_stack)
header = "{w%02i/%02i{G: %s{n" % (ptr, stacklen, header)
# add extra space to the side for padding.
header = "%s%s" % (header, " "*(width - len(header)))
header = "%s%s" % (header, " " * (width - len(header)))
header = header.replace('\n', '\\n')
return header
def format_code(entry):
"""
Formats the viewing of code and errors
@ -109,6 +110,7 @@ def format_code(entry):
code += "\n{G>>>{n %s" % line
return code.strip()
def batch_cmd_exec(caller):
"""
Helper function for executing a single batch-command entry
@ -124,6 +126,7 @@ def batch_cmd_exec(caller):
return False
return True
def batch_code_exec(caller):
"""
Helper function for executing a single batch-code entry
@ -135,12 +138,13 @@ def batch_code_exec(caller):
caller.msg(format_header(caller, codedict['code']))
err = BATCHCODE.code_exec(codedict,
extra_environ={"caller":caller}, debug=debug)
extra_environ={"caller": caller}, debug=debug)
if err:
caller.msg(format_code(err))
return False
return True
def step_pointer(caller, step=1):
"""
Step in stack, returning the item located.
@ -156,7 +160,8 @@ def step_pointer(caller, step=1):
caller.msg("{RBeginning of batch file.")
if ptr + step >= nstack:
caller.msg("{REnd of batch file.")
caller.ndb.batch_stackptr = max(0, min(nstack-1, ptr + step))
caller.ndb.batch_stackptr = max(0, min(nstack - 1, ptr + step))
def show_curr(caller, showall=False):
"""
@ -186,6 +191,7 @@ def show_curr(caller, showall=False):
string += "\n{G|{n %s" % line
caller.msg(string)
def purge_processor(caller):
"""
This purges all effects running
@ -201,12 +207,13 @@ def purge_processor(caller):
# clear everything but the default cmdset.
caller.cmdset.delete(BatchSafeCmdSet)
caller.cmdset.clear()
caller.scripts.validate() # this will purge interactive mode
caller.scripts.validate() # this will purge interactive mode
#------------------------------------------------------------
# main access commands
#------------------------------------------------------------
class CmdBatchCommands(MuxCommand):
"""
Build from batch-command file
@ -275,19 +282,25 @@ class CmdBatchCommands(MuxCommand):
procpool = False
if "PythonProcPool" in utils.server_services():
if utils.uses_database("sqlite3"):
caller.msg("Batchprocessor disabled ProcPool under SQLite3.")
caller.msg("Batchprocessor disabled ProcPool under SQLite3.")
else:
procpool=True
procpool = True
if procpool:
# run in parallel process
def callback(r):
caller.msg(" {GBatchfile '%s' applied." % python_path)
purge_processor(caller)
def errback(e):
caller.msg(" {RError from processor: '%s'" % e)
purge_processor(caller)
utils.run_async(_PROCPOOL_BATCHCMD_SOURCE, commands=commands, caller=caller, at_return=callback, at_err=errback)
utils.run_async(_PROCPOOL_BATCHCMD_SOURCE,
commands=commands,
caller=caller,
at_return=callback,
at_err=errback)
else:
# run in-process (might block)
for inum in range(len(commands)):
@ -295,11 +308,13 @@ class CmdBatchCommands(MuxCommand):
if not batch_cmd_exec(caller):
return
step_pointer(caller, 1)
# clean out the safety cmdset and clean out all other temporary attrs.
# clean out the safety cmdset and clean out all other
# temporary attrs.
string = " Batchfile '%s' applied." % python_path
caller.msg("{G%s" % string)
purge_processor(caller)
class CmdBatchCode(MuxCommand):
"""
Build from batch-code file
@ -352,7 +367,7 @@ class CmdBatchCode(MuxCommand):
debug = False
if 'debug' in switches:
debug = True
debug = True
# Store work data in cache
caller.ndb.batch_stack = codes
@ -376,18 +391,23 @@ class CmdBatchCode(MuxCommand):
procpool = False
if "PythonProcPool" in utils.server_services():
if utils.uses_database("sqlite3"):
caller.msg("Batchprocessor disabled ProcPool under SQLite3.")
caller.msg("Batchprocessor disabled ProcPool under SQLite3.")
else:
procpool=True
procpool = True
if procpool:
# run in parallel process
def callback(r):
caller.msg(" {GBatchfile '%s' applied." % python_path)
purge_processor(caller)
def errback(e):
caller.msg(" {RError from processor: '%s'" % e)
purge_processor(caller)
utils.run_async(_PROCPOOL_BATCHCODE_SOURCE, codes=codes, caller=caller, at_return=callback, at_err=errback)
utils.run_async(_PROCPOOL_BATCHCODE_SOURCE,
codes=codes,
caller=caller,
at_return=callback,
at_err=errback)
else:
# un in-process (will block)
for inum in range(len(codes)):
@ -395,7 +415,8 @@ class CmdBatchCode(MuxCommand):
if not batch_code_exec(caller):
return
step_pointer(caller, 1)
# clean out the safety cmdset and clean out all other temporary attrs.
# clean out the safety cmdset and clean out all other
# temporary attrs.
string = " Batchfile '%s' applied." % python_path
caller.msg("{G%s" % string)
purge_processor(caller)
@ -423,6 +444,7 @@ class CmdStateAbort(MuxCommand):
purge_processor(self.caller)
self.caller.msg("Exited processor and reset out active cmdset back to the default one.")
class CmdStateLL(MuxCommand):
"""
ll
@ -479,6 +501,7 @@ class CmdStateRR(MuxCommand):
caller.msg(format_code("File reloaded. Staying on same command."))
show_curr(caller)
class CmdStateRRR(MuxCommand):
"""
rrr
@ -500,6 +523,7 @@ class CmdStateRRR(MuxCommand):
caller.msg(format_code("File reloaded. Restarting from top."))
show_curr(caller)
class CmdStateNN(MuxCommand):
"""
nn
@ -520,6 +544,7 @@ class CmdStateNN(MuxCommand):
step_pointer(caller, step)
show_curr(caller)
class CmdStateNL(MuxCommand):
"""
nl
@ -541,6 +566,7 @@ class CmdStateNL(MuxCommand):
step_pointer(caller, step)
show_curr(caller, showall=True)
class CmdStateBB(MuxCommand):
"""
bb
@ -562,6 +588,7 @@ class CmdStateBB(MuxCommand):
step_pointer(caller, step)
show_curr(caller)
class CmdStateBL(MuxCommand):
"""
bl
@ -583,6 +610,7 @@ class CmdStateBL(MuxCommand):
step_pointer(caller, step)
show_curr(caller, showall=True)
class CmdStateSS(MuxCommand):
"""
ss [steps]
@ -611,6 +639,7 @@ class CmdStateSS(MuxCommand):
step_pointer(caller, 1)
show_curr(caller)
class CmdStateSL(MuxCommand):
"""
sl [steps]
@ -639,6 +668,7 @@ class CmdStateSL(MuxCommand):
step_pointer(caller, 1)
show_curr(caller)
class CmdStateCC(MuxCommand):
"""
cc
@ -670,6 +700,7 @@ class CmdStateCC(MuxCommand):
del caller.ndb.batch_batchmode
caller.msg(format_code("Finished processing batch file."))
class CmdStateJJ(MuxCommand):
"""
j <command number>
@ -684,7 +715,7 @@ class CmdStateJJ(MuxCommand):
caller = self.caller
arg = self.args
if arg and arg.isdigit():
number = int(self.args)-1
number = int(self.args) - 1
else:
caller.msg(format_code("You must give a number index."))
return
@ -693,6 +724,7 @@ class CmdStateJJ(MuxCommand):
step_pointer(caller, step)
show_curr(caller)
class CmdStateJL(MuxCommand):
"""
jl <command number>
@ -707,7 +739,7 @@ class CmdStateJL(MuxCommand):
caller = self.caller
arg = self.args
if arg and arg.isdigit():
number = int(self.args)-1
number = int(self.args) - 1
else:
caller.msg(format_code("You must give a number index."))
return
@ -716,6 +748,7 @@ class CmdStateJL(MuxCommand):
step_pointer(caller, step)
show_curr(caller, showall=True)
class CmdStateQQ(MuxCommand):
"""
qq
@ -730,6 +763,7 @@ class CmdStateQQ(MuxCommand):
purge_processor(self.caller)
self.caller.msg("Aborted interactive batch mode.")
class CmdStateHH(MuxCommand):
"Help command"
@ -766,7 +800,6 @@ class CmdStateHH(MuxCommand):
self.caller.msg(string)
#------------------------------------------------------------
#
# Defining the cmdsets for the interactive batchprocessor
@ -781,12 +814,13 @@ class BatchSafeCmdSet(CmdSet):
always be available to get out of everything.
"""
key = "Batch_default"
priority = 104 # override other cmdsets.
priority = 104 # override other cmdsets.
def at_cmdset_creation(self):
"Init the cmdset"
self.add(CmdStateAbort())
class BatchInteractiveCmdSet(CmdSet):
"""
The cmdset for the interactive batch processor mode.

View file

@ -29,6 +29,7 @@ except ImportError:
# used by @find
CHAR_TYPECLASS = settings.BASE_CHARACTER_TYPECLASS
class ObjManipCommand(MuxCommand):
"""
This is a parent class for some of the defining objmanip commands
@ -60,7 +61,7 @@ class ObjManipCommand(MuxCommand):
# get all the normal parsing done (switches etc)
super(ObjManipCommand, self).parse()
obj_defs = ([],[]) # stores left- and right-hand side of '='
obj_defs = ([], []) # stores left- and right-hand side of '='
obj_attrs = ([], []) # "
for iside, arglist in enumerate((self.lhslist, self.rhslist)):
@ -101,7 +102,7 @@ class CmdSetObjAlias(MuxCommand):
by everyone.
"""
key = "@alias"
key = "@alias"
aliases = "@setobjalias"
locks = "cmd:perm(setobjalias) or perm(Builders)"
help_category = "Building"
@ -121,7 +122,7 @@ class CmdSetObjAlias(MuxCommand):
obj = caller.search(objname)
if not obj:
return
if self.rhs == None:
if self.rhs is None:
# no =, so we just list aliases on object.
aliases = obj.aliases.all()
if aliases:
@ -146,15 +147,18 @@ class CmdSetObjAlias(MuxCommand):
# 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()]
new_aliases = [alias.strip().lower() for alias in self.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)
# we treat this as a re-caching (relevant for exits to re-build their exit commands with the correct aliases)
# we treat this as a re-caching (relevant for exits to re-build their
# exit commands with the correct aliases)
caller.msg("Alias(es) for '%s' set to %s." % (obj.key, str(obj.aliases)))
class CmdCopy(ObjManipCommand):
"""
@copy - copy objects
@ -167,8 +171,8 @@ class CmdCopy(ObjManipCommand):
removing any changes that might have been made to the original
since it was first created.
Create one or more copies of an object. If you don't supply any targets, one exact copy
of the original object will be created with the name *_copy.
Create one or more copies of an object. If you don't supply any targets,
one exact copt of the original object will be created with the name *_copy.
"""
key = "@copy"
@ -210,12 +214,15 @@ class CmdCopy(ObjManipCommand):
to_obj_aliases = objdef['aliases']
to_obj_location = objdef['option']
if to_obj_location:
to_obj_location = caller.search(to_obj_location, global_search=True)
to_obj_location = caller.search(to_obj_location,
global_search=True)
if not to_obj_location:
return
copiedobj = ObjectDB.objects.copy_object(from_obj, new_key=to_obj_name,
new_location=to_obj_location, new_aliases=to_obj_aliases)
copiedobj = ObjectDB.objects.copy_object(from_obj,
new_key=to_obj_name,
new_location=to_obj_location,
new_aliases=to_obj_aliases)
if copiedobj:
string = "Copied %s to '%s' (aliases: %s)." % (from_obj_name, to_obj_name,
to_obj_aliases)
@ -225,6 +232,7 @@ class CmdCopy(ObjManipCommand):
# we are done, echo to user
caller.msg(string)
class CmdCpAttr(ObjManipCommand):
"""
@cpattr - copy attributes
@ -244,8 +252,8 @@ class CmdCpAttr(ObjManipCommand):
copies the coolness attribute (defined on yourself), to attributes
on Anna and Tom.
Copy the attribute one object to one or more attributes on another object. If
you don't supply a source object, yourself is used.
Copy the attribute one object to one or more attributes on another object.
If you don't supply a source object, yourself is used.
"""
key = "@cpattr"
locks = "cmd:perm(cpattr) or perm(Builders)"
@ -272,7 +280,8 @@ class CmdCpAttr(ObjManipCommand):
from_obj_attrs = lhs_objattr[0]['attrs']
if not from_obj_attrs:
# this means the from_obj_name is actually an attribute name on self.
# this means the from_obj_name is actually an attribute
# name on self.
from_obj_attrs = [from_obj_name]
from_obj = self.caller
from_obj_name = self.caller.name
@ -282,7 +291,8 @@ class CmdCpAttr(ObjManipCommand):
caller.msg("You have to supply both source object and target(s).")
return
if not from_obj.attributes.has(from_obj_attrs[0]):
caller.msg("%s doesn't have an attribute %s." % (from_obj_name, from_obj_attrs[0]))
caller.msg("%s doesn't have an attribute %s." % (from_obj_name,
from_obj_attrs[0]))
return
srcvalue = from_obj.attributes.get(from_obj_attrs[0])
@ -291,7 +301,8 @@ class CmdCpAttr(ObjManipCommand):
string = "Moving "
else:
string = "Copying "
string += "%s/%s (with value %s) ..." % (from_obj_name, from_obj_attrs[0], srcvalue)
string += "%s/%s (with value %s) ..." % (from_obj_name,
from_obj_attrs[0], srcvalue)
for to_obj in to_objs:
to_obj_name = to_obj['name']
@ -308,15 +319,20 @@ class CmdCpAttr(ObjManipCommand):
# on the to_obj, we copy the original name instead.
to_attr = from_attr
to_obj.attributes.add(to_attr, srcvalue)
if "move" in self.switches and not (from_obj == to_obj and from_attr == to_attr):
if ("move" in self.switches and not (from_obj == to_obj and
from_attr == to_attr)):
from_obj.del_attribute(from_attr)
string += "\nMoved %s.%s -> %s.%s." % (from_obj.name, from_attr,
string += "\nMoved %s.%s -> %s.%s." % (from_obj.name,
from_attr,
to_obj_name, to_attr)
else:
string += "\nCopied %s.%s -> %s.%s." % (from_obj.name, from_attr,
to_obj_name, to_attr)
string += "\nCopied %s.%s -> %s.%s." % (from_obj.name,
from_attr,
to_obj_name,
to_attr)
caller.msg(string)
class CmdMvAttr(ObjManipCommand):
"""
@mvattr - move attributes
@ -330,8 +346,8 @@ class CmdMvAttr(ObjManipCommand):
Switches:
copy - Don't delete the original after moving.
Move an attribute from one object to one or more attributes on another object. If
you don't supply a source object, yourself is used.
Move an attribute from one object to one or more attributes on another
object. If you don't supply a source object, yourself is used.
"""
key = "@mvattr"
locks = "cmd:perm(mvattr) or perm(Builders)"
@ -356,6 +372,7 @@ class CmdMvAttr(ObjManipCommand):
else:
self.caller.execute_cmd("@cpattr/move %s" % self.args)
class CmdCreate(ObjManipCommand):
"""
@create - create new objects
@ -364,8 +381,9 @@ class CmdCreate(ObjManipCommand):
@create[/drop] objname[;alias;alias...][:typeclass], objname...
switch:
drop - automatically drop the new object into your current location (this is not echoed)
this also sets the new object's home to the current location rather than to you.
drop - automatically drop the new object into your current
location (this is not echoed). This also sets the new
object's home to the current location rather than to you.
Creates one or more new objects. If typeclass is given, the object
is created as a child of this typeclass. The typeclass script is
@ -406,7 +424,8 @@ class CmdCreate(ObjManipCommand):
# object typeclass will automatically be used)
lockstring = "control:id(%s);examine:perm(Builders);delete:id(%s) or perm(Wizards);get:all()" % (caller.id, caller.id)
obj = create.create_object(typeclass, name, caller,
home=caller, aliases=aliases, locks=lockstring, report_to=caller)
home=caller, aliases=aliases,
locks=lockstring, report_to=caller)
if not obj:
continue
if aliases:
@ -423,7 +442,8 @@ class CmdCreate(ObjManipCommand):
obj.home = caller.location
obj.move_to(caller.location, quiet=True)
if string:
caller.msg(string)
caller.msg(string)
class CmdDesc(MuxCommand):
"""
@ -471,8 +491,8 @@ class CmdDestroy(MuxCommand):
@destroy[/switches] [obj, obj2, obj3, [dbref-dbref], ...]
switches:
override - The @destroy command will usually avoid accidentally destroying
player objects. This switch overrides this safety.
override - The @destroy command will usually avoid accidentally
destroying player objects. This switch overrides this safety.
examples:
@destroy house, roof, door, 44-78
@destroy 5-10, flower, 45
@ -502,7 +522,8 @@ class CmdDestroy(MuxCommand):
if not obj:
self.caller.msg(" (Objects to destroy must either be local or specified with a unique #dbref.)")
return ""
if not "override" in self.switches and obj.dbid == int(settings.CHARACTER_DEFAULT_HOME.lstrip("#")):
if (not "override" in self.switches and
obj.dbid == int(settings.CHARACTER_DEFAULT_HOME.lstrip("#"))):
return "\nYou are trying to delete CHARACTER_DEFAULT_HOME. If you want to do this, use the /override switch."
objname = obj.name
if not obj.access(caller, 'delete'):
@ -529,9 +550,10 @@ class CmdDestroy(MuxCommand):
for objname in self.lhslist:
if '-' in objname:
# might be a range of dbrefs
dmin, dmax = [utils.dbref(part, reqhash=False) for part in objname.split('-', 1)]
dmin, dmax = [utils.dbref(part, reqhash=False)
for part in objname.split('-', 1)]
if dmin and dmax:
for dbref in range(int(dmin),int(dmax+1)):
for dbref in range(int(dmin), int(dmax + 1)):
string += delobj("#" + str(dbref), True)
else:
string += delobj(objname)
@ -558,9 +580,11 @@ class CmdDig(ObjManipCommand):
@dig house:myrooms.MyHouseTypeclass
@dig sheer cliff;cliff;sheer = climb up, climb down
This command is a convenient way to build rooms quickly; it creates the new room and you can optionally
set up exits back and forth between your current room and the new one. You can add as many aliases as you
like to the name of the room and the exits in question; an example would be 'north;no;n'.
This command is a convenient way to build rooms quickly; it creates the
new room and you can optionally set up exits back and forth between your
current room and the new one. You can add as many aliases as you
like to the name of the room and the exits in question; an example
would be 'north;no;n'.
"""
key = "@dig"
locks = "cmd:perm(dig) or perm(Builders)"
@ -595,13 +619,14 @@ class CmdDig(ObjManipCommand):
lockstring = lockstring % (caller.dbref, caller.dbref, caller.dbref)
new_room = create.create_object(typeclass, room["name"],
aliases=room["aliases"], report_to=caller)
aliases=room["aliases"],
report_to=caller)
new_room.locks.add(lockstring)
alias_string = ""
if new_room.aliases.all():
alias_string = " (%s)" % ", ".join(new_room.aliases.all())
room_string = "Created room %s(%s)%s of type %s." % (new_room, new_room.dbref, alias_string, typeclass)
room_string = "Created room %s(%s)%s of type %s." % (new_room,
new_room.dbref, alias_string, typeclass)
# create exit to room
@ -622,15 +647,21 @@ class CmdDig(ObjManipCommand):
if not typeclass:
typeclass = settings.BASE_EXIT_TYPECLASS
new_to_exit = create.create_object(typeclass, to_exit["name"], location,
new_to_exit = create.create_object(typeclass, to_exit["name"],
location,
aliases=to_exit["aliases"],
locks=lockstring, destination=new_room, report_to=caller)
locks=lockstring,
destination=new_room,
report_to=caller)
alias_string = ""
if new_to_exit.aliases.all():
alias_string = " (%s)" % ", ".join(new_to_exit.aliases.all())
exit_to_string = "\nCreated Exit from %s to %s: %s(%s)%s."
exit_to_string = exit_to_string % (location.name, new_room.name, new_to_exit,
new_to_exit.dbref, alias_string)
exit_to_string = exit_to_string % (location.name,
new_room.name,
new_to_exit,
new_to_exit.dbref,
alias_string)
# Create exit back from new room
@ -647,15 +678,22 @@ class CmdDig(ObjManipCommand):
typeclass = back_exit["option"]
if not typeclass:
typeclass = settings.BASE_EXIT_TYPECLASS
new_back_exit = create.create_object(typeclass, back_exit["name"],
new_room, aliases=back_exit["aliases"],
locks=lockstring, destination=location, report_to=caller)
new_back_exit = create.create_object(typeclass,
back_exit["name"],
new_room,
aliases=back_exit["aliases"],
locks=lockstring,
destination=location,
report_to=caller)
alias_string = ""
if new_back_exit.aliases.all():
alias_string = " (%s)" % ", ".join(new_back_exit.aliases.all())
exit_back_string = "\nCreated Exit back from %s to %s: %s(%s)%s."
exit_back_string = exit_back_string % (new_room.name, location.name,
new_back_exit, new_back_exit.dbref, alias_string)
exit_back_string = exit_back_string % (new_room.name,
location.name,
new_back_exit,
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):
caller.move_to(new_room)
@ -693,18 +731,18 @@ class CmdTunnel(MuxCommand):
help_category = "Building"
# store the direction, full name and its opposite
directions = {"n" : ("north", "s"),
directions = {"n": ("north", "s"),
"ne": ("northeast", "sw"),
"e" : ("east", "w"),
"e": ("east", "w"),
"se": ("southeast", "nw"),
"s" : ("south", "n"),
"s": ("south", "n"),
"sw": ("southwest", "ne"),
"w" : ("west", "e"),
"w": ("west", "e"),
"nw": ("northwest", "se"),
"u" : ("up", "d"),
"d" : ("down", "u"),
"i" : ("in", "o"),
"o" : ("out", "i")}
"u": ("up", "d"),
"d": ("down", "u"),
"i": ("in", "o"),
"o": ("out", "i")}
def func(self):
"Implements the tunnel command"
@ -725,7 +763,7 @@ class CmdTunnel(MuxCommand):
roomname = "Some place"
if self.rhs:
roomname = self.rhs # this may include aliases; that's fine.
roomname = self.rhs # this may include aliases; that's fine.
telswitch = ""
if "tel" in self.switches:
@ -735,9 +773,11 @@ class CmdTunnel(MuxCommand):
backstring = ", %s;%s" % (backname, backshort)
# build the string we will use to call @dig
digstring = "@dig%s %s = %s;%s%s" % (telswitch, roomname, exitname, exitshort, backstring)
digstring = "@dig%s %s = %s;%s%s" % (telswitch, roomname,
exitname, exitshort, backstring)
self.caller.execute_cmd(digstring)
class CmdLink(MuxCommand):
"""
@link - connect objects
@ -754,8 +794,9 @@ class CmdLink(MuxCommand):
If <object> is an exit, set its destination to <target>. Two-way operation
instead sets the destination to the *locations* of the respective given
arguments.
The second form (a lone =) sets the destination to None (same as the @unlink command)
and the third form (without =) just shows the currently set destination.
The second form (a lone =) sets the destination to None (same as
the @unlink command) and the third form (without =) just shows the
currently set destination.
"""
key = "@link"
@ -802,7 +843,7 @@ class CmdLink(MuxCommand):
obj.destination = target
string += "\nLink created %s -> %s (one way)." % (obj.name, target)
elif self.rhs == None:
elif self.rhs is None:
# this means that no = was given (otherwise rhs
# would have been an empty string). So we inspect
# the home/destination on object
@ -823,6 +864,7 @@ class CmdLink(MuxCommand):
# give feedback
caller.msg(string.strip())
class CmdUnLink(CmdLink):
"""
@unlink - unconnect objects
@ -857,6 +899,7 @@ class CmdUnLink(CmdLink):
# call the @link functionality
super(CmdUnLink, self).func()
class CmdSetHome(CmdLink):
"""
@home - control an object's home location
@ -893,7 +936,8 @@ class CmdSetHome(CmdLink):
if not home:
string = "This object has no home location set!"
else:
string = "%s's current home is %s(%s)." % (obj, home, home.dbref)
string = "%s's current home is %s(%s)." % (obj, home,
home.dbref)
else:
# set a home location
new_home = self.caller.search(self.rhs, global_search=True)
@ -907,6 +951,7 @@ class CmdSetHome(CmdLink):
string = "%s' home location was set to %s(%s)." % (obj, new_home, new_home.dbref)
self.caller.msg(string)
class CmdListCmdSets(MuxCommand):
"""
list command sets on an object
@ -935,6 +980,7 @@ class CmdListCmdSets(MuxCommand):
string = "%s" % obj.cmdset
caller.msg(string)
class CmdName(ObjManipCommand):
"""
cname - change the name and/or aliases of an object
@ -1006,7 +1052,8 @@ class CmdOpen(ObjManipCommand):
help_category = "Building"
# a custom member method to chug out exits and do checks
def create_exit(self, exit_name, location, destination, exit_aliases=None, typeclass=None):
def create_exit(self, exit_name, location, destination,
exit_aliases=None, typeclass=None):
"""
Helper function to avoid code duplication.
At this point we know destination is a valid location
@ -1047,9 +1094,11 @@ class CmdOpen(ObjManipCommand):
# exit does not exist before. Create a new one.
if not typeclass:
typeclass = settings.BASE_EXIT_TYPECLASS
exit_obj = create.create_object(typeclass, key=exit_name,
exit_obj = create.create_object(typeclass,
key=exit_name,
location=location,
aliases=exit_aliases, report_to=caller)
aliases=exit_aliases,
report_to=caller)
if exit_obj:
# storing a destination is what makes it an exit!
exit_obj.destination = destination
@ -1095,7 +1144,11 @@ class CmdOpen(ObjManipCommand):
return
# Create exit
ok = self.create_exit(exit_name, location, destination, exit_aliases, exit_typeclass)
ok = self.create_exit(exit_name,
location,
destination,
exit_aliases,
exit_typeclass)
if not ok:
# an error; the exit was not created, so we quit.
return
@ -1104,7 +1157,11 @@ class CmdOpen(ObjManipCommand):
back_exit_name = self.lhs_objs[1]['name']
back_exit_aliases = self.lhs_objs[1]['aliases']
back_exit_typeclass = self.lhs_objs[1]['option']
ok = self.create_exit(back_exit_name, destination, location, back_exit_aliases, back_exit_typeclass)
ok = self.create_exit(back_exit_name,
destination,
location,
back_exit_aliases,
back_exit_typeclass)
class CmdSetAttribute(ObjManipCommand):
@ -1126,7 +1183,8 @@ class CmdSetAttribute(ObjManipCommand):
numbers. You can however also set Python primities such as lists,
dictionaries and tuples on objects (this might be important for
the functionality of certain custom objects). This is indicated
by you starting your value with one of {c'{n, {c"{n, {c({n, {c[{n or {c{ {n.
by you starting your value with one of {c'{n, {c"{n, {c({n, {c[{n
or {c{ {n.
Note that you should leave a space after starting a dictionary ('{ ')
so as to not confuse the dictionary start with a colour code like \{g.
Remember that if you use Python primitives like this, you must
@ -1169,10 +1227,14 @@ class CmdSetAttribute(ObjManipCommand):
used for Python <=2.5. After that literal_eval is available.
"""
# simple types
try: return int(obj)
except ValueError: pass
try: return float(obj)
except ValueError: pass
try:
return int(obj)
except ValueError:
pass
try:
return float(obj)
except ValueError:
pass
# iterables
if obj.startswith('[') and obj.endswith(']'):
"A list. Traverse recursively."
@ -1182,7 +1244,8 @@ class CmdSetAttribute(ObjManipCommand):
return tuple([rec_convert(val) for val in obj[1:-1].split(',')])
if obj.startswith('{') and obj.endswith('}') and ':' in obj:
"A dict. Traverse recursively."
return dict([(rec_convert(pair.split(":",1)[0]), rec_convert(pair.split(":",1)[1]))
return dict([(rec_convert(pair.split(":", 1)[0]),
rec_convert(pair.split(":", 1)[1]))
for pair in obj[1:-1].split(',') if ":" in pair])
# if nothing matches, return as-is
return obj
@ -1198,7 +1261,8 @@ class CmdSetAttribute(ObjManipCommand):
self.caller.msg(string)
return utils.to_str(strobj)
else:
# fall back to old recursive solution (does not support nested lists/dicts)
# fall back to old recursive solution (does not support
# nested lists/dicts)
return rec_convert(strobj.strip())
def func(self):
@ -1223,17 +1287,18 @@ class CmdSetAttribute(ObjManipCommand):
string = ""
if not value:
if self.rhs == None:
if self.rhs is None:
# no = means we inspect the attribute(s)
if not attrs:
attrs = [attr.key for attr in obj.get_all_attributes()]
for attr in attrs:
if obj.attributes.has(attr):
string += "\nAttribute %s/%s = %s" % (obj.name, attr, obj.attributes.get(attr))
string += "\nAttribute %s/%s = %s" % (obj.name, attr,
obj.attributes.get(attr))
else:
string += "\n%s has no attribute '%s'." % (obj.name, attr)
# we view it without parsing markup.
self.caller.msg(string.strip(), data={"raw":True})
self.caller.msg(string.strip(), data={"raw": True})
return
else:
# deleting the attribute(s)
@ -1252,9 +1317,11 @@ class CmdSetAttribute(ObjManipCommand):
string += "\nCreated attribute %s/%s = %s" % (obj.name, attr, value)
except SyntaxError:
# this means literal_eval tried to parse a faulty string
string = "{RCritical Python syntax error in your value. Only primitive Python structures"
string += "\nare allowed. You also need to use correct Python syntax. Remember especially"
string += "\nto put quotes around all strings inside lists and dicts.{n"
string = "{RCritical Python syntax error in your value. "
string += "Only primitive Python structures are allowed. "
string += "\nYou also need to use correct Python syntax. "
string += "Remember especially to put quotes around all "
string += "strings inside lists and dicts.{n"
# send feedback
caller.msg(string.strip('\n'))
@ -1314,7 +1381,8 @@ class CmdTypeclass(MuxCommand):
# we did not supply a new typeclass, view the
# current one instead.
if hasattr(obj, "typeclass"):
string = "%s's current typeclass is '%s' (%s)." % (obj.name, obj.typeclass.typename, obj.typeclass.path)
string = "%s's current typeclass is '%s' (%s)." % (obj.name,
obj.typeclass.typename, obj.typeclass.path)
else:
string = "%s is not a typed object." % obj.name
caller.msg(string)
@ -1343,8 +1411,8 @@ class CmdTypeclass(MuxCommand):
string = "%s updated its existing typeclass (%s).\n" % (obj.name, obj.typeclass.path)
else:
string = "%s changed typeclass from %s to %s.\n" % (obj.name,
old_typeclass_path,
obj.typeclass_path)
old_typeclass_path,
obj.typeclass_path)
string += "Creation hooks were run."
if reset:
string += " All old attributes where deleted before the swap."
@ -1354,8 +1422,8 @@ class CmdTypeclass(MuxCommand):
else:
string = obj.typeclass_last_errmsg
string += "\nCould not swap '%s' (%s) to typeclass '%s'." % (obj.name,
old_typeclass_path,
typeclass)
old_typeclass_path,
typeclass)
caller.msg(string)
@ -1410,6 +1478,7 @@ class CmdWipe(ObjManipCommand):
string = string % (",".join(attrs), obj.name)
caller.msg(string)
class CmdLock(ObjManipCommand):
"""
lock - assign a lock definition to an object
@ -1493,6 +1562,7 @@ class CmdLock(ObjManipCommand):
return
caller.msg(obj.locks)
class CmdExamine(ObjManipCommand):
"""
examine - detailed info on objects
@ -1545,7 +1615,9 @@ class CmdExamine(ObjManipCommand):
else:
db_attr = [(attr.key, attr.value) for attr in obj.db_attributes.all()]
try:
ndb_attr = [(aname, avalue) for aname, avalue in obj.ndb.__dict__.items() if not aname.startswith("_")]
ndb_attr = [(aname, avalue)
for aname, avalue in obj.ndb.__dict__.items()
if not aname.startswith("_")]
except Exception:
ndb_attr = None
string = ""
@ -1572,7 +1644,8 @@ class CmdExamine(ObjManipCommand):
if hasattr(obj, "sessid") and obj.sessid:
string += "\n{wsession{n: %s" % obj.sessid
elif hasattr(obj, "sessions") and obj.sessions:
string += "\n{wsession(s){n: %s" % (", ".join(str(sess.sessid) for sess in obj.sessions))
string += "\n{wsession(s){n: %s" % (", ".join(str(sess.sessid)
for sess in obj.sessions))
if hasattr(obj, "has_player") and obj.has_player:
string += "\n{wPlayer{n: {c%s{n" % obj.player.name
perms = obj.player.permissions.all()
@ -1581,7 +1654,8 @@ class CmdExamine(ObjManipCommand):
elif not perms:
perms = ["<None>"]
string += "\n{wPlayer Perms{n: %s" % (", ".join(perms))
string += "\n{wTypeclass{n: %s (%s)" % (obj.typeclass.typename, obj.typeclass_path)
string += "\n{wTypeclass{n: %s (%s)" % (obj.typeclass.typename,
obj.typeclass_path)
if hasattr(obj, "location"):
string += "\n{wLocation{n: %s" % obj.location
if obj.location:
@ -1610,14 +1684,20 @@ class CmdExamine(ObjManipCommand):
if not (len(obj.cmdset.all()) == 1 and obj.cmdset.current.key == "Empty"):
# list the current cmdsets
all_cmdsets = obj.cmdset.all() + (hasattr(obj, "player") and obj.player and obj.player.cmdset.all() or [])
all_cmdsets += hasattr(obj, "sessid") and hasattr(obj, "player") and obj.player.get_session(obj.sessid).cmdset.all()
all_cmdsets.sort(key=lambda x:x.priority, reverse=True)
string += "\n{wStored Cmdset(s){n:\n %s" % ("\n ".join("%s [%s] (prio %s)" %
(cmdset.path, cmdset.key, cmdset.priority) for cmdset in all_cmdsets))
all_cmdsets = (obj.cmdset.all() +
(hasattr(obj, "player") and
obj.player and obj.player.cmdset.all() or []))
all_cmdsets += (hasattr(obj, "sessid") and
hasattr(obj, "player") and
obj.player.get_session(obj.sessid).cmdset.all())
all_cmdsets.sort(key=lambda x: x.priority, reverse=True)
string += "\n{wStored Cmdset(s){n:\n %s" % ("\n ".join("%s [%s] (prio %s)" % \
(cmdset.path, cmdset.key, 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")])
avail_cmdset = sorted([cmd.key for cmd in avail_cmdset
if cmd.access(obj, "cmd")])
cmdsetstr = utils.fill(", ".join(avail_cmdset), indent=2)
string += "\n{wCommands available to %s (all cmdsets + exits and external cmds){n:\n %s" % (obj.key, cmdsetstr)
@ -1644,10 +1724,10 @@ class CmdExamine(ObjManipCommand):
string += "\n{wCharacters{n: %s" % ", ".join(["{c%s{n" % pobj.name for pobj in pobjs])
if things:
string += "\n{wContents{n: %s" % ", ".join([cont.name for cont in obj.contents
if cont not in exits and cont not in pobjs])
separator = "-"*78
if cont not in exits and cont not in pobjs])
separator = "-" * 78
#output info
return '%s\n%s\n%s' % ( separator, string.strip(), separator )
return '%s\n%s\n%s' % (separator, string.strip(), separator)
def func(self):
"Process command"
@ -1686,7 +1766,7 @@ class CmdExamine(ObjManipCommand):
obj_attrs = objdef['attrs']
self.player_mode = utils.inherits_from(caller, "src.players.player.Player") or \
"player" in self.switches or obj_name.startswith('*')
"player" in self.switches or obj_name.startswith('*')
if self.player_mode:
try:
obj = caller.search_player(obj_name.lstrip('*'))
@ -1699,7 +1779,8 @@ class CmdExamine(ObjManipCommand):
continue
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.
caller.execute_cmd('look %s' % obj_name)
continue
@ -1727,7 +1808,8 @@ class CmdFind(MuxCommand):
Searches the database for an object of a particular name or dbref.
Use *playername to search for a player. The switches allows for
limiting object matches to certain game entities. Dbrefmin and dbrefmax
limits matches to within the given dbrefs, or above/below if only one is given.
limits matches to within the given dbrefs, or above/below if only
one is given.
"""
key = "@find"
@ -1772,11 +1854,13 @@ class CmdFind(MuxCommand):
if not low <= int(result.id) <= high:
string += "\n {RNo match found for '%s' within the given dbref limits.{n" % searchstring
else:
string += "\n{g %s(%s) - %s{n" % (result.key, result.dbref, result.typeclass.path)
string += "\n{g %s(%s) - %s{n" % (result.key, result.dbref,
result.typeclass.path)
else:
# Not a player/dbref search but a wider search; build a queryset.
results = ObjectDB.objects.filter(db_key__istartswith=searchstring, id__gte=low, id__lte=high)
results = ObjectDB.objects.filter(db_key__istartswith=searchstring,
id__gte=low, id__lte=high)
if "room" in switches:
results = results.filter(db_location__isnull=True)
if "exit" in switches:
@ -1909,12 +1993,14 @@ class CmdTeleport(MuxCommand):
use_destination = False
# try the teleport
if obj_to_teleport.move_to(destination, quiet=tel_quietly, emit_to_obj=caller,
if obj_to_teleport.move_to(destination, quiet=tel_quietly,
emit_to_obj=caller,
use_destination=use_destination):
if obj_to_teleport == caller:
caller.msg("Teleported to %s." % destination)
else:
caller.msg("Teleported %s -> %s." % (obj_to_teleport, destination))
caller.msg("Teleported %s -> %s." % (obj_to_teleport,
destination))
class CmdScript(MuxCommand):
@ -1931,9 +2017,10 @@ class CmdScript(MuxCommand):
If no script path/key is given, lists all scripts active on the given
object.
Script path can be given from the base location for scripts as given in
settings. If adding a new script, it will be started automatically (no /start
switch is needed). Using the /start or /stop switches on an object without
specifying a script key/path will start/stop ALL scripts on the object.
settings. If adding a new script, it will be started automatically
(no /start switch is needed). Using the /start or /stop switches on an
object without specifying a script key/path will start/stop ALL scripts on
the object.
"""
key = "@script"
@ -1970,7 +2057,8 @@ class CmdScript(MuxCommand):
string += "%s scripts started on %s." % (num, obj.key)
elif "stop" in self.switches:
for script in scripts:
string += "Stopping script %s on %s." % (script.key, obj.key)
string += "Stopping script %s on %s." % (script.key,
obj.key)
script.stop()
string = string.strip()
obj.scripts.validate()

View file

@ -1,14 +1,15 @@
"""
This module ties together all the commands default Character objects have
available (i.e. IC commands). Note that some commands, such as communication-commands are
instead put on the player level, in the Player cmdset. Player commands remain
available also to Characters.
available (i.e. IC commands). Note that some commands, such as
communication-commands are instead put on the player level, in the
Player cmdset. Player commands remain available also to Characters.
"""
from src.commands.cmdset import CmdSet
from src.commands.default import general, help, admin, system
from src.commands.default import building
from src.commands.default import batchprocess
class CharacterCmdSet(CmdSet):
"""
Implements the default command set.

View file

@ -13,6 +13,7 @@ from src.commands.cmdset import CmdSet
from src.commands.default import help, comms, admin, system
from src.commands.default import building, player
class PlayerCmdSet(CmdSet):
"""
Implements the player command set.

View file

@ -6,6 +6,7 @@ of the state instance in this module.
from src.commands.cmdset import CmdSet
from src.commands.default import unloggedin
class UnloggedinCmdSet(CmdSet):
"""
Sets up the unlogged cmdset.

View file

@ -22,6 +22,7 @@ __all__ = ("CmdAddCom", "CmdDelCom", "CmdAllCom",
"CmdPage", "CmdIRC2Chan", "CmdIMC2Chan", "CmdIMCInfo",
"CmdIMCTell", "CmdRSS2Chan")
def find_channel(caller, channelname, silent=False, noaliases=False):
"""
Helper function for searching for a single channel with
@ -30,7 +31,8 @@ def find_channel(caller, channelname, silent=False, noaliases=False):
channels = ChannelDB.objects.channel_search(channelname)
if not channels:
if not noaliases:
channels = [chan for chan in ChannelDB.objects.get_all_channels() if channelname in chan.aliases.all()]
channels = [chan for chan in ChannelDB.objects.get_all_channels()
if channelname in chan.aliases.all()]
if channels:
return channels[0]
if not silent:
@ -43,6 +45,7 @@ def find_channel(caller, channelname, silent=False, noaliases=False):
return None
return channels[0]
class CmdAddCom(MuxPlayerCommand):
"""
addcom - subscribe to a channel with optional alias
@ -57,7 +60,7 @@ class CmdAddCom(MuxPlayerCommand):
"""
key = "addcom"
aliases = ["aliaschan","chanalias"]
aliases = ["aliaschan", "chanalias"]
help_category = "Comms"
locks = "cmd:not pperm(channel_banned)"
@ -168,6 +171,7 @@ class CmdDelCom(MuxPlayerCommand):
else:
self.msg("You had no such alias defined for this channel.")
class CmdAllCom(MuxPlayerCommand):
"""
allcom - operate on all channels
@ -197,8 +201,10 @@ class CmdAllCom(MuxPlayerCommand):
return
if args == "on":
# get names of all channels available to listen to and activate them all
channels = [chan for chan in ChannelDB.objects.get_all_channels() if chan.access(caller, 'listen')]
# get names of all channels available to listen to
# and activate them all
channels = [chan for chan in ChannelDB.objects.get_all_channels()
if chan.access(caller, 'listen')]
for channel in channels:
caller.execute_cmd("addcom %s" % channel.key)
elif args == "off":
@ -208,13 +214,15 @@ class CmdAllCom(MuxPlayerCommand):
caller.execute_cmd("delcom %s" % channel.key)
elif args == "destroy":
# destroy all channels you control
channels = [chan for chan in ChannelDB.objects.get_all_channels() if chan.access(caller, 'control')]
channels = [chan for chan in ChannelDB.objects.get_all_channels()
if chan.access(caller, 'control')]
for channel in channels:
caller.execute_cmd("@cdestroy %s" % channel.key)
elif args == "who":
# run a who, listing the subscribers on visible channels.
string = "\n{CChannel subscriptions{n"
channels = [chan for chan in ChannelDB.objects.get_all_channels() if chan.access(caller, 'listen')]
channels = [chan for chan in ChannelDB.objects.get_all_channels()
if chan.access(caller, 'listen')]
if not channels:
string += "No channels."
for channel in channels:
@ -229,6 +237,7 @@ class CmdAllCom(MuxPlayerCommand):
# wrong input
self.msg("Usage: allcom on | off | who | clear")
class CmdChannels(MuxPlayerCommand):
"""
@clist
@ -253,7 +262,8 @@ class CmdChannels(MuxPlayerCommand):
caller = self.caller
# all channels we have available to listen to
channels = [chan for chan in ChannelDB.objects.get_all_channels() if chan.access(caller, 'listen')]
channels = [chan for chan in ChannelDB.objects.get_all_channels()
if chan.access(caller, 'listen')]
#print channels
if not channels:
self.msg("No channels available.")
@ -264,28 +274,39 @@ class CmdChannels(MuxPlayerCommand):
if self.cmdstring == "comlist":
# just display the subscribed channels with no extra info
comtable = prettytable.PrettyTable(["{wchannel","{wmy aliases", "{wdescription"])
comtable = prettytable.PrettyTable(["{wchannel",
"{wmy aliases",
"{wdescription"])
for chan in subs:
clower = chan.key.lower()
nicks = caller.nicks.get(category="channel")
comtable.add_row(["%s%s" % (chan.key, chan.aliases.all() and "(%s)" % ",".join(chan.aliases.all()) or ""),
"%s".join(nick for nick in make_iter(nicks) if nick and nick.lower()==clower),
comtable.add_row(["%s%s" % (chan.key, chan.aliases.all() and
"(%s)" % ",".join(chan.aliases.all()) or ""),
"%s".join(nick for nick in make_iter(nicks)
if nick and nick.lower() == clower),
chan.db.desc])
caller.msg("\n{wChannel subscriptions{n (use {w@channels{n to list all, {waddcom{n/{wdelcom{n to sub/unsub):{n\n%s" % comtable)
else:
# full listing (of channels caller is able to listen to)
comtable = prettytable.PrettyTable(["{wsub","{wchannel","{wmy aliases","{wlocks","{wdescription"])
comtable = prettytable.PrettyTable(["{wsub",
"{wchannel",
"{wmy aliases",
"{wlocks",
"{wdescription"])
for chan in channels:
clower = chan.key.lower()
nicks = caller.nicks.get(category="channel")
nicks = nicks or []
comtable.add_row([chan in subs and "{gYes{n" or "{rNo{n",
"%s%s" % (chan.key, chan.aliases.all() and "(%s)" % ",".join(chan.aliases.all()) or ""),
"%s".join(nick for nick in make_iter(nicks) if nick.lower()==clower),
"%s%s" % (chan.key, chan.aliases.all() and
"(%s)" % ",".join(chan.aliases.all()) or ""),
"%s".join(nick for nick in make_iter(nicks)
if nick.lower() == clower),
str(chan.locks),
chan.db.desc])
caller.msg("\n{wAvailable channels{n (use {wcomlist{n,{waddcom{n and {wdelcom{n to manage subscriptions):\n%s" % comtable)
class CmdCdestroy(MuxPlayerCommand):
"""
@cdestroy
@ -322,6 +343,7 @@ class CmdCdestroy(MuxPlayerCommand):
CHANNELHANDLER.update()
self.msg("Channel '%s' was destroyed." % channel)
class CmdCBoot(MuxPlayerCommand):
"""
@cboot
@ -382,6 +404,7 @@ class CmdCBoot(MuxPlayerCommand):
channel.disconnect_from(player)
CHANNELHANDLER.update()
class CmdCemit(MuxPlayerCommand):
"""
@cemit - send a message to channel
@ -429,6 +452,7 @@ class CmdCemit(MuxPlayerCommand):
string = "Sent to channel %s: %s" % (channel.key, message)
self.msg(string)
class CmdCWho(MuxPlayerCommand):
"""
@cwho
@ -466,6 +490,7 @@ class CmdCWho(MuxPlayerCommand):
string += " <None>"
self.msg(string.strip())
class CmdChannelCreate(MuxPlayerCommand):
"""
@ccreate
@ -508,7 +533,10 @@ class CmdChannelCreate(MuxPlayerCommand):
return
# Create and set the channel up
lockstring = "send:all();listen:all();control:id(%s)" % caller.id
new_chan = create.create_channel(channame, aliases, description, locks=lockstring)
new_chan = create.create_channel(channame,
aliases,
description,
locks=lockstring)
new_chan.connect_to(caller)
self.msg("Created channel %s and connected to it." % new_chan.key)
@ -593,7 +621,9 @@ class CmdCdesc(MuxPlayerCommand):
# set the description
channel.db.desc = self.rhs
channel.save()
self.msg("Description of channel '%s' set to '%s'." % (channel.key, self.rhs))
self.msg("Description of channel '%s' set to '%s'." % (channel.key,
self.rhs))
class CmdPage(MuxPlayerCommand):
"""
@ -624,15 +654,16 @@ class CmdPage(MuxPlayerCommand):
caller = self.caller
# get the messages we've sent (not to channels)
pages_we_sent = Msg.objects.get_messages_by_sender(caller, exclude_channel_messages=True)
pages_we_sent = Msg.objects.get_messages_by_sender(caller,
exclude_channel_messages=True)
# get last messages we've got
pages_we_got = Msg.objects.get_messages_by_receiver(caller)
if 'last' in self.switches:
if pages_we_sent:
recv = ",".join(obj.key for obj in pages_we_sent[-1].receivers)
self.msg("You last paged {c%s{n:%s" % (recv, pages_we_sent[-1].message))
self.msg("You last paged {c%s{n:%s" % (recv,
pages_we_sent[-1].message))
return
else:
self.msg("You haven't paged anyone yet.")
@ -654,12 +685,12 @@ class CmdPage(MuxPlayerCommand):
lastpages = pages[-number:]
else:
lastpages = pages
lastpages = "\n ".join("{w%s{n {c%s{n to {c%s{n: %s" % (utils.datetime_format(page.date_sent),
",".join(obj.key for obj in page.senders),
"{n,{c ".join([obj.name for obj in page.receivers]),
page.message)
for page in lastpages)
template = "{w%s{n {c%s{n to {c%s{n: %s"
lastpages = "\n ".join(template %
(utils.datetime_format(page.date_sent),
",".join(obj.key for obj in page.senders),
"{n,{c ".join([obj.name for obj in page.receivers]),
page.message) for page in lastpages)
if lastpages:
string = "Your latest pages:\n %s" % lastpages
@ -668,7 +699,6 @@ class CmdPage(MuxPlayerCommand):
self.msg(string)
return
# We are sending. Build a list of targets
if not self.lhs:
@ -722,7 +752,7 @@ class CmdPage(MuxPlayerCommand):
else:
received.append("{c%s{n" % pobj.name)
if rstrings:
self.msg(rstrings = "\n".join(rstrings))
self.msg(rstrings="\n".join(rstrings))
self.msg("You paged %s with: '%s'." % (", ".join(received), message))
@ -734,18 +764,20 @@ class CmdIRC2Chan(MuxCommand):
@irc2chan[/switches] <evennia_channel> = <ircnetwork> <port> <#irchannel> <botname>
Switches:
/disconnect - this will delete the bot and remove the irc connection to the channel.
/disconnect - this will delete the bot and remove the irc connection
to the channel.
/remove - "
/list - show all irc<->evennia mappings
Example:
@irc2chan myircchan = irc.dalnet.net 6667 myevennia-channel evennia-bot
This creates an IRC bot that connects to a given IRC network and channel. It will
relay everything said in the evennia channel to the IRC channel and vice versa. The
bot will automatically connect at server start, so this comman need only be given once.
The /disconnect switch will permanently delete the bot. To only temporarily deactivate it,
use the @services command instead.
This creates an IRC bot that connects to a given IRC network and channel.
It will relay everything said in the evennia channel to the IRC channel and
vice versa. The bot will automatically connect at server start, so this
comman need only be given once. The /disconnect switch will permanently
delete the bot. To only temporarily deactivate it, use the {w@services{n
command instead.
"""
key = "@irc2chan"
@ -780,19 +812,25 @@ class CmdIRC2Chan(MuxCommand):
channel = self.lhs
self.rhs = self.rhs.replace('#', ' ') # to avoid Python comment issues
try:
irc_network, irc_port, irc_channel, irc_botname = [part.strip() for part in self.rhs.split(None, 3)]
irc_network, irc_port, irc_channel, irc_botname = \
[part.strip() for part in self.rhs.split(None, 3)]
irc_channel = "#%s" % irc_channel
except Exception:
string = "IRC bot definition '%s' is not valid." % self.rhs
self.msg(string)
return
if 'disconnect' in self.switches or 'remove' in self.switches or 'delete' in self.switches:
if('disconnect' in self.switches or 'remove' in self.switches or
'delete' in self.switches):
chanmatch = find_channel(self.caller, channel, silent=True)
if chanmatch:
channel = chanmatch.key
ok = irc.delete_connection(channel, irc_network, irc_port, irc_channel, irc_botname)
ok = irc.delete_connection(channel,
irc_network,
irc_port,
irc_channel,
irc_botname)
if not ok:
self.msg("IRC connection/bot could not be removed, does it exist?")
else:
@ -802,12 +840,17 @@ class CmdIRC2Chan(MuxCommand):
channel = find_channel(self.caller, channel)
if not channel:
return
ok = irc.create_connection(channel, irc_network, irc_port, irc_channel, irc_botname)
ok = irc.create_connection(channel,
irc_network,
irc_port,
irc_channel,
irc_botname)
if not ok:
self.msg("This IRC connection already exists.")
return
self.msg("Connection created. Starting IRC bot.")
class CmdIMC2Chan(MuxCommand):
"""
imc2chan - link an evennia channel to imc2
@ -863,9 +906,10 @@ class CmdIMC2Chan(MuxCommand):
channel = self.lhs
imc2_channel = self.rhs
if 'disconnect' in self.switches or 'remove' in self.switches or 'delete' in self.switches:
# we don't search for channels before this since we want to clear the link
# also if the channel no longer exists.
if('disconnect' in self.switches or 'remove' in self.switches or
'delete' in self.switches):
# we don't search for channels before this since we want
# to clear the link also if the channel no longer exists.
ok = imc2.delete_connection(channel, imc2_channel)
if not ok:
self.msg("IMC2 connection could not be removed, does it exist?")
@ -932,7 +976,8 @@ class CmdIMCInfo(MuxCommand):
IMC2_CLIENT.send_packet(pck.IMC2PacketIceRefresh())
self.msg("IMC2 lists were re-synced.")
elif "games" in self.switches or "muds" in self.switches or self.cmdstring == "@imclist":
elif("games" in self.switches or "muds" in self.switches
or self.cmdstring == "@imclist"):
# list muds
from src.comms.imc2 import IMC2_MUDLIST
@ -956,9 +1001,13 @@ class CmdIMCInfo(MuxCommand):
return
from src.comms.imc2 import IMC2_CLIENT
self.msg("Sending IMC whois request. If you receive no response, no matches were found.")
IMC2_CLIENT.msg_imc2(None, from_obj=self.caller, packet_type="imcwhois", target=self.args)
IMC2_CLIENT.msg_imc2(None,
from_obj=self.caller,
packet_type="imcwhois",
target=self.args)
elif not self.switches or "channels" in self.switches or self.cmdstring == "@imcchanlist":
elif(not self.switches or "channels" in self.switches or
self.cmdstring == "@imcchanlist"):
# show channels
from src.comms.imc2 import IMC2_CHANLIST, IMC2_CLIENT
@ -968,7 +1017,8 @@ class CmdIMCInfo(MuxCommand):
table = prettytable.PrettyTable(["Full name", "Name", "Owner", "Perm", "Policy"])
for chan in channels:
nchans += 1
table.add_row([chan.name, chan.localname, chan.owner, chan.level, chan.policy])
table.add_row([chan.name, chan.localname, chan.owner,
chan.level, chan.policy])
string += "\n{wChannels on %s:{n\n%s" % (IMC2_CLIENT.factory.network, table)
string += "\n%i Channels found." % nchans
self.msg(string)
@ -977,6 +1027,7 @@ class CmdIMCInfo(MuxCommand):
string = "Usage: imcinfo|imcchanlist|imclist"
self.msg(string)
# unclear if this is working ...
class CmdIMCTell(MuxCommand):
"""
@ -1028,19 +1079,21 @@ class CmdRSS2Chan(MuxCommand):
@rss2chan[/switches] <evennia_channel> = <rss_url>
Switches:
/disconnect - this will stop the feed and remove the connection to the channel.
/disconnect - this will stop the feed and remove the connection to the
channel.
/remove - "
/list - show all rss->evennia mappings
Example:
@rss2chan rsschan = http://code.google.com/feeds/p/evennia/updates/basic
This creates an RSS reader that connects to a given RSS feed url. Updates will be
echoed as a title and news link to the given channel. The rate of updating is set
with the RSS_UPDATE_INTERVAL variable in settings (default is every 10 minutes).
This creates an RSS reader that connects to a given RSS feed url. Updates
will be echoed as a title and news link to the given channel. The rate of
updating is set with the RSS_UPDATE_INTERVAL variable in settings (default
is every 10 minutes).
When disconnecting you need to supply both the channel and url again so as to identify
the connection uniquely.
When disconnecting you need to supply both the channel and url again so as
to identify the connection uniquely.
"""
key = "@rss2chan"
@ -1075,7 +1128,8 @@ class CmdRSS2Chan(MuxCommand):
channel = self.lhs
url = self.rhs
if 'disconnect' in self.switches or 'remove' in self.switches or 'delete' in self.switches:
if('disconnect' in self.switches or 'remove' in self.switches or
'delete' in self.switches):
chanmatch = find_channel(self.caller, channel, silent=True)
if chanmatch:
channel = chanmatch.key

View file

@ -13,6 +13,7 @@ __all__ = ("CmdHome", "CmdLook", "CmdNick",
AT_SEARCH_RESULT = utils.variable_from_module(*settings.SEARCH_AT_RESULT.rsplit('.', 1))
class CmdHome(MuxCommand):
"""
home
@ -38,6 +39,7 @@ class CmdHome(MuxCommand):
caller.move_to(home)
caller.msg("There's no place like home ...")
class CmdLook(MuxCommand):
"""
look
@ -126,7 +128,9 @@ class CmdNick(MuxCommand):
nicks = caller.nicks.get(category="channel")
if 'list' in switches:
table = prettytable.PrettyTable(["{wNickType", "{wNickname", "{wTranslates-to"])
table = prettytable.PrettyTable(["{wNickType",
"{wNickname",
"{wTranslates-to"])
for nick in nicks:
table.add_row([nick.db_category, nick.db_key, nick.db_data])
string = "{wDefined Nicks:{n\n%s" % table
@ -170,6 +174,7 @@ class CmdNick(MuxCommand):
caller.nicks.add(nick, real, category=switch)
caller.msg(string)
class CmdInventory(MuxCommand):
"""
inventory
@ -198,6 +203,7 @@ class CmdInventory(MuxCommand):
string = "{wYou are carrying:\n%s" % table
self.caller.msg(string)
class CmdGet(MuxCommand):
"""
get
@ -327,7 +333,6 @@ class CmdGive(MuxCommand):
target.msg("%s gives you %s." % (caller.key, to_give.key))
class CmdSay(MuxCommand):
"""
say
@ -365,6 +370,7 @@ class CmdSay(MuxCommand):
caller.location.msg_contents(emit_string,
exclude=caller)
class CmdPose(MuxCommand):
"""
pose - strike a pose
@ -407,6 +413,7 @@ class CmdPose(MuxCommand):
msg = "%s%s" % (self.caller.name, self.args)
self.caller.location.msg_contents(msg)
class CmdAccess(MuxCommand):
"""
access - show access groups
@ -440,5 +447,4 @@ class CmdAccess(MuxCommand):
string += "\nCharacter {c%s{n: %s" % (caller.key, cperms)
if hasattr(caller, 'player'):
string += "\nPlayer {c%s{n: %s" % (caller.player.key, pperms)
caller.msg(string)
caller.msg(string)

View file

@ -18,7 +18,8 @@ from src.commands.default.muxcommand import MuxCommand
__all__ = ("CmdHelp", "CmdSetHelp")
SEP = "{C" + "-"*78 + "{n"
SEP = "{C" + "-" * 78 + "{n"
def format_help_entry(title, help_text, aliases=None, suggested=None):
"""
@ -38,6 +39,7 @@ def format_help_entry(title, help_text, aliases=None, suggested=None):
string += "\n" + SEP
return string
def format_help_list(hdict_cmds, hdict_db):
"""
Output a category-ordered list. The input are the
@ -57,6 +59,7 @@ def format_help_list(hdict_cmds, hdict_db):
string += "{G" + fill(", ".join(sorted([str(topic) for topic in hdict_db[category]]))) + "{n"
return string
class CmdHelp(Command):
"""
The main help command
@ -129,13 +132,18 @@ class CmdHelp(Command):
# try an exact command auto-help match
match = [cmd for cmd in all_cmds if cmd == query]
if len(match) == 1:
self.msg(format_help_entry(match[0].key, match[0].__doc__, aliases=match[0].aliases, suggested=suggestions))
self.msg(format_help_entry(match[0].key,
match[0].__doc__,
aliases=match[0].aliases,
suggested=suggestions))
return
# try an exact database help entry match
match = list(HelpEntry.objects.find_topicmatch(query, exact=True))
if len(match) == 1:
self.msg(format_help_entry(match[0].key, match[0].entrytext, suggested=suggestions))
self.msg(format_help_entry(match[0].key,
match[0].entrytext,
suggested=suggestions))
return
# try to see if a category name was entered
@ -147,6 +155,7 @@ class CmdHelp(Command):
# no exact matches found. Just give suggestions.
self.msg(format_help_entry("", "No help entry found for '%s'" % query, None, suggested=suggestions))
class CmdSetHelp(MuxCommand):
"""
@help - edit the help database
@ -169,9 +178,9 @@ class CmdSetHelp(MuxCommand):
@sethelp/append pickpocketing, ,attr(is_thief) = This steals ...
This command manipulates the help database. A help entry can be created,
appended/merged to and deleted. If you don't assign a category, the "General"
category will be used. If no lockstring is specified, default is to let everyone read
the help file.
appended/merged to and deleted. If you don't assign a category, the
"General" category will be used. If no lockstring is specified, default
is to let everyone read the help file.
"""
key = "@help"

View file

@ -74,8 +74,8 @@ class MuxCommand(Command):
The 'name[ with several words]' part is already dealt with by the
cmdhandler at this point, and stored in self.cmdname (we don't use
it here). The rest of the command is stored in self.args, which can start
with the switch indicator /.
it here). The rest of the command is stored in self.args, which can
start with the switch indicator /.
This parser breaks self.args into its constituents and stores them in the
following variables:

View file

@ -24,8 +24,9 @@ from src.utils import utils, create, search, prettytable
from settings import MAX_NR_CHARACTERS, MULTISESSION_MODE
# limit symbol import for API
__all__ = ("CmdOOCLook", "CmdIC", "CmdOOC", "CmdPassword", "CmdQuit", "CmdCharCreate",
"CmdEncoding", "CmdSessions", "CmdWho", "CmdColorTest", "CmdQuell")
__all__ = ("CmdOOCLook", "CmdIC", "CmdOOC", "CmdPassword", "CmdQuit",
"CmdCharCreate", "CmdEncoding", "CmdSessions", "CmdWho",
"CmdColorTest", "CmdQuell")
# force max nr chars to 1 if mode is 0 or 1
MAX_NR_CHARACTERS = MULTISESSION_MODE < 2 and 1 or MAX_NR_CHARACTERS
@ -58,7 +59,8 @@ class CmdOOCLook(MuxPlayerCommand):
"Hook method for when an argument is given."
player = self.caller
key = self.args.lower()
chars = dict((utils.to_str(char.key.lower()), char) for char in player.db._playable_characters)
chars = dict((utils.to_str(char.key.lower()), char)
for char in player.db._playable_characters)
looktarget = chars.get(key)
if looktarget:
self.msg(looktarget.return_appearance(player))
@ -101,7 +103,7 @@ class CmdOOCLook(MuxPlayerCommand):
string += "\n\nAvailable character%s (%i/unlimited):" % (string_s_ending, len(characters))
else:
string += "\n\nAvailable character%s%s:" % (string_s_ending,
MAX_NR_CHARACTERS > 1 and " (%i/%i)" % (len(characters), MAX_NR_CHARACTERS) or "")
MAX_NR_CHARACTERS > 1 and " (%i/%i)" % (len(characters), MAX_NR_CHARACTERS) or "")
for char in characters:
csessid = char.sessid
@ -171,8 +173,10 @@ class CmdCharCreate(MuxPlayerCommand):
typeclass = settings.BASE_CHARACTER_TYPECLASS
permissions = settings.PERMISSION_PLAYER_DEFAULT
new_character = create.create_object(typeclass, key=key, location=default_home,
home=default_home, permissions=permissions)
new_character = create.create_object(typeclass, key=key,
location=default_home,
home=default_home,
permissions=permissions)
# only allow creator (and immortals) to puppet this char
new_character.locks.add("puppet:id(%i) or pid(%i) or perm(Immortals) or pperm(Immortals)" %
(new_character.id, player.id))
@ -203,7 +207,8 @@ class CmdIC(MuxPlayerCommand):
"""
key = "@ic"
locks = "cmd:all()" # must be all() or different puppeted objects won't be able to access it.
# lockmust be all() for different puppeted objects to access it.
locks = "cmd:all()"
aliases = "@puppet"
help_category = "General"
@ -235,7 +240,8 @@ class CmdIC(MuxPlayerCommand):
if new_character.player:
# may not puppet an already puppeted character
if new_character.sessid and new_character.player == player:
# as a safeguard we allow "taking over chars from your own sessions.
# as a safeguard we allow "taking over chars from
# your own sessions.
player.msg("{c%s{n{R is now acted from another of your sessions.{n" % (new_character.name), sessid=new_character.sessid)
player.unpuppet_object(new_character.sessid)
self.msg("Taking over {c%s{n from another of your sessions." % new_character.name)
@ -251,6 +257,7 @@ class CmdIC(MuxPlayerCommand):
else:
self.msg("{rYou cannot become {C%s{n." % new_character.name)
class CmdOOC(MuxPlayerCommand):
"""
go ooc
@ -264,7 +271,8 @@ class CmdOOC(MuxPlayerCommand):
"""
key = "@ooc"
locks = "cmd:all()" # this must be all(), or different puppeted objects won't be able to access it.
# lock must be all(), for different puppeted objects to access it.
locks = "cmd:all()"
aliases = "@unpuppet"
help_category = "General"
@ -311,17 +319,22 @@ class CmdSessions(MuxPlayerCommand):
player = self.caller
sessions = player.get_all_sessions()
table = prettytable.PrettyTable(["{wsessid", "{wprotocol", "{whost", "{wpuppet/character", "{wlocation"])
for sess in sorted(sessions, key=lambda x:x.sessid):
table = prettytable.PrettyTable(["{wsessid",
"{wprotocol",
"{whost",
"{wpuppet/character",
"{wlocation"])
for sess in sorted(sessions, key=lambda x: x.sessid):
sessid = sess.sessid
char = player.get_puppet(sessid)
table.add_row([str(sessid), str(sess.protocol_key),
type(sess.address)==tuple and sess.address[0] or sess.address,
type(sess.address) == tuple and sess.address[0] or sess.address,
char and str(char) or "None",
char and str(char.location) or "N/A"])
string = "{wYour current session(s):{n\n%s" % table
self.msg(string)
class CmdWho(MuxPlayerCommand):
"""
who
@ -355,7 +368,13 @@ class CmdWho(MuxPlayerCommand):
nplayers = (SESSIONS.player_count())
if show_session_data:
table = prettytable.PrettyTable(["{wPlayer Name","{wOn for", "{wIdle", "{wRoom", "{wCmds", "{wProtocol", "{wHost"])
table = prettytable.PrettyTable(["{wPlayer Name",
"{wOn for",
"{wIdle",
"{wRoom",
"{wCmds",
"{wProtocol",
"{wHost"])
for session in session_list:
if not session.logged_in: continue
delta_cmd = time.time() - session.cmd_last_visible
@ -372,7 +391,8 @@ class CmdWho(MuxPlayerCommand):
else:
table = prettytable.PrettyTable(["{wPlayer name", "{wOn for", "{wIdle"])
for session in session_list:
if not session.logged_in: continue
if not session.logged_in:
continue
delta_cmd = time.time() - session.cmd_last_visible
delta_conn = time.time() - session.conn_time
plr_pobject = session.get_puppet()
@ -397,14 +417,16 @@ class CmdEncoding(MuxPlayerCommand):
clear - clear your custom encoding
This sets the text encoding for communicating with Evennia. This is mostly an issue only if
you want to use non-ASCII characters (i.e. letters/symbols not found in English). If you see
that your characters look strange (or you get encoding errors), you should use this command
to set the server encoding to be the same used in your client program.
This sets the text encoding for communicating with Evennia. This is mostly
an issue only if you want to use non-ASCII characters (i.e. letters/symbols
not found in English). If you see that your characters look strange (or you
get encoding errors), you should use this command to set the server
encoding to be the same used in your client program.
Common encodings are utf-8 (default), latin-1, ISO-8859-1 etc.
If you don't submit an encoding, the current encoding will be displayed instead.
If you don't submit an encoding, the current encoding will be displayed
instead.
"""
key = "@encoding"
@ -444,6 +466,7 @@ class CmdEncoding(MuxPlayerCommand):
string = "Your custom text encoding was changed from '%s' to '%s'." % (old_encoding, encoding)
self.msg(string.strip())
class CmdPassword(MuxPlayerCommand):
"""
@password - set your password
@ -463,8 +486,8 @@ class CmdPassword(MuxPlayerCommand):
if not self.rhs:
self.msg("Usage: @password <oldpass> = <newpass>")
return
oldpass = self.lhslist[0] # this is already stripped by parse()
newpass = self.rhslist[0] # ''
oldpass = self.lhslist[0] # this is already stripped by parse()
newpass = self.rhslist[0] # ''
if not player.check_password(oldpass):
self.msg("The specified old password isn't correct.")
elif len(newpass) < 3:
@ -474,6 +497,7 @@ class CmdPassword(MuxPlayerCommand):
player.save()
self.msg("Password changed.")
class CmdQuit(MuxPlayerCommand):
"""
quit
@ -518,10 +542,10 @@ class CmdColorTest(MuxPlayerCommand):
Usage:
@color ansi|xterm256
Print a color map along with in-mud color codes, while testing what is supported in your client.
Choices are 16-color ansi (supported in most muds) or the 256-color xterm256 standard.
No checking is done to determine your client supports color - if not you will
see rubbish appear.
Print a color map along with in-mud color codes, while testing what is
supported in your client. Choices are 16-color ansi (supported in most
muds) or the 256-color xterm256 standard. No checking is done to determine
your client supports color - if not you will see rubbish appear.
"""
key = "@color"
locks = "cmd:all()"
@ -552,10 +576,10 @@ class CmdColorTest(MuxPlayerCommand):
ap = ansi.ANSI_PARSER
# ansi colors
# show all ansi color-related codes
col1 = ["%s%s{n" % (code, code.replace("{","{{")) for code, _ in ap.ext_ansi_map[:-1]]
col1 = ["%s%s{n" % (code, code.replace("{", "{{")) for code, _ in ap.ext_ansi_map[:-1]]
hi = "%ch"
col2 = ["%s%s{n" % (code, code.replace("%", "%%")) for code, _ in ap.mux_ansi_map[3:-2]]
col3 = ["%s%s{n" % (hi+code, (hi+code).replace("%", "%%")) for code, _ in ap.mux_ansi_map[3:-2]]
col3 = ["%s%s{n" % (hi + code, (hi + code).replace("%", "%%")) for code, _ in ap.mux_ansi_map[3:-2]]
table = utils.format_table([col1, col2, col3], extra_space=1)
string = "ANSI colors:"
for row in table:
@ -566,16 +590,16 @@ class CmdColorTest(MuxPlayerCommand):
elif self.args.startswith("x"):
# show xterm256 table
table = [[],[],[],[],[],[],[],[],[],[],[],[]]
table = [[], [], [], [], [], [], [], [], [], [], [], []]
for ir in range(6):
for ig in range(6):
for ib in range(6):
# foreground table
table[ir].append("%%c%i%i%i%s{n" % (ir,ig,ib, "{{%i%i%i" % (ir,ig,ib)))
table[ir].append("%%c%i%i%i%s{n" % (ir, ig, ib, "{{%i%i%i" % (ir, ig, ib)))
# background table
table[6+ir].append("%%cb%i%i%i%%c%i%i%i%s{n" % (ir,ig,ib,
5-ir,5-ig,5-ib,
"{{b%i%i%i" % (ir,ig,ib)))
table[6+ir].append("%%cb%i%i%i%%c%i%i%i%s{n" % (ir, ig, ib,
5 - ir, 5 - ig, 5 - ib,
"{{b%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):"
for row in table:
@ -586,6 +610,7 @@ class CmdColorTest(MuxPlayerCommand):
# malformed input
self.msg("Usage: @color ansi|xterm256")
class CmdQuell(MuxPlayerCommand):
"""
Quelling permissions
@ -604,7 +629,7 @@ class CmdQuell(MuxPlayerCommand):
"""
key = "@quell"
aliases =["@unquell"]
aliases = ["@unquell"]
locks = "cmd:all()"
help_category = "General"
@ -613,8 +638,9 @@ class CmdQuell(MuxPlayerCommand):
if self.sessid:
char = player.get_puppet(self.sessid)
if char:
# we are already puppeting an object. We need to reset the lock caches
# (otherwise the superuser status change won't be visible until repuppet)
# we are already puppeting an object. We need to reset
# the lock caches (otherwise the superuser status change
# won't be visible until repuppet)
char.locks.reset()
player.locks.reset()

View file

@ -33,6 +33,7 @@ from src.commands.default.muxcommand import MuxCommand
# Command called when there is no input at line
# (i.e. an lone return key)
class SystemNoInput(MuxCommand):
"""
This is called when there is no input given
@ -44,11 +45,11 @@ class SystemNoInput(MuxCommand):
"Do nothing."
pass
#
# Command called when there was no match to the
# command name
#
class SystemNoMatch(MuxCommand):
"""
No command was found matching the given input.
@ -62,6 +63,7 @@ class SystemNoMatch(MuxCommand):
"""
self.caller.msg("Huh?")
#
# Command called when there were mulitple matches to the command.
#
@ -100,7 +102,7 @@ class SystemMultimatch(MuxCommand):
is_channel = ""
is_exit = hasattr(cmd, "is_exit") and cmd.is_exit
if is_exit and cmd.destination:
is_exit = " (exit to %s)" % cmd.destination
is_exit = " (exit to %s)" % cmd.destination
else:
is_exit = ""
@ -124,6 +126,7 @@ class SystemMultimatch(MuxCommand):
string = self.format_multimatches(self.caller, self.matches)
self.caller.msg(string)
# Command called when the command given at the command line
# was identified as a channel name, like there existing a
# channel named 'ooc' and the user wrote
@ -167,4 +170,4 @@ class SystemSendToChannel(MuxCommand):
return
msg = "[%s] %s: %s" % (channel.key, caller.name, msg)
msgobj = create.create_message(caller, msg, channels=[channel])
channel.msg(msgobj)
channel.msg(msgobj)

View file

@ -5,10 +5,13 @@ System commands
"""
import traceback
import os, datetime, time
from time import time as timemeasure
import os
import datetime
import time
import sys
import django, twisted
import django
import twisted
from time import time as timemeasure
from django.conf import settings
from src.server.caches import get_cache_sizes
@ -30,6 +33,7 @@ __all__ = ("CmdReload", "CmdReset", "CmdShutdown", "CmdPy",
"CmdScripts", "CmdObjects", "CmdService", "CmdAbout",
"CmdTime", "CmdServerLoad")
class CmdReload(MuxCommand):
"""
Reload the system
@ -55,6 +59,7 @@ class CmdReload(MuxCommand):
SESSIONS.announce_all(" Server restarting %s..." % reason)
SESSIONS.server.shutdown(mode='reload')
class CmdReset(MuxCommand):
"""
Reset and reboot the system
@ -110,6 +115,7 @@ class CmdShutdown(MuxCommand):
SESSIONS.portal_shutdown()
SESSIONS.server.shutdown(mode='shutdown')
class CmdPy(MuxCommand):
"""
Execute a snippet of python code
@ -157,18 +163,17 @@ class CmdPy(MuxCommand):
# import useful variables
import ev
available_vars = {'self':caller,
'me':caller,
'here':hasattr(caller, "location") and caller.location or None,
'ev':ev,
'inherits_from':utils.inherits_from}
available_vars = {'self': caller,
'me': caller,
'here': hasattr(caller, "location") and caller.location or None,
'ev': ev,
'inherits_from': utils.inherits_from}
try:
self.msg(">>> %s" % pycode, raw=True, sessid=self.sessid)
except TypeError:
self.msg(">>> %s" % pycode, raw=True)
mode = "eval"
try:
try:
@ -195,7 +200,7 @@ class CmdPy(MuxCommand):
errlist = errlist[4:]
ret = "\n".join("{n<<< %s" % line for line in errlist if line)
if ret != None:
if ret is not None:
try:
self.msg(ret, sessid=self.sessid)
except TypeError:
@ -210,7 +215,16 @@ def format_script_list(scripts):
if not scripts:
return "<No scripts>"
table = prettytable.PrettyTable(["{wid","{wobj","{wkey","{wintval","{wnext","{wrept","{wdb"," {wtypeclass","{wdesc"],align='r')
table = prettytable.PrettyTable(["{wid",
"{wobj",
"{wkey",
"{wintval",
"{wnext",
"{wrept",
"{wdb",
"{wtypeclass",
"{wdesc"],
align='r')
table.align = 'r'
for script in scripts:
nextrep = script.time_until_next_repeat()
@ -322,7 +336,6 @@ class CmdScripts(MuxCommand):
caller.msg(string)
class CmdObjects(MuxCommand):
"""
@objects - Give a summary of object types in database
@ -357,32 +370,37 @@ class CmdObjects(MuxCommand):
nother = nobjs - nchars - nrooms - nexits
# total object sum table
totaltable = prettytable.PrettyTable(["{wtype","{wcomment","{wcount", "{w%%"])
totaltable = prettytable.PrettyTable(["{wtype", "{wcomment", "{wcount", "{w%%"])
totaltable.align = 'l'
totaltable.add_row(["Characters", "(BASE_CHARACTER_TYPECLASS)", nchars, "%.2f" % ((float(nchars)/nobjs)*100)])
totaltable.add_row(["Rooms", "(location=None)", nrooms, "%.2f" % ((float(nrooms)/nobjs)*100)])
totaltable.add_row(["Exits", "(destination!=None)", nexits, "%.2f" % ((float(nexits)/nobjs)*100)])
totaltable.add_row(["Other", "", nother, "%.2f" % ((float(nother)/nobjs)*100)])
totaltable.add_row(["Characters", "(BASE_CHARACTER_TYPECLASS)", nchars, "%.2f" % ((float(nchars) / nobjs) * 100)])
totaltable.add_row(["Rooms", "(location=None)", nrooms, "%.2f" % ((float(nrooms) / nobjs) * 100)])
totaltable.add_row(["Exits", "(destination!=None)", nexits, "%.2f" % ((float(nexits) / nobjs) * 100)])
totaltable.add_row(["Other", "", nother, "%.2f" % ((float(nother) / nobjs) * 100)])
# typeclass table
typetable = prettytable.PrettyTable(["{wtypeclass","{wcount", "{w%%"])
typetable = prettytable.PrettyTable(["{wtypeclass", "{wcount", "{w%%"])
typetable.align = 'l'
dbtotals = ObjectDB.objects.object_totals()
for path, count in dbtotals.items():
typetable.add_row([path, count, "%.2f" % ((float(count)/nobjs)*100)])
typetable.add_row([path, count, "%.2f" % ((float(count) / nobjs) * 100)])
# last N table
objs = ObjectDB.objects.all().order_by("db_date_created")[max(0, nobjs - nlim):]
latesttable = prettytable.PrettyTable(["{wcreated","{wdbref","{wname","{wtypeclass"])
latesttable = prettytable.PrettyTable(["{wcreated",
"{wdbref",
"{wname",
"{wtypeclass"])
latesttable.align = 'l'
for obj in objs:
latesttable.add_row([utils.datetime_format(obj.date_created), obj.dbref, obj.key, obj.typeclass.path])
latesttable.add_row([utils.datetime_format(obj.date_created),
obj.dbref, obj.key, obj.typeclass.path])
string = "\n{wObject subtype totals (out of %i Objects):{n\n%s" % (nobjs, totaltable)
string += "\n{wObject typeclass distribution:{n\n%s" % typetable
string += "\n{wLast %s Objects created:{n\n%s" % (min(nobjs, nlim), latesttable)
caller.msg(string)
class CmdPlayers(MuxCommand):
"""
@players - give a summary of all registed Players
@ -397,6 +415,7 @@ class CmdPlayers(MuxCommand):
key = "@players"
aliases = ["@listplayers"]
locks = "cmd:perm(listplayers) or perm(Wizards)"
def func(self):
"List the players"
@ -413,10 +432,10 @@ class CmdPlayers(MuxCommand):
typetable = prettytable.PrettyTable(["{wtypeclass", "{wcount", "{w%%"])
typetable.align = 'l'
for path, count in dbtotals.items():
typetable.add_row([path, count, "%.2f" % ((float(count)/nplayers)*100)])
typetable.add_row([path, count, "%.2f" % ((float(count) / nplayers) * 100)])
# last N table
plyrs = PlayerDB.objects.all().order_by("db_date_created")[max(0, nplayers - nlim):]
latesttable = prettytable.PrettyTable(["{wcreated", "{wdbref","{wname","{wtypeclass"])
latesttable = prettytable.PrettyTable(["{wcreated", "{wdbref", "{wname", "{wtypeclass"])
latesttable.align = 'l'
for ply in plyrs:
latesttable.add_row([utils.datetime_format(ply.date_created), ply.dbref, ply.key, ply.typeclass.path])
@ -425,6 +444,7 @@ class CmdPlayers(MuxCommand):
string += "\n{wLast %s Players created:{n\n%s" % (min(nplayers, nlim), latesttable)
caller.msg(string)
class CmdService(MuxCommand):
"""
@service - manage services
@ -441,7 +461,8 @@ class CmdService(MuxCommand):
Service management system. Allows for the listing,
starting, and stopping of services. If no switches
are given, services will be listed. Note that to operate on the
service you have to supply the full (green or red) name as given in the list.
service you have to supply the full (green or red) name as given
in the list.
"""
key = "@service"
@ -520,6 +541,7 @@ class CmdService(MuxCommand):
caller.msg("Starting service '%s'." % self.args)
service.startService()
class CmdAbout(MuxCommand):
"""
@about - game engine info
@ -567,6 +589,7 @@ class CmdAbout(MuxCommand):
sversion)
self.caller.msg(string)
class CmdTime(MuxCommand):
"""
@time
@ -591,6 +614,7 @@ class CmdTime(MuxCommand):
table.add_row(["Server time stamp", datetime.datetime.now()])
self.caller.msg(str(table))
class CmdServerLoad(MuxCommand):
"""
server load and memory statistics
@ -648,20 +672,20 @@ class CmdServerLoad(MuxCommand):
pid = os.getpid()
rmem = float(os.popen('ps -p %d -o %s | tail -1' % (pid, "rss")).read()) / 1024.0 # resident memory
vmem = float(os.popen('ps -p %d -o %s | tail -1' % (pid, "vsz")).read()) / 1024.0 # virtual memory
pmem = float(os.popen('ps -p %d -o %s | tail -1' % (pid, "%mem")).read()) # percent of resident memory to total
pmem = float(os.popen('ps -p %d -o %s | tail -1' % (pid, "%mem")).read()) # percent of resident memory to total
rusage = resource.getrusage(resource.RUSAGE_SELF)
# load table
loadtable = prettytable.PrettyTable(["property", "statistic"])
loadtable.align = 'l'
loadtable.add_row(["Server load (1 min)","%g" % loadavg[0]])
loadtable.add_row(["Process ID","%g" % pid]),
loadtable.add_row(["Bytes per page","%g " % psize])
loadtable.add_row(["Server load (1 min)", "%g" % loadavg[0]])
loadtable.add_row(["Process ID", "%g" % pid]),
loadtable.add_row(["Bytes per page", "%g " % psize])
loadtable.add_row(["CPU time used (total)", "%s (%gs)" % (utils.time_format(rusage.ru_utime), rusage.ru_utime)])
loadtable.add_row(["CPU time used (user)", "%s (%gs)" % (utils.time_format(rusage.ru_stime), rusage.ru_stime)])
loadtable.add_row(["Memory usage","%g MB (%g%%)" % (rmem, pmem)])
loadtable.add_row(["Virtual address space\n {x(resident+swap+caching){n", "%g MB" % vmem])
loadtable.add_row(["Page faults","%g hard, %g soft, %g swapouts" % (rusage.ru_majflt, rusage.ru_minflt, rusage.ru_nswap)])
loadtable.add_row(["Page faults", "%g hard, %g soft, %g swapouts" % (rusage.ru_majflt, rusage.ru_minflt, rusage.ru_nswap)])
loadtable.add_row(["Disk I/O", "%g reads, %g writes" % (rusage.ru_inblock, rusage.ru_oublock)])
loadtable.add_row(["Network I/O", "%g in, %g out" % (rusage.ru_msgrcv, rusage.ru_msgsnd)])
loadtable.add_row(["Context switching", "%g vol, %g forced, %g signals" % (rusage.ru_nvcsw, rusage.ru_nivcsw, rusage.ru_nsignals)])
@ -669,17 +693,24 @@ class CmdServerLoad(MuxCommand):
string = "{wServer CPU and Memory load:{n\n%s" % loadtable
if not is_pypy:
# Cache size measurements are not available on PyPy because it lacks sys.getsizeof
# Cache size measurements are not available on PyPy
# because it lacks sys.getsizeof
# object cache size
cachedict = _idmapper.cache_size()
totcache = cachedict["_total"]
sorted_cache = sorted([(key, tup[0], tup[1]) for key, tup in cachedict.items() if key !="_total" and tup[0] > 0],
key=lambda tup: tup[2], reverse=True)
memtable = prettytable.PrettyTable(["entity name", "number", "cache (MB)", "idmapper %%"])
memtable = prettytable.PrettyTable(["entity name",
"number",
"cache (MB)",
"idmapper %%"])
memtable.align = 'l'
for tup in sorted_cache:
memtable.add_row([tup[0], "%i" % tup [1], "%5.2f" % tup[2], "%.2f" % (float(tup[2]/totcache[1])*100)])
memtable.add_row([tup[0],
"%i" % tup[1],
"%5.2f" % tup[2],
"%.2f" % (float(tup[2] / totcache[1]) * 100)])
# get sizes of other caches
attr_cache_info, field_cache_info, prop_cache_info = get_cache_sizes()

View file

@ -18,7 +18,7 @@ from django.utils.unittest import TestCase
from src.server.serversession import ServerSession
from src.objects.objects import Object, Character
from src.players.player import Player
from src.utils import create, utils, ansi
from src.utils import create, ansi
from src.server.sessionhandler import SESSIONS
from django.db.models.signals import pre_save
@ -33,16 +33,20 @@ _RE = re.compile(r"^\+|-+\+|\+-+|--*|\|", re.MULTILINE)
# Command testing
# ------------------------------------------------------------
def dummy(self, *args, **kwargs):
pass
SESSIONS.data_out = dummy
SESSIONS.disconnect = dummy
class TestObjectClass(Object):
def msg(self, text="", **kwargs):
"test message"
pass
class TestCharacterClass(Character):
def msg(self, text="", **kwargs):
"test message"
@ -52,17 +56,21 @@ class TestCharacterClass(Character):
if not self.ndb.stored_msg:
self.ndb.stored_msg = []
self.ndb.stored_msg.append(text)
class TestPlayerClass(Player):
def msg(self, text="", **kwargs):
"test message"
if not self.ndb.stored_msg:
self.ndb.stored_msg = []
self.ndb.stored_msg.append(text)
def _get_superuser(self):
"test with superuser flag"
return self.ndb.is_superuser
is_superuser = property(_get_superuser)
class CommandTest(TestCase):
"""
Tests a command
@ -93,6 +101,7 @@ class CommandTest(TestCase):
SESSIONS.portal_connect(session.get_sync_data())
SESSIONS.login(SESSIONS.session_from_sessid(self.CID), self.player, testmode=True)
def call(self, cmdobj, args, msg=None, cmdset=None, noansi=True, caller=None):
"""
Test a command by assigning all the needed
@ -141,6 +150,7 @@ class CommandTest(TestCase):
from src.commands.default import general
class TestGeneral(CommandTest):
CID = 1
def test_cmds(self):
self.call(general.CmdLook(), "here", "Room1\n room_desc")
self.call(general.CmdHome(), "", "You are already home")
@ -158,6 +168,7 @@ class TestGeneral(CommandTest):
self.call(general.CmdSay(), "Testing", "You say, \"Testing\"")
self.call(general.CmdAccess(), "", "Permission Hierarchy (climbing):")
from src.commands.default import help
from src.commands.default.cmdset_character import CharacterCmdSet
class TestHelp(CommandTest):
@ -167,6 +178,7 @@ class TestHelp(CommandTest):
self.call(help.CmdSetHelp(), "testhelp, General = This is a test", "Topic 'testhelp' was successfully created.")
self.call(help.CmdHelp(), "testhelp", "Help topic for testhelp", cmdset=CharacterCmdSet())
from src.commands.default import system
class TestSystem(CommandTest):
CID = 3
@ -179,6 +191,7 @@ class TestSystem(CommandTest):
self.call(system.CmdAbout(), "", None)
self.call(system.CmdServerLoad(), "", "Server CPU and Memory load:")
from src.commands.default import admin
class TestAdmin(CommandTest):
CID = 4
@ -190,6 +203,7 @@ class TestAdmin(CommandTest):
self.call(admin.CmdPerm(), "Char4b = Builders","Permission 'Builders' given to Char4b.")
self.call(admin.CmdBan(), "Char4", "NameBan char4 was added.")
from src.commands.default import player
class TestPlayer(CommandTest):
CID = 5
@ -209,6 +223,7 @@ class TestPlayer(CommandTest):
self.call(player.CmdCharCreate(), "Test1=Test char","Created new character Test1. Use @ic Test1 to enter the game", caller=self.player)
self.call(player.CmdQuell(), "", "Quelling Player permissions (immortals). Use @unquell to get them back.", caller=self.player)
from src.commands.default import building
class TestBuilding(CommandTest):
CID = 6
@ -239,6 +254,7 @@ class TestBuilding(CommandTest):
self.call(building.CmdScript(), "Obj6 = src.scripts.scripts.Script", "Script src.scripts.scripts.Script successfully added")
self.call(building.CmdTeleport(), "TestRoom1", "TestRoom1\nExits: back|Teleported to TestRoom1.")
from src.commands.default import comms
class TestComms(CommandTest):
CID = 7
@ -257,6 +273,7 @@ class TestComms(CommandTest):
self.call(comms.CmdCBoot(), "", "Usage: @cboot[/quiet] <channel> = <player> [:reason]") # noone else connected to boot
self.call(comms.CmdCdestroy(), "testchan" ,"Channel 'testchan' was destroyed.")
from src.commands.default import batchprocess
class TestBatchProcess(CommandTest):
CID = 8

View file

@ -14,7 +14,8 @@ from src.commands.default.muxcommand import MuxCommand
from src.commands.cmdhandler import CMD_LOGINSTART
# limit symbol import for API
__all__ = ("CmdUnconnectedConnect", "CmdUnconnectedCreate", "CmdUnconnectedQuit", "CmdUnconnectedLook", "CmdUnconnectedHelp")
__all__ = ("CmdUnconnectedConnect", "CmdUnconnectedCreate",
"CmdUnconnectedQuit", "CmdUnconnectedLook", "CmdUnconnectedHelp")
MULTISESSION_MODE = settings.MULTISESSION_MODE
CONNECTION_SCREEN_MODULE = settings.CONNECTION_SCREEN_MODULE
@ -26,6 +27,7 @@ except Exception:
if not CONNECTION_SCREEN:
CONNECTION_SCREEN = "\nEvennia: Error in CONNECTION_SCREEN MODULE (randomly picked connection screen variable is not a string). \nEnter 'help' for aid."
class CmdUnconnectedConnect(MuxCommand):
"""
Connect to the game.
@ -40,7 +42,7 @@ class CmdUnconnectedConnect(MuxCommand):
"""
key = "connect"
aliases = ["conn", "con", "co"]
locks = "cmd:all()" # not really needed
locks = "cmd:all()" # not really needed
def func(self):
"""
@ -92,12 +94,13 @@ class CmdUnconnectedConnect(MuxCommand):
# actually do the login. This will call all other hooks:
# session.at_login()
# player.at_init() # always called when object is loaded from disk
# player.at_init() # always called when object is loaded from disk
# player.at_pre_login()
# player.at_first_login() # only once
# player.at_post_login(sessid=sessid)
session.sessionhandler.login(session, player)
class CmdUnconnectedCreate(MuxCommand):
"""
Create a new account.
@ -134,8 +137,9 @@ class CmdUnconnectedCreate(MuxCommand):
# sanity checks
if not re.findall('^[\w. @+-]+$', playername) or not (0 < len(playername) <= 30):
# this echoes the restrictions made by django's auth module (except not
# allowing spaces, for convenience of logging in).
# this echoes the restrictions made by django's auth
# module (except not allowing spaces, for convenience of
# logging in).
string = "\n\r Playername can max be 30 characters or fewer. Letters, spaces, digits and @/./+/-/_ only."
session.msg(string)
return
@ -163,14 +167,14 @@ class CmdUnconnectedCreate(MuxCommand):
new_player = create.create_player(playername, None, password,
permissions=permissions)
except Exception, e:
session.msg("There was an error creating the default Player/Character:\n%s\n If this problem persists, contact an admin." % e)
logger.log_trace()
return
# This needs to be called so the engine knows this player is logging in for the first time.
# (so it knows to call the right hooks during login later)
# This needs to be called so the engine knows this player is
# logging in for the first time. (so it knows to call the right
# hooks during login later)
utils.init_new_player(new_player)
# join the new player to the public channel
@ -181,7 +185,6 @@ class CmdUnconnectedCreate(MuxCommand):
string = "New player '%s' could not connect to public channel!" % new_player.key
logger.log_errmsg(string)
if MULTISESSION_MODE < 2:
# if we only allow one character, create one with the same name as Player
# (in mode 2, the character must be created manually once logging in)
@ -210,12 +213,14 @@ class CmdUnconnectedCreate(MuxCommand):
session.msg(string % (playername, playername))
except Exception:
# We are in the middle between logged in and -not, so we have to handle tracebacks
# ourselves at this point. If we don't, we won't see any errors at all.
# We are in the middle between logged in and -not, so we have
# to handle tracebacks ourselves at this point. If we don't,
# we won't see any errors at all.
string = "%s\nThis is a bug. Please e-mail an admin if the problem persists."
session.msg(string % (traceback.format_exc()))
logger.log_errmsg(traceback.format_exc())
class CmdUnconnectedQuit(MuxCommand):
"""
We maintain a different version of the quit command
@ -230,7 +235,8 @@ class CmdUnconnectedQuit(MuxCommand):
"Simply close the connection."
session = self.caller
#session.msg("Good bye! Disconnecting ...")
session.sessionhandler.disconnect(session, "Good bye! Disconnecting ...")
session.sessionhandler.disconnect(session, "Good bye! Disconnecting.")
class CmdUnconnectedLook(MuxCommand):
"""
@ -247,6 +253,7 @@ class CmdUnconnectedLook(MuxCommand):
"Show the connect screen."
self.caller.msg(CONNECTION_SCREEN)
class CmdUnconnectedHelp(MuxCommand):
"""
This is an unconnected version of the help command,