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

@ -75,9 +75,11 @@ class ObjectManager(models.Manager):
else: else:
o_query = self.filter(name__icontains=ostring) o_query = self.filter(name__icontains=ostring)
return o_query.exclude(type=defines_global.OTYPE_GARBAGE) return o_query.exclude(type__in=[defines_global.OTYPE_GARBAGE,
defines_global.OTYPE_GOING])
def list_search_object_namestr(self, searchlist, ostring, dbref_only=False, limit_types=False, match_type="fuzzy"): def list_search_object_namestr(self, searchlist, ostring, dbref_only=False,
limit_types=False, match_type="fuzzy"):
""" """
Iterates through a list of objects and returns a list of Iterates through a list of objects and returns a list of
name matches. name matches.
@ -98,7 +100,9 @@ class ObjectManager(models.Manager):
return [prospect for prospect in searchlist if prospect.name_match(ostring, match_type=match_type)] return [prospect for prospect in searchlist if prospect.name_match(ostring, match_type=match_type)]
def standard_plr_objsearch(self, session, ostring, search_contents=True, search_location=True, dbref_only=False, limit_types=False): def standard_plr_objsearch(self, session, ostring, search_contents=True,
search_location=True, dbref_only=False,
limit_types=False):
""" """
Perform a standard object search via a player session, handling multiple Perform a standard object search via a player session, handling multiple
results and lack thereof gracefully. results and lack thereof gracefully.
@ -107,7 +111,11 @@ class ObjectManager(models.Manager):
ostring: (str) The string to match object names against. ostring: (str) The string to match object names against.
""" """
pobject = session.get_pobject() pobject = session.get_pobject()
results = self.local_and_global_search(pobject, ostring, search_contents=search_contents, search_location=search_location, dbref_only=dbref_only, limit_types=limit_types) results = self.local_and_global_search(pobject, ostring,
search_contents=search_contents,
search_location=search_location,
dbref_only=dbref_only,
limit_types=limit_types)
if len(results) > 1: if len(results) > 1:
session.msg("More than one match found (please narrow target):") session.msg("More than one match found (please narrow target):")
@ -136,14 +144,14 @@ class ObjectManager(models.Manager):
def player_alias_search(self, searcher, ostring): def player_alias_search(self, searcher, ostring):
""" """
Search players by alias. Returns a list of objects whose "ALIAS" attribute Search players by alias. Returns a list of objects whose "ALIAS"
exactly (not case-sensitive) matches ostring. attribute exactly (not case-sensitive) matches ostring.
searcher: (Object) The object doing the searching. searcher: (Object) The object doing the searching.
ostring: (string) The alias string to search for. ostring: (string) The alias string to search for.
""" """
search_query = ''.join(ostring) Attribute = ContentType.objects.get(app_label="objects",
Attribute = ContentType.objects.get(app_label="objects", model="attribute").get_model() model="attribute").model_class()
results = Attribute.objects.select_related().filter(attr_name__exact="ALIAS").filter(attr_value__iexact=ostring) results = Attribute.objects.select_related().filter(attr_name__exact="ALIAS").filter(attr_value__iexact=ostring)
return [prospect.get_object() for prospect in results if prospect.get_object().is_player()] return [prospect.get_object() for prospect in results if prospect.get_object().is_player()]
@ -171,11 +179,17 @@ class ObjectManager(models.Manager):
except IndexError: except IndexError:
return None return None
def is_dbref(self, dbstring):
"""
Is the input a well-formed dbref number?
"""
util_object.is_dbref(dbstring)
def dbref_search(self, dbref_string, limit_types=False): def dbref_search(self, dbref_string, limit_types=False):
""" """
Searches for a given dbref. Searches for a given dbref.
dbref_number: (string) The dbref to search for dbref_number: (string) The dbref to search for. With # sign.
limit_types: (list of int) A list of Object type numbers to filter by. limit_types: (list of int) A list of Object type numbers to filter by.
""" """
if not util_object.is_dbref(dbref_string): if not util_object.is_dbref(dbref_string):
@ -192,7 +206,9 @@ class ObjectManager(models.Manager):
except IndexError: except IndexError:
return None return None
def local_and_global_search(self, searcher, ostring, search_contents=True, search_location=True, dbref_only=False, limit_types=False): def local_and_global_search(self, searcher, ostring, search_contents=True,
search_location=True, dbref_only=False,
limit_types=False):
""" """
Searches an object's location then globally for a dbref or name match. Searches an object's location then globally for a dbref or name match.
@ -203,14 +219,13 @@ class ObjectManager(models.Manager):
dbref_only: (bool) Only compare dbrefs. dbref_only: (bool) Only compare dbrefs.
limit_types: (list of int) A list of Object type numbers to filter by. limit_types: (list of int) A list of Object type numbers to filter by.
""" """
search_query = ''.join(ostring) search_query = ostring
# This is a global dbref search. Not applicable if we're only searching # This is a global dbref search. Not applicable if we're only searching
# searcher's contents/locations, dbref comparisons for location/contents # searcher's contents/locations, dbref comparisons for location/contents
# searches are handled by list_search_object_namestr() below. # searches are handled by list_search_object_namestr() below.
if util_object.is_dbref(ostring): if util_object.is_dbref(ostring):
search_num = search_query[1:] dbref_match = self.dbref_search(search_query, limit_types)
dbref_match = dbref_search(search_num, limit_types)
if dbref_match is not None: if dbref_match is not None:
return [dbref_match] return [dbref_match]
@ -224,7 +239,7 @@ class ObjectManager(models.Manager):
if search_query[0] == "*": if search_query[0] == "*":
# Player search- gotta search by name or alias # Player search- gotta search by name or alias
search_target = search_query[1:] search_target = search_query[1:]
player_match = player_name_search(search_target) player_match = self.player_name_search(search_target)
if player_match is not None: if player_match is not None:
return [player_match] return [player_match]
@ -232,9 +247,11 @@ class ObjectManager(models.Manager):
# Handle our location/contents searches. list_search_object_namestr() does # Handle our location/contents searches. list_search_object_namestr() does
# name and dbref comparisons against search_query. # name and dbref comparisons against search_query.
if search_contents: if search_contents:
local_matches += list_search_object_namestr(searcher.get_contents(), search_query, limit_types) local_matches += self.list_search_object_namestr(searcher.get_contents(),
search_query, limit_types)
if search_location: if search_location:
local_matches += list_search_object_namestr(searcher.get_location().get_contents(), search_query, limit_types=limit_types) local_matches += self.list_search_object_namestr(searcher.get_location().get_contents(),
search_query, limit_types=limit_types)
return local_matches return local_matches
def get_user_from_email(self, uemail): def get_user_from_email(self, uemail):
@ -264,7 +281,9 @@ class ObjectManager(models.Manager):
* home: Reference to another object to home to. If not specified, use * home: Reference to another object to home to. If not specified, use
location key for home. location key for home.
""" """
next_dbref = get_nextfree_dbnum() next_dbref = self.get_nextfree_dbnum()
Object = ContentType.objects.get(app_label="objects",
model="object").model_class()
new_object = Object() new_object = Object()
new_object.id = next_dbref new_object.id = next_dbref
@ -301,27 +320,25 @@ class ObjectManager(models.Manager):
return new_object return new_object
def create_user(self, cdat, uname, email, password): def create_user(self, command, uname, email, password):
""" """
Handles the creation of new users. Handles the creation of new users.
""" """
session = cdat['session'] session = command.session
server = cdat['server'] server = command.server
start_room = int(ConfigValue.objects.get_configvalue('player_dbnum_start')) start_room = int(ConfigValue.objects.get_configvalue('player_dbnum_start'))
start_room_obj = get_object_from_dbref(start_room) start_room_obj = self.get_object_from_dbref(start_room)
# The user's entry in the User table must match up to an object # The user's entry in the User table must match up to an object
# on the object table. The id's are the same, we need to figure out # on the object table. The id's are the same, we need to figure out
# the next free unique ID to use and make sure the two entries are # the next free unique ID to use and make sure the two entries are
# the same number. # the same number.
uid = get_nextfree_dbnum() uid = self.get_nextfree_dbnum()
print 'UID', uid
# If this is an object, we know to recycle it since it's garbage. We'll # If this is an object, we know to recycle it since it's garbage. We'll
# pluck the user ID from it. # pluck the user ID from it.
if not str(uid).isdigit(): if not str(uid).isdigit():
uid = uid.id uid = uid.id
print 'UID2', uid
user = User.objects.create_user(uname, email, password) user = User.objects.create_user(uname, email, password)
# It stinks to have to do this but it's the only trivial way now. # It stinks to have to do this but it's the only trivial way now.
@ -337,8 +354,12 @@ class ObjectManager(models.Manager):
user = User.objects.get(id=uid) user = User.objects.get(id=uid)
# Create a player object of the same ID in the Objects table. # Create a player object of the same ID in the Objects table.
odat = {"id": uid, "name": uname, "type": 1, "location": start_room_obj, "owner": None} odat = {"id": uid,
user_object = create_object(odat) "name": uname,
"type": 1,
"location": start_room_obj,
"owner": None}
user_object = self.create_object(odat)
# Activate the player's session and set them loose. # Activate the player's session and set them loose.
session.login(user) session.login(user)

View file

@ -413,7 +413,8 @@ class Object(models.Model):
uobj.is_active = False uobj.is_active = False
uobj.save() uobj.save()
except: except:
functions_general.log_errmsg('Destroying object %s but no matching player.' % (self,)) functions_general.log_errmsg('Destroying object %s but no matching player.'
% (self,))
# Set the object type to GOING # Set the object type to GOING
self.type = 5 self.type = 5
@ -490,7 +491,7 @@ class Object(models.Model):
obj.emit_to("You seem to have found a place that does not exist.") obj.emit_to("You seem to have found a place that does not exist.")
# If home is still None, it goes to a null location. # If home is still None, it goes to a null location.
obj.move_to(home, True) obj.move_to(home)
obj.save() obj.save()
def set_attribute(self, attribute, new_value): def set_attribute(self, attribute, new_value):
@ -538,7 +539,8 @@ class Object(models.Model):
attrs = Attribute.objects.filter(attr_object=self) attrs = Attribute.objects.filter(attr_object=self)
# Compile a regular expression that is converted from the user's # Compile a regular expression that is converted from the user's
# wild-carded search string. # wild-carded search string.
match_exp = re.compile(functions_general.wildcard_to_regexp(searchstr), re.IGNORECASE) match_exp = re.compile(functions_general.wildcard_to_regexp(searchstr),
re.IGNORECASE)
# If the regular expression search returns a match object, add to results. # If the regular expression search returns a match object, add to results.
if exclude_noset: if exclude_noset:
return [attr for attr in attrs if match_exp.search(attr.get_name()) and not attr.is_hidden() and not attr.is_noset()] return [attr for attr in attrs if match_exp.search(attr.get_name()) and not attr.is_hidden() and not attr.is_noset()]
@ -707,22 +709,34 @@ class Object(models.Model):
except: except:
return None return None
def move_to(self, target, quiet=False): def move_to(self, target, quiet=False, force_look=True):
""" """
Moves the object to a new location. Moves the object to a new location.
target: (Object) Reference to the object to move to. target: (Object) Reference to the object to move to.
quiet: (bool) If true, don't emit left/arrived messages. quiet: (bool) If true, don't emit left/arrived messages.
force_look: (bool) If true and target is a player, make them 'look'.
""" """
if not quiet: if not quiet:
if self.get_location(): location = self.get_location()
self.get_location().emit_to_contents("%s has left." % (self.get_name(),), exclude=self) if location:
location.emit_to_contents("%s has left." %
(self.get_name(),), exclude=self)
if location.is_player():
location.emit_to("%s has left your inventory." %
(self.get_name()))
self.location = target self.location = target
self.save() self.save()
if not quiet: if not quiet:
self.get_location().emit_to_contents("%s has arrived." % (self.get_name(),), exclude=self) arrival_message = "%s has arrived." % (self.get_name())
self.get_location().emit_to_contents(arrival_message, exclude=self)
if self.location.is_player():
self.location.emit_to("%s is now in your inventory." % (self.get_name()))
if force_look and self.is_player():
self.get_session().execute_cmd('look')
def dbref_match(self, oname): def dbref_match(self, oname):
""" """
@ -750,7 +764,7 @@ class Object(models.Model):
NOTE: A 'name' can be a dbref or the actual name of the object. See NOTE: A 'name' can be a dbref or the actual name of the object. See
dbref_match for an exclusively name-based match. dbref_match for an exclusively name-based match.
""" """
if oname[0] == '#': if util_object.is_dbref(oname):
# First character is a pound sign, looks to be a dbref. # First character is a pound sign, looks to be a dbref.
return self.dbref_match(oname) return self.dbref_match(oname)
elif match_type == "exact": elif match_type == "exact":

View file

@ -10,6 +10,8 @@ def is_dbref(dbstring):
number = int(dbstring[1:]) number = int(dbstring[1:])
except ValueError: except ValueError:
return False return False
except TypeError:
return False
if not dbstring.startswith("#"): if not dbstring.startswith("#"):
return False return False

View file

@ -17,89 +17,104 @@ class UnknownCommand(Exception):
""" """
Throw this when a user enters an an invalid command. Throw this when a user enters an an invalid command.
""" """
pass
class Command(object):
# Reference to the master server object.
server = None
# The player session that the command originated from.
session = None
# The entire raw, un-parsed command.
raw_input = None
# Just the root command. IE: if input is "look dog", this is just "look".
command_string = None
# A list of switches in the form of strings.
command_switches = []
# The un-parsed argument provided. IE: if input is "look dog", this is "dog".
command_argument = None
def parse_command_switches(self):
"""
Splits any switches out of a command_string into the command_switches
list, and yanks the switches out of the original command_string.
"""
splitted_command = self.command_string.split('/')
self.command_switches = splitted_command[1:]
self.command_string = splitted_command[0]
def parse_command(self):
"""
Breaks the command up into the main command string, a list of switches,
and a string containing the argument provided with the command. More
specific processing is left up to the individual command functions.
"""
try:
"""
Break the command in half into command and argument. If the
command string can't be parsed, it has no argument and is
handled by the except ValueError block below.
"""
(self.command_string, self.command_argument) = self.raw_input.split(' ', 1)
self.command_argument = self.command_argument.strip()
if self.command_argument == '':
self.command_argument = None
except ValueError:
"""
No arguments. IE: look, who.
"""
self.command_string = self.raw_input
finally:
# Parse command_string for switches, regardless of what happens.
self.parse_command_switches()
def __init__(self, raw_input, server=None, session=None):
self.server = server
self.raw_input = raw_input
self.session = session
self.parse_command()
def arg_has_target(self):
"""
Returns true if the argument looks to be target-style. IE:
page blah=hi
kick ball=north
"""
return "=" in self.command_argument
def get_arg_targets(self, delim=','):
"""
Returns a list of targets from the argument. These happen before
the '=' sign and may be separated by a delimiter.
"""
# Make sure we even have a target (= sign).
if not self.arg_has_target():
return None
target = self.command_argument.split('=', 1)[0]
return [targ.strip() for targ in target.split(delim)]
def get_arg_target_value(self):
"""
In a case of something like: page bob=Hello there, the target is "bob",
while the value is "Hello there". This function returns the portion
of the command that takes place after the first equal sign.
"""
# Make sure we even have a target (= sign).
if not self.arg_has_target():
return None
return self.command_argument.split('=', 1)[1]
def match_exits(pobject, searchstr): def match_exits(pobject, searchstr):
""" """
See if we can find an input match to exits. See if we can find an input match to exits.
""" """
exits = pobject.get_location().get_contents(filter_type=4) exits = pobject.get_location().get_contents(filter_type=defines_global.OTYPE_EXIT)
return Object.objects.list_search_object_namestr(exits, searchstr, match_type="exact") return Object.objects.list_search_object_namestr(exits,
searchstr,
match_type="exact")
def parse_command(command_string): def handle(command):
"""
Tries to handle the most common command strings and returns a dictionary with various data.
Common command types:
- Complex:
@pemit[/option] <target>[/option]=<data>
- Simple:
look
look <target>
I'm not married to either of these terms, but I couldn't think of anything
better. If you can, lets change it :)
The only cases that I haven't handled is if someone enters something like:
@pemit <target> <target>/<switch>=<data>
- Ends up considering both targets as one with a space between them,
and the switch as a switch.
@pemit <target>/<switch> <target>=<data>
- Ends up considering the first target a target, and the second
target as part of the switch.
"""
# Each of the bits of data starts off as None, except for the raw, original
# command
parsed_command = dict(
raw_command=command_string,
data=None,
original_command=None,
original_targets=None,
base_command=None,
command_switches=None,
targets=None,
target_switches=None
)
try:
# If we make it past this next statement, then this is what we
# consider a complex command
(command_parts, data) = command_string.split('=', 1)
parsed_command['data'] = data
# First we deal with the command part of the command and break it
# down into the base command, along with switches
# If we make it past the next statement, then they must have
# entered a command like:
# p =<data>
# So we should probably just let it get caught by the ValueError
# again and consider it a simple command
(total_command, total_targets) = command_parts.split(' ', 1)
parsed_command['original_command'] = total_command
parsed_command['original_targets'] = total_targets
split_command = total_command.split('/')
parsed_command['base_command'] = split_command[0]
parsed_command['command_switches'] = split_command[1:]
# Now we move onto the target data
try:
# Look for switches- if they give target switches, then we don't
# accept multiple targets
(target, switch_string) = total_targets.split('/', 1)
parsed_command['targets'] = [target]
parsed_command['target_switches'] = switch_string.split('/')
except ValueError:
# Alright, no switches, so lets consider multiple targets
parsed_command['targets'] = total_targets.split()
except ValueError:
# Ok, couldn't find an =, so not a complex command
try:
(command, data) = command_string.split(' ', 1)
parsed_command['base_command'] = command
parsed_command['data'] = data
except ValueError:
# No arguments
# ie:
# - look
parsed_command['base_command'] = command_string
return parsed_command
def handle(cdat):
""" """
Use the spliced (list) uinput variable to retrieve the correct Use the spliced (list) uinput variable to retrieve the correct
command, or return an invalid command error. command, or return an invalid command error.
@ -108,32 +123,22 @@ def handle(cdat):
their input on to 'cmd_' and looking it up in the GenCommands their input on to 'cmd_' and looking it up in the GenCommands
class. class.
""" """
session = cdat['session'] session = command.session
server = cdat['server'] server = command.server
try: try:
# TODO: Protect against non-standard characters. # TODO: Protect against non-standard characters.
if cdat['uinput'] == '': if command.raw_input == '':
# Nothing sent in of value, ignore it.
return return
parsed_input = {}
parsed_input['parsed_command'] = parse_command(cdat['uinput'])
# First we split the input up by spaces.
parsed_input['splitted'] = cdat['uinput'].split()
# Now we find the root command chunk (with switches attached).
parsed_input['root_chunk'] = parsed_input['splitted'][0].split('/')
# And now for the actual root command. It's the first entry in root_chunk.
parsed_input['root_cmd'] = parsed_input['root_chunk'][0].lower()
# Keep around the full, raw input in case a command needs it
cdat['raw_input'] = cdat['uinput']
# Now we'll see if the user is using an alias. We do a dictionary lookup, # Now we'll see if the user is using an alias. We do a dictionary lookup,
# if the key (the player's root command) doesn't exist on the dict, we # if the key (the player's command_string) doesn't exist on the dict,
# don't replace the existing root_cmd. If the key exists, its value # just keep the command_string the same. If the key exists, its value
# replaces the previously splitted root_cmd. For example, sa -> say. # replaces the command_string. For example, sa -> say.
alias_list = server.cmd_alias_list command.command_string = server.cmd_alias_list.get(
parsed_input['root_cmd'] = alias_list.get(parsed_input['root_cmd'],parsed_input['root_cmd']) command.command_string,
command.command_string)
# This will hold the reference to the command's function. # This will hold the reference to the command's function.
cmd = None cmd = None
@ -143,7 +148,7 @@ def handle(cdat):
session.cmd_last = time.time() session.cmd_last = time.time()
# Lets the users get around badly configured NAT timeouts. # Lets the users get around badly configured NAT timeouts.
if parsed_input['root_cmd'] == 'idle': if command.command_string == 'idle':
return return
# Increment our user's command counter. # Increment our user's command counter.
@ -152,55 +157,34 @@ def handle(cdat):
session.cmd_last_visible = time.time() session.cmd_last_visible = time.time()
# Just in case. Prevents some really funky-case crashes. # Just in case. Prevents some really funky-case crashes.
if len(parsed_input['root_cmd']) == 0: if len(command.command_string) == 0:
raise UnknownCommand raise UnknownCommand
# Shortened say alias. if comsys.plr_has_channel(session, command.command_string,
if parsed_input['root_cmd'][0] == '"': alias_search=True, return_muted=True):
parsed_input['splitted'].insert(0, "say")
parsed_input['splitted'][1] = parsed_input['splitted'][1][1:]
parsed_input['root_cmd'] = 'say'
# Shortened pose alias.
elif parsed_input['root_cmd'][0] == ':':
parsed_input['splitted'].insert(0, "pose")
parsed_input['splitted'][1] = parsed_input['splitted'][1][1:]
parsed_input['root_cmd'] = 'pose'
# Pose without space alias.
elif parsed_input['root_cmd'][0] == ';':
parsed_input['splitted'].insert(0, "pose/nospace")
parsed_input['root_chunk'] = ['pose', 'nospace']
parsed_input['splitted'][1] = parsed_input['splitted'][1][1:]
parsed_input['root_cmd'] = 'pose'
# Channel alias match.
elif comsys.plr_has_channel(session,
parsed_input['root_cmd'],
alias_search=True,
return_muted=True):
calias = parsed_input['root_cmd'] calias = command.command_string
cname = comsys.plr_cname_from_alias(session, calias) cname = comsys.plr_cname_from_alias(session, calias)
cmessage = ' '.join(parsed_input['splitted'][1:])
if cmessage == "who": if command.command_argument == "who":
comsys.msg_cwho(session, cname) comsys.msg_cwho(session, cname)
return return
elif cmessage == "on": elif command.command_argument == "on":
comsys.plr_chan_on(session, calias) comsys.plr_chan_on(session, calias)
return return
elif cmessage == "off": elif command.command_argument == "off":
comsys.plr_chan_off(session, calias) comsys.plr_chan_off(session, calias)
return return
elif cmessage == "last": elif command.command_argument == "last":
comsys.msg_chan_hist(session, cname) comsys.msg_chan_hist(session, cname)
return return
second_arg = "%s=%s" % (cname, cmessage) second_arg = "%s=%s" % (cname, command.command_argument)
parsed_input['splitted'] = ["@cemit/sendername", second_arg] command.command_string = "@cemit"
parsed_input['root_chunk'] = ['@cemit', 'sendername', 'quiet'] command.command_switches = ["sendername", "quiet"]
parsed_input['root_cmd'] = '@cemit'
# Get the command's function reference (Or False) # Get the command's function reference (Or False)
cmdtuple = cmdtable.GLOBAL_CMD_TABLE.get_command_tuple(parsed_input['root_cmd']) cmdtuple = cmdtable.GLOBAL_CMD_TABLE.get_command_tuple(command.command_string)
if cmdtuple: if cmdtuple:
# If there is a permissions element to the entry, check perms. # If there is a permissions element to the entry, check perms.
if cmdtuple[1]: if cmdtuple[1]:
@ -212,7 +196,7 @@ def handle(cdat):
else: else:
# Not logged in, look through the unlogged-in command table. # Not logged in, look through the unlogged-in command table.
cmdtuple = cmdtable.GLOBAL_UNCON_CMD_TABLE.get_command_tuple(parsed_input['root_cmd']) cmdtuple = cmdtable.GLOBAL_UNCON_CMD_TABLE.get_command_tuple(command.command_string)
if cmdtuple: if cmdtuple:
cmd = cmdtuple[0] cmd = cmdtuple[0]
@ -221,9 +205,8 @@ def handle(cdat):
#session.msg("SPLIT: %s" % (parsed_input['splitted'],)) #session.msg("SPLIT: %s" % (parsed_input['splitted'],))
if callable(cmd): if callable(cmd):
cdat['uinput'] = parsed_input
try: try:
cmd(cdat) cmd(command)
except: except:
session.msg("Untrapped error, please file a bug report:\n%s" % (format_exc(),)) session.msg("Untrapped error, please file a bug report:\n%s" % (format_exc(),))
logger.log_errmsg("Untrapped error, evoker %s: %s" % logger.log_errmsg("Untrapped error, evoker %s: %s" %
@ -233,12 +216,10 @@ def handle(cdat):
if session.logged_in: if session.logged_in:
# If we're not logged in, don't check exits. # If we're not logged in, don't check exits.
pobject = session.get_pobject() pobject = session.get_pobject()
exit_matches = match_exits(pobject, ' '.join(parsed_input['splitted'])) exit_matches = match_exits(pobject, command.command_string)
if exit_matches: if exit_matches:
targ_exit = exit_matches[0] targ_exit = exit_matches[0]
if targ_exit.get_home(): if targ_exit.get_home():
cdat['uinput'] = parsed_input
# SCRIPT: See if the player can traverse the exit # SCRIPT: See if the player can traverse the exit
if not targ_exit.scriptlink.default_lock({ if not targ_exit.scriptlink.default_lock({
"pobject": pobject "pobject": pobject

View file

@ -10,6 +10,7 @@ privilege checking in the command function), use None in place of the
permissions tuple. permissions tuple.
""" """
import commands.general import commands.general
import commands.paging
import commands.privileged import commands.privileged
import commands.comsys import commands.comsys
import commands.unloggedin import commands.unloggedin
@ -54,7 +55,7 @@ GLOBAL_CMD_TABLE.add_command("help", commands.general.cmd_help),
GLOBAL_CMD_TABLE.add_command("idle", commands.general.cmd_idle), GLOBAL_CMD_TABLE.add_command("idle", commands.general.cmd_idle),
GLOBAL_CMD_TABLE.add_command("inventory", commands.general.cmd_inventory), GLOBAL_CMD_TABLE.add_command("inventory", commands.general.cmd_inventory),
GLOBAL_CMD_TABLE.add_command("look", commands.general.cmd_look), GLOBAL_CMD_TABLE.add_command("look", commands.general.cmd_look),
GLOBAL_CMD_TABLE.add_command("page", commands.general.cmd_page), GLOBAL_CMD_TABLE.add_command("page", commands.paging.cmd_page),
GLOBAL_CMD_TABLE.add_command("pose", commands.general.cmd_pose), GLOBAL_CMD_TABLE.add_command("pose", commands.general.cmd_pose),
GLOBAL_CMD_TABLE.add_command("quit", commands.general.cmd_quit), GLOBAL_CMD_TABLE.add_command("quit", commands.general.cmd_quit),
GLOBAL_CMD_TABLE.add_command("say", commands.general.cmd_say), GLOBAL_CMD_TABLE.add_command("say", commands.general.cmd_say),
@ -80,7 +81,7 @@ GLOBAL_CMD_TABLE.add_command("@dig", commands.objmanip.cmd_dig,
priv_tuple=("genperms.builder")), priv_tuple=("genperms.builder")),
GLOBAL_CMD_TABLE.add_command("@emit", commands.general.cmd_emit, GLOBAL_CMD_TABLE.add_command("@emit", commands.general.cmd_emit,
priv_tuple=("genperms.announce")), priv_tuple=("genperms.announce")),
#GLOBAL_CMD_TABLE.add_command("@pemit", commands.general.cmd_pemit, None), #GLOBAL_CMD_TABLE.add_command("@pemit", commands.general.cmd_pemit),
GLOBAL_CMD_TABLE.add_command("@find", commands.objmanip.cmd_find, GLOBAL_CMD_TABLE.add_command("@find", commands.objmanip.cmd_find,
priv_tuple=("genperms.builder")), priv_tuple=("genperms.builder")),
GLOBAL_CMD_TABLE.add_command("@link", commands.objmanip.cmd_link, GLOBAL_CMD_TABLE.add_command("@link", commands.objmanip.cmd_link,

View file

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

View file

@ -14,18 +14,22 @@ from src import session_mgr
from src import ansi from src import ansi
from src.util import functions_general from src.util import functions_general
def cmd_password(cdat): def cmd_password(command):
""" """
Changes your own password. Changes your own password.
@newpass <Oldpass>=<Newpass> @password <Oldpass>=<Newpass>
""" """
session = cdat['session'] session = command.session
pobject = session.get_pobject() pobject = session.get_pobject()
args = cdat['uinput']['splitted'][1:] eq_args = command.command_argument.split('=', 1)
eq_args = ' '.join(args).split('=')
oldpass = ''.join(eq_args[0]) if len(eq_args) != 2:
newpass = ''.join(eq_args[1:]) session.msg("Incorrect number of arguments.")
return
oldpass = eq_args[0]
newpass = eq_args[1]
if len(oldpass) == 0: if len(oldpass) == 0:
session.msg("You must provide your old password.") session.msg("You must provide your old password.")
@ -44,47 +48,52 @@ def cmd_password(cdat):
uaccount.save() uaccount.save()
session.msg("Password changed.") 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. Emits something to your location.
""" """
session = cdat['session'] session = command.session
pobject = session.get_pobject() pobject = session.get_pobject()
uinput= cdat['uinput']['splitted'] message = command.command_argument
message = ' '.join(uinput[1:])
if message == '': if message:
session.msg("Emit what?")
else:
pobject.get_location().emit_to_contents(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. Announces a message to all connected players.
""" """
session = cdat['session'] session = command.session
wallstring = ' '.join(cdat['uinput']['splitted'][1:]) wallstring = command.command_argument
pobject = session.get_pobject() pobject = session.get_pobject()
if wallstring == '': if not wallstring:
session.msg("Announce what?") session.msg("Announce what?")
return return
message = "%s shouts \"%s\"" % (session.get_pobject().get_name(show_dbref=False), wallstring) message = "%s shouts \"%s\"" % (session.get_pobject().get_name(show_dbref=False), wallstring)
session_mgr.announce_all(message) 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 Returns nothing, this lets the player set an idle timer without spamming
his screen. his screen.
""" """
pass pass
def cmd_inventory(cdat): def cmd_inventory(command):
""" """
Shows a player's inventory. Shows a player's inventory.
""" """
session = cdat['session'] session = command.session
pobject = session.get_pobject() pobject = session.get_pobject()
session.msg("You are carrying:") session.msg("You are carrying:")
@ -99,21 +108,23 @@ def cmd_inventory(cdat):
session.msg("You have %d %s." % (money,money_name)) session.msg("You have %d %s." % (money,money_name))
def cmd_look(cdat): def cmd_look(command):
""" """
Handle looking at objects. Handle looking at objects.
""" """
session = cdat['session'] session = command.session
pobject = session.get_pobject() pobject = session.get_pobject()
args = cdat['uinput']['splitted'][1:]
# If an argument is provided with the command, search for the object.
if len(args) == 0: # else look at the current room.
target_obj = pobject.get_location() if command.command_argument:
else: target_obj = Object.objects.standard_plr_objsearch(session,
target_obj = Object.objects.standard_plr_objsearch(session, ' '.join(args)) command.command_argument)
# Use standard_plr_objsearch to handle duplicate/nonexistant results. # Use standard_plr_objsearch to handle duplicate/nonexistant results.
if not target_obj: if not target_obj:
return return
else:
target_obj = pobject.get_location()
# SCRIPT: Get the item's appearance from the scriptlink. # SCRIPT: Get the item's appearance from the scriptlink.
session.msg(target_obj.scriptlink.return_appearance({ session.msg(target_obj.scriptlink.return_appearance({
@ -126,20 +137,21 @@ def cmd_look(cdat):
"target_obj": pobject "target_obj": pobject
}) })
def cmd_get(cdat): def cmd_get(command):
""" """
Get an object and put it in a player's inventory. Get an object and put it in a player's inventory.
""" """
session = cdat['session'] session = command.session
pobject = session.get_pobject() pobject = session.get_pobject()
args = cdat['uinput']['splitted'][1:]
plr_is_staff = pobject.is_staff() plr_is_staff = pobject.is_staff()
if len(args) == 0: if not command.command_argument:
session.msg("Get what?") session.msg("Get what?")
return return
else: 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. # Use standard_plr_objsearch to handle duplicate/nonexistant results.
if not target_obj: if not target_obj:
return return
@ -158,27 +170,31 @@ def cmd_get(cdat):
target_obj.move_to(pobject, quiet=True) target_obj.move_to(pobject, quiet=True)
session.msg("You pick up %s." % (target_obj.get_name(),)) 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. # SCRIPT: Call the object's script's a_get() method.
target_obj.scriptlink.a_get({ target_obj.scriptlink.a_get({
"pobject": pobject "pobject": pobject
}) })
def cmd_drop(cdat): def cmd_drop(command):
""" """
Drop an object from a player's inventory into their current location. Drop an object from a player's inventory into their current location.
""" """
session = cdat['session'] session = command.session
pobject = session.get_pobject() pobject = session.get_pobject()
args = cdat['uinput']['splitted'][1:]
plr_is_staff = pobject.is_staff() plr_is_staff = pobject.is_staff()
if len(args) == 0: if not command.command_argument:
session.msg("Drop what?") session.msg("Drop what?")
return return
else: 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. # Use standard_plr_objsearch to handle duplicate/nonexistant results.
if not target_obj: if not target_obj:
return return
@ -189,28 +205,30 @@ def cmd_drop(cdat):
target_obj.move_to(pobject.get_location(), quiet=True) target_obj.move_to(pobject.get_location(), quiet=True)
session.msg("You drop %s." % (target_obj.get_name(),)) 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. # SCRIPT: Call the object's script's a_drop() method.
target_obj.scriptlink.a_drop({ target_obj.scriptlink.a_drop({
"pobject": pobject "pobject": pobject
}) })
def cmd_examine(cdat): def cmd_examine(command):
""" """
Detailed object examine command Detailed object examine command
""" """
session = cdat['session'] session = command.session
pobject = session.get_pobject() pobject = session.get_pobject()
args = cdat['uinput']['splitted'][1:]
attr_search = False attr_search = False
if len(args) == 0: if not command.command_argument:
# If no arguments are provided, examine the invoker's location. # If no arguments are provided, examine the invoker's location.
target_obj = pobject.get_location() target_obj = pobject.get_location()
else: else:
# Look for a slash in the input, indicating an attribute search. # 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 # If the splitting by the "/" character returns a list with more than 1
# entry, it's an attribute match. # entry, it's an attribute match.
@ -218,41 +236,59 @@ def cmd_examine(cdat):
attr_search = True attr_search = True
# Strip the object search string from the input with the # Strip the object search string from the input with the
# object/attribute pair. # object/attribute pair.
searchstr = attr_split[0] obj_searchstr = attr_split[0]
# Just in case there's a slash in an attribute name. attr_searchstr = attr_split[1].strip()
attr_searchstr = '/'.join(attr_split[1:])
# Protect against stuff like: ex me/
if attr_searchstr == '':
session.msg('No attribute name provided.')
return
else: 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. # Use standard_plr_objsearch to handle duplicate/nonexistant results.
if not target_obj: if not target_obj:
return return
if attr_search: 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) attr_matches = target_obj.attribute_namesearch(attr_searchstr)
if attr_matches: if attr_matches:
for attribute in attr_matches: for attribute in attr_matches:
session.msg(attribute.get_attrline()) session.msg(attribute.get_attrline())
else: else:
session.msg("No matching attributes found.") session.msg("No matching attributes found.")
# End attr_search if()
else: 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" % ( session.msg("%s\r\n%s" % (
target_obj.get_name(fullname=True), target_obj.get_name(fullname=True),
target_obj.get_description(no_parsing=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("Owner: %s " % (target_obj.get_owner(),))
session.msg("Zone: %s" % (target_obj.get_zone(),)) session.msg("Zone: %s" % (target_obj.get_zone(),))
for attribute in target_obj.get_all_attributes(): for attribute in target_obj.get_all_attributes():
session.msg(attribute.get_attrline()) session.msg(attribute.get_attrline())
# Contents container lists for sorting by type.
con_players = [] con_players = []
con_things = [] con_things = []
con_exits = [] con_exits = []
# Break each object out into their own list.
for obj in target_obj.get_contents(): for obj in target_obj.get_contents():
if obj.is_player(): if obj.is_player():
con_players.append(obj) con_players.append(obj)
@ -261,157 +297,47 @@ def cmd_examine(cdat):
elif obj.is_thing(): elif obj.is_thing():
con_things.append(obj) con_things.append(obj)
# Render Contents display.
if con_players or con_things: 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: for player in con_players:
session.msg('%s' % (player.get_name(fullname=True),)) session.msg('%s' % (player.get_name(fullname=True),))
for thing in con_things: for thing in con_things:
session.msg('%s' % (thing.get_name(fullname=True),)) session.msg('%s' % (thing.get_name(fullname=True),))
# Render Exists display.
if con_exits: 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: for exit in con_exits:
session.msg('%s' %(exit.get_name(fullname=True),)) session.msg('%s' %(exit.get_name(fullname=True),))
# Render the object's home or destination (for exits).
if not target_obj.is_room(): if not target_obj.is_room():
if target_obj.is_exit(): if target_obj.is_exit():
# The Home attribute on an exit is really its destination.
session.msg("Destination: %s" % (target_obj.get_home(),)) session.msg("Destination: %s" % (target_obj.get_home(),))
else: else:
# For everything else, home is home.
session.msg("Home: %s" % (target_obj.get_home(),)) session.msg("Home: %s" % (target_obj.get_home(),))
# This obviously isn't valid for rooms.
session.msg("Location: %s" % (target_obj.get_location(),)) session.msg("Location: %s" % (target_obj.get_location(),))
def cmd_page(cdat): def cmd_quit(command):
"""
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):
""" """
Gracefully disconnect the user as per his own request. Gracefully disconnect the user as per his own request.
""" """
session = cdat['session'] session = command.session
session.msg("Quitting!") session.msg("Quitting!")
session.handle_close() session.handle_close()
def cmd_who(cdat): def cmd_who(command):
""" """
Generic WHO command. Generic WHO command.
""" """
session_list = session_mgr.get_session_list() session_list = session_mgr.get_session_list()
session = cdat['session'] session = command.session
pobject = session.get_pobject() pobject = session.get_pobject()
show_session_data = pobject.user_has_perm("genperms.see_session_data") show_session_data = pobject.user_has_perm("genperms.see_session_data")
@ -457,18 +383,19 @@ def cmd_who(cdat):
session.msg(retval) session.msg(retval)
def cmd_say(cdat): def cmd_say(command):
""" """
Room-based speech 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 return
session_list = session_mgr.get_session_list() session_list = session_mgr.get_session_list()
pobject = session.get_pobject() 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] 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) session.msg(retval)
def cmd_pose(cdat): def cmd_pose(command):
""" """
Pose/emote command. Pose/emote command.
""" """
session = cdat['session'] session = command.session
pobject = session.get_pobject() 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 return
session_list = session_mgr.get_session_list() 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) sent_msg = "%s%s" % (pobject.get_name(show_dbref=False), speech)
else: else:
# No switches, default.
sent_msg = "%s %s" % (pobject.get_name(show_dbref=False), speech) 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()] 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: for player in players_present:
player.msg(sent_msg) player.msg(sent_msg)
def cmd_help(cdat): def cmd_help(command):
""" """
Help system commands. Help system commands.
""" """
session = cdat['session'] session = command.session
pobject = session.get_pobject() 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" topicstr = "Help Index"
elif len(topicstr) < 2 and not topicstr.isdigit(): elif len(topicstr) < 2 and not topicstr.isdigit():
session.msg("Your search query is too short. It must be at least three letters long.") 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 apps.objects.models import Object
from src import scheduler from src import scheduler
from src import defines_global from src import defines_global
from src import flags
def cmd_version(cdat): def cmd_version(command):
""" """
Version info command. Version info command.
""" """
session = cdat['session'] session = command.session
retval = "-"*50 +"\n\r" retval = "-"*50 +"\n\r"
retval += " Evennia %s\n\r" % (defines_global.EVENNIA_VERSION,) retval += " Evennia %s\n\r" % (defines_global.EVENNIA_VERSION,)
retval += " Django %s\n\r" % (django.get_version()) retval += " Django %s\n\r" % (django.get_version())
retval += "-"*50 retval += "-"*50
session.msg(retval) session.msg(retval)
def cmd_time(cdat): def cmd_time(command):
""" """
Server local time. Server local time.
""" """
session = cdat['session'] session = command.session
session.msg('Current server time : %s' % (time.strftime('%a %b %d %H:%M:%S %Y (%Z)', time.localtime(),))) 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. Server uptime and stats.
""" """
session = cdat['session'] session = command.session
server = cdat['server'] server = command.server
start_delta = time.time() - server.start_time 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('Current server time : %s' %
session.msg('Server start time : %s' % (time.strftime('%a %b %d %H:%M %Y', time.localtime(server.start_time),))) (time.strftime('%a %b %d %H:%M %Y (%Z)', time.localtime(),)))
session.msg('Server uptime : %s' % functions_general.time_format(start_delta, style=2)) session.msg('Server start time : %s' %
session.msg('Server load (1 min) : %.2f' % loadavg[0]) (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. Shows some game related information.
""" """
session = cdat['session'] session = command.session
pobject = session.get_pobject() pobject = session.get_pobject()
args = cdat['uinput']['splitted'][1:]
argstr = ''.join(args)
msg_invalid = "Unknown option. Use one of: commands, flags, process" msg_invalid = "Unknown option. Use one of: commands, flags, process"
if len(argstr) == 0: if not command.command_argument:
session.msg(msg_invalid) session.msg(msg_invalid)
elif argstr == "commands": elif command.command_argument == "commands":
session.msg('Commands: '+ ' '.join(session.server.command_list())) session.msg('Commands: '+ ' '.join(session.server.command_list()))
elif argstr == "process": elif command.command_argument == "process":
if not functions_general.host_os_is('nt'): if not functions_general.host_os_is('nt'):
loadvg = os.getloadavg() loadvg = os.getloadavg()
psize = resource.getpagesize() psize = resource.getpagesize()
rusage = resource.getrusage(resource.RUSAGE_SELF) rusage = resource.getrusage(resource.RUSAGE_SELF)
session.msg("Process ID: %10d %10d bytes per page" % (os.getpid(), psize)) session.msg("Process ID: %10d %10d bytes per page" %
session.msg("Time used: %10d user %10d sys" % (rusage[0],rusage[1])) (os.getpid(), psize))
session.msg("Integral mem:%10d shared %10d private%10d stack" % (rusage[3], rusage[4], rusage[5])) session.msg("Time used: %10d user %10d sys" %
session.msg("Max res mem: %10d pages %10d bytes" % (rusage[2],rusage[2] * psize)) (rusage[0],rusage[1]))
session.msg("Page faults: %10d hard %10d soft %10d swapouts" % (rusage[7], rusage[6], rusage[8])) session.msg("Integral mem:%10d shared %10d private%10d stack" %
session.msg("Disk I/O: %10d reads %10d writes" % (rusage[9], rusage[10])) (rusage[3], rusage[4], rusage[5]))
session.msg("Network I/O: %10d in %10d out" % (rusage[12], rusage[11])) session.msg("Max res mem: %10d pages %10d bytes" %
session.msg("Context swi: %10d vol %10d forced %10d sigs" % (rusage[14], rusage[15], rusage[13])) (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: else:
session.msg("Feature not available on Windows.") session.msg("Feature not available on Windows.")
return return
elif argstr == "flags": elif command.command_argument == "flags":
session.msg("Flags: "+" ".join(defines_global.SERVER_FLAGS)) session.msg("Flags: "+" ".join(flags.SERVER_FLAGS))
else: else:
session.msg(msg_invalid) session.msg(msg_invalid)
def cmd_ps(cdat): def cmd_ps(command):
""" """
Shows the process/event table. Shows the process/event table.
""" """
session = cdat['session'] session = command.session
session.msg("-- Interval Events --") session.msg("-- Interval Events --")
for event in scheduler.schedule: for event in scheduler.schedule:
session.msg(" [%d/%d] %s" % (scheduler.get_event_nextfire(event), session.msg(" [%d/%d] %s" % (scheduler.get_event_nextfire(event),
@ -96,14 +112,15 @@ def cmd_ps(cdat):
scheduler.get_event_description(event))) scheduler.get_event_description(event)))
session.msg("Totals: %d interval events" % (len(scheduler.schedule),)) session.msg("Totals: %d interval events" % (len(scheduler.schedule),))
def cmd_stats(cdat): def cmd_stats(command):
""" """
Shows stats about the database. Shows stats about the database.
4012 objects = 144 rooms, 212 exits, 613 things, 1878 players. (1165 garbage) 4012 objects = 144 rooms, 212 exits, 613 things, 1878 players. (1165 garbage)
""" """
session = cdat['session'] session = command.session
stats_dict = Object.objects.object_totals() 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["rooms"],
stats_dict["exits"], stats_dict["exits"],
stats_dict["things"], stats_dict["things"],

View file

@ -1,27 +1,31 @@
""" """
These commands typically are to do with building or modifying Objects. 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. # We'll import this as the full path to avoid local variable clashes.
import src.flags import src.flags
from src import ansi from src import ansi
from src import session_mgr from src import session_mgr
def cmd_teleport(cdat): def cmd_teleport(command):
""" """
Teleports an object somewhere. Teleports an object somewhere.
""" """
session = cdat['session'] session = command.session
pobject = session.get_pobject() pobject = session.get_pobject()
server = cdat['server'] server = command.server
args = cdat['uinput']['splitted'][1:]
if len(args) == 0: if not command.command_argument:
session.msg("Teleport where/what?") session.msg("Teleport where/what?")
return return
eq_args = args[0].split('=') eq_args = command.command_argument.split('=', 1)
search_str = ''.join(args)
# 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, # 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 # 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!") session.msg("You can't teleport an object inside of itself!")
return return
session.msg("Teleported.") session.msg("Teleported.")
victim.move_to(destination) victim.move_to(destination, quiet=tel_quietly)
# 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")
else: else:
# Direct teleport (no equal sign) # 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. # Use standard_plr_objsearch to handle duplicate/nonexistant results.
if not target_obj: if not target_obj:
return return
@ -67,76 +63,82 @@ def cmd_teleport(cdat):
session.msg("You can't teleport inside yourself!") session.msg("You can't teleport inside yourself!")
return return
session.msg("Teleported.") 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. Shows stats about the database.
4012 objects = 144 rooms, 212 exits, 613 things, 1878 players. (1165 garbage) 4012 objects = 144 rooms, 212 exits, 613 things, 1878 players. (1165 garbage)
""" """
session = cdat['session'] session = command.session
stats_dict = Object.objects.object_totals() 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["rooms"],
stats_dict["exits"], stats_dict["exits"],
stats_dict["things"], stats_dict["things"],
stats_dict["players"], stats_dict["players"],
stats_dict["garbage"])) stats_dict["garbage"]))
def cmd_alias(cdat): def cmd_alias(command):
""" """
Assigns an alias to a player object for ease of paging, etc. Assigns an alias to a player object for ease of paging, etc.
""" """
session = cdat['session'] session = command.session
pobject = session.get_pobject() pobject = session.get_pobject()
args = cdat['uinput']['splitted'][1:]
if len(args) == 0: if not command.command_argument:
session.msg("Alias whom?") session.msg("Alias whom?")
return return
# Resplit the args on = to check for an almost-required = eq_args = command.command_argument.split('=', 1)
eq_args = ' '.join(args).split('=')
if len(eq_args) < 2: if len(eq_args) < 2:
session.msg("Alias missing.") session.msg("Alias missing.")
return 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. # Use standard_plr_objsearch to handle duplicate/nonexistant results.
if not target: if not target:
session.msg("Alias whom?") session.msg("I can't find that player.")
return return
duplicates = Object.objects.player_alias_search(pobject, eq_args[1]) old_alias = target.get_attribute_value('ALIAS')
duplicates = Object.objects.player_alias_search(pobject, new_alias)
if duplicates: if not duplicates or old_alias.lower() == new_alias.lower():
session.msg("Alias '%s' already exists." % (eq_args[1],)) # Either no duplicates or just changing the case of existing alias.
return
else:
if pobject.controls_other(target): if pobject.controls_other(target):
target.set_attribute('ALIAS', eq_args[1]) target.set_attribute('ALIAS', new_alias)
session.msg("Alias '%s' set for %s." % (eq_args[1], target.get_name())) session.msg("Alias '%s' set for %s." % (new_alias,
target.get_name()))
else: 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 Wipes an object's attributes, or optionally only those matching a search
string. string.
""" """
session = cdat['session'] session = command.session
pobject = session.get_pobject() pobject = session.get_pobject()
args = cdat['uinput']['splitted'][1:]
attr_search = False attr_search = False
if len(args) == 0: if not command.command_argument:
session.msg("Wipe what?") session.msg("Wipe what?")
return return
# Look for a slash in the input, indicating an attribute wipe. # 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 # If the splitting by the "/" character returns a list with more than 1
# entry, it's an attribute match. # entry, it's an attribute match.
@ -144,13 +146,11 @@ def cmd_wipe(cdat):
attr_search = True attr_search = True
# Strip the object search string from the input with the # Strip the object search string from the input with the
# object/attribute pair. # object/attribute pair.
searchstr = attr_split[0] searchstr = attr_split[1]
# Just in case there's a slash in an attribute name.
attr_searchstr = '/'.join(attr_split[1:])
else: 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. # Use standard_plr_objsearch to handle duplicate/nonexistant results.
if not target_obj: if not target_obj:
return return
@ -158,11 +158,13 @@ def cmd_wipe(cdat):
if attr_search: if attr_search:
# User has passed an attribute wild-card string. Search for name matches # User has passed an attribute wild-card string. Search for name matches
# and wipe. # 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: if attr_matches:
for attr in attr_matches: for attr in attr_matches:
target_obj.clear_attribute(attr.get_name()) 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: else:
session.msg("No matching attributes found.") session.msg("No matching attributes found.")
else: else:
@ -170,27 +172,25 @@ def cmd_wipe(cdat):
attr_matches = target_obj.attribute_namesearch("*", exclude_noset=True) attr_matches = target_obj.attribute_namesearch("*", exclude_noset=True)
for attr in attr_matches: for attr in attr_matches:
target_obj.clear_attribute(attr.get_name()) 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. Sets flags or attributes on objects.
""" """
session = cdat['session'] session = command.session
pobject = session.get_pobject() pobject = session.get_pobject()
server = cdat['server'] server = command.server
args = cdat['uinput']['splitted'][1:]
if len(args) == 0: if not command.command_argument:
session.msg("Set what?") session.msg("Set what?")
return return
# There's probably a better way to do this. Break the arguments (minus # Break into target and value by the equal sign.
# the root command) up so we have two items in the list, 0 being the victim, eq_args = command.command_argument.split('=', 1)
# 1 being the list of flags or the attribute/value pair.
eq_args = ' '.join(args).split('=')
if len(eq_args) < 2: if len(eq_args) < 2:
# Equal signs are not optional for @set.
session.msg("Set what?") session.msg("Set what?")
return return
@ -203,8 +203,7 @@ def cmd_set(cdat):
session.msg(defines_global.NOCONTROL_MSG) session.msg(defines_global.NOCONTROL_MSG)
return return
attrib_args = eq_args[1].split(':') attrib_args = eq_args[1].split(':', 1)
if len(attrib_args) > 1: if len(attrib_args) > 1:
# We're dealing with an attribute/value pair. # We're dealing with an attribute/value pair.
attrib_name = attrib_args[0].upper() attrib_name = attrib_args[0].upper()
@ -212,7 +211,7 @@ def cmd_set(cdat):
attrib_value = eq_args[1][splicenum:] attrib_value = eq_args[1][splicenum:]
# In global_defines.py, see NOSET_ATTRIBS for protected attribute names. # 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.") session.msg("You can't modify that attribute.")
return return
@ -237,30 +236,32 @@ def cmd_set(cdat):
if not src.flags.is_modifiable_flag(flag): if not src.flags.is_modifiable_flag(flag):
session.msg("You can't set/unset the flag - %s." % (flag,)) session.msg("You can't set/unset the flag - %s." % (flag,))
else: 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) victim.set_flag(flag, False)
else: else:
# We're setting the flag. # We're setting the flag.
if not src.flags.is_modifiable_flag(flag): if not src.flags.is_modifiable_flag(flag):
session.msg("You can't set/unset the flag - %s." % (flag,)) session.msg("You can't set/unset the flag - %s." % (flag,))
else: 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) victim.set_flag(flag, True)
def cmd_find(cdat): def cmd_find(command):
""" """
Searches for an object of a particular name. Searches for an object of a particular name.
""" """
session = cdat['session'] session = command.session
server = cdat['server'] server = command.server
searchstring = ' '.join(cdat['uinput']['splitted'][1:])
pobject = session.get_pobject() pobject = session.get_pobject()
can_find = pobject.user_has_perm("genperms.builder") can_find = pobject.user_has_perm("genperms.builder")
if searchstring == '': if not command.command_argument:
session.msg("No search pattern given.") session.msg("No search pattern given.")
return return
searchstring = command.command_argument
results = Object.objects.global_object_name_search(searchstring) results = Object.objects.global_object_name_search(searchstring)
if len(results) > 0: if len(results) > 0:
@ -271,35 +272,37 @@ def cmd_find(cdat):
else: else:
session.msg("No name matches found for: %s" % (searchstring,)) session.msg("No name matches found for: %s" % (searchstring,))
def cmd_create(cdat): def cmd_create(command):
""" """
Creates a new object of type 'THING'. Creates a new object of type 'THING'.
""" """
session = cdat['session'] session = command.session
server = session.server server = session.server
pobject = session.get_pobject() 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!") session.msg("You must supply a name!")
else: else:
# Create and set the object up. # 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) new_object = Object.objects.create_object(odat)
session.msg("You create a new thing: %s" % (new_object,)) session.msg("You create a new thing: %s" % (new_object,))
def cmd_nextfree(cdat): def cmd_nextfree(command):
""" """
Returns the next free object number. Returns the next free object number.
""" """
session = cdat['session'] session = command.session
nextfree = Object.objects.get_nextfree_dbnum() nextfree = Object.objects.get_nextfree_dbnum()
session.msg("Next free object number: #%s" % (nextfree,)) session.msg("Next free object number: #%s" % (nextfree,))
def cmd_open(cdat): def cmd_open(command):
""" """
Handle the opening of exits. Handle the opening of exits.
@ -308,16 +311,15 @@ def cmd_open(cdat):
@open <Name>=<Dbref> @open <Name>=<Dbref>
@open <Name>=<Dbref>,<Name> @open <Name>=<Dbref>,<Name>
""" """
session = cdat['session'] session = command.session
pobject = session.get_pobject() pobject = session.get_pobject()
server = cdat['server'] server = command.server
args = cdat['uinput']['splitted'][1:]
if len(args) == 0: if not command.command_argument:
session.msg("Open an exit to where?") session.msg("Open an exit to where?")
return return
eq_args = ' '.join(args).split('=') eq_args = command.command_argument.split('=', 1)
exit_name = eq_args[0] exit_name = eq_args[0]
if len(exit_name) == 0: if len(exit_name) == 0:
@ -329,8 +331,9 @@ def cmd_open(cdat):
# an un-linked exit, @open <Name>. # an un-linked exit, @open <Name>.
if len(eq_args) > 1: if len(eq_args) > 1:
# Opening an exit to another location via @open <Name>=<Dbref>[,<Name>]. # Opening an exit to another location via @open <Name>=<Dbref>[,<Name>].
comma_split = eq_args[1].split(',') comma_split = eq_args[1].split(',', 1)
destination = Object.objects.standard_plr_objsearch(session, comma_split[0]) destination = Object.objects.standard_plr_objsearch(session,
comma_split[0])
# Use standard_plr_objsearch to handle duplicate/nonexistant results. # Use standard_plr_objsearch to handle duplicate/nonexistant results.
if not destination: if not destination:
return return
@ -339,43 +342,56 @@ def cmd_open(cdat):
session.msg("You can't open an exit to an exit!") session.msg("You can't open an exit to an exit!")
return 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) 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: if len(comma_split) > 1:
second_exit_name = ','.join(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) 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: else:
# Create an un-linked exit. # 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) new_object = Object.objects.create_object(odat)
session.msg("You open an unlinked exit - %s" % (new_object,)) 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. Sets an object's home or an exit's destination.
Forms: Forms:
@link <Object>=<Target> @link <Object>=<Target>
""" """
session = cdat['session'] session = command.session
pobject = session.get_pobject() pobject = session.get_pobject()
server = cdat['server'] server = command.server
args = cdat['uinput']['splitted'][1:]
if len(args) == 0: if not command.command_argument:
session.msg("Link what?") session.msg("Link what?")
return return
eq_args = args[0].split('=') eq_args = command.command_argument.split('=', 1)
target_name = eq_args[0] target_name = eq_args[0]
dest_name = '='.join(eq_args[1:]) dest_name = eq_args[1]
if len(target_name) == 0: if len(target_name) == 0:
session.msg("What do you want to link?") 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.") session.msg("You must provide a destination to link to.")
return return
def cmd_unlink(cdat): def cmd_unlink(command):
""" """
Unlinks an object. 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?") session.msg("Unlink what?")
return return
else: 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. # Use standard_plr_objsearch to handle duplicate/nonexistant results.
if not target_obj: if not target_obj:
return return
@ -434,67 +452,75 @@ def cmd_unlink(cdat):
target_obj.set_home(None) target_obj.set_home(None)
session.msg("You have unlinked %s." % (target_obj.get_name(),)) 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'. 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!") session.msg("You must supply a name!")
else: else:
# Create and set the object up. # 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) new_object = Object.objects.create_object(odat)
session.msg("You create a new room: %s" % (new_object,)) session.msg("You create a new room: %s" % (new_object,))
def cmd_name(cdat): def cmd_name(command):
""" """
Handle naming an object. 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?") 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?") session.msg("What would you like to name that object?")
else: 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. # Use standard_plr_objsearch to handle duplicate/nonexistant results.
if not target_obj: if not target_obj:
return return
if len(eq_args[1]) == 0: ansi_name = ansi.parse_ansi(new_name, strip_formatting=True)
session.msg("What would you like to name that object?") session.msg("You have renamed %s to %s." % (target_obj, ansi_name))
else: target_obj.set_name(new_name)
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)
def cmd_description(cdat): def cmd_description(command):
""" """
Set an object's description. Set an object's description.
""" """
session = cdat['session'] session = command.session
pobject = session.get_pobject() 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?") 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?") session.msg("How would you like to describe that object?")
else: 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. # Use standard_plr_objsearch to handle duplicate/nonexistant results.
if not target_obj: if not target_obj:
return return
@ -503,45 +529,45 @@ def cmd_description(cdat):
session.msg(defines_global.NOCONTROL_MSG) session.msg(defines_global.NOCONTROL_MSG)
return return
new_desc = '='.join(eq_args[1:]) new_desc = eq_args[1]
session.msg("%s - DESCRIPTION set." % (target_obj,)) session.msg("%s - DESCRIPTION set." % (target_obj,))
target_obj.set_description(new_desc) target_obj.set_description(new_desc)
def cmd_destroy(cdat): def cmd_destroy(command):
""" """
Destroy an object. Destroy an object.
""" """
session = cdat['session'] session = command.session
pobject = session.get_pobject() pobject = session.get_pobject()
args = cdat['uinput']['splitted'][1:]
switches = cdat['uinput']['root_chunk'][1:]
switch_override = False switch_override = False
if "override" in switches: if not command.command_argument:
switch_override = True
if len(args) == 0:
session.msg("Destroy what?") session.msg("Destroy what?")
return return
else:
target_obj = Object.objects.standard_plr_objsearch(session, ' '.join(args)) # Safety feature. Switch required to delete players and SAFE objects.
# Use standard_plr_objsearch to handle duplicate/nonexistant results. if "override" in command.command_switches:
if not target_obj: switch_override = True
return
if target_obj.is_player(): target_obj = Object.objects.standard_plr_objsearch(session,
if pobject.id == target_obj.id: command.command_argument)
session.msg("You can't destroy yourself.") # Use standard_plr_objsearch to handle duplicate/nonexistant results.
return if not target_obj:
if not switch_override: return
session.msg("You must use @destroy/override on players.")
return if target_obj.is_player():
if target_obj.is_superuser(): if pobject.id == target_obj.id:
session.msg("You can't destroy a superuser.") session.msg("You can't destroy yourself.")
return
elif target_obj.is_going() or target_obj.is_garbage():
session.msg("That object is already destroyed.")
return 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(),)) session.msg("You destroy %s." % (target_obj.get_name(),))
target_obj.destroy() 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 apps.objects.models import Object
from src import defines_global from src import defines_global
from src import ansi from src import ansi
from src import session_mgr
from src.util import functions_general from src.util import functions_general
def cmd_reload(cdat): def cmd_reload(command):
""" """
Reloads all modules. Reloads all modules.
""" """
session = cdat['session'] session = command.session
server = session.server.reload(session) server = session.server.reload(session)
def cmd_boot(cdat): def cmd_boot(command):
""" """
Boot a player object from the server. Boot a player object from the server.
""" """
session = cdat['session'] session = command.session
pobject = session.get_pobject() 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_quiet = False
switch_port = False switch_port = False
if not pobject.is_staff(): if "quiet" in command.command_switches:
session.msg("You do not have permission to do that.") # Don't tell the player they've been disconnected, silently boot them.
return
if "quiet" in switches:
switch_quiet = True 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 switch_port = True
if len(args) == 0: if not command.command_argument:
session.msg("Who would you like to boot?") session.msg("Who would you like to boot?")
return return
else: else:
boot_list = [] boot_list = []
if switch_port: if switch_port:
# Boot a particular port.
sessions = session_mgr.get_session_list(True) sessions = session_mgr.get_session_list(True)
for sess in sessions: 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) boot_list.append(sess)
# We're done here # Match found, kill the loop and continue with booting.
break break
else: else:
# Grab the objects that match # 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: if not objs:
session.msg("Who would you like to boot?") session.msg("No name or dbref match found for booting.")
return return
if not objs[0].is_player(): if not objs[0].is_player():
@ -71,7 +69,15 @@ def cmd_boot(cdat):
if objs[0].is_connected_plr(): if objs[0].is_connected_plr():
boot_list.append(session_mgr.session_from_object(objs[0])) 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: for boot in boot_list:
if not switch_quiet: if not switch_quiet:
boot.msg("You have been disconnected by %s." % (pobject.name)) boot.msg("You have been disconnected by %s." % (pobject.name))
@ -79,25 +85,24 @@ def cmd_boot(cdat):
session_mgr.remove_session(boot) session_mgr.remove_session(boot)
return return
def cmd_newpassword(cdat): def cmd_newpassword(command):
""" """
Set a player's password. Set a player's password.
""" """
session = cdat['session'] session = command.session
pobject = session.get_pobject() pobject = session.get_pobject()
args = cdat['uinput']['splitted'][1:] eq_args = command.command_argument.split('=', 1)
eq_args = ' '.join(args).split('=') searchstring = eq_args[0]
searchstring = ''.join(eq_args[0]) newpass = eq_args[1]
newpass = ''.join(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") session.msg("What player's password do you want to change")
return return
if len(newpass) == 0: if len(newpass) == 0:
session.msg("You must supply a new password.") session.msg("You must supply a new password.")
return 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. # Use standard_plr_objsearch to handle duplicate/nonexistant results.
if not target_obj: if not target_obj:
return return
@ -114,14 +119,15 @@ def cmd_newpassword(cdat):
uaccount.set_password(newpass) uaccount.set_password(newpass)
uaccount.save() uaccount.save()
session.msg("%s - PASSWORD set." % (target_obj.get_name(),)) 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. Shut the server down gracefully.
""" """
session = cdat['session'] session = command.session
server = cdat['server'] server = command.server
pobject = session.get_pobject() pobject = session.get_pobject()
session.msg('Shutting down...') session.msg('Shutting down...')

View file

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

View file

@ -239,17 +239,16 @@ def get_cobj_from_name(cname):
""" """
return CommChannel.objects.get(name=cname) return CommChannel.objects.get(name=cname)
def create_channel(cdat): def create_channel(name, owner):
""" """
Create a new channel. cdat is a dictionary that contains the following keys. Create a new channel.
REQUIRED KEYS: name: (string) Name of the new channel
* name: The name of the new channel. owner: (Object) Objec that owns the channel
* owner: The creator of the channel.
""" """
new_chan = CommChannel() new_chan = CommChannel()
new_chan.name = ansi.parse_ansi(cdat["name"], strip_ansi=True) new_chan.name = ansi.parse_ansi(name, strip_ansi=True)
new_chan.ansi_name = "[%s]" % (ansi.parse_ansi(cdat["name"]),) new_chan.ansi_name = "[%s]" % (ansi.parse_ansi(name),)
new_chan.set_owner(cdat["owner"]) new_chan.set_owner(owner)
new_chan.save() new_chan.save()
return new_chan return new_chan

View file

@ -85,7 +85,7 @@ class EvenniaService(service.Service):
""" """
Return a string representing the server's command list. Return a string representing the server's command list.
""" """
clist = cmdtable.ctable.keys() clist = cmdtable.GLOBAL_CMD_TABLE.ctable.keys()
clist.sort() clist.sort()
return clist return clist

View file

@ -74,13 +74,20 @@ class SessionProtocol(StatefulTelnetProtocol):
Any line return indicates a command for the purpose of a MUD. So we take Any line return indicates a command for the purpose of a MUD. So we take
the user input and pass it to our command handler. the user input and pass it to our command handler.
""" """
# Clean up the input.
line = (''.join(data)) line = (''.join(data))
line = line.strip('\r') line = line.strip('\r')
uinput = line uinput = line
# Stuff anything we need to pass in this dictionary. # The Command object has all of the methods for parsing and preparing
cdat = {"server": self.factory.server, "uinput": uinput, "session": self} # for searching and execution.
cmdhandler.handle(cdat) command = cmdhandler.Command(uinput,
server=self.factory.server,
session=self)
# Send the command object to the command handler for parsing
# and eventual execution.
cmdhandler.handle(command)
def execute_cmd(self, cmdstr): def execute_cmd(self, cmdstr):
""" """

View file

@ -33,7 +33,7 @@ def cmd_check_num_args(session, arg_list, min_args, errortext="Missing arguments
Check a player command's splitted argument list to make sure it contains Check a player command's splitted argument list to make sure it contains
the minimum allowable number of arguments. the minimum allowable number of arguments.
""" """
if len(arg_list) < min_args+1: if len(arg_list) < min_args:
session.msg(errortext) session.msg(errortext)
return False return False
return True return True