mirror of
https://github.com/evennia/evennia.git
synced 2026-03-17 05:16:31 +01:00
Added gamesrc/utils.py as a convenient shorthand for often-used methods from the engine
Added a @deluser command and gave it and @boot an option to give a reason for booting/deleting a player Fixed a bug in @dig that confused exit directions in text Small bug fixes /Griatch
This commit is contained in:
parent
81bec61d7d
commit
df29defbcd
8 changed files with 239 additions and 28 deletions
|
|
@ -11,6 +11,7 @@ as 'game.gamesrc.commands.examples.misc_tests'.
|
|||
None of these commands are auto-added to the help database
|
||||
(they have no docstrings) in order to help make it clean.
|
||||
"""
|
||||
|
||||
from src.cmdtable import GLOBAL_CMD_TABLE
|
||||
|
||||
#------------------------------------------------------------
|
||||
|
|
|
|||
123
game/gamesrc/utils.py
Normal file
123
game/gamesrc/utils.py
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
"""
|
||||
This module offers a collection of useful general functions from the
|
||||
game engine to make things easier to find.
|
||||
Just import game.gamesrc.utils and refer to the globals defined herein.
|
||||
|
||||
Note that this is not intended as a comprehensive collection, merely
|
||||
a convenient place to refer to for the methods we have found to be
|
||||
often used. You will still have to refer to the modules
|
||||
in evennia/src for more specialized operations.
|
||||
|
||||
You will also want to be well familiar with all the facilities each
|
||||
object offers. The object model is defined in src/objects/models.py.
|
||||
"""
|
||||
#------------------------------------------------------------
|
||||
# imports
|
||||
#------------------------------------------------------------
|
||||
|
||||
from django.conf import settings as in_settings
|
||||
from src import logger
|
||||
from src import scheduler as in_scheduler
|
||||
from src.objects.models import Object
|
||||
from src import defines_global
|
||||
from src.cmdtable import GLOBAL_CMD_TABLE as in_GLOBAL_CMD_TABLE
|
||||
from src.statetable import GLOBAL_STATE_TABLE as in_GLOBAL_STATE_TABLE
|
||||
from src.events import IntervalEvent as in_IntervalEvent
|
||||
|
||||
#------------------------------------------------------------
|
||||
# Import targets
|
||||
#------------------------------------------------------------
|
||||
|
||||
settings = in_settings
|
||||
GLOBAL_CMD_TABLE = in_GLOBAL_CMD_TABLE
|
||||
GLOBAL_STATE_TABLE = in_GLOBAL_STATE_TABLE
|
||||
|
||||
# Events
|
||||
scheduler = in_scheduler
|
||||
IntervalEvent = in_IntervalEvent
|
||||
|
||||
|
||||
#------------------------------------------------------------
|
||||
# Log to file/stdio
|
||||
# log_xxxmsg(msg)
|
||||
#------------------------------------------------------------
|
||||
|
||||
log_errmsg = logger.log_errmsg
|
||||
log_warnmsg = logger.log_warnmsg
|
||||
log_infomsg = logger.log_infomsg
|
||||
|
||||
|
||||
#------------------------------------------------------------
|
||||
# Search methods
|
||||
#------------------------------------------------------------
|
||||
|
||||
# NOTE: All objects also has search_for_object() defined
|
||||
# directly on themselves, which is a convenient entryway into a
|
||||
# local and global search with automatic feedback to the
|
||||
# calling player.
|
||||
|
||||
# def get_object_from_dbref(dbref):
|
||||
# Returns an object when given a dbref.
|
||||
get_object_from_dbref = Object.objects.get_object_from_dbref
|
||||
|
||||
# def dbref_search(dbref_string, limit_types=False):
|
||||
# Searches for a given dbref.
|
||||
dbref_search = Object.objects.dbref_search
|
||||
|
||||
# def global_object_name_search(ostring, exact_match=True, limit_types=[]):
|
||||
# Searches through all objects for a name match.
|
||||
global_object_name_search = Object.objects.global_object_name_search
|
||||
|
||||
# def global_object_script_parent_search(script_parent):
|
||||
# Searches through all objects returning those which has a certain script parent.
|
||||
global_object_script_parent_search = Object.objects.global_object_script_parent_search
|
||||
|
||||
# def player_name_search(searcher, ostring):
|
||||
# Search players by name.
|
||||
player_name_search = Object.objects.player_name_search
|
||||
|
||||
# def local_and_global_search(searcher, ostring, search_contents=True,
|
||||
# search_location=True, dbref_only=False,
|
||||
# limit_types=False, attribute_name=None):
|
||||
# Searches an object's location then globally for a dbref or name match.
|
||||
local_and_global_search = Object.objects.local_and_global_search
|
||||
|
||||
|
||||
#------------------------------------------------------------
|
||||
# Creation commands
|
||||
#------------------------------------------------------------
|
||||
|
||||
# def create_object(name, otype, location, owner, home=None, script_parent=None):
|
||||
# Create a new object
|
||||
create_object = Object.objects.create_object
|
||||
|
||||
# def copy_object(original_object, new_name=None, new_location=None, reset=False):
|
||||
# Create and return a new object as a copy of the source object. All will
|
||||
# be identical to the original except for the dbref. Does not allow the
|
||||
# copying of Player objects.
|
||||
copy_object = Object.objects.copy_object
|
||||
|
||||
|
||||
#------------------------------------------------------------
|
||||
# Validation
|
||||
#------------------------------------------------------------
|
||||
|
||||
# NOTE: The easiest way to check if an object
|
||||
# is of a particular type is to use each object's
|
||||
# is_X() function, like is_superuser(), is_thing(),
|
||||
# is_room(), is_player(), is_exit() and get_type().
|
||||
|
||||
OTYPE_NOTHING = defines_global.OTYPE_NOTHING
|
||||
OTYPE_PLAYER = defines_global.OTYPE_PLAYER
|
||||
OTYPE_ROOM = defines_global.OTYPE_ROOM
|
||||
OTYPE_THING = defines_global.OTYPE_THING
|
||||
OTYPE_EXIT = defines_global.OTYPE_EXIT
|
||||
OTYPE_GOING = defines_global.OTYPE_GOING
|
||||
TYPE_GARBAGE = defines_global.OTYPE_GARBAGE
|
||||
|
||||
NOPERMS_MSG = defines_global.NOPERMS_MSG
|
||||
NOCONTROL_MSG = defines_global.NOCONTROL_MSG
|
||||
|
||||
# def is_dbref(self, dbstring, require_pound=True):
|
||||
# Is the input a well-formed dbref number?
|
||||
is_dbref = Object.objects.is_dbref
|
||||
|
|
@ -1085,7 +1085,7 @@ def cmd_dig(command):
|
|||
else:
|
||||
ptext += " of default type (parent '%s' failed!)" % script_parent
|
||||
source_object.emit_to("Created exit%s back from %s to %s named '%s'." % \
|
||||
(ptext, destination, location, new_object))
|
||||
(ptext, location, destination, new_object))
|
||||
|
||||
if new_room and 'teleport' in switches:
|
||||
source_object.move_to(new_room)
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ This file contains commands that require special permissions to use. These
|
|||
are generally @-prefixed commands, but there are exceptions.
|
||||
"""
|
||||
|
||||
from django.contrib.auth.models import Permission, Group
|
||||
from django.contrib.auth.models import Permission, Group, User
|
||||
from django.conf import settings
|
||||
from src.objects.models import Object
|
||||
from src import session_mgr
|
||||
|
|
@ -79,9 +79,14 @@ def cmd_boot(command):
|
|||
@boot
|
||||
|
||||
Usage
|
||||
@boot <player obj>
|
||||
@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.
|
||||
Boot a player object from the server. If a reason is
|
||||
supplied it will be echoed to the user unless /quiet is set.
|
||||
"""
|
||||
source_object = command.source_object
|
||||
switch_quiet = False
|
||||
|
|
@ -96,23 +101,27 @@ def cmd_boot(command):
|
|||
switch_port = True
|
||||
|
||||
if not command.command_argument:
|
||||
source_object.emit_to("Who would you like to boot?")
|
||||
source_object.emit_to("Usage: @boot[/switches] <player> [:reason]")
|
||||
return
|
||||
else:
|
||||
arg = command.command_argument
|
||||
reason = ""
|
||||
if ':' in arg:
|
||||
arg, reason = [a.strip() for a in arg.split(':',1)]
|
||||
|
||||
boot_list = []
|
||||
if switch_port:
|
||||
# Boot a particular port.
|
||||
sessions = session_mgr.get_session_list(True)
|
||||
for sess in sessions:
|
||||
# Find the session with the matching port number.
|
||||
if sess.getClientAddress()[1] == int(command.command_argument):
|
||||
if sess.getClientAddress()[1] == int(arg):
|
||||
boot_list.append(sess)
|
||||
# Match found, kill the loop and continue with booting.
|
||||
break
|
||||
else:
|
||||
# Grab the objects that match
|
||||
objs = Object.objects.local_and_global_search(source_object,
|
||||
command.command_argument)
|
||||
objs = Object.objects.local_and_global_search(source_object, arg)
|
||||
|
||||
if not objs:
|
||||
source_object.emit_to("No name or dbref match found for booting.")
|
||||
|
|
@ -145,7 +154,10 @@ def cmd_boot(command):
|
|||
# Carry out the booting of the sessions in the boot list.
|
||||
for boot in boot_list:
|
||||
if not switch_quiet:
|
||||
boot.msg("You have been disconnected by %s." % (source_object.name))
|
||||
msg = "You have been disconnected by %s." % (source_object.name)
|
||||
if reason:
|
||||
msg += "\n Reason given:\n '%s'" % reason
|
||||
boot.msg(msg)
|
||||
boot.disconnectClient()
|
||||
session_mgr.remove_session(boot)
|
||||
return
|
||||
|
|
@ -153,6 +165,54 @@ GLOBAL_CMD_TABLE.add_command("@boot", cmd_boot,
|
|||
priv_tuple=("genperms.manage_players",),
|
||||
help_category="Admin")
|
||||
|
||||
|
||||
def cmd_delplayer(command):
|
||||
"""
|
||||
delplayer - delete player from server
|
||||
|
||||
Usage:
|
||||
@delplayer <name> [: reason]
|
||||
|
||||
Completely deletes a user from the server database,
|
||||
making their nick and e-mail again available.
|
||||
"""
|
||||
source_object = command.source_object
|
||||
arg = command.command_argument
|
||||
if not arg:
|
||||
source_object.emit_to("Usage: @delplayer <player name or #id>")
|
||||
return
|
||||
|
||||
reason = ""
|
||||
if ':' in arg:
|
||||
arg, reason = [a.strip() for a in arg.split(':',1)]
|
||||
|
||||
objs = Object.objects.local_and_global_search(source_object, arg)
|
||||
if not objs:
|
||||
source_object.emit_to("No player object matches found for '%s'." % arg)
|
||||
return
|
||||
pobj = objs[0]
|
||||
if not source_object.controls_other(pobj):
|
||||
if pobj.is_superuser():
|
||||
source_object.emit_to("You cannot delete a Superuser.")
|
||||
return
|
||||
else:
|
||||
source_object.emit_to("You do not have permission to delete that player.")
|
||||
return
|
||||
# boot the player then delete
|
||||
source_object.emit_to("Booting and informing player if currently online ...")
|
||||
name = pobj.get_name()
|
||||
msg = "\nYour account '%s' is being *permanently* deleted.\n" % name
|
||||
if reason:
|
||||
msg += " Reason given:\n '%s'" % reason
|
||||
pobj.emit_to(msg)
|
||||
source_object.execute_cmd("@boot %s" % arg)
|
||||
pobj.delete()
|
||||
source_object.emit_to("Player %s was successfully deleted." % name)
|
||||
GLOBAL_CMD_TABLE.add_command("@delplayer", cmd_delplayer,
|
||||
priv_tuple=("genperms.manage_players",),
|
||||
help_category="Admin")
|
||||
|
||||
|
||||
def cmd_newpassword(command):
|
||||
"""
|
||||
@newpassword
|
||||
|
|
|
|||
|
|
@ -131,7 +131,8 @@ def plr_set_channel_listening(session, alias, listening):
|
|||
alias: (str) The channel alias.
|
||||
listening: (bool) A True or False value to determine listening status.
|
||||
"""
|
||||
membership = session.pobject.channel_membership_set.get(user_alias=alias)
|
||||
|
||||
membership = session.get_pobject().channel_membership_set.get(user_alias=alias)
|
||||
membership.is_listening = listening
|
||||
membership.save()
|
||||
plr_get_cdict(session).get(alias)[1] = listening
|
||||
|
|
|
|||
|
|
@ -64,8 +64,10 @@ class ObjectManager(models.Manager):
|
|||
"""
|
||||
Returns an object when given a dbref.
|
||||
"""
|
||||
if len(dbref)>1 and dbref[0]=="#":
|
||||
dbref = dbref[1:]
|
||||
if type(dbref) == type(str()):
|
||||
if len(dbref)>1 and dbref[0]=="#":
|
||||
dbref = dbref[1:]
|
||||
dbref = "%s" % dbref
|
||||
try:
|
||||
return self.get(id=dbref)
|
||||
except self.model.DoesNotExist:
|
||||
|
|
|
|||
|
|
@ -573,6 +573,11 @@ class Object(models.Model):
|
|||
# Delete the associated player object permanently.
|
||||
uobj = User.objects.filter(id=self.id)
|
||||
if len(uobj) > 0:
|
||||
# clean out channel memberships
|
||||
memberships = self.channel_membership_set.filter(listener=self)
|
||||
for membership in memberships:
|
||||
membership.delete()
|
||||
# delete user
|
||||
uobj[0].delete()
|
||||
|
||||
# Set the object to type GARBAGE.
|
||||
|
|
@ -1045,16 +1050,27 @@ class Object(models.Model):
|
|||
self.emit_to(lock_desc)
|
||||
else:
|
||||
self.emit_to("That destination is blocked from you.")
|
||||
return
|
||||
|
||||
# Before the move, call eventual pre-commands.
|
||||
if self.scriptlink.at_before_move(target) != None:
|
||||
return
|
||||
return
|
||||
|
||||
source_location = self.location
|
||||
owner = self.get_owner()
|
||||
errtxt = "There was a bug in a move_to() scriptlink. Contact an admin.\n"
|
||||
|
||||
# Before the move, call eventual pre-commands.
|
||||
try:
|
||||
if self.scriptlink.at_before_move(target) != None:
|
||||
return
|
||||
except:
|
||||
owner.emit_to("%s%s" % (errtxt, traceback.print_exc()))
|
||||
return
|
||||
|
||||
if not quiet:
|
||||
#tell the old room we are leaving
|
||||
self.scriptlink.announce_move_from(target)
|
||||
source_location = self.location
|
||||
try:
|
||||
self.scriptlink.announce_move_from(target)
|
||||
except:
|
||||
owner.emit_to("%s%s" % (errtxt, traceback.print_exc()))
|
||||
|
||||
|
||||
# Perform move
|
||||
self.location = target
|
||||
|
|
@ -1062,15 +1078,23 @@ class Object(models.Model):
|
|||
|
||||
if not quiet:
|
||||
# Tell the new room we are there.
|
||||
self.scriptlink.announce_move_to(source_location)
|
||||
|
||||
try:
|
||||
self.scriptlink.announce_move_to(source_location)
|
||||
except:
|
||||
owner.emit_to("%s%s" % (errtxt, traceback.print_exc()))
|
||||
|
||||
# Execute eventual extra commands on this object after moving it
|
||||
self.scriptlink.at_after_move()
|
||||
|
||||
try:
|
||||
self.scriptlink.at_after_move(source_location)
|
||||
except:
|
||||
owner.emit_to("%s%s" % (errtxt, traceback.print_exc()))
|
||||
# Perform eventual extra commands on the receiving location
|
||||
target.scriptlink.at_obj_receive(self)
|
||||
|
||||
if force_look and self.is_player():
|
||||
try:
|
||||
target.scriptlink.at_obj_receive(self, source_location)
|
||||
except:
|
||||
owner.emit_to("%s%s" % (errtxt, traceback.print_exc()))
|
||||
|
||||
if force_look and self.is_player():
|
||||
self.execute_cmd('look')
|
||||
|
||||
def dbref_match(self, oname):
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ class EvenniaBasicObject(object):
|
|||
if loc.is_player():
|
||||
loc.emit_to("%s is now in your inventory." % obj.get_name())
|
||||
|
||||
def at_after_move(self):
|
||||
def at_after_move(self, old_loc=None):
|
||||
"""
|
||||
This hook is called just after the object was successfully moved.
|
||||
No return values.
|
||||
|
|
@ -127,7 +127,7 @@ class EvenniaBasicObject(object):
|
|||
#print "SCRIPT TEST: %s dropped %s." % (pobject, self.scripted_obj)
|
||||
pass
|
||||
|
||||
def at_obj_receive(self, object=None):
|
||||
def at_obj_receive(self, object=None, old_loc=None):
|
||||
"""
|
||||
Called whenever an object is added to the contents of this object.
|
||||
"""
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue