Made changes to idmapper that might help alleviate issue101 (more people need to run it to make sure). Moved around default command modules to be more logically named and distributed.

This commit is contained in:
Griatch 2010-10-31 08:10:02 +00:00
parent 19dd476115
commit 3f703efc2d
17 changed files with 1920 additions and 1851 deletions

View file

@ -0,0 +1,484 @@
"""
Admin commands
"""
from django.conf import settings
from django.contrib.auth.models import User
from src.players.models import PlayerDB
from game.gamesrc.commands.default.muxcommand import MuxCommand
from src.server import sessionhandler
from src.permissions.permissions import has_perm, has_perm_string
from src.permissions.models import PermissionGroup
from src.utils import utils
class CmdBoot(MuxCommand):
"""
@boot
Usage
@boot[/switches] <player obj> [: reason]
Switches:
quiet - Silently boot without informing player
port - boot by port number instead of name or dbref
Boot a player object from the server. If a reason is
supplied it will be echoed to the user unless /quiet is set.
"""
key = "@boot"
permissions = "cmd:boot"
help_category = "Admin"
def func(self):
"Implementing the function"
caller = self.caller
args = self.args
if not args:
caller.msg("Usage: @boot[/switches] <player> [:reason]")
return
if ':' in args:
args, reason = [a.strip() for a in args.split(':', 1)]
boot_list = []
reason = ""
if 'port' in self.switches:
# Boot a particular port.
sessions = sessionhandler.get_session_list(True)
for sess in sessions:
# Find the session with the matching port number.
if sess.getClientAddress()[1] == int(args):
boot_list.append(sess)
break
else:
# Boot by player object
pobj = caller.search("*%s" % args, global_search=True)
if not pobj:
return
pobj = pobj
if pobj.has_player:
if not has_perm(caller, pobj, 'can_boot'):
string = "You don't have the permission to boot %s."
pobj.msg(string)
return
# we have a bootable object with a connected user
matches = sessionhandler.sessions_from_object(pobj)
for match in matches:
boot_list.append(match)
else:
caller.msg("That object has no connected player.")
return
if not boot_list:
caller.msg("No matches found.")
return
# Carry out the booting of the sessions in the boot list.
feedback = None
if not 'quiet' in self.switches:
feedback = "You have been disconnected by %s.\n" % caller.name
if reason:
feedback += "\nReason given: %s" % reason
for session in boot_list:
name = session.name
if feedback:
session.msg(feedback)
session.disconnectClient()
sessionhandler.remove_session(session)
caller.msg("You booted %s." % name)
class CmdDelPlayer(MuxCommand):
"""
delplayer - delete player from server
Usage:
@delplayer[/switch] <name> [: reason]
Switch:
delobj - also delete the player's currently
assigned in-game object.
Completely deletes a user from the server database,
making their nick and e-mail again available.
"""
key = "@delplayer"
permissions = "cmd:delplayer"
help_category = "Admin"
def func(self):
"Implements the command."
caller = self.caller
args = self.args
if not args:
caller.msg("Usage: @delplayer[/delobj] <player/user name or #id>")
return
reason = ""
if ':' in args:
args, reason = [arg.strip() for arg in args.split(':', 1)]
# We use player_search since we want to be sure to find also players
# that lack characters.
players = PlayerDB.objects.filter(db_key=args)
if not players:
try:
players = PlayerDB.objects.filter(id=args)
except ValueError:
pass
if not players:
# try to find a user instead of a Player
try:
user = User.objects.get(id=args)
except Exception:
try:
user = User.objects.get(username__iexact=args)
except Exception:
string = "No Player nor User found matching '%s'." % args
caller.msg(string)
return
try:
player = user.get_profile()
except Exception:
player = None
if not has_perm_string(caller, 'manage_players'):
string = "You don't have the permissions to delete this player."
caller.msg(string)
return
string = ""
name = user.username
user.delete()
if player:
name = player.name
player.delete()
string = "Player %s was deleted." % name
else:
string += "The User %s was deleted, but had no Player associated with it." % name
caller.msg(string)
return
elif len(players) > 1:
string = "There where multiple matches:"
for player in players:
string += "\n %s %s" % (player.id, player.key)
return
else:
# one single match
player = players[0]
user = player.user
character = player.character
if not has_perm(caller, player, 'manage_players'):
string = "You don't have the permissions to delete that player."
caller.msg(string)
return
uname = user.username
# boot the player then delete
if character and character.has_player:
caller.msg("Booting and informing player ...")
string = "\nYour account '%s' is being *permanently* deleted.\n" % uname
if reason:
string += " Reason given:\n '%s'" % reason
character.msg(string)
caller.execute_cmd("@boot %s" % uname)
player.delete()
user.delete()
caller.msg("Player %s was successfully deleted." % uname)
class CmdEmit(MuxCommand):
"""
@emit
Usage:
@emit[/switches] [<obj>, <obj>, ... =] <message>
@remit [<obj>, <obj>, ... =] <message>
@pemit [<obj>, <obj>, ... =] <message>
Switches:
room : limit emits to rooms only
players : limit emits to players 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,
send to its contents. @remit and @pemit are just
limited forms of @emit, for sending to rooms and
to players respectively.
"""
key = "@emit"
aliases = ["@pemit", "@remit"]
permissions = "cmd:emit"
help_category = "Admin"
def func(self):
"Implement the command"
caller = self.caller
args = self.args
if not args:
string = "Usage: "
string += "\n@emit[/switches] [<obj>, <obj>, ... =] <message>"
string += "\n@remit [<obj>, <obj>, ... =] <message>"
string += "\n@pemit [<obj>, <obj>, ... =] <message>"
caller.msg(string)
return
rooms_only = 'rooms' in self.switches
players_only = 'players' in self.switches
send_to_contents = 'contents' in self.switches
# we check which command was used to force the switches
if self.cmdstring == '@remit':
rooms_only = True
elif self.cmdstring == '@pemit':
players_only = True
if not self.rhs:
message = self.args
objnames = [caller.location.key]
else:
message = self.rhs
objnames = self.lhslist
# send to all objects
for objname in objnames:
obj = caller.search(objname, global_search=True)
if not obj:
return
if rooms_only and not obj.location == None:
caller.msg("%s is not a room. Ignored." % objname)
continue
if players_only and not obj.has_player:
caller.msg("%s has no active player. Ignored." % objname)
continue
if has_perm(caller, obj, 'send_to'):
obj.msg(message)
if send_to_contents:
for content in obj.contents:
content.msg(message)
caller.msg("Emitted to %s and its contents." % objname)
else:
caller.msg("Emitted to %s." % objname)
else:
caller.msg("You are not allowed to send to %s." % objname)
class CmdNewPassword(MuxCommand):
"""
@setpassword
Usage:
@userpassword <user obj> = <new password>
Set a player's password.
"""
key = "@userpassword"
permissions = "cmd:newpassword"
help_category = "Admin"
def func(self):
"Implement the function."
caller = self.caller
if not self.rhs:
caller.msg("Usage: @userpassword <user obj> = <new password>")
return
# the player search also matches 'me' etc.
character = caller.search("*%s" % self.lhs, global_search=True)
if not character:
return
player = character.player
player.user.set_password(self.rhs)
player.user.save()
caller.msg("%s - new password set to '%s'." % (player.name, self.rhs))
if character != caller:
player.msg("%s has changed your password to '%s'." % (caller.name, self.rhs))
class CmdPerm(MuxCommand):
"""
@perm - set permissions
Usage:
@perm[/switch] [<object>] = [<permission>]
@perm[/switch] [*<player>] = [<permission>]
Switches:
del : delete the given permission from <object>.
list : list all permissions, or those set on <object>
Use * before the search string to add permissions to a player.
This command sets/clears individual permission strings on an object.
Use /list without any arguments to see all available permissions
or those defined on the <object>/<player> argument.
"""
key = "@perm"
aliases = "@setperm"
permissions = "cmd:perm"
help_category = "Admin"
def func(self):
"Implement function"
caller = self.caller
switches = self.switches
lhs, rhs = self.lhs, self.rhs
if not self.args:
if "list" not in switches:
string = "Usage: @setperm[/switch] [object = permission]\n"
string += " @setperm[/switch] [*player = permission]"
caller.msg(string)
return
else:
#just print all available permissions
string = "\nAll defined permission groups and keys (i.e. not locks):"
pgroups = list(PermissionGroup.objects.all())
pgroups.sort(lambda x, y: cmp(x.key, y.key)) # sort by group key
for pgroup in pgroups:
string += "\n\n - {w%s{n (%s):" % (pgroup.key, pgroup.desc)
string += "\n%s" % \
utils.fill(", ".join(sorted(pgroup.group_permissions)))
caller.msg(string)
return
# locate the object/player
obj = caller.search(lhs, global_search=True)
if not obj:
return
pstring = ""
if utils.inherits_from(obj, settings.BASE_PLAYER_TYPECLASS):
pstring = " Player "
if not rhs:
string = "Permission string on %s{w%s{n: " % (pstring, obj.key)
if not obj.permissions:
string += "<None>"
else:
string += ", ".join(obj.permissions)
if pstring and obj.is_superuser:
string += "\n(... But this player is a SUPERUSER! "
string += "All access checked are passed automatically.)"
elif obj.player and obj.player.is_superuser:
string += "\n(... But this object's player is a SUPERUSER! "
string += "All access checked are passed automatically.)"
caller.msg(string)
return
# we supplied an argument on the form obj = perm
cstring = ""
tstring = ""
if 'del' in switches:
# delete the given permission(s) from object.
for perm in self.rhslist:
try:
index = obj.permissions.index(perm)
except ValueError:
cstring += "\nPermission '%s' was not defined on %s%s." % (perm, pstring, lhs)
continue
permissions = obj.permissions
del permissions[index]
obj.permissions = permissions
cstring += "\nPermission '%s' was removed from %s%s." % (perm, pstring, obj.name)
tstring += "\n%s revokes the permission '%s' from you." % (caller.name, perm)
else:
# As an extra check, we warn the user if they customize the
# permission string (which is okay, and is used by the lock system)
permissions = obj.permissions
for perm in self.rhslist:
if perm in permissions:
cstring += "\nPermission '%s' is already defined on %s%s." % (rhs, pstring, obj.name)
else:
permissions.append(perm)
obj.permissions = permissions
cstring += "\nPermission '%s' given to %s%s." % (rhs, pstring, obj.name)
tstring += "\n%s granted you the permission '%s'." % (caller.name, rhs)
caller.msg(cstring.strip())
if tstring:
obj.msg(tstring.strip())
class CmdPuppet(MuxCommand):
"""
Switch control to an object
Usage:
@puppet <character object>
This will attempt to "become" a different character. Note that this command does not check so that
the target object has the appropriate cmdset. You cannot puppet a character that is already "taken".
"""
key = "@puppet"
permissions = "cmd:puppet"
help_category = "Admin"
def func(self):
"""
Simple puppet method (does not check permissions)
"""
caller = self.caller
if not self.args:
caller.msg("Usage: @puppet <character>")
return
player = caller.player
new_character = caller.search(self.args)
if not new_character:
return
if not utils.inherits_from(new_character, settings.BASE_CHARACTER_TYPECLASS):
caller.msg("%s is not a Character." % self.args)
return
if player.swap_character(new_character):
new_character.msg("You now control %s." % new_character.name)
else:
caller.msg("You couldn't control %s." % new_character.name)
class CmdWall(MuxCommand):
"""
@wall
Usage:
@wall <message>
Announces a message to all connected players.
"""
key = "@wall"
permissions = "cmd:wall"
help_category = "Admin"
def func(self):
"Implements command"
if not self.args:
self.caller.msg("Usage: @wall <message>")
return
message = "%s shouts \"%s\"" % (self.caller.name, self.args)
sessionhandler.announce_all(message)

View file

@ -2,9 +2,9 @@
This module ties together all the commands of the default command set.
"""
from src.commands.cmdset import CmdSet
from game.gamesrc.commands.default import general, help, privileged
from game.gamesrc.commands.default import tests, comms, objmanip
from game.gamesrc.commands.default import info, batchprocess
from game.gamesrc.commands.default import general, help, admin, system
from game.gamesrc.commands.default import tests, comms, building
from game.gamesrc.commands.default import batchprocess
class DefaultCmdSet(CmdSet):
"""
@ -17,13 +17,12 @@ class DefaultCmdSet(CmdSet):
# The general commands
self.add(general.CmdLook())
self.add(general.CmdHome())
self.add(general.CmdPassword())
self.add(general.CmdWall())
self.add(general.CmdInventory())
self.add(general.CmdQuit())
self.add(general.CmdPose())
self.add(general.CmdNick())
self.add(general.CmdEmit())
self.add(general.CmdGet())
self.add(general.CmdDrop())
self.add(general.CmdWho())
@ -35,47 +34,49 @@ class DefaultCmdSet(CmdSet):
self.add(help.CmdHelp())
self.add(help.CmdSetHelp())
# Privileged commands
self.add(privileged.CmdReload())
self.add(privileged.CmdPy())
self.add(privileged.CmdListScripts())
self.add(privileged.CmdListCmdSets())
self.add(privileged.CmdListObjects())
self.add(privileged.CmdBoot())
self.add(privileged.CmdDelPlayer())
self.add(privileged.CmdNewPassword())
self.add(privileged.CmdHome())
self.add(privileged.CmdService())
self.add(privileged.CmdShutdown())
self.add(privileged.CmdPerm())
# System commands
self.add(system.CmdReload())
self.add(system.CmdPy())
self.add(system.CmdListScripts())
self.add(system.CmdListObjects())
self.add(system.CmdService())
self.add(system.CmdShutdown())
self.add(system.CmdVersion())
self.add(system.CmdTime())
self.add(system.CmdList())
self.add(system.CmdPs())
self.add(system.CmdStats())
# Info commands
self.add(info.CmdVersion())
self.add(info.CmdTime())
self.add(info.CmdList())
self.add(info.CmdPs())
self.add(info.CmdStats())
# Admin commands
self.add(admin.CmdBoot())
self.add(admin.CmdDelPlayer())
self.add(admin.CmdEmit())
self.add(admin.CmdNewPassword())
self.add(admin.CmdPerm())
self.add(admin.CmdPuppet())
self.add(admin.CmdWall())
# Object manipulation commands
self.add(objmanip.CmdTeleport())
self.add(objmanip.CmdSetObjAlias())
self.add(objmanip.CmdWipe())
self.add(objmanip.CmdSetAttribute())
self.add(objmanip.CmdName())
self.add(objmanip.CmdDesc())
#self.add(objmanip.CmdCpAttr()) #TODO - need testing/debugging
#self.add(objmanip.CmdMvAttr()) #TODO - need testing/debugging
self.add(objmanip.CmdFind())
self.add(objmanip.CmdCopy()) #TODO - need testing/debugging
self.add(objmanip.CmdOpen())
self.add(objmanip.CmdLink())
self.add(objmanip.CmdUnLink())
self.add(objmanip.CmdCreate())
self.add(objmanip.CmdDig())
self.add(objmanip.CmdDestroy())
self.add(objmanip.CmdExamine())
self.add(objmanip.CmdTypeclass())
self.add(objmanip.CmdPuppet())
# Building and world manipulation
self.add(building.CmdTeleport())
self.add(building.CmdSetObjAlias())
self.add(building.CmdListCmdSets())
self.add(building.CmdDebug())
self.add(building.CmdWipe())
self.add(building.CmdSetAttribute())
self.add(building.CmdName())
self.add(building.CmdDesc())
#self.add(building.CmdCpAttr()) #TODO - need testing/debugging
#self.add(building.CmdMvAttr()) #TODO - need testing/debugging
self.add(building.CmdFind())
self.add(building.CmdCopy()) #TODO - need testing/debugging
self.add(building.CmdOpen())
self.add(building.CmdLink())
self.add(building.CmdUnLink())
self.add(building.CmdCreate())
self.add(building.CmdDig())
self.add(building.CmdDestroy())
self.add(building.CmdExamine())
self.add(building.CmdTypeclass())
# Comm commands
self.add(comms.CmdAddCom())
@ -95,4 +96,3 @@ class DefaultCmdSet(CmdSet):
self.add(tests.CmdTest())
self.add(tests.CmdTestPerms())
self.add(tests.TestCom())
self.add(tests.CmdDebug())

View file

@ -704,7 +704,6 @@ class CmdCdesc(MuxCommand):
channel.save()
caller.msg("Description of channel '%s' set to '%s'." % (channel.key, self.rhs))
class CmdPage(MuxCommand):
"""
page - send private message

View file

@ -12,6 +12,29 @@ from src.utils import utils
from game.gamesrc.commands.default.muxcommand import MuxCommand
class CmdHome(MuxCommand):
"""
home
Usage:
home
Teleports the player to their home.
"""
key = "home"
permissions = "cmd:home"
def func(self):
"Implement the command"
caller = self.caller
home = caller.home
if not home:
caller.msg("You have no home set.")
else:
caller.move_to(home)
caller.msg("There's no place like home ...")
class CmdLook(MuxCommand):
"""
look
@ -107,8 +130,8 @@ class CmdNick(MuxCommand):
if you want to change the inherent aliases of an object,
use the @alias command instead.
"""
key = "alias"
aliases = ["nick"]
key = "nickname"
aliases = ["nick, @nick, alias"]
def func(self):
"Create the nickname"
@ -164,104 +187,6 @@ class CmdNick(MuxCommand):
err = "Set %salias '%s' = '%s'" % (atype, alias, rstring)
caller.msg(err.capitalize())
class CmdEmit(MuxCommand):
"""
@emit
Usage:
@emit[/switches] [<obj>, <obj>, ... =] <message>
@remit [<obj>, <obj>, ... =] <message>
@pemit [<obj>, <obj>, ... =] <message>
Switches:
room : limit emits to rooms only
players : limit emits to players 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,
send to its contents. @remit and @pemit are just
limited forms of @emit, for sending to rooms and
to players respectively.
"""
key = "@emit"
aliases = ["@pemit", "@remit"]
permissions = "cmd:emit"
help_category = "Comms"
def func(self):
"Implement the command"
caller = self.caller
args = self.args
if not args:
string = "Usage: "
string += "\n@emit[/switches] [<obj>, <obj>, ... =] <message>"
string += "\n@remit [<obj>, <obj>, ... =] <message>"
string += "\n@pemit [<obj>, <obj>, ... =] <message>"
caller.msg(string)
return
rooms_only = 'rooms' in self.switches
players_only = 'players' in self.switches
send_to_contents = 'contents' in self.switches
# we check which command was used to force the switches
if self.cmdstring == '@remit':
rooms_only = True
elif self.cmdstring == '@pemit':
players_only = True
if not self.rhs:
message = self.args
objnames = [caller.location.key]
else:
message = self.rhs
objnames = self.lhslist
# send to all objects
for objname in objnames:
obj = caller.search(objname, global_search=True)
if not obj:
return
if rooms_only and not obj.location == None:
caller.msg("%s is not a room. Ignored." % objname)
continue
if players_only and not obj.has_player:
caller.msg("%s has no active player. Ignored." % objname)
continue
if has_perm(caller, obj, 'send_to'):
obj.msg(message)
if send_to_contents:
for content in obj.contents:
content.msg(message)
caller.msg("Emitted to %s and its contents." % objname)
else:
caller.msg("Emitted to %s." % objname)
else:
caller.msg("You are not allowed to send to %s." % objname)
class CmdWall(MuxCommand):
"""
@wall
Usage:
@wall <message>
Announces a message to all connected players.
"""
key = "@wall"
permissions = "cmd:wall"
def func(self):
"Implements command"
if not self.args:
self.caller.msg("Usage: @wall <message>")
return
message = "%s shouts \"%s\"" % (self.caller.name, self.args)
sessionhandler.announce_all(message)
class CmdInventory(MuxCommand):
"""
@ -383,11 +308,11 @@ class CmdQuit(MuxCommand):
quit
Usage:
quit
@quit
Gracefully disconnect from the game.
"""
key = "quit"
key = "@quit"
def func(self):
"hook function"
@ -716,8 +641,8 @@ class CmdGroup(MuxCommand):
This command shows you which user permission groups
you are a member of, if any.
"""
key = "group"
aliases = "groups"
key = "access"
aliases = "groups"
def func(self):
"Load the permission groups"

View file

@ -181,10 +181,10 @@ class CmdHelp(Command):
class CmdSetHelp(MuxCommand):
"""
@sethelp - edit the help database
@help - edit the help database
Usage:
@sethelp[/switches] <topic>[,category[,permission,permission,...]] = <text>
@help[/switches] <topic>[,category[,permission,permission,...]] = <text>
Switches:
add - add or replace a new topic with text.
@ -201,7 +201,8 @@ class CmdSetHelp(MuxCommand):
@sethelp/append pickpocketing, ,is_thief, is_staff) = This steals ...
"""
key = "@sethelp"
key = "@help"
aliases = "@sethelp"
permissions = "cmd:sethelp"
help_category = "Building"

View file

@ -1,261 +0,0 @@
"""
Commands that are generally staff-oriented that show information regarding
the server instance.
"""
import os, datetime
import django, twisted
from django.contrib.auth.models import User
from src.objects.models import ObjectDB
from src.scripts.models import ScriptDB
from src.utils import utils
from src.utils import gametime
from game.gamesrc.commands.default.muxcommand import MuxCommand
from src.commands import cmdsethandler
class CmdVersion(MuxCommand):
"""
@version - game version
Usage:
@version
Display the game version info.
"""
key = "@version"
help_category = "System"
def func(self):
"Show the version"
version = utils.get_evennia_version()
string = "-"*50 +"\n\r"
string += " {cEvennia{n %s\n\r" % version
string += " (Django %s, " % (django.get_version())
string += " Twisted %s)\n\r" % (twisted.version.short())
string += "-"*50
self.caller.msg(string)
class CmdTime(MuxCommand):
"""
@time
Usage:
@time
Server local time.
"""
key = "@time"
aliases = "@uptime"
permissions = "cmd:time"
help_category = "System"
def func(self):
"Show times."
string1 = "\nCurrent server uptime: \t"
string1 += "{w%s{n" % (utils.time_format(gametime.uptime(format=False), 2))
string2 = "\nTotal server running time: \t"
string2 += "{w%s{n" % (utils.time_format(gametime.runtime(format=False), 2))
string3 = "\nTotal in-game time (realtime x %g):\t" % (gametime.TIMEFACTOR)
string3 += "{w%s{n" % (utils.time_format(gametime.gametime(format=False), 2))
string4 = "\nServer time stamp: \t"
string4 += "{w%s{n" % (str(datetime.datetime.now()))
string5 = ""
if not utils.host_os_is('nt'):
# os.getloadavg() is not available on Windows.
loadavg = os.getloadavg()
string5 += "\nServer load (per minute): \t"
string5 += "{w%g%%{n" % (100 * loadavg[0])
string = "%s%s%s%s%s" % (string1, string2, string3, string4, string5)
self.caller.msg(string)
class CmdList(MuxCommand):
"""
@list - list info
Usage:
@list <option>
Options:
process - list processes
objects - list objects
scripts - list scripts
perms - list permission keys and groups
Shows game related information depending
on which argument is given.
"""
key = "@list"
permissions = "cmd:list"
help_category = "System"
def func(self):
"Show list."
caller = self.caller
if not self.args:
caller.msg("Usage: @list process|objects|scripts|perms")
return
string = ""
if self.arglist[0] in ["proc","process"]:
# display active processes
if utils.host_os_is('nt'):
string = "Feature not available on Windows."
else:
import resource
loadavg = os.getloadavg()
psize = resource.getpagesize()
rusage = resource.getrusage(resource.RUSAGE_SELF)
table = [["Server load (1 min):",
"Process ID:",
"Bytes per page:",
"Time used:",
"Integral memory:",
"Max res memory:",
"Page faults:",
"Disk I/O:",
"Network I/O",
"Context switching:"
],
["%g%%" % (100 * loadavg[0]),
"%10d" % os.getpid(),
"%10d " % psize,
"%10d" % rusage[0],
"%10d shared" % rusage[3],
"%10d pages" % rusage[2],
"%10d hard" % rusage[7],
"%10d reads" % rusage[9],
"%10d in" % rusage[12],
"%10d vol" % rusage[14]
],
["", "", "",
"(user: %g)" % rusage[1],
"%10d private" % rusage[4],
"%10d bytes" % (rusage[2] * psize),
"%10d soft" % rusage[6],
"%10d writes" % rusage[10],
"%10d out" % rusage[11],
"%10d forced" % rusage[15]
],
["", "", "", "",
"%10d stack" % rusage[5],
"",
"%10d swapouts" % rusage[8],
"", "",
"%10d sigs" % rusage[13]
]
]
stable = []
for col in table:
stable.append([str(val).strip() for val in col])
ftable = utils.format_table(stable, 5)
string = ""
for row in ftable:
string += "\n " + "{w%s{n" % row[0] + "".join(row[1:])
# string = "\n Server load (1 min) : %.2f " % loadavg[0]
# string += "\n Process ID: %10d" % os.getpid()
# string += "\n Bytes per page: %10d" % psize
# string += "\n Time used: %10d, user: %g" % (rusage[0], rusage[1])
# string += "\n Integral mem: %10d shared, %10d, private, %10d stack " % \
# (rusage[3], rusage[4], rusage[5])
# string += "\n Max res mem: %10d pages %10d bytes" % \
# (rusage[2],rusage[2] * psize)
# string += "\n Page faults: %10d hard %10d soft %10d swapouts " % \
# (rusage[7], rusage[6], rusage[8])
# string += "\n Disk I/O: %10d reads %10d writes " % \
# (rusage[9], rusage[10])
# string += "\n Network I/O: %10d in %10d out " % \
# (rusage[12], rusage[11])
# string += "\n Context swi: %10d vol %10d forced %10d sigs " % \
# (rusage[14], rusage[15], rusage[13])
elif self.arglist[0] in ["obj","objects"]:
caller.execute_cmd("@objects")
elif self.arglist[0] in ["scr","scripts"]:
caller.execute_cmd("@scripts")
elif self.arglist[0] in ["perm","perms","permissions"]:
caller.execute_cmd("@perm/list")
else:
string = "'%s' is not a valid option." % self.arglist[0]
# send info
caller.msg(string)
#TODO - expand @ps as we add irc/imc2 support.
class CmdPs(MuxCommand):
"""
@ps - list processes
Usage
@ps
Shows the process/event table.
"""
key = "@ps"
permissions = "cmd:ps"
help_category = "System"
def func(self):
"run the function."
string = "Processes Scheduled:\n-- PID [time/interval] [repeats] description --"
all_scripts = ScriptDB.objects.get_all_scripts()
repeat_scripts = [script for script in all_scripts if script.interval]
nrepeat_scripts = [script for script in all_scripts if script not in repeat_scripts]
string = "\nNon-timed scripts:"
for script in nrepeat_scripts:
string += "\n %i %s %s" % (script.id, script.key, script.desc)
string += "\n\nTimed scripts:"
for script in repeat_scripts:
repeats = "[inf] "
if script.repeats:
repeats = "[%i] " % script.repeats
string += "\n %i %s [%d/%d] %s%s" % (script.id, script.key,
script.time_until_next_repeat(),
script.interval,
repeats,
script.desc)
string += "\nTotals: %d interval scripts" % len(all_scripts)
self.caller.msg(string)
class CmdStats(MuxCommand):
"""
@stats - show object stats
Usage:
@stats
Shows stats about the database.
"""
key = "@stats"
aliases = "@db"
permissions = "cmd:stats"
help_category = "System"
def func(self):
"Show all stats"
# get counts for all typeclasses
stats_dict = ObjectDB.objects.object_totals()
# get all objects
stats_allobj = ObjectDB.objects.all().count()
# get all rooms
stats_room = ObjectDB.objects.filter(db_location=None).count()
# get all players
stats_users = User.objects.all().count()
string = "\n{wNumber of users:{n %i" % stats_users
string += "\n{wTotal number of objects:{n %i" % stats_allobj
string += "\n{wNumber of rooms (location==None):{n %i" % stats_room
string += "\n (Use @objects for detailed info)"
self.caller.msg(string)

View file

@ -1,23 +1,21 @@
"""
This file contains commands that require special permissions to
use. These are generally @-prefixed commands, but there are
exceptions.
System commands
"""
import traceback
import os, datetime
import django, twisted
from django.contrib.auth.models import User
from django.conf import settings
from src.server import sessionhandler
from src.players.models import PlayerDB
from src.scripts.models import ScriptDB
from src.objects.models import ObjectDB
from src.config.models import ConfigValue
from src.permissions.models import PermissionGroup
from src.utils import reloads, create, logger, utils
from src.permissions.permissions import has_perm, has_perm_string
from src.utils import reloads, create, logger, utils, gametime
from game.gamesrc.commands.default.muxcommand import MuxCommand
class CmdReload(MuxCommand):
"""
Reload the system
@ -54,7 +52,6 @@ class CmdReload(MuxCommand):
except AttributeError:
if attempt < max_attempts-1:
caller.msg(" Waiting for modules(s) to finish (%s) ..." % attempt)
pass
else:
string = " ... The module(s) took too long to reload, "
string += "\n so the remaining reloads where skipped."
@ -87,7 +84,7 @@ class CmdPy(MuxCommand):
key = "@py"
aliases = ["!"]
permissions = "cmd:py"
help_category = "Admin"
help_category = "System"
def func(self):
"hook function"
@ -152,7 +149,7 @@ class CmdListScripts(MuxCommand):
key = "@scripts"
aliases = "@listscripts"
permissions = "cmd:listscripts"
help_category = "Admin"
help_category = "System"
def format_script_list(self, scripts):
"Takes a list of scripts and formats the output."
@ -256,31 +253,6 @@ class CmdListScripts(MuxCommand):
caller.msg(string)
class CmdListCmdSets(MuxCommand):
"""
list command sets on an object
Usage:
@listcmdsets [obj]
This displays all cmdsets assigned
to a user. Defaults to yourself.
"""
key = "@listcmdsets"
permissions = "cmd:listcmdsets"
def func(self):
"list the cmdsets"
caller = self.caller
if self.arglist:
obj = caller.search(self.arglist[0])
if not obj:
return
else:
obj = caller
string = "%s" % obj.cmdset
caller.msg(string)
class CmdListObjects(MuxCommand):
"""
@ -296,7 +268,7 @@ class CmdListObjects(MuxCommand):
key = "@objects"
aliases = ["@listobjects", "@listobjs"]
permissions = "cmd:listobjects"
help_category = "Building"
help_category = "System"
def func(self):
"Implement the command"
@ -340,252 +312,7 @@ class CmdListObjects(MuxCommand):
string += srow
caller.msg(string)
class CmdBoot(MuxCommand):
"""
@boot
Usage
@boot[/switches] <player obj> [: reason]
Switches:
quiet - Silently boot without informing player
port - boot by port number instead of name or dbref
Boot a player object from the server. If a reason is
supplied it will be echoed to the user unless /quiet is set.
"""
key = "@boot"
permissions = "cmd:boot"
help_category = "Admin"
def func(self):
"Implementing the function"
caller = self.caller
args = self.args
if not args:
caller.msg("Usage: @boot[/switches] <player> [:reason]")
return
if ':' in args:
args, reason = [a.strip() for a in args.split(':', 1)]
boot_list = []
reason = ""
if 'port' in self.switches:
# Boot a particular port.
sessions = sessionhandler.get_session_list(True)
for sess in sessions:
# Find the session with the matching port number.
if sess.getClientAddress()[1] == int(args):
boot_list.append(sess)
break
else:
# Boot by player object
pobj = caller.search("*%s" % args, global_search=True)
if not pobj:
return
pobj = pobj
if pobj.has_player:
if not has_perm(caller, pobj, 'can_boot'):
string = "You don't have the permission to boot %s."
pobj.msg(string)
return
# we have a bootable object with a connected user
matches = sessionhandler.sessions_from_object(pobj)
for match in matches:
boot_list.append(match)
else:
caller.msg("That object has no connected player.")
return
if not boot_list:
caller.msg("No matches found.")
return
# Carry out the booting of the sessions in the boot list.
feedback = None
if not 'quiet' in self.switches:
feedback = "You have been disconnected by %s.\n" % caller.name
if reason:
feedback += "\nReason given: %s" % reason
for session in boot_list:
name = session.name
if feedback:
session.msg(feedback)
session.disconnectClient()
sessionhandler.remove_session(session)
caller.msg("You booted %s." % name)
class CmdDelPlayer(MuxCommand):
"""
delplayer - delete player from server
Usage:
@delplayer[/switch] <name> [: reason]
Switch:
delobj - also delete the player's currently
assigned in-game object.
Completely deletes a user from the server database,
making their nick and e-mail again available.
"""
key = "@delplayer"
permissions = "cmd:delplayer"
help_category = "Admin"
def func(self):
"Implements the command."
caller = self.caller
args = self.args
if not args:
caller.msg("Usage: @delplayer[/delobj] <player/user name or #id>")
return
reason = ""
if ':' in args:
args, reason = [arg.strip() for arg in args.split(':', 1)]
# We use player_search since we want to be sure to find also players
# that lack characters.
players = PlayerDB.objects.filter(db_key=args)
if not players:
try:
players = PlayerDB.objects.filter(id=args)
except ValueError:
pass
if not players:
# try to find a user instead of a Player
try:
user = User.objects.get(id=args)
except Exception:
try:
user = User.objects.get(username__iexact=args)
except Exception:
string = "No Player nor User found matching '%s'." % args
caller.msg(string)
return
try:
player = user.get_profile()
except Exception:
player = None
if not has_perm_string(caller, 'manage_players'):
string = "You don't have the permissions to delete this player."
caller.msg(string)
return
string = ""
name = user.username
user.delete()
if player:
name = player.name
player.delete()
string = "Player %s was deleted." % name
else:
string += "The User %s was deleted, but had no Player associated with it." % name
caller.msg(string)
return
elif len(players) > 1:
string = "There where multiple matches:"
for player in players:
string += "\n %s %s" % (player.id, player.key)
return
else:
# one single match
player = players[0]
user = player.user
character = player.character
if not has_perm(caller, player, 'manage_players'):
string = "You don't have the permissions to delete that player."
caller.msg(string)
return
uname = user.username
# boot the player then delete
if character and character.has_player:
caller.msg("Booting and informing player ...")
string = "\nYour account '%s' is being *permanently* deleted.\n" % uname
if reason:
string += " Reason given:\n '%s'" % reason
character.msg(string)
caller.execute_cmd("@boot %s" % uname)
player.delete()
user.delete()
caller.msg("Player %s was successfully deleted." % uname)
class CmdNewPassword(MuxCommand):
"""
@newpassword
Usage:
@newpassword <user obj> = <new password>
Set a player's password.
"""
key = "@newpassword"
permissions = "cmd:newpassword"
help_category = "Admin"
def func(self):
"Implement the function."
caller = self.caller
if not self.rhs:
caller.msg("Usage: @newpassword <user obj> = <new password>")
return
# the player search also matches 'me' etc.
character = caller.search("*%s" % self.lhs, global_search=True)
if not character:
return
player = character.player
player.user.set_password(self.rhs)
player.user.save()
caller.msg("%s - new password set to '%s'." % (player.name, self.rhs))
if character != caller:
player.msg("%s has changed your password to '%s'." % (caller.name, self.rhs))
class CmdHome(MuxCommand):
"""
home
Usage:
home
Teleport the player to their home.
"""
key = "home"
permissions = "cmd:home"
def func(self):
"Implement the command"
caller = self.caller
home = caller.home
if not home:
caller.msg("You have no home set.")
else:
caller.move_to(home)
caller.msg("There's no place like home ...")
class CmdService(MuxCommand):
"""
@ -605,7 +332,7 @@ class CmdService(MuxCommand):
key = "@service"
permissions = "cmd:service"
help_category = "Admin"
help_category = "System"
def func(self):
"Implement command"
@ -710,109 +437,250 @@ class CmdShutdown(MuxCommand):
# (importing it directly would restart it...)
session.server.shutdown()
class CmdPerm(MuxCommand):
class CmdVersion(MuxCommand):
"""
@perm - set permissions
@version - game version
Usage:
@perm[/switch] [<object>] = [<permission>]
@perm[/switch] [*<player>] = [<permission>]
@version
Switches:
del : delete the given permission from <object>.
list : list all permissions, or those set on <object>
Use * before the search string to add permissions to a player.
This command sets/clears individual permission strings on an object.
Use /list without any arguments to see all available permissions
or those defined on the <object>/<player> argument.
Display the game version info.
"""
key = "@perm"
aliases = "@setperm"
permissions = "cmd:perm"
help_category = "Admin"
key = "@version"
help_category = "System"
def func(self):
"Show the version"
version = utils.get_evennia_version()
string = "-"*50 +"\n\r"
string += " {cEvennia{n %s\n\r" % version
string += " (Django %s, " % (django.get_version())
string += " Twisted %s)\n\r" % (twisted.version.short())
string += "-"*50
self.caller.msg(string)
class CmdTime(MuxCommand):
"""
@time
Usage:
@time
Server local time.
"""
key = "@time"
aliases = "@uptime"
permissions = "cmd:time"
help_category = "System"
def func(self):
"Implement function"
"Show times."
caller = self.caller
switches = self.switches
lhs, rhs = self.lhs, self.rhs
string1 = "\nCurrent server uptime: \t"
string1 += "{w%s{n" % (utils.time_format(gametime.uptime(format=False), 2))
string2 = "\nTotal server running time: \t"
string2 += "{w%s{n" % (utils.time_format(gametime.runtime(format=False), 2))
string3 = "\nTotal in-game time (realtime x %g):\t" % (gametime.TIMEFACTOR)
string3 += "{w%s{n" % (utils.time_format(gametime.gametime(format=False), 2))
string4 = "\nServer time stamp: \t"
string4 += "{w%s{n" % (str(datetime.datetime.now()))
string5 = ""
if not utils.host_os_is('nt'):
# os.getloadavg() is not available on Windows.
loadavg = os.getloadavg()
string5 += "\nServer load (per minute): \t"
string5 += "{w%g%%{n" % (100 * loadavg[0])
string = "%s%s%s%s%s" % (string1, string2, string3, string4, string5)
self.caller.msg(string)
class CmdList(MuxCommand):
"""
@list - list info
Usage:
@list <option>
Options:
process - list processes
objects - list objects
scripts - list scripts
perms - list permission keys and groups
Shows game related information depending
on which argument is given.
"""
key = "@list"
permissions = "cmd:list"
help_category = "System"
def func(self):
"Show list."
caller = self.caller
if not self.args:
if "list" not in switches:
string = "Usage: @setperm[/switch] [object = permission]\n"
string +=" @setperm[/switch] [*player = permission]"
caller.msg(string)
return
else:
#just print all available permissions
string = "\nAll defined permission groups and keys (i.e. not locks):"
pgroups = list(PermissionGroup.objects.all())
pgroups.sort(lambda x,y: cmp(x.key, y.key)) # sort by group key
for pgroup in pgroups:
string += "\n\n - {w%s{n (%s):" % (pgroup.key, pgroup.desc)
string += "\n%s" % \
utils.fill(", ".join(sorted(pgroup.group_permissions)))
caller.msg(string)
return
# locate the object/player
obj = caller.search(lhs, global_search=True)
if not obj:
return
pstring = ""
if utils.inherits_from(obj, settings.BASE_PLAYER_TYPECLASS):
pstring = " Player "
if not rhs:
string = "Permission string on %s{w%s{n: " % (pstring, obj.key)
if not obj.permissions:
string += "<None>"
else:
string += ", ".join(obj.permissions)
if pstring and obj.is_superuser:
string += "\n(... But this player is a SUPERUSER! "
string += "All access checked are passed automatically.)"
elif obj.player and obj.player.is_superuser:
string += "\n(... But this object's player is a SUPERUSER! "
string += "All access checked are passed automatically.)"
caller.msg(string)
caller.msg("Usage: @list process|objects|scripts|perms")
return
# we supplied an argument on the form obj = perm
cstring = ""
tstring = ""
if 'del' in switches:
# delete the given permission(s) from object.
for perm in self.rhslist:
try:
index = obj.permissions.index(perm)
except ValueError:
cstring += "\nPermission '%s' was not defined on %s%s." % (perm, pstring, lhs)
continue
permissions = obj.permissions
del permissions[index]
obj.permissions = permissions
cstring += "\nPermission '%s' was removed from %s%s." % (perm, pstring, obj.name)
tstring += "\n%s revokes the permission '%s' from you." % (caller.name, perm)
string = ""
if self.arglist[0] in ["proc","process"]:
# display active processes
if utils.host_os_is('nt'):
string = "Feature not available on Windows."
else:
import resource
loadavg = os.getloadavg()
psize = resource.getpagesize()
rusage = resource.getrusage(resource.RUSAGE_SELF)
table = [["Server load (1 min):",
"Process ID:",
"Bytes per page:",
"Time used:",
"Integral memory:",
"Max res memory:",
"Page faults:",
"Disk I/O:",
"Network I/O",
"Context switching:"
],
["%g%%" % (100 * loadavg[0]),
"%10d" % os.getpid(),
"%10d " % psize,
"%10d" % rusage[0],
"%10d shared" % rusage[3],
"%10d pages" % rusage[2],
"%10d hard" % rusage[7],
"%10d reads" % rusage[9],
"%10d in" % rusage[12],
"%10d vol" % rusage[14]
],
["", "", "",
"(user: %g)" % rusage[1],
"%10d private" % rusage[4],
"%10d bytes" % (rusage[2] * psize),
"%10d soft" % rusage[6],
"%10d writes" % rusage[10],
"%10d out" % rusage[11],
"%10d forced" % rusage[15]
],
["", "", "", "",
"%10d stack" % rusage[5],
"",
"%10d swapouts" % rusage[8],
"", "",
"%10d sigs" % rusage[13]
]
]
stable = []
for col in table:
stable.append([str(val).strip() for val in col])
ftable = utils.format_table(stable, 5)
string = ""
for row in ftable:
string += "\n " + "{w%s{n" % row[0] + "".join(row[1:])
# string = "\n Server load (1 min) : %.2f " % loadavg[0]
# string += "\n Process ID: %10d" % os.getpid()
# string += "\n Bytes per page: %10d" % psize
# string += "\n Time used: %10d, user: %g" % (rusage[0], rusage[1])
# string += "\n Integral mem: %10d shared, %10d, private, %10d stack " % \
# (rusage[3], rusage[4], rusage[5])
# string += "\n Max res mem: %10d pages %10d bytes" % \
# (rusage[2],rusage[2] * psize)
# string += "\n Page faults: %10d hard %10d soft %10d swapouts " % \
# (rusage[7], rusage[6], rusage[8])
# string += "\n Disk I/O: %10d reads %10d writes " % \
# (rusage[9], rusage[10])
# string += "\n Network I/O: %10d in %10d out " % \
# (rusage[12], rusage[11])
# string += "\n Context swi: %10d vol %10d forced %10d sigs " % \
# (rusage[14], rusage[15], rusage[13])
elif self.arglist[0] in ["obj", "objects"]:
caller.execute_cmd("@objects")
elif self.arglist[0] in ["scr", "scripts"]:
caller.execute_cmd("@scripts")
elif self.arglist[0] in ["perm", "perms","permissions"]:
caller.execute_cmd("@perm/list")
else:
# As an extra check, we warn the user if they customize the
# permission string (which is okay, and is used by the lock system)
permissions = obj.permissions
for perm in self.rhslist:
string = "'%s' is not a valid option." % self.arglist[0]
# send info
caller.msg(string)
#TODO - expand @ps as we add irc/imc2 support.
class CmdPs(MuxCommand):
"""
@ps - list processes
Usage
@ps
Shows the process/event table.
"""
key = "@ps"
permissions = "cmd:ps"
help_category = "System"
def func(self):
"run the function."
string = "Processes Scheduled:\n-- PID [time/interval] [repeats] description --"
all_scripts = ScriptDB.objects.get_all_scripts()
repeat_scripts = [script for script in all_scripts if script.interval]
nrepeat_scripts = [script for script in all_scripts if script not in repeat_scripts]
string = "\nNon-timed scripts:"
for script in nrepeat_scripts:
string += "\n %i %s %s" % (script.id, script.key, script.desc)
string += "\n\nTimed scripts:"
for script in repeat_scripts:
repeats = "[inf] "
if script.repeats:
repeats = "[%i] " % script.repeats
string += "\n %i %s [%d/%d] %s%s" % (script.id, script.key,
script.time_until_next_repeat(),
script.interval,
repeats,
script.desc)
string += "\nTotals: %d interval scripts" % len(all_scripts)
self.caller.msg(string)
class CmdStats(MuxCommand):
"""
@stats - show object stats
Usage:
@stats
Shows stats about the database.
"""
key = "@stats"
aliases = "@db"
permissions = "cmd:stats"
help_category = "System"
def func(self):
"Show all stats"
# get counts for all typeclasses
stats_dict = ObjectDB.objects.object_totals()
# get all objects
stats_allobj = ObjectDB.objects.all().count()
# get all rooms
stats_room = ObjectDB.objects.filter(db_location=None).count()
# get all players
stats_users = User.objects.all().count()
string = "\n{wNumber of users:{n %i" % stats_users
string += "\n{wTotal number of objects:{n %i" % stats_allobj
string += "\n{wNumber of rooms (location==None):{n %i" % stats_room
string += "\n (Use @objects for detailed info)"
self.caller.msg(string)
if perm in permissions:
cstring += "\nPermission '%s' is already defined on %s%s." % (rhs, pstring, obj.name)
else:
permissions.append(perm)
obj.permissions = permissions
cstring += "\nPermission '%s' given to %s%s." % (rhs, pstring, obj.name)
tstring += "\n%s granted you the permission '%s'." % (caller.name, rhs)
caller.msg(cstring.strip())
if tstring:
obj.msg(tstring.strip())

View file

@ -28,7 +28,8 @@ class CmdTest(MuxCommand):
key = "@test"
aliases = ["@te", "@test all"]
#permissions = "cmd:Immortals" #Wizards
help_category = "Testing"
permissions = "cmd:Immortals" #Wizards
# the muxcommand class itself handles the display
# so we just defer to it by not adding any function.
@ -81,7 +82,7 @@ class CmdTestPerms(MuxCommand):
"""
key = "@testperm"
permissions = "cmd:Immortals Wizards"
help_category = "Testing"
def func(self):
"""
Run tests
@ -195,7 +196,7 @@ class TestCom(MuxCommand):
"""
key = "@testcom"
permissions = "cmd:Immortals Wizards"
help_category = "Testing"
def func(self):
"Run the test program"
caller = self.caller
@ -226,64 +227,3 @@ class TestCom(MuxCommand):
caller.msg("Usage: @testcom/create channel")
#TODO: make @debug more clever with arbitrary hooks?
class CmdDebug(MuxCommand):
"""
Debug game entities
Usage:
@debug[/switch] <path to code>
Switches:
obj - debug an object
script - debug a script
Examples:
@debug/script game.gamesrc.scripts.myscript.MyScript
@debug/script myscript.MyScript
@debug/obj examples.red_button.RedButton
This command helps when debugging the codes of objects and scripts.
It creates the given object and runs tests on its hooks. You can
supply both full paths (starting from the evennia base directory),
otherwise the system will start from the defined root directory
for scripts and objects respectively (defined in settings file).
"""
key = "@debug"
permissions = "cmd:debug"
help_category = "Building"
def func(self):
"Running the debug"
if not self.args or not self.switches:
self.caller.msg("Usage: @debug[/obj][/script] <path>")
return
path = self.args
if 'obj' in self.switches or 'object' in self.switches:
# analyze path. If it starts at the evennia basedir,
# (i.e. starts with game or src) we let it be, otherwise we
# add a base path as defined in settings
if path and not (path.startswith('src.') or
path.startswith('game.')):
path = "%s.%s" % (settings.BASE_TYPECLASS_PATH,
path)
# create and debug the object
self.caller.msg(debug.debug_object(path, self.caller))
self.caller.msg(debug.debug_object_scripts(path, self.caller))
elif 'script' in self.switches:
# analyze path. If it starts at the evennia basedir,
# (i.e. starts with game or src) we let it be, otherwise we
# add a base path as defined in settings
if path and not (path.startswith('src.') or
path.startswith('game.')):
path = "%s.%s" % (settings.BASE_SCRIPT_PATH,
path)
self.caller.msg(debug.debug_syntax_script(path))

View file

@ -0,0 +1,263 @@
"""
These commands typically are to do with building or modifying Objects.
"""
from django.conf import settings
from src.permissions.permissions import has_perm, has_perm_string
from src.objects.models import ObjectDB, ObjAttribute
from game.gamesrc.commands.default.muxcommand import MuxCommand
from src.utils import create, utils
##
## def cmd_chown(command):
## """
## @chown - change ownerships
## Usage:
## @chown <Object> = <NewOwner>
## Changes the ownership of an object. The new owner specified must be a
## player object.
## """
## caller = command.caller
## if not command.command_argument:
## caller.msg("Usage: @chown <object> = <newowner>")
## return
## eq_args = command.command_argument.split('=', 1)
## target_name = eq_args[0]
## owner_name = eq_args[1]
## if len(target_name) == 0:
## caller.msg("Change the ownership of what?")
## return
## if len(eq_args) > 1:
## target_obj = caller.search_for_object(target_name)
## # Use search_for_object to handle duplicate/nonexistant results.
## if not target_obj:
## return
## if not caller.controls_other(target_obj) and not caller.has_perm("objects.admin_ownership"):
## caller.msg(defines_global.NOCONTROL_MSG)
## return
## owner_obj = caller.search_for_object(owner_name)
## # Use search_for_object to handle duplicate/nonexistant results.
## if not owner_obj:
## return
## if not owner_obj.is_player():
## caller.msg("Only players may own objects.")
## return
## if target_obj.is_player():
## caller.msg("You may not change the ownership of player objects.")
## return
## target_obj.set_owner(owner_obj)
## caller.msg("%s now owns %s." % (owner_obj, target_obj))
## else:
## # We haven't provided a target.
## caller.msg("Who should be the new owner of the object?")
## return
## GLOBAL_CMD_TABLE.add_command("@chown", cmd_chown, priv_tuple=("objects.modify_attributes",
## "objects.admin_ownership"),
## help_category="Building" )
#NOT VALID IN NEW SYSTEM!
## def cmd_lock(command):
## """
## @lock - limit use of objects
## Usage:
## @lock[/switch] <obj> [:type] [= <key>[,key2,key3,...]]
## Switches:
## add - add a lock (default) from object
## del - remove a lock from object
## list - view all locks on object (default)
## type:
## DefaultLock - the default lock type (default)
## UseLock - prevents usage of objects' commands
## EnterLock - blocking objects from entering the object
## Locks an object for everyone except those matching the keys.
## The keys can be of the following types (and searched in this order):
## - a user #dbref (#2, #45 etc)
## - a Group name (Builder, Immortal etc, case sensitive)
## - a Permission string (genperms.get, etc)
## - a Function():return_value pair. (ex: alliance():Red). The
## function() is called on the locked object (if it exists) and
## if its return value matches the Key is passed. If no
## return_value is given, matches against True.
## - an Attribute:return_value pair (ex: key:yellow_key). The
## Attribute is the name of an attribute defined on the locked
## object. If this attribute has a value matching return_value,
## the lock is passed. If no return_value is given,
## attributes will be searched, requiring a True
## value.
## If no keys at all are given, the object is locked for everyone.
## When the lock blocks a user, you may customize which error is given by
## storing error messages in an attribute. For DefaultLocks, UseLocks and
## EnterLocks, these attributes are called lock_msg, use_lock_msg and
## enter_lock_msg respectively.
## [[lock_types]]
## Lock types:
## Name: Affects: Effect:
## -----------------------------------------------------------------------
## DefaultLock: Exits: controls who may traverse the exit to
## its destination.
## Rooms: controls whether the player sees a failure
## message after the room description when
## looking at the room.
## Players/Things: controls who may 'get' the object.
## UseLock: All but Exits: controls who may use commands defined on
## the locked object.
## EnterLock: Players/Things: controls who may enter/teleport into
## the object.
## VisibleLock: Players/Things: controls if the object is visible to
## someone using the look command.
## Fail messages echoed to the player are stored in the attributes 'lock_msg',
## 'use_lock_msg', 'enter_lock_msg' and 'visible_lock_msg' on the locked object
## in question. If no such message is stored, a default will be used (or none at
## all in some cases).
## """
## caller = command.caller
## arg = command.command_argument
## switches = command.command_switches
## if not arg:
## caller.msg("Usage: @lock[/switch] <obj> [:type] [= <key>[,key2,key3,...]]")
## return
## keys = ""
## #deal with all possible arguments.
## try:
## lside, keys = arg.split("=",1)
## except ValueError:
## lside = arg
## lside, keys = lside.strip(), keys.strip()
## try:
## obj_name, ltype = lside.split(":",1)
## except:
## obj_name = lside
## ltype = "DefaultLock"
## obj_name, ltype = obj_name.strip(), ltype.strip()
## if ltype not in ["DefaultLock","UseLock","EnterLock","VisibleLock"]:
## caller.msg("Lock type '%s' not recognized." % ltype)
## return
## obj = caller.search_for_object(obj_name)
## if not obj:
## return
## obj_locks = obj.LOCKS
## if "list" in switches:
## if not obj_locks:
## s = "There are no locks on %s." % obj.name
## else:
## s = "Locks on %s:" % obj.name
## s += obj_locks.show()
## caller.msg(s)
## return
## # we are trying to change things. Check permissions.
## if not caller.controls_other(obj):
## caller.msg(defines_global.NOCONTROL_MSG)
## return
## if "del" in switches:
## # clear a lock
## if obj_locks:
## if not obj_locks.has_type(ltype):
## caller.msg("No %s set on this object." % ltype)
## else:
## obj_locks.del_type(ltype)
## obj.LOCKS = obj_locks
## caller.msg("Cleared lock %s on %s." % (ltype, obj.name))
## else:
## caller.msg("No %s set on this object." % ltype)
## return
## else:
## #try to add a lock
## if not obj_locks:
## obj_locks = locks.Locks()
## if not keys:
## #add an impassable lock
## obj_locks.add_type(ltype, locks.Key())
## caller.msg("Added impassable '%s' lock to %s." % (ltype, obj.name))
## else:
## keys = [k.strip() for k in keys.split(",")]
## obj_keys, group_keys, perm_keys = [], [], []
## func_keys, attr_keys = [], []
## allgroups = [g.name for g in Group.objects.all()]
## allperms = ["%s.%s" % (p.content_type.app_label, p.codename)
## for p in Permission.objects.all()]
## for key in keys:
## #differentiate different type of keys
## if Object.objects.is_dbref(key):
## # this is an object key, like #2, #6 etc
## obj_keys.append(key)
## elif key in allgroups:
## # a group key
## group_keys.append(key)
## elif key in allperms:
## # a permission string
## perm_keys.append(key)
## elif '()' in key:
## # a function()[:returnvalue] tuple.
## # Check if we also request a return value
## funcname, rvalue = [k.strip() for k in key.split('()',1)]
## if not funcname:
## funcname = "lock_func"
## rvalue = rvalue.lstrip(':')
## if not rvalue:
## rvalue = True
## # pack for later adding.
## func_keys.append((funcname, rvalue))
## elif ':' in key:
## # an attribute[:returnvalue] tuple.
## attr_name, rvalue = [k.strip() for k in key.split(':',1)]
## # pack for later adding
## attr_keys.append((attr_name, rvalue))
## else:
## caller.msg("Key '%s' is not recognized as a valid dbref, group or permission." % key)
## return
## # Create actual key objects from the respective lists
## keys = []
## if obj_keys:
## keys.append(locks.ObjKey(obj_keys))
## if group_keys:
## keys.append(locks.GroupKey(group_keys))
## if perm_keys:
## keys.append(locks.PermKey(perm_keys))
## if func_keys:
## keys.append(locks.FuncKey(func_keys, obj.dbref))
## if attr_keys:
## keys.append(locks.AttrKey(attr_keys))
## #store the keys in the lock
## obj_locks.add_type(ltype, keys)
## kstring = " "
## for key in keys:
## kstring += " %s," % key
## kstring = kstring[:-1]
## caller.msg("Added lock '%s' to %s with keys%s." % (ltype, obj.name, kstring))
## obj.LOCKS = obj_locks
## GLOBAL_CMD_TABLE.add_command("@lock", cmd_lock, priv_tuple=("objects.create",), help_category="Building")

View file

@ -73,7 +73,7 @@ class Command(object):
# access to this command.
permissions = []
# used by the help system to group commands in lists.
help_category = "default"
help_category = "general"
# There is also the property 'obj'. This gets set by the system
# on the fly to tie this particular command to a certain in-game entity.
# self.obj should NOT be defined here since it will not be overwritten

View file

@ -736,3 +736,12 @@ class ObjectDB(TypedObject):
# Deferred import to avoid circular import errors.
from src.commands import cmdhandler
# from src.typeclasses import idmap
# class CachedObj(models.Model):
# key = models.CharField(max_length=255, null=True, blank=True)
# test = models.BooleanField(default=False)
# objects = idmap.CachingManager()
# def id(self):
# return id(self)

View file

@ -247,7 +247,7 @@ class ValidateScripts(Script):
def at_repeat(self):
"called every hour"
print "ValidateScripts run."
#print "ValidateScripts run."
ScriptDB.objects.validate()
class ValidateChannelHandler(Script):
@ -262,7 +262,7 @@ class ValidateChannelHandler(Script):
def at_repeat(self):
"called every hour+"
print "ValidateChannelHandler run."
#print "ValidateChannelHandler run."
channelhandler.CHANNELHANDLER.update()
class AddCmdSet(Script):
@ -308,9 +308,7 @@ class AddCmdSet(Script):
"""
This removes the cmdset when the script stops
"""
cmdset = self.db.cmdset
print "AddCmdSets: at_stop() for %s called." % self.obj
cmdset = self.db.cmdset
if cmdset:
if self.db.add_default:
self.obj.cmdset.delete_default()

View file

@ -424,6 +424,7 @@ INSTALLED_APPS = (
'src.permissions',
'game.web.news',
'game.web.website',)
# The user profile extends the User object with more functionality;
# This should usually not be changed.
AUTH_PROFILE_MODULE = "players.PlayerDB"
@ -439,3 +440,9 @@ try:
INSTALLED_APPS = INSTALLED_APPS + ('django_extensions',)
except ImportError:
pass
# South handles automatic database scheme migrations when evennia updates
#try:
# import south
# INSTALLED_APPS = INSTALLED_APPS + ('south',)
#except ImportError:
# pass

View file

@ -4,6 +4,8 @@ abstract models in dbobjects.py (and which are thus shared by
all Attributes and TypedObjects).
"""
from django.db import models
from src.utils import idmapper
#from src.typeclasses import idmap
# Managers
@ -76,7 +78,10 @@ def returns_typeclass(method):
return None
return func
class TypedObjectManager(models.Manager):
#class TypedObjectManager(idmap.CachingManager):
#class TypedObjectManager(models.Manager):
class TypedObjectManager(idmapper.manager.SharedMemoryManager):
"""
Common ObjectManager for all dbobjects.
"""

View file

@ -958,8 +958,3 @@ class TypedObject(SharedMemoryModel):
"Stop accidental deletion."
raise Exception("Cannot delete the ndb object!")
ndb = property(ndb_get, ndb_set, ndb_del)

View file

@ -1,9 +1,11 @@
from weakref import WeakValueDictionary
from weakref import WeakValueDictionary, ref
from django.db.models.base import Model, ModelBase
from manager import SharedMemoryManager
TCACHE = {}
class SharedMemoryModelBase(ModelBase):
def __new__(cls, name, bases, attrs):
super_new = super(ModelBase, cls).__new__
@ -37,7 +39,7 @@ class SharedMemoryModelBase(ModelBase):
return cached_instance
def _prepare(cls):
cls.__instance_cache__ = WeakValueDictionary()
cls.__instance_cache__ = {} #WeakValueDictionary()
super(SharedMemoryModelBase, cls)._prepare()
@ -91,7 +93,11 @@ class SharedMemoryModel(Model):
Method to store an instance in the cache.
"""
if instance._get_pk_val() is not None:
cls.__instance_cache__[instance._get_pk_val()] = instance
cls.__instance_cache__[instance._get_pk_val()] = instance
#key = "%s-%s" % (cls, instance.pk)
#TCACHE[key] = instance
#print "cached: %s (%s: %s) (total cached: %s)" % (instance, cls.__name__, len(cls.__instance_cache__), len(TCACHE))
cache_instance = classmethod(cache_instance)
def _flush_cached_by_key(cls, key):
@ -104,6 +110,10 @@ class SharedMemoryModel(Model):
since this is most likely called from delete(), and we want to make sure we don't cache dead objects.
"""
cls._flush_cached_by_key(instance._get_pk_val())
#key = "%s-%s" % (cls, instance.pk)
#del TCACHE[key]
#print "uncached: %s (%s: %s) (total cached: %s)" % (instance, cls.__name__, len(cls.__instance_cache__), len(TCACHE))
flush_cached_instance = classmethod(flush_cached_instance)
def save(self, *args, **kwargs):
@ -126,4 +136,4 @@ pre_delete.connect(flush_singleton_cache)
# def update_singleton_cache(sender, instance, **kwargs):
# if isinstance(instance.__class__, SharedMemoryModel):
# instance.__class__.cache_instance(instance)
# post_save.connect(flush_singleton_cache)
# post_save.connect(flush_singleton_cache)