Looking through our command code after a long hiatus, I realized that it was pretty much awful. So here's part 1 of the command interpreter overhaul.

- The command handler has been drastically simplified. We were doing way too much processing in the handler that should have been done in the individual command functions themselves.
- The 'cdat' dict we were previously passing around has been replaced with a Command object that has useful methods for performing some of the parsing command functions will probably want to do from time to time.
- All commands were updated to use the new Command object, tested, and cleaned up in general.
- A lot of formatting was cleaned up.
- A lot of previously un-found bugs and limitations were fixed.
- The 'page' command has been broken out into its own file, since it's going to have a number of functions that would otherwise clutter commands/general.py.

Expect a commit (probably later today) that will clean up the second half of cmdhandler.py.
This commit is contained in:
Greg Taylor 2008-12-14 20:21:02 +00:00
parent 37d66093cc
commit d58f4eb517
16 changed files with 818 additions and 698 deletions

View file

@ -11,32 +11,26 @@ from src import defines_global
from src import ansi
from src.util import functions_general
def cmd_addcom(cdat):
def cmd_addcom(command):
"""
addcom
Adds an alias for a channel.
addcom foo=Bar
"""
session = cdat['session']
session = command.session
pobject = session.get_pobject()
server = cdat['server']
args = cdat['uinput']['splitted'][1:]
server = command.server
eq_args = command.command_argument.split('=', 1)
if len(args) == 0:
if not command.command_argument:
session.msg("You need to specify a channel alias and name.")
return
eq_args = args[0].split('=')
if len(eq_args) < 2:
session.msg("You need to specify a channel name.")
return
chan_alias = eq_args[0]
chan_name = eq_args[1]
if len(chan_name) == 0:
if len(eq_args) < 2 or len(chan_name) == 0:
session.msg("You need to specify a channel name.")
return
@ -59,40 +53,38 @@ def cmd_addcom(cdat):
else:
session.msg("Could not find channel %s." % (chan_name,))
def cmd_delcom(cdat):
def cmd_delcom(command):
"""
delcom
Removes the specified alias to a channel. If this is the last alias,
the user is effectively removed from the channel.
"""
session = cdat['session']
session = command.session
pobject = session.get_pobject()
uinput= cdat['uinput']['splitted']
chan_alias = ' '.join(uinput[1:])
if len(chan_alias) == 0:
if len(command.command_argument) == 0:
session.msg("You must specify a channel alias.")
return
if chan_alias not in session.channels_subscribed:
if command.command_argument not in session.channels_subscribed:
session.msg("You are not on that channel.")
return
chan_name = session.channels_subscribed[chan_alias][0]
chan_name = session.channels_subscribed[command.command_argument][0]
session.msg("You have left %s." % (chan_name,))
src.comsys.plr_del_channel(session, chan_alias)
src.comsys.plr_del_channel(session, command.command_argument)
# Announce the user's leaving.
leave_msg = "[%s] %s has left the channel." % \
(chan_name, pobject.get_name(show_dbref=False))
src.comsys.send_cmessage(chan_name, leave_msg)
def cmd_comlist(cdat):
def cmd_comlist(command):
"""
Lists the channels a user is subscribed to.
"""
session = cdat['session']
session = command.session
session.msg("Alias Channel Status")
for chan in session.channels_subscribed:
@ -105,46 +97,48 @@ def cmd_comlist(cdat):
(chan, session.channels_subscribed[chan][0], chan_on))
session.msg("-- End of comlist --")
def cmd_allcom(cdat):
def cmd_allcom(command):
"""
allcom
Allows the user to universally turn off or on all channels they are on,
as well as perform a "who" for all channels they are on.
"""
# TODO: Implement cmd_allcom
pass
def cmd_clearcom(cdat):
def cmd_clearcom(command):
"""
clearcom
Effectively runs delcom on all channels the user is on. It will remove their aliases,
remove them from the channel, and clear any titles they have set.
"""
# TODO: Implement cmd_clearcom
pass
def cmd_clist(cdat):
def cmd_clist(command):
"""
@clist
Lists all available channels on the game.
"""
session = cdat['session']
session = command.session
session.msg("** Channel Owner Description")
for chan in src.comsys.get_all_channels():
session.msg("%s%s %-13.13s %-15.15s %-45.45s" %
('-', '-', chan.get_name(), chan.get_owner().get_name(), 'No Description'))
('-', '-', chan.get_name(), chan.get_owner().get_name(),
'No Description'))
session.msg("-- End of Channel List --")
def cmd_cdestroy(cdat):
def cmd_cdestroy(command):
"""
@cdestroy
Destroys a channel.
"""
session = cdat['session']
uinput= cdat['uinput']['splitted']
cname = ' '.join(uinput[1:])
session = command.session
cname = command.command_argument
if cname == '':
session.msg("You must supply a name!")
@ -158,56 +152,56 @@ def cmd_cdestroy(cdat):
session.msg("Channel %s destroyed." % (name_matches[0],))
name_matches.delete()
def cmd_cset(cdat):
def cmd_cset(command):
"""
@cset
Sets various flags on a channel.
"""
# TODO: Implement cmd_cset
pass
def cmd_ccharge(cdat):
def cmd_ccharge(command):
"""
@ccharge
Sets the cost to transmit over a channel. Default is free.
"""
# TODO: Implement cmd_ccharge
pass
def cmd_cboot(cdat):
def cmd_cboot(command):
"""
@cboot
Kicks a player or object from the channel.
"""
# TODO: Implement cmd_cboot
pass
def cmd_cemit(cdat):
def cmd_cemit(command):
"""
@cemit
@cemit/noheader <message>
@cemit/sendername <message>
@cemit <channel>=<message>
@cemit/noheader <channel>=<message>
@cemit/sendername <channel>=<message>
Allows the user to send a message over a channel as long as
they own or control it. It does not show the user's name unless they
provide the /sendername switch.
"""
session = cdat['session']
session = command.session
pobject = session.get_pobject()
server = cdat['server']
args = cdat['uinput']['splitted'][1:]
switches = cdat['uinput']['root_chunk'][1:]
server = command.server
if len(args) == 0:
if command.command_argument == 0:
session.msg("Channel emit what?")
return
# Combine the arguments into one string, split it by equal signs into
# channel (entry 0 in the list), and message (entry 1 and above).
eq_args = ' '.join(args).split('=')
eq_args = command.command_argument.split('=', 1)
cname = eq_args[0]
cmessage = ' '.join(eq_args[1:])
cmessage = eq_args[1]
if len(eq_args) != 2:
session.msg("You must provide a channel name and a message to emit.")
return
@ -219,36 +213,37 @@ def cmd_cemit(cdat):
return
name_matches = src.comsys.cname_search(cname, exact=True)
try:
# Safety first, kids!
if name_matches:
cname_parsed = name_matches[0].get_name()
except:
else:
session.msg("Could not find channel %s." % (cname,))
return
if "noheader" in switches:
if "noheader" in command.command_switches:
if not pobject.user_has_perm("objects.emit_commchannel"):
session.msg(defines_global.NOPERMS_MSG)
return
final_cmessage = cmessage
else:
if "sendername" in switches:
if not src.comsys.plr_has_channel(session, cname_parsed, return_muted=False):
if "sendername" in command.command_switches:
if not src.comsys.plr_has_channel(session, cname_parsed,
return_muted=False):
session.msg("You must be on %s to do that." % (cname_parsed,))
return
final_cmessage = "[%s] %s: %s" % (cname_parsed, pobject.get_name(show_dbref=False), cmessage)
final_cmessage = "[%s] %s: %s" % (cname_parsed,
pobject.get_name(show_dbref=False),
cmessage)
else:
if not pobject.user_has_perm("objects.emit_commchannel"):
session.msg(defines_global.NOPERMS_MSG)
return
final_cmessage = "[%s] %s" % (cname_parsed, cmessage)
if not "quiet" in switches:
if not "quiet" in command.command_switches:
session.msg("Sent - %s" % (name_matches[0],))
src.comsys.send_cmessage(cname_parsed, final_cmessage)
def cmd_cwho(cdat):
def cmd_cwho(command):
"""
@cwho
@ -256,22 +251,24 @@ def cmd_cwho(cdat):
Adding /all after the channel name will list disconnected players
as well.
"""
# TODO: Implement cmd_cwho
pass
def cmd_ccreate(cdat):
def cmd_ccreate(command):
"""
@ccreate
Creates a new channel with the invoker being the default owner.
"""
session = cdat['session']
# TODO: Implement cmd_ccreate
session = command.session
pobject = session.get_pobject()
uinput= cdat['uinput']['splitted']
cname = ' '.join(uinput[1:])
if cname == '':
if not command.command_argument:
session.msg("You must supply a name!")
return
cname = command.command_argument
name_matches = src.comsys.cname_search(cname, exact=True)
@ -279,14 +276,14 @@ def cmd_ccreate(cdat):
session.msg("A channel with that name already exists.")
else:
# Create and set the object up.
cdat = {"name": cname, "owner": pobject}
new_chan = src.comsys.create_channel(cdat)
new_chan = src.comsys.create_channel(cname, pobject)
session.msg("Channel %s created." % (new_chan.get_name(),))
def cmd_cchown(cdat):
def cmd_cchown(command):
"""
@cchown
Changes the owner of a channel.
"""
# TODO: Implement cmd_cchown.
pass

View file

@ -14,18 +14,22 @@ from src import session_mgr
from src import ansi
from src.util import functions_general
def cmd_password(cdat):
def cmd_password(command):
"""
Changes your own password.
@newpass <Oldpass>=<Newpass>
@password <Oldpass>=<Newpass>
"""
session = cdat['session']
session = command.session
pobject = session.get_pobject()
args = cdat['uinput']['splitted'][1:]
eq_args = ' '.join(args).split('=')
oldpass = ''.join(eq_args[0])
newpass = ''.join(eq_args[1:])
eq_args = command.command_argument.split('=', 1)
if len(eq_args) != 2:
session.msg("Incorrect number of arguments.")
return
oldpass = eq_args[0]
newpass = eq_args[1]
if len(oldpass) == 0:
session.msg("You must provide your old password.")
@ -44,47 +48,52 @@ def cmd_password(cdat):
uaccount.save()
session.msg("Password changed.")
def cmd_emit(cdat):
def cmd_pemit(command):
"""
Emits something to a player.
"""
# TODO: Implement cmd_pemit
def cmd_emit(command):
"""
Emits something to your location.
"""
session = cdat['session']
session = command.session
pobject = session.get_pobject()
uinput= cdat['uinput']['splitted']
message = ' '.join(uinput[1:])
message = command.command_argument
if message == '':
session.msg("Emit what?")
else:
if message:
pobject.get_location().emit_to_contents(message)
else:
session.msg("Emit what?")
def cmd_wall(cdat):
def cmd_wall(command):
"""
Announces a message to all connected players.
"""
session = cdat['session']
wallstring = ' '.join(cdat['uinput']['splitted'][1:])
session = command.session
wallstring = command.command_argument
pobject = session.get_pobject()
if wallstring == '':
if not wallstring:
session.msg("Announce what?")
return
message = "%s shouts \"%s\"" % (session.get_pobject().get_name(show_dbref=False), wallstring)
session_mgr.announce_all(message)
def cmd_idle(cdat):
def cmd_idle(command):
"""
Returns nothing, this lets the player set an idle timer without spamming
his screen.
"""
pass
def cmd_inventory(cdat):
def cmd_inventory(command):
"""
Shows a player's inventory.
"""
session = cdat['session']
session = command.session
pobject = session.get_pobject()
session.msg("You are carrying:")
@ -99,21 +108,23 @@ def cmd_inventory(cdat):
session.msg("You have %d %s." % (money,money_name))
def cmd_look(cdat):
def cmd_look(command):
"""
Handle looking at objects.
"""
session = cdat['session']
session = command.session
pobject = session.get_pobject()
args = cdat['uinput']['splitted'][1:]
if len(args) == 0:
target_obj = pobject.get_location()
else:
target_obj = Object.objects.standard_plr_objsearch(session, ' '.join(args))
# If an argument is provided with the command, search for the object.
# else look at the current room.
if command.command_argument:
target_obj = Object.objects.standard_plr_objsearch(session,
command.command_argument)
# Use standard_plr_objsearch to handle duplicate/nonexistant results.
if not target_obj:
return
else:
target_obj = pobject.get_location()
# SCRIPT: Get the item's appearance from the scriptlink.
session.msg(target_obj.scriptlink.return_appearance({
@ -126,20 +137,21 @@ def cmd_look(cdat):
"target_obj": pobject
})
def cmd_get(cdat):
def cmd_get(command):
"""
Get an object and put it in a player's inventory.
"""
session = cdat['session']
session = command.session
pobject = session.get_pobject()
args = cdat['uinput']['splitted'][1:]
plr_is_staff = pobject.is_staff()
if len(args) == 0:
if not command.command_argument:
session.msg("Get what?")
return
else:
target_obj = Object.objects.standard_plr_objsearch(session, ' '.join(args), search_contents=False)
target_obj = Object.objects.standard_plr_objsearch(session,
command.command_argument,
search_contents=False)
# Use standard_plr_objsearch to handle duplicate/nonexistant results.
if not target_obj:
return
@ -158,27 +170,31 @@ def cmd_get(cdat):
target_obj.move_to(pobject, quiet=True)
session.msg("You pick up %s." % (target_obj.get_name(),))
pobject.get_location().emit_to_contents("%s picks up %s." % (pobject.get_name(), target_obj.get_name()), exclude=pobject)
pobject.get_location().emit_to_contents("%s picks up %s." %
(pobject.get_name(),
target_obj.get_name()),
exclude=pobject)
# SCRIPT: Call the object's script's a_get() method.
target_obj.scriptlink.a_get({
"pobject": pobject
})
def cmd_drop(cdat):
def cmd_drop(command):
"""
Drop an object from a player's inventory into their current location.
"""
session = cdat['session']
session = command.session
pobject = session.get_pobject()
args = cdat['uinput']['splitted'][1:]
plr_is_staff = pobject.is_staff()
if len(args) == 0:
if not command.command_argument:
session.msg("Drop what?")
return
else:
target_obj = Object.objects.standard_plr_objsearch(session, ' '.join(args), search_location=False)
target_obj = Object.objects.standard_plr_objsearch(session,
command.command_argument,
search_location=False)
# Use standard_plr_objsearch to handle duplicate/nonexistant results.
if not target_obj:
return
@ -189,28 +205,30 @@ def cmd_drop(cdat):
target_obj.move_to(pobject.get_location(), quiet=True)
session.msg("You drop %s." % (target_obj.get_name(),))
pobject.get_location().emit_to_contents("%s drops %s." % (pobject.get_name(), target_obj.get_name()), exclude=pobject)
pobject.get_location().emit_to_contents("%s drops %s." %
(pobject.get_name(),
target_obj.get_name()),
exclude=pobject)
# SCRIPT: Call the object's script's a_drop() method.
target_obj.scriptlink.a_drop({
"pobject": pobject
})
def cmd_examine(cdat):
def cmd_examine(command):
"""
Detailed object examine command
"""
session = cdat['session']
session = command.session
pobject = session.get_pobject()
args = cdat['uinput']['splitted'][1:]
attr_search = False
if len(args) == 0:
if not command.command_argument:
# If no arguments are provided, examine the invoker's location.
target_obj = pobject.get_location()
else:
# Look for a slash in the input, indicating an attribute search.
attr_split = args[0].split("/")
attr_split = command.command_argument.split("/", 1)
# If the splitting by the "/" character returns a list with more than 1
# entry, it's an attribute match.
@ -218,41 +236,59 @@ def cmd_examine(cdat):
attr_search = True
# Strip the object search string from the input with the
# object/attribute pair.
searchstr = attr_split[0]
# Just in case there's a slash in an attribute name.
attr_searchstr = '/'.join(attr_split[1:])
obj_searchstr = attr_split[0]
attr_searchstr = attr_split[1].strip()
# Protect against stuff like: ex me/
if attr_searchstr == '':
session.msg('No attribute name provided.')
return
else:
searchstr = ' '.join(args)
# No slash in argument, just examine an object.
obj_searchstr = command.command_argument
target_obj = Object.objects.standard_plr_objsearch(session, searchstr)
# Resolve the target object.
target_obj = Object.objects.standard_plr_objsearch(session,
obj_searchstr)
# Use standard_plr_objsearch to handle duplicate/nonexistant results.
if not target_obj:
return
if attr_search:
"""
Player did something like: examine me/* or examine me/TE*. Return
each matching attribute with its value.
"""
attr_matches = target_obj.attribute_namesearch(attr_searchstr)
if attr_matches:
for attribute in attr_matches:
session.msg(attribute.get_attrline())
else:
session.msg("No matching attributes found.")
# End attr_search if()
else:
"""
Player is examining an object. Return a full readout of attributes,
along with detailed information about said object.
"""
# Format the examine header area with general flag/type info.
session.msg("%s\r\n%s" % (
target_obj.get_name(fullname=True),
target_obj.get_description(no_parsing=True),
))
session.msg("Type: %s Flags: %s" % (target_obj.get_type(), target_obj.get_flags()))
session.msg("Type: %s Flags: %s" % (target_obj.get_type(),
target_obj.get_flags()))
session.msg("Owner: %s " % (target_obj.get_owner(),))
session.msg("Zone: %s" % (target_obj.get_zone(),))
for attribute in target_obj.get_all_attributes():
session.msg(attribute.get_attrline())
# Contents container lists for sorting by type.
con_players = []
con_things = []
con_exits = []
# Break each object out into their own list.
for obj in target_obj.get_contents():
if obj.is_player():
con_players.append(obj)
@ -261,157 +297,47 @@ def cmd_examine(cdat):
elif obj.is_thing():
con_things.append(obj)
# Render Contents display.
if con_players or con_things:
session.msg("%sContents:%s" % (ansi.ansi["hilite"], ansi.ansi["normal"],))
session.msg("%sContents:%s" % (ansi.ansi["hilite"],
ansi.ansi["normal"],))
for player in con_players:
session.msg('%s' % (player.get_name(fullname=True),))
for thing in con_things:
session.msg('%s' % (thing.get_name(fullname=True),))
# Render Exists display.
if con_exits:
session.msg("%sExits:%s" % (ansi.ansi["hilite"], ansi.ansi["normal"],))
session.msg("%sExits:%s" % (ansi.ansi["hilite"],
ansi.ansi["normal"],))
for exit in con_exits:
session.msg('%s' %(exit.get_name(fullname=True),))
# Render the object's home or destination (for exits).
if not target_obj.is_room():
if target_obj.is_exit():
# The Home attribute on an exit is really its destination.
session.msg("Destination: %s" % (target_obj.get_home(),))
else:
# For everything else, home is home.
session.msg("Home: %s" % (target_obj.get_home(),))
# This obviously isn't valid for rooms.
session.msg("Location: %s" % (target_obj.get_location(),))
def cmd_page(cdat):
"""
Send a message to target user (if online).
"""
session = cdat['session']
pobject = session.get_pobject()
server = cdat['server']
args = cdat['uinput']['splitted'][1:]
parsed_command = cdat['uinput']['parsed_command']
# We use a dict to ensure that the list of targets is unique
targets = dict()
# Get the last paged person
last_paged_dbrefs = pobject.get_attribute_value("LASTPAGED")
# If they have paged someone before, go ahead and grab the object of
# that person.
if last_paged_dbrefs is not False:
last_paged_objects = list()
try:
last_paged_dbref_list = [
x.strip() for x in last_paged_dbrefs.split(',')]
for dbref in last_paged_dbref_list:
if not Object.objects.is_dbref(dbref):
raise ValueError
last_paged_object = Object.objects.dbref_search(dbref)
if last_paged_object is not None:
last_paged_objects.append(last_paged_object)
except ValueError:
# LASTPAGED Attribute is not a list of dbrefs
last_paged_dbrefs = False
# Remove the invalid LASTPAGED attribute
pobject.clear_attribute("LASTPAGED")
# If they don't give a target, or any data to send to the target
# then tell them who they last paged if they paged someone, if not
# tell them they haven't paged anyone.
if parsed_command['targets'] is None and parsed_command['data'] is None:
if last_paged_dbrefs is not False and not last_paged_objects == list():
session.msg("You last paged: %s." % (
', '.join([x.name for x in last_paged_objects])))
return
session.msg("You have not paged anyone.")
return
# Build a list of targets
# If there are no targets, then set the targets to the last person they
# paged.
if parsed_command['targets'] is None:
if not last_paged_objects == list():
targets = dict([(target, 1) for target in last_paged_objects])
else:
# First try to match the entire target string against a single player
full_target_match = Object.objects.player_name_search(
parsed_command['original_targets'])
if full_target_match is not None:
targets[full_target_match] = 1
else:
# For each of the targets listed, grab their objects and append
# it to the targets list
for target in parsed_command['targets']:
# If the target is a dbref, behave appropriately
if Object.objects.is_dbref(target):
session.msg("Is dbref.")
matched_object = Object.objects.dbref_search(target,
limit_types=[defines_global.OTYPE_PLAYER])
if matched_object is not None:
targets[matched_object] = 1
else:
# search returned None
session.msg("Player '%s' does not exist." % (
target))
else:
# Not a dbref, so must be a username, treat it as such
matched_object = Object.objects.player_name_search(
target)
if matched_object is not None:
targets[matched_object] = 1
else:
# search returned None
session.msg("Player '%s' does not exist." % (
target))
data = parsed_command['data']
sender_name = pobject.get_name(show_dbref=False)
# Build our messages
target_message = "%s pages: %s"
sender_message = "You paged %s with '%s'."
# Handle paged emotes
if data.startswith(':'):
data = data[1:]
target_message = "From afar, %s %s"
sender_message = "Long distance to %s: %s %s"
# Handle paged emotes without spaces
if data.startswith(';'):
data = data[1:]
target_message = "From afar, %s%s"
sender_message = "Long distance to %s: %s%s"
# We build a list of target_names for the sender_message later
target_names = []
for target in targets.keys():
# Check to make sure they're connected, or a player
if target.is_connected_plr():
target.emit_to(target_message % (sender_name, data))
target_names.append(target.get_name(show_dbref=False))
else:
session.msg("Player %s does not exist or is not online." % (
target.get_name(show_dbref=False)))
if len(target_names) > 0:
target_names_string = ', '.join(target_names)
try:
session.msg(sender_message % (target_names_string, sender_name, data))
except TypeError:
session.msg(sender_message % (target_names_string, data))
# Now set the LASTPAGED attribute
pobject.set_attribute("LASTPAGED", ','.join(
["#%d" % (x.id) for x in targets.keys()]))
def cmd_quit(cdat):
def cmd_quit(command):
"""
Gracefully disconnect the user as per his own request.
"""
session = cdat['session']
session = command.session
session.msg("Quitting!")
session.handle_close()
def cmd_who(cdat):
def cmd_who(command):
"""
Generic WHO command.
"""
session_list = session_mgr.get_session_list()
session = cdat['session']
session = command.session
pobject = session.get_pobject()
show_session_data = pobject.user_has_perm("genperms.see_session_data")
@ -457,18 +383,19 @@ def cmd_who(cdat):
session.msg(retval)
def cmd_say(cdat):
def cmd_say(command):
"""
Room-based speech command.
"""
session = cdat['session']
session = command.session
if not functions_general.cmd_check_num_args(session, cdat['uinput']['splitted'], 1, errortext="Say what?"):
if not command.command_argument:
session.msg("Say what?")
return
session_list = session_mgr.get_session_list()
pobject = session.get_pobject()
speech = ' '.join(cdat['uinput']['splitted'][1:])
speech = command.command_argument
players_present = [player for player in session_list if player.get_pobject().get_location() == session.get_pobject().get_location() and player != session]
@ -478,23 +405,25 @@ def cmd_say(cdat):
session.msg(retval)
def cmd_pose(cdat):
def cmd_pose(command):
"""
Pose/emote command.
"""
session = cdat['session']
session = command.session
pobject = session.get_pobject()
switches = cdat['uinput']['root_chunk'][1:]
if not functions_general.cmd_check_num_args(session, cdat['uinput']['splitted'], 1, errortext="Do what?"):
if not command.command_argument:
session.msg("Do what?")
return
session_list = session_mgr.get_session_list()
speech = ' '.join(cdat['uinput']['splitted'][1:])
speech = command.command_argument
if "nospace" in switches:
if "nospace" in command.command_switches:
# Output without a space between the player name and the emote.
sent_msg = "%s%s" % (pobject.get_name(show_dbref=False), speech)
else:
# No switches, default.
sent_msg = "%s %s" % (pobject.get_name(show_dbref=False), speech)
players_present = [player for player in session_list if player.get_pobject().get_location() == session.get_pobject().get_location()]
@ -502,15 +431,15 @@ def cmd_pose(cdat):
for player in players_present:
player.msg(sent_msg)
def cmd_help(cdat):
def cmd_help(command):
"""
Help system commands.
"""
session = cdat['session']
session = command.session
pobject = session.get_pobject()
topicstr = ' '.join(cdat['uinput']['splitted'][1:])
topicstr = command.command_argument
if len(topicstr) == 0:
if not command.command_argument:
topicstr = "Help Index"
elif len(topicstr) < 2 and not topicstr.isdigit():
session.msg("Your search query is too short. It must be at least three letters long.")

View file

@ -16,79 +16,95 @@ import django
from apps.objects.models import Object
from src import scheduler
from src import defines_global
from src import flags
def cmd_version(cdat):
def cmd_version(command):
"""
Version info command.
"""
session = cdat['session']
session = command.session
retval = "-"*50 +"\n\r"
retval += " Evennia %s\n\r" % (defines_global.EVENNIA_VERSION,)
retval += " Django %s\n\r" % (django.get_version())
retval += "-"*50
session.msg(retval)
def cmd_time(cdat):
def cmd_time(command):
"""
Server local time.
"""
session = cdat['session']
session.msg('Current server time : %s' % (time.strftime('%a %b %d %H:%M:%S %Y (%Z)', time.localtime(),)))
session = command.session
session.msg('Current server time : %s' %
(time.strftime('%a %b %d %H:%M:%S %Y (%Z)', time.localtime(),)))
def cmd_uptime(cdat):
def cmd_uptime(command):
"""
Server uptime and stats.
"""
session = cdat['session']
server = cdat['server']
session = command.session
server = command.server
start_delta = time.time() - server.start_time
loadavg = os.getloadavg()
session.msg('Current server time : %s' % (time.strftime('%a %b %d %H:%M %Y (%Z)', time.localtime(),)))
session.msg('Server start time : %s' % (time.strftime('%a %b %d %H:%M %Y', time.localtime(server.start_time),)))
session.msg('Server uptime : %s' % functions_general.time_format(start_delta, style=2))
session.msg('Server load (1 min) : %.2f' % loadavg[0])
session.msg('Current server time : %s' %
(time.strftime('%a %b %d %H:%M %Y (%Z)', time.localtime(),)))
session.msg('Server start time : %s' %
(time.strftime('%a %b %d %H:%M %Y', time.localtime(server.start_time),)))
session.msg('Server uptime : %s' %
functions_general.time_format(start_delta, style=2))
# os.getloadavg() is not available on Windows.
if not functions_general.host_os_is('nt'):
loadavg = os.getloadavg()
session.msg('Server load (1 min) : %.2f' %
loadavg[0])
def cmd_list(cdat):
def cmd_list(command):
"""
Shows some game related information.
"""
session = cdat['session']
session = command.session
pobject = session.get_pobject()
args = cdat['uinput']['splitted'][1:]
argstr = ''.join(args)
msg_invalid = "Unknown option. Use one of: commands, flags, process"
if len(argstr) == 0:
if not command.command_argument:
session.msg(msg_invalid)
elif argstr == "commands":
elif command.command_argument == "commands":
session.msg('Commands: '+ ' '.join(session.server.command_list()))
elif argstr == "process":
elif command.command_argument == "process":
if not functions_general.host_os_is('nt'):
loadvg = os.getloadavg()
psize = resource.getpagesize()
rusage = resource.getrusage(resource.RUSAGE_SELF)
session.msg("Process ID: %10d %10d bytes per page" % (os.getpid(), psize))
session.msg("Time used: %10d user %10d sys" % (rusage[0],rusage[1]))
session.msg("Integral mem:%10d shared %10d private%10d stack" % (rusage[3], rusage[4], rusage[5]))
session.msg("Max res mem: %10d pages %10d bytes" % (rusage[2],rusage[2] * psize))
session.msg("Page faults: %10d hard %10d soft %10d swapouts" % (rusage[7], rusage[6], rusage[8]))
session.msg("Disk I/O: %10d reads %10d writes" % (rusage[9], rusage[10]))
session.msg("Network I/O: %10d in %10d out" % (rusage[12], rusage[11]))
session.msg("Context swi: %10d vol %10d forced %10d sigs" % (rusage[14], rusage[15], rusage[13]))
session.msg("Process ID: %10d %10d bytes per page" %
(os.getpid(), psize))
session.msg("Time used: %10d user %10d sys" %
(rusage[0],rusage[1]))
session.msg("Integral mem:%10d shared %10d private%10d stack" %
(rusage[3], rusage[4], rusage[5]))
session.msg("Max res mem: %10d pages %10d bytes" %
(rusage[2],rusage[2] * psize))
session.msg("Page faults: %10d hard %10d soft %10d swapouts" %
(rusage[7], rusage[6], rusage[8]))
session.msg("Disk I/O: %10d reads %10d writes" %
(rusage[9], rusage[10]))
session.msg("Network I/O: %10d in %10d out" %
(rusage[12], rusage[11]))
session.msg("Context swi: %10d vol %10d forced %10d sigs" %
(rusage[14], rusage[15], rusage[13]))
else:
session.msg("Feature not available on Windows.")
return
elif argstr == "flags":
session.msg("Flags: "+" ".join(defines_global.SERVER_FLAGS))
elif command.command_argument == "flags":
session.msg("Flags: "+" ".join(flags.SERVER_FLAGS))
else:
session.msg(msg_invalid)
def cmd_ps(cdat):
def cmd_ps(command):
"""
Shows the process/event table.
"""
session = cdat['session']
session = command.session
session.msg("-- Interval Events --")
for event in scheduler.schedule:
session.msg(" [%d/%d] %s" % (scheduler.get_event_nextfire(event),
@ -96,14 +112,15 @@ def cmd_ps(cdat):
scheduler.get_event_description(event)))
session.msg("Totals: %d interval events" % (len(scheduler.schedule),))
def cmd_stats(cdat):
def cmd_stats(command):
"""
Shows stats about the database.
4012 objects = 144 rooms, 212 exits, 613 things, 1878 players. (1165 garbage)
"""
session = cdat['session']
session = command.session
stats_dict = Object.objects.object_totals()
session.msg("%d objects = %d rooms, %d exits, %d things, %d players. (%d garbage)" % (stats_dict["objects"],
session.msg("%d objects = %d rooms, %d exits, %d things, %d players. (%d garbage)" %
(stats_dict["objects"],
stats_dict["rooms"],
stats_dict["exits"],
stats_dict["things"],

View file

@ -1,27 +1,31 @@
"""
These commands typically are to do with building or modifying Objects.
"""
from apps.objects.models import Object
from apps.objects.models import Object, Attribute
# We'll import this as the full path to avoid local variable clashes.
import src.flags
from src import ansi
from src import session_mgr
def cmd_teleport(cdat):
def cmd_teleport(command):
"""
Teleports an object somewhere.
"""
session = cdat['session']
session = command.session
pobject = session.get_pobject()
server = cdat['server']
args = cdat['uinput']['splitted'][1:]
server = command.server
if len(args) == 0:
if not command.command_argument:
session.msg("Teleport where/what?")
return
eq_args = args[0].split('=')
search_str = ''.join(args)
eq_args = command.command_argument.split('=', 1)
# The quiet switch suppresses leaving and arrival messages.
if "quiet" in command.command_switches:
tel_quietly = True
else:
tel_quietly = False
# If we have more than one entry in our '=' delimited argument list,
# then we're doing a @tel <victim>=<location>. If not, we're doing
@ -46,19 +50,11 @@ def cmd_teleport(cdat):
session.msg("You can't teleport an object inside of itself!")
return
session.msg("Teleported.")
victim.move_to(destination)
# This is somewhat kludgy right now, we'll have to find a better way
# to do it sometime else. If we can find a session in the server's
# session list matching the object we're teleporting, force it to
# look. This is going to typically be a player.
victim_session = session_mgr.session_from_object(victim)
if victim_session:
victim_session.execute_cmd("look")
victim.move_to(destination, quiet=tel_quietly)
else:
# Direct teleport (no equal sign)
target_obj = Object.objects.standard_plr_objsearch(session, search_str)
target_obj = Object.objects.standard_plr_objsearch(session,
command.command_argument)
# Use standard_plr_objsearch to handle duplicate/nonexistant results.
if not target_obj:
return
@ -67,76 +63,82 @@ def cmd_teleport(cdat):
session.msg("You can't teleport inside yourself!")
return
session.msg("Teleported.")
pobject.move_to(target_obj)
session.execute_cmd("look")
pobject.move_to(target_obj, quiet=tel_quietly)
def cmd_stats(cdat):
def cmd_stats(command):
"""
Shows stats about the database.
4012 objects = 144 rooms, 212 exits, 613 things, 1878 players. (1165 garbage)
"""
session = cdat['session']
session = command.session
stats_dict = Object.objects.object_totals()
session.msg("%d objects = %d rooms, %d exits, %d things, %d players. (%d garbage)" % (stats_dict["objects"],
session.msg("%d objects = %d rooms, %d exits, %d things, %d players. (%d garbage)" %
(stats_dict["objects"],
stats_dict["rooms"],
stats_dict["exits"],
stats_dict["things"],
stats_dict["players"],
stats_dict["garbage"]))
def cmd_alias(cdat):
def cmd_alias(command):
"""
Assigns an alias to a player object for ease of paging, etc.
"""
session = cdat['session']
session = command.session
pobject = session.get_pobject()
args = cdat['uinput']['splitted'][1:]
if len(args) == 0:
if not command.command_argument:
session.msg("Alias whom?")
return
# Resplit the args on = to check for an almost-required =
eq_args = ' '.join(args).split('=')
eq_args = command.command_argument.split('=', 1)
if len(eq_args) < 2:
session.msg("Alias missing.")
return
target = Object.objects.standard_plr_objsearch(session, eq_args[0])
target_string = eq_args[0]
new_alias = eq_args[1]
# An Object instance for the victim.
target = Object.objects.standard_plr_objsearch(session, target_string)
# Use standard_plr_objsearch to handle duplicate/nonexistant results.
if not target:
session.msg("Alias whom?")
session.msg("I can't find that player.")
return
duplicates = Object.objects.player_alias_search(pobject, eq_args[1])
if duplicates:
session.msg("Alias '%s' already exists." % (eq_args[1],))
return
else:
old_alias = target.get_attribute_value('ALIAS')
duplicates = Object.objects.player_alias_search(pobject, new_alias)
if not duplicates or old_alias.lower() == new_alias.lower():
# Either no duplicates or just changing the case of existing alias.
if pobject.controls_other(target):
target.set_attribute('ALIAS', eq_args[1])
session.msg("Alias '%s' set for %s." % (eq_args[1], target.get_name()))
target.set_attribute('ALIAS', new_alias)
session.msg("Alias '%s' set for %s." % (new_alias,
target.get_name()))
else:
session.msg("You do not have access to set an alias for %s." % (target.get_name(),))
session.msg("You do not have access to set an alias for %s." %
(target.get_name(),))
else:
# Duplicates were found.
session.msg("Alias '%s' is already in use." % (new_alias,))
return
def cmd_wipe(cdat):
def cmd_wipe(command):
"""
Wipes an object's attributes, or optionally only those matching a search
string.
"""
session = cdat['session']
session = command.session
pobject = session.get_pobject()
args = cdat['uinput']['splitted'][1:]
attr_search = False
if len(args) == 0:
if not command.command_argument:
session.msg("Wipe what?")
return
# Look for a slash in the input, indicating an attribute wipe.
attr_split = args[0].split("/")
attr_split = command.command_argument.split("/", 1)
# If the splitting by the "/" character returns a list with more than 1
# entry, it's an attribute match.
@ -144,13 +146,11 @@ def cmd_wipe(cdat):
attr_search = True
# Strip the object search string from the input with the
# object/attribute pair.
searchstr = attr_split[0]
# Just in case there's a slash in an attribute name.
attr_searchstr = '/'.join(attr_split[1:])
searchstr = attr_split[1]
else:
searchstr = ' '.join(args)
searchstr = command.command_argument
target_obj = Object.objects.standard_plr_objsearch(session, searchstr)
target_obj = Object.objects.standard_plr_objsearch(session, attr_split[0])
# Use standard_plr_objsearch to handle duplicate/nonexistant results.
if not target_obj:
return
@ -158,11 +158,13 @@ def cmd_wipe(cdat):
if attr_search:
# User has passed an attribute wild-card string. Search for name matches
# and wipe.
attr_matches = target_obj.attribute_namesearch(attr_searchstr, exclude_noset=True)
attr_matches = target_obj.attribute_namesearch(searchstr,
exclude_noset=True)
if attr_matches:
for attr in attr_matches:
target_obj.clear_attribute(attr.get_name())
session.msg("%s - %d attributes wiped." % (target_obj.get_name(), len(attr_matches)))
session.msg("%s - %d attributes wiped." % (target_obj.get_name(),
len(attr_matches)))
else:
session.msg("No matching attributes found.")
else:
@ -170,27 +172,25 @@ def cmd_wipe(cdat):
attr_matches = target_obj.attribute_namesearch("*", exclude_noset=True)
for attr in attr_matches:
target_obj.clear_attribute(attr.get_name())
session.msg("%s - %d attributes wiped." % (target_obj.get_name(), len(attr_matches)))
session.msg("%s - %d attributes wiped." % (target_obj.get_name(),
len(attr_matches)))
def cmd_set(cdat):
def cmd_set(command):
"""
Sets flags or attributes on objects.
"""
session = cdat['session']
session = command.session
pobject = session.get_pobject()
server = cdat['server']
args = cdat['uinput']['splitted'][1:]
server = command.server
if len(args) == 0:
if not command.command_argument:
session.msg("Set what?")
return
# There's probably a better way to do this. Break the arguments (minus
# the root command) up so we have two items in the list, 0 being the victim,
# 1 being the list of flags or the attribute/value pair.
eq_args = ' '.join(args).split('=')
# Break into target and value by the equal sign.
eq_args = command.command_argument.split('=', 1)
if len(eq_args) < 2:
# Equal signs are not optional for @set.
session.msg("Set what?")
return
@ -203,8 +203,7 @@ def cmd_set(cdat):
session.msg(defines_global.NOCONTROL_MSG)
return
attrib_args = eq_args[1].split(':')
attrib_args = eq_args[1].split(':', 1)
if len(attrib_args) > 1:
# We're dealing with an attribute/value pair.
attrib_name = attrib_args[0].upper()
@ -212,7 +211,7 @@ def cmd_set(cdat):
attrib_value = eq_args[1][splicenum:]
# In global_defines.py, see NOSET_ATTRIBS for protected attribute names.
if not src.flags.is_modifiable_attrib(attrib_name) and not pobject.is_superuser():
if not Attribute.objects.is_modifiable_attrib(attrib_name) and not pobject.is_superuser():
session.msg("You can't modify that attribute.")
return
@ -237,30 +236,32 @@ def cmd_set(cdat):
if not src.flags.is_modifiable_flag(flag):
session.msg("You can't set/unset the flag - %s." % (flag,))
else:
session.msg('%s - %s cleared.' % (victim.get_name(), flag.upper(),))
session.msg('%s - %s cleared.' % (victim.get_name(),
flag.upper(),))
victim.set_flag(flag, False)
else:
# We're setting the flag.
if not src.flags.is_modifiable_flag(flag):
session.msg("You can't set/unset the flag - %s." % (flag,))
else:
session.msg('%s - %s set.' % (victim.get_name(), flag.upper(),))
session.msg('%s - %s set.' % (victim.get_name(),
flag.upper(),))
victim.set_flag(flag, True)
def cmd_find(cdat):
def cmd_find(command):
"""
Searches for an object of a particular name.
"""
session = cdat['session']
server = cdat['server']
searchstring = ' '.join(cdat['uinput']['splitted'][1:])
session = command.session
server = command.server
pobject = session.get_pobject()
can_find = pobject.user_has_perm("genperms.builder")
if searchstring == '':
if not command.command_argument:
session.msg("No search pattern given.")
return
searchstring = command.command_argument
results = Object.objects.global_object_name_search(searchstring)
if len(results) > 0:
@ -271,35 +272,37 @@ def cmd_find(cdat):
else:
session.msg("No name matches found for: %s" % (searchstring,))
def cmd_create(cdat):
def cmd_create(command):
"""
Creates a new object of type 'THING'.
"""
session = cdat['session']
session = command.session
server = session.server
pobject = session.get_pobject()
uinput= cdat['uinput']['splitted']
thingname = ' '.join(uinput[1:])
if thingname == '':
if not command.command_argument:
session.msg("You must supply a name!")
else:
# Create and set the object up.
odat = {"name": thingname, "type": 3, "location": pobject, "owner": pobject}
# TODO: This dictionary stuff is silly. Feex.
odat = {"name": command.command_argument,
"type": 3,
"location": pobject,
"owner": pobject}
new_object = Object.objects.create_object(odat)
session.msg("You create a new thing: %s" % (new_object,))
def cmd_nextfree(cdat):
def cmd_nextfree(command):
"""
Returns the next free object number.
"""
session = cdat['session']
session = command.session
nextfree = Object.objects.get_nextfree_dbnum()
session.msg("Next free object number: #%s" % (nextfree,))
def cmd_open(cdat):
def cmd_open(command):
"""
Handle the opening of exits.
@ -308,16 +311,15 @@ def cmd_open(cdat):
@open <Name>=<Dbref>
@open <Name>=<Dbref>,<Name>
"""
session = cdat['session']
session = command.session
pobject = session.get_pobject()
server = cdat['server']
args = cdat['uinput']['splitted'][1:]
server = command.server
if len(args) == 0:
if not command.command_argument:
session.msg("Open an exit to where?")
return
eq_args = ' '.join(args).split('=')
eq_args = command.command_argument.split('=', 1)
exit_name = eq_args[0]
if len(exit_name) == 0:
@ -329,8 +331,9 @@ def cmd_open(cdat):
# an un-linked exit, @open <Name>.
if len(eq_args) > 1:
# Opening an exit to another location via @open <Name>=<Dbref>[,<Name>].
comma_split = eq_args[1].split(',')
destination = Object.objects.standard_plr_objsearch(session, comma_split[0])
comma_split = eq_args[1].split(',', 1)
destination = Object.objects.standard_plr_objsearch(session,
comma_split[0])
# Use standard_plr_objsearch to handle duplicate/nonexistant results.
if not destination:
return
@ -339,43 +342,56 @@ def cmd_open(cdat):
session.msg("You can't open an exit to an exit!")
return
odat = {"name": exit_name, "type": 4, "location": pobject.get_location(), "owner": pobject, "home":destination}
odat = {"name": exit_name,
"type": 4,
"location": pobject.get_location(),
"owner": pobject,
"home":destination}
new_object = Object.objects.create_object(odat)
session.msg("You open the an exit - %s to %s" % (new_object.get_name(),destination.get_name()))
session.msg("You open the an exit - %s to %s" % (new_object.get_name(),
destination.get_name()))
if len(comma_split) > 1:
second_exit_name = ','.join(comma_split[1:])
odat = {"name": second_exit_name, "type": 4, "location": destination, "owner": pobject, "home": pobject.get_location()}
odat = {"name": second_exit_name,
"type": 4,
"location": destination,
"owner": pobject,
"home": pobject.get_location()}
new_object = Object.objects.create_object(odat)
session.msg("You open the an exit - %s to %s" % (new_object.get_name(),pobject.get_location().get_name()))
session.msg("You open the an exit - %s to %s" % (
new_object.get_name(),
pobject.get_location().get_name()))
else:
# Create an un-linked exit.
odat = {"name": exit_name, "type": 4, "location": pobject.get_location(), "owner": pobject, "home":None}
odat = {"name": exit_name,
"type": 4,
"location": pobject.get_location(),
"owner": pobject,
"home":None}
new_object = Object.objects.create_object(odat)
session.msg("You open an unlinked exit - %s" % (new_object,))
def cmd_link(cdat):
def cmd_link(command):
"""
Sets an object's home or an exit's destination.
Forms:
@link <Object>=<Target>
"""
session = cdat['session']
session = command.session
pobject = session.get_pobject()
server = cdat['server']
args = cdat['uinput']['splitted'][1:]
server = command.server
if len(args) == 0:
if not command.command_argument:
session.msg("Link what?")
return
eq_args = args[0].split('=')
eq_args = command.command_argument.split('=', 1)
target_name = eq_args[0]
dest_name = '='.join(eq_args[1:])
dest_name = eq_args[1]
if len(target_name) == 0:
session.msg("What do you want to link?")
@ -410,19 +426,21 @@ def cmd_link(cdat):
session.msg("You must provide a destination to link to.")
return
def cmd_unlink(cdat):
def cmd_unlink(command):
"""
Unlinks an object.
"""
session = cdat['session']
pobject = session.get_pobject()
args = cdat['uinput']['splitted'][1:]
if len(args) == 0:
@unlink <Object>
"""
session = command.session
pobject = session.get_pobject()
if not command.command_argument:
session.msg("Unlink what?")
return
else:
target_obj = Object.objects.standard_plr_objsearch(session, ' '.join(args))
target_obj = Object.objects.standard_plr_objsearch(session,
command.command_argument)
# Use standard_plr_objsearch to handle duplicate/nonexistant results.
if not target_obj:
return
@ -434,67 +452,75 @@ def cmd_unlink(cdat):
target_obj.set_home(None)
session.msg("You have unlinked %s." % (target_obj.get_name(),))
def cmd_dig(cdat):
def cmd_dig(command):
"""
Creates a new object of type 'ROOM'.
"""
session = cdat['session']
pobject = session.get_pobject()
uinput= cdat['uinput']['splitted']
roomname = ' '.join(uinput[1:])
if roomname == '':
@dig <Name>
"""
session = command.session
pobject = session.get_pobject()
roomname = command.command_argument
if not roomname:
session.msg("You must supply a name!")
else:
# Create and set the object up.
odat = {"name": roomname, "type": 2, "location": None, "owner": pobject}
odat = {"name": roomname,
"type": 2,
"location": None,
"owner": pobject}
new_object = Object.objects.create_object(odat)
session.msg("You create a new room: %s" % (new_object,))
def cmd_name(cdat):
def cmd_name(command):
"""
Handle naming an object.
"""
session = cdat['session']
pobject = session.get_pobject()
args = cdat['uinput']['splitted'][1:]
eq_args = ' '.join(args).split('=')
searchstring = ''.join(eq_args[0])
if len(args) == 0:
@name <Object>=<Value>
"""
session = command.session
pobject = session.get_pobject()
if not command.command_string:
session.msg("What do you want to name?")
elif len(eq_args) < 2:
return
eq_args = command.command_argument.split('=', 1)
# Only strip spaces from right side in case they want to be silly and
# have a left-padded object name.
new_name = eq_args[1].rstrip()
if len(eq_args) < 2 or eq_args[1] == '':
session.msg("What would you like to name that object?")
else:
target_obj = Object.objects.standard_plr_objsearch(session, searchstring)
target_obj = Object.objects.standard_plr_objsearch(session, eq_args[0])
# Use standard_plr_objsearch to handle duplicate/nonexistant results.
if not target_obj:
return
if len(eq_args[1]) == 0:
session.msg("What would you like to name that object?")
else:
newname = '='.join(eq_args[1:])
session.msg("You have renamed %s to %s." % (target_obj, ansi.parse_ansi(newname, strip_formatting=True)))
target_obj.set_name(newname)
ansi_name = ansi.parse_ansi(new_name, strip_formatting=True)
session.msg("You have renamed %s to %s." % (target_obj, ansi_name))
target_obj.set_name(new_name)
def cmd_description(cdat):
def cmd_description(command):
"""
Set an object's description.
"""
session = cdat['session']
session = command.session
pobject = session.get_pobject()
args = cdat['uinput']['splitted'][1:]
eq_args = ' '.join(args).split('=')
searchstring = ''.join(eq_args[0])
if len(args) == 0:
if not command.command_argument:
session.msg("What do you want to describe?")
elif len(eq_args) < 2:
return
eq_args = command.command_argument.split('=', 1)
if len(eq_args) < 2 or eq_args[1] == '':
session.msg("How would you like to describe that object?")
else:
target_obj = Object.objects.standard_plr_objsearch(session, searchstring)
target_obj = Object.objects.standard_plr_objsearch(session, eq_args[0])
# Use standard_plr_objsearch to handle duplicate/nonexistant results.
if not target_obj:
return
@ -503,45 +529,45 @@ def cmd_description(cdat):
session.msg(defines_global.NOCONTROL_MSG)
return
new_desc = '='.join(eq_args[1:])
new_desc = eq_args[1]
session.msg("%s - DESCRIPTION set." % (target_obj,))
target_obj.set_description(new_desc)
def cmd_destroy(cdat):
def cmd_destroy(command):
"""
Destroy an object.
"""
session = cdat['session']
session = command.session
pobject = session.get_pobject()
args = cdat['uinput']['splitted'][1:]
switches = cdat['uinput']['root_chunk'][1:]
switch_override = False
if "override" in switches:
switch_override = True
if len(args) == 0:
if not command.command_argument:
session.msg("Destroy what?")
return
else:
target_obj = Object.objects.standard_plr_objsearch(session, ' '.join(args))
# Use standard_plr_objsearch to handle duplicate/nonexistant results.
if not target_obj:
return
# Safety feature. Switch required to delete players and SAFE objects.
if "override" in command.command_switches:
switch_override = True
if target_obj.is_player():
if pobject.id == target_obj.id:
session.msg("You can't destroy yourself.")
return
if not switch_override:
session.msg("You must use @destroy/override on players.")
return
if target_obj.is_superuser():
session.msg("You can't destroy a superuser.")
return
elif target_obj.is_going() or target_obj.is_garbage():
session.msg("That object is already destroyed.")
target_obj = Object.objects.standard_plr_objsearch(session,
command.command_argument)
# Use standard_plr_objsearch to handle duplicate/nonexistant results.
if not target_obj:
return
if target_obj.is_player():
if pobject.id == target_obj.id:
session.msg("You can't destroy yourself.")
return
if not switch_override:
session.msg("You must use @destroy/override on players.")
return
if target_obj.is_superuser():
session.msg("You can't destroy a superuser.")
return
elif target_obj.is_going() or target_obj.is_garbage():
session.msg("That object is already destroyed.")
return
session.msg("You destroy %s." % (target_obj.get_name(),))
target_obj.destroy()

119
src/commands/paging.py Normal file
View file

@ -0,0 +1,119 @@
"""
Paging command and support functions.
"""
from apps.objects.models import Object
from src import defines_global
def get_last_paged_objects(pobject):
"""
Returns a list of objects of the user's last paged list, or None if invalid
or non-existant.
"""
last_paged_dbrefs = pobject.get_attribute_value("LASTPAGED")
if last_paged_dbrefs is not False:
last_paged_objects = list()
try:
last_paged_dbref_list = [
x.strip() for x in last_paged_dbrefs.split(',')
]
for dbref in last_paged_dbref_list:
if not Object.objects.is_dbref(dbref):
raise ValueError
last_paged_object = Object.objects.dbref_search(dbref)
if last_paged_object is not None:
last_paged_objects.append(last_paged_object)
return last_paged_objects
except ValueError:
# Remove the invalid LASTPAGED attribute
pobject.clear_attribute("LASTPAGED")
return None
def cmd_page(command):
"""
Send a message to target user (if online).
"""
session = command.session
pobject = session.get_pobject()
server = command.server
args = command.command_argument.split()
targets = []
# Get the last paged person(s)
last_paged_objects = get_last_paged_objects(pobject)
# If they don't give a target, or any data to send to the target
# then tell them who they last paged if they paged someone, if not
# tell them they haven't paged anyone.
if not command.command_argument:
if last_paged_objects:
session.msg("You last paged: %s." % (
', '.join([x.name for x in last_paged_objects])))
return
session.msg("You have not paged anyone.")
return
# Build a list of targets
# If there are no targets, then set the targets to the last person they
# paged.
cmd_targets = command.get_arg_targets()
if cmd_targets is None:
targets = last_paged_objects
else:
# For each of the targets listed, grab their objects and append
# it to the targets list
for target in cmd_targets:
matched_object = Object.objects.local_and_global_search(pobject,
target,
limit_types=[defines_global.OTYPE_PLAYER])
if matched_object:
targets.append(matched_object[0])
print "MATCH:", matched_object[0]
else:
# search returned None
session.msg("Player '%s' can not be found." % (
target))
# Depending on the argument provided, either send the entire thing as
# a message or break off the point after the equal sign.
if command.arg_has_target():
message = command.get_arg_target_value()
else:
message = command.command_argument
sender_name = pobject.get_name(show_dbref=False)
# Build our messages
target_message = "%s pages: %s"
sender_message = "You paged %s with '%s'."
# Handle paged emotes
if message.startswith(':'):
message = message[1:]
target_message = "From afar, %s %s"
sender_message = "Long distance to %s: %s %s"
# Handle paged emotes without spaces
if message.startswith(';'):
message = message[1:]
target_message = "From afar, %s%s"
sender_message = "Long distance to %s: %s%s"
# We build a list of target_names for the sender_message later
target_names = []
for target in targets:
# Check to make sure they're connected, or a player
if target.is_connected_plr():
target.emit_to(target_message % (sender_name, message))
target_names.append(target.get_name(show_dbref=False))
else:
session.msg("Player %s does not exist or is not online." % (
target.get_name(show_dbref=False)))
# Now send a confirmation to the person doing the paging.
if len(target_names) > 0:
target_names_string = ', '.join(target_names)
try:
session.msg(sender_message % (target_names_string, sender_name, message))
except TypeError:
session.msg(sender_message % (target_names_string, message))
# Now set the LASTPAGED attribute
pobject.set_attribute("LASTPAGED", ','.join(
["#%d" % (x.id) for x in targets]))

View file

@ -5,56 +5,54 @@ are generally @-prefixed commands, but there are exceptions.
from apps.objects.models import Object
from src import defines_global
from src import ansi
from src import session_mgr
from src.util import functions_general
def cmd_reload(cdat):
def cmd_reload(command):
"""
Reloads all modules.
"""
session = cdat['session']
session = command.session
server = session.server.reload(session)
def cmd_boot(cdat):
def cmd_boot(command):
"""
Boot a player object from the server.
"""
session = cdat['session']
session = command.session
pobject = session.get_pobject()
args = cdat['uinput']['splitted'][1:]
eq_args = ' '.join(args).split('=')
searchstring = ''.join(eq_args[0])
switches = cdat['uinput']['root_chunk'][1:]
switch_quiet = False
switch_port = False
if not pobject.is_staff():
session.msg("You do not have permission to do that.")
return
if "quiet" in switches:
if "quiet" in command.command_switches:
# Don't tell the player they've been disconnected, silently boot them.
switch_quiet = True
if "port" in switches:
if "port" in command.command_switches:
# Boot by port number instead of name or dbref.
switch_port = True
if len(args) == 0:
if not command.command_argument:
session.msg("Who would you like to boot?")
return
else:
boot_list = []
if switch_port:
# Boot a particular port.
sessions = session_mgr.get_session_list(True)
for sess in sessions:
if sess.getClientAddress()[1] == int(searchstring):
# Find the session with the matching port number.
if sess.getClientAddress()[1] == int(command.command_argument):
boot_list.append(sess)
# We're done here
# Match found, kill the loop and continue with booting.
break
else:
# Grab the objects that match
objs = Objects.object.global_object_name_search(searchstring)
objs = Object.objects.local_and_global_search(pobject,
command.command_argument)
if len(objs) < 1:
session.msg("Who would you like to boot?")
if not objs:
session.msg("No name or dbref match found for booting.")
return
if not objs[0].is_player():
@ -71,7 +69,15 @@ def cmd_boot(cdat):
if objs[0].is_connected_plr():
boot_list.append(session_mgr.session_from_object(objs[0]))
else:
session.msg("That player is not connected.")
return
if not boot_list:
session.msg("No matches found.")
return
# 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." % (pobject.name))
@ -79,25 +85,24 @@ def cmd_boot(cdat):
session_mgr.remove_session(boot)
return
def cmd_newpassword(cdat):
def cmd_newpassword(command):
"""
Set a player's password.
"""
session = cdat['session']
session = command.session
pobject = session.get_pobject()
args = cdat['uinput']['splitted'][1:]
eq_args = ' '.join(args).split('=')
searchstring = ''.join(eq_args[0])
newpass = ''.join(eq_args[1:])
eq_args = command.command_argument.split('=', 1)
searchstring = eq_args[0]
newpass = eq_args[1]
if len(args) == 0:
if not command.command_argument or len(searchstring) == 0:
session.msg("What player's password do you want to change")
return
if len(newpass) == 0:
session.msg("You must supply a new password.")
return
target_obj = Objects.object.standard_plr_objsearch(session, searchstring)
target_obj = Object.objects.standard_plr_objsearch(session, searchstring)
# Use standard_plr_objsearch to handle duplicate/nonexistant results.
if not target_obj:
return
@ -114,14 +119,15 @@ def cmd_newpassword(cdat):
uaccount.set_password(newpass)
uaccount.save()
session.msg("%s - PASSWORD set." % (target_obj.get_name(),))
target_obj.emit_to("%s has changed your password." % (pobject.get_name(show_dbref=False),))
target_obj.emit_to("%s has changed your password." %
(pobject.get_name(show_dbref=False),))
def cmd_shutdown(cdat):
def cmd_shutdown(command):
"""
Shut the server down gracefully.
"""
session = cdat['session']
server = cdat['server']
session = command.session
server = command.server
pobject = session.get_pobject()
session.msg('Shutting down...')

View file

@ -7,51 +7,52 @@ from apps.objects.models import Attribute, Object
from src import defines_global
from src.util import functions_general
def cmd_connect(cdat):
def cmd_connect(command):
"""
This is the connect command at the connection screen. Fairly simple,
uses the Django database API and User model to make it extremely simple.
"""
session = cdat['session']
session = command.session
# Argument check.
if not functions_general.cmd_check_num_args(session, cdat['uinput']['splitted'], 2):
arg_list = command.command_argument.split()
if not functions_general.cmd_check_num_args(session, arg_list, 2):
return
uemail = cdat['uinput']['splitted'][1]
password = cdat['uinput']['splitted'][2]
uemail = arg_list[0]
password = arg_list[1]
# Match an email address to an account.
email_matches = Object.objects.get_user_from_email(uemail)
autherror = "Specified email does not match any accounts!"
# No username match
if email_matches.count() == 0:
session.msg(autherror)
session.msg("Specified email does not match any accounts!")
return
# We have at least one result, so we can check the password.
user = email_matches[0]
if not user.check_password(password):
session.msg(autherror)
session.msg("Incorrect password.")
else:
uname = user.username
session.login(user)
def cmd_create(cdat):
def cmd_create(command):
"""
Handle the creation of new accounts.
"""
session = cdat['session']
session = command.session
# Argument check.
if not functions_general.cmd_check_num_args(session, cdat['uinput']['splitted'], 2):
arg_list = command.command_argument.split()
if not functions_general.cmd_check_num_args(session, arg_list, 2):
return
server = session.server
quote_split = ' '.join(cdat['uinput']['splitted']).split("\"")
quote_split = command.command_argument.split("\"")
if len(quote_split) < 2:
session.msg("You must enclose your username in quotation marks.")
@ -84,14 +85,14 @@ def cmd_create(cdat):
elif len(password) < 3:
session.msg("Your password must be 3 characters or longer.")
else:
Object.objects.create_user(cdat, uname, email, password)
Object.objects.create_user(command, uname, email, password)
def cmd_quit(cdat):
def cmd_quit(command):
"""
We're going to maintain a different version of the quit command
here for unconnected users for the sake of simplicity. The logged in
version will be a bit more complicated.
"""
session = cdat['session']
session = command.session
session.msg("Disconnecting...")
session.handle_close()