basicobject.py

---------------
  - Checks for NULL description on objects- if Null, it doesn't print the extra line any more.
  - Made the checks for contents a little less ambiguous

cmdhandler.py
--------------
  - Added new method 'parse_command' which takes a command string and tries to break it up based on common command parsing rules.  Mostly complete, but could use some work on the edge cases.  Check out the docstring on the function- I tried to make it fairly well documented.
  - Changed the check for 'non-standard characters' to just return, rather than throw an Exception.  Not sure if this causes any issues, but I noticed that when you hit enter without entering a command it would trigger this code.  Now it just fails silently.
  - The handle function now calls the parse_command function now and stores the results in parsed_input['parsed_command'].  This then gets put into cdat['uinput'] at the end of handle() like before.  The old data in parsed_input is still there, this is just a new field.
  - Added cdat['raw_input'] to pass the full, untouched command string on.  This is also stored in parsed_input['parsed_command']['raw_command'] so not sure fi this is necessary any longer, probably not.

cmdtable.py
------------
  - Just cleaned it up a bit and straightened out the columns after changing 3-4 space indentation.

apps/objects/models.py
-----------------------
  - set_description now sets the description attribute to 'None' (or Null in the db) when given a blank description.  This is used for the change mentioned above in basicobject.py
  - get_description now returns None if self.description is None
  - used defines_global in the comparison methods like is_player

functions_db.py
----------------
  - Changed import defines_global as defines_global to just 'import defines_global'- wasn't sure why this was this way, if I broke something (I didn't seem to) let me know.
  - renamed player_search to player_name_search.  Removed the use of local_and_global_search inside of it.  local_and_global_search now calls it when it receives a search_string that starts with *.
  - alias_search now only looks at attributes with attr_name == ALIAS.  It used to just look at attr_value, which could match anything, it seemed.
  - added 'dbref_search'
  - local_and_global_search changes:
    - Now uses dbref_search & player_search if the string starts with "#" or "*" respectively
    - Changed when it uses dbref_search to whenever the search_string is a dbref.  It used to check that it was a dbref, and that search_contents & search_location were set, but I *believe* in most MU*'s when you supply a dbref it never fails to find the object.

commands/unloggedin.py
-----------------------
  - removed hardcoded object type #'s and started using defines_global instead
  - when creating a new account, made sure that no object with an alias matching the player name requested exists.  This is behavior from TinyMUSH, and I think most MUSHs follow this, but if not this is easy enough to change back.

commands/general.py
--------------------
  - Rewrote cmd_page:
    - New Features
      - Page by dbref
      - Page multiple people
      - pose (:) and no space pose (;) pages
      - When someone hits page without a target or data, it now will tell the player who they last paged, or say they haven't paged anyone if they don't have a LASTPAGED
    - uses parse_command, made it a lot easier to work through the extra functionality added above
    - When there are multiple words in a page target, it first tries to find a player that matches the entire string.  If that fails, then it goes through each word, assuming each is a separate target, and works out paging them.

commands/objmanip.py
---------------------
  - I started to muck with cmd_name & cmd_page, but decided to hold off for now.  Largely, if everyone is cool with the idea that names & aliases should be totally unique, then we need to go ahead and re-write these.  I'll do that if everyone is cool with it.
This commit is contained in:
loki77 2008-06-13 18:15:54 +00:00
parent 87fb121427
commit ad009e20ab
8 changed files with 2634 additions and 2441 deletions

File diff suppressed because it is too large Load diff

View file

@ -14,170 +14,245 @@ something.
""" """
class UnknownCommand(Exception): class UnknownCommand(Exception):
""" """
Throw this when a user enters an an invalid command. Throw this when a user enters an an invalid command.
""" """
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=4)
return functions_db.list_search_object_namestr(exits, searchstr, match_type="exact") return functions_db.list_search_object_namestr(exits, searchstr, match_type="exact")
def parse_command(command_string):
"""
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): 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.
We're basically grabbing the player's command by tacking We're basically grabbing the player's command by tacking
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 = cdat['session']
server = cdat['server'] server = cdat['server']
try: try:
# TODO: Protect against non-standard characters. # TODO: Protect against non-standard characters.
if cdat['uinput'] == '': if cdat['uinput'] == '':
raise UnknownCommand
uinput = cdat['uinput'].split()
parsed_input = {}
# First we split the input up by spaces.
parsed_input['splitted'] = uinput
# 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()
# 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
# don't replace the existing root_cmd. If the key exists, its value
# replaces the previously splitted root_cmd. For example, sa -> say.
alias_list = server.cmd_alias_list
parsed_input['root_cmd'] = alias_list.get(parsed_input['root_cmd'],parsed_input['root_cmd'])
# This will hold the reference to the command's function.
cmd = None
if session.logged_in:
# Store the timestamp of the user's last command.
session.cmd_last = time.time()
# Lets the users get around badly configured NAT timeouts.
if parsed_input['root_cmd'] == 'idle':
return return
# Increment our user's command counter. parsed_input = {}
session.cmd_total += 1 parsed_input['parsed_command'] = parse_command(cdat['uinput'])
# Player-visible idle time, not used in idle timeout calcs.
session.cmd_last_visible = time.time()
# Just in case. Prevents some really funky-case crashes. # First we split the input up by spaces.
if len(parsed_input['root_cmd']) == 0: parsed_input['splitted'] = cdat['uinput'].split()
raise UnknownCommand # 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']
# Shortened say alias. # Now we'll see if the user is using an alias. We do a dictionary lookup,
if parsed_input['root_cmd'][0] == '"': # if the key (the player's root command) doesn't exist on the dict, we
parsed_input['splitted'].insert(0, "say") # don't replace the existing root_cmd. If the key exists, its value
parsed_input['splitted'][1] = parsed_input['splitted'][1][1:] # replaces the previously splitted root_cmd. For example, sa -> say.
parsed_input['root_cmd'] = 'say' alias_list = server.cmd_alias_list
# Shortened pose alias. parsed_input['root_cmd'] = alias_list.get(parsed_input['root_cmd'],parsed_input['root_cmd'])
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 functions_comsys.plr_has_channel(session,
parsed_input['root_cmd'],
alias_search=True,
return_muted=True):
calias = parsed_input['root_cmd'] # This will hold the reference to the command's function.
cname = functions_comsys.plr_cname_from_alias(session, calias) cmd = None
cmessage = ' '.join(parsed_input['splitted'][1:])
if cmessage == "who": if session.logged_in:
functions_comsys.msg_cwho(session, cname) # Store the timestamp of the user's last command.
return session.cmd_last = time.time()
elif cmessage == "on":
functions_comsys.plr_chan_on(session, calias)
return
elif cmessage == "off":
functions_comsys.plr_chan_off(session, calias)
return
elif cmessage == "last":
functions_comsys.msg_chan_hist(session, cname)
return
second_arg = "%s=%s" % (cname, cmessage) # Lets the users get around badly configured NAT timeouts.
parsed_input['splitted'] = ["@cemit/sendername", second_arg] if parsed_input['root_cmd'] == 'idle':
parsed_input['root_chunk'] = ['@cemit', 'sendername', 'quiet'] return
parsed_input['root_cmd'] = '@cemit'
# Get the command's function reference (Or False) # Increment our user's command counter.
cmdtuple = cmdtable.return_cmdtuple(parsed_input['root_cmd']) session.cmd_total += 1
if cmdtuple: # Player-visible idle time, not used in idle timeout calcs.
# If there is a permissions element to the entry, check perms. session.cmd_last_visible = time.time()
if cmdtuple[1]:
if not session.get_pobject().user_has_perm_list(cmdtuple[1]):
session.msg(defines_global.NOPERMS_MSG)
return
# If flow reaches this point, user has perms and command is ready.
cmd = cmdtuple[0]
else: # Just in case. Prevents some really funky-case crashes.
# Not logged in, look through the unlogged-in command table. if len(parsed_input['root_cmd']) == 0:
cmdtuple = cmdtable.return_cmdtuple(parsed_input['root_cmd'], unlogged_cmd=True) raise UnknownCommand
if cmdtuple:
cmd = cmdtuple[0]
# Debugging stuff. # Shortened say alias.
#session.msg("ROOT : %s" % (parsed_input['root_cmd'],)) if parsed_input['root_cmd'][0] == '"':
#session.msg("SPLIT: %s" % (parsed_input['splitted'],)) 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 functions_comsys.plr_has_channel(session,
parsed_input['root_cmd'],
alias_search=True,
return_muted=True):
if callable(cmd): calias = parsed_input['root_cmd']
cdat['uinput'] = parsed_input cname = functions_comsys.plr_cname_from_alias(session, calias)
try: cmessage = ' '.join(parsed_input['splitted'][1:])
cmd(cdat)
except:
session.msg("Untrapped error, please file a bug report:\n%s" % (format_exc(),))
functions_general.log_errmsg("Untrapped error, evoker %s: %s" %
(session, format_exc()))
return
if session.logged_in: if cmessage == "who":
# If we're not logged in, don't check exits. functions_comsys.msg_cwho(session, cname)
pobject = session.get_pobject() return
exit_matches = match_exits(pobject, ' '.join(parsed_input['splitted'])) elif cmessage == "on":
if exit_matches: functions_comsys.plr_chan_on(session, calias)
targ_exit = exit_matches[0] return
if targ_exit.get_home(): elif cmessage == "off":
cdat['uinput'] = parsed_input functions_comsys.plr_chan_off(session, calias)
return
elif cmessage == "last":
functions_comsys.msg_chan_hist(session, cname)
return
# SCRIPT: See if the player can traverse the exit second_arg = "%s=%s" % (cname, cmessage)
if not targ_exit.get_scriptlink().default_lock({ parsed_input['splitted'] = ["@cemit/sendername", second_arg]
"pobject": pobject parsed_input['root_chunk'] = ['@cemit', 'sendername', 'quiet']
}): parsed_input['root_cmd'] = '@cemit'
session.msg("You can't traverse that exit.")
else: # Get the command's function reference (Or False)
pobject.move_to(targ_exit.get_home()) cmdtuple = cmdtable.return_cmdtuple(parsed_input['root_cmd'])
session.execute_cmd("look") if cmdtuple:
else: # If there is a permissions element to the entry, check perms.
session.msg("That exit leads to nowhere.") if cmdtuple[1]:
if not session.get_pobject().user_has_perm_list(cmdtuple[1]):
session.msg(defines_global.NOPERMS_MSG)
return
# If flow reaches this point, user has perms and command is ready.
cmd = cmdtuple[0]
else:
# Not logged in, look through the unlogged-in command table.
cmdtuple = cmdtable.return_cmdtuple(parsed_input['root_cmd'], unlogged_cmd=True)
if cmdtuple:
cmd = cmdtuple[0]
# Debugging stuff.
#session.msg("ROOT : %s" % (parsed_input['root_cmd'],))
#session.msg("SPLIT: %s" % (parsed_input['splitted'],))
if callable(cmd):
cdat['uinput'] = parsed_input
try:
cmd(cdat)
except:
session.msg("Untrapped error, please file a bug report:\n%s" % (format_exc(),))
functions_general.log_errmsg("Untrapped error, evoker %s: %s" %
(session, format_exc()))
return return
# If we reach this point, we haven't matched anything. if session.logged_in:
raise UnknownCommand # If we're not logged in, don't check exits.
pobject = session.get_pobject()
exit_matches = match_exits(pobject, ' '.join(parsed_input['splitted']))
if exit_matches:
targ_exit = exit_matches[0]
if targ_exit.get_home():
cdat['uinput'] = parsed_input
except UnknownCommand: # SCRIPT: See if the player can traverse the exit
session.msg("Huh? (Type \"help\" for help.)") if not targ_exit.get_scriptlink().default_lock({
"pobject": pobject
}):
session.msg("You can't traverse that exit.")
else:
pobject.move_to(targ_exit.get_home())
session.execute_cmd("look")
else:
session.msg("That exit leads to nowhere.")
return
# If we reach this point, we haven't matched anything.
raise UnknownCommand
except UnknownCommand:
session.msg("Huh? (Type \"help\" for help.)")

View file

@ -18,73 +18,73 @@ permissions tuple.
""" """
# -- Unlogged-in Command Table -- # -- Unlogged-in Command Table --
# Command Name Command Function Privilege Tuple # Command Name Command Function Privilege Tuple
uncon_ctable = { uncon_ctable = {
"connect": (commands.unloggedin.cmd_connect, None), "connect": (commands.unloggedin.cmd_connect, None),
"create": (commands.unloggedin.cmd_create, None), "create": (commands.unloggedin.cmd_create, None),
"quit": (commands.unloggedin.cmd_quit, None), "quit": (commands.unloggedin.cmd_quit, None),
} }
# -- Command Table -- # -- Command Table --
# Command Name Command Function Privilege Tuple # Command Name Command Function Privilege Tuple
ctable = { ctable = {
"addcom": (commands.comsys.cmd_addcom, None), "addcom": (commands.comsys.cmd_addcom, None),
"comlist": (commands.comsys.cmd_comlist, None), "comlist": (commands.comsys.cmd_comlist, None),
"delcom": (commands.comsys.cmd_delcom, None), "delcom": (commands.comsys.cmd_delcom, None),
"drop": (commands.general.cmd_drop, None), "drop": (commands.general.cmd_drop, None),
"examine": (commands.general.cmd_examine, None), "examine": (commands.general.cmd_examine, None),
"get": (commands.general.cmd_get, None), "get": (commands.general.cmd_get, None),
"help": (commands.general.cmd_help, None), "help": (commands.general.cmd_help, None),
"idle": (commands.general.cmd_idle, None), "idle": (commands.general.cmd_idle, None),
"inventory": (commands.general.cmd_inventory, None), "inventory": (commands.general.cmd_inventory, None),
"look": (commands.general.cmd_look, None), "look": (commands.general.cmd_look, None),
"page": (commands.general.cmd_page, None), "page": (commands.general.cmd_page, None),
"pose": (commands.general.cmd_pose, None), "pose": (commands.general.cmd_pose, None),
"quit": (commands.general.cmd_quit, None), "quit": (commands.general.cmd_quit, None),
"say": (commands.general.cmd_say, None), "say": (commands.general.cmd_say, None),
"time": (commands.general.cmd_time, None), "time": (commands.general.cmd_time, None),
"uptime": (commands.general.cmd_uptime, None), "uptime": (commands.general.cmd_uptime, None),
"version": (commands.general.cmd_version, None), "version": (commands.general.cmd_version, None),
"who": (commands.general.cmd_who, None), "who": (commands.general.cmd_who, None),
"@alias": (commands.objmanip.cmd_alias, None), "@alias": (commands.objmanip.cmd_alias, None),
"@boot": (commands.privileged.cmd_boot, ("genperms.manage_players")), "@boot": (commands.privileged.cmd_boot, ("genperms.manage_players")),
"@ccreate": (commands.comsys.cmd_ccreate, ("objects.add_commchannel")), "@ccreate": (commands.comsys.cmd_ccreate, ("objects.add_commchannel")),
"@cdestroy": (commands.comsys.cmd_cdestroy, ("objects.delete_commchannel")), "@cdestroy": (commands.comsys.cmd_cdestroy, ("objects.delete_commchannel")),
"@cemit": (commands.comsys.cmd_cemit, None), "@cemit": (commands.comsys.cmd_cemit, None),
"@clist": (commands.comsys.cmd_clist, None), "@clist": (commands.comsys.cmd_clist, None),
"@create": (commands.objmanip.cmd_create, ("genperms.builder")), "@create": (commands.objmanip.cmd_create, ("genperms.builder")),
"@describe": (commands.objmanip.cmd_description, None), "@describe": (commands.objmanip.cmd_description, None),
"@destroy": (commands.objmanip.cmd_destroy, ("genperms.builder")), "@destroy": (commands.objmanip.cmd_destroy, ("genperms.builder")),
"@dig": (commands.objmanip.cmd_dig, ("genperms.builder")), "@dig": (commands.objmanip.cmd_dig, ("genperms.builder")),
"@emit": (commands.general.cmd_emit, ("genperms.announce")), "@emit": (commands.general.cmd_emit, ("genperms.announce")),
"@find": (commands.objmanip.cmd_find, ("genperms.builder")), # "@pemit": (commands.general.cmd_pemit, None),
"@link": (commands.objmanip.cmd_link, ("genperms.builder")), "@find": (commands.objmanip.cmd_find, ("genperms.builder")),
"@list": (commands.info.cmd_list, ("genperms.process_control")), "@link": (commands.objmanip.cmd_link, ("genperms.builder")),
"@name": (commands.objmanip.cmd_name, None), "@list": (commands.info.cmd_list, ("genperms.process_control")),
"@nextfree": (commands.objmanip.cmd_nextfree, ("genperms.builder")), "@name": (commands.objmanip.cmd_name, None),
"@newpassword": (commands.privileged.cmd_newpassword, ("genperms.manage_players")), "@nextfree": (commands.objmanip.cmd_nextfree, ("genperms.builder")),
"@open": (commands.objmanip.cmd_open, ("genperms.builder")), "@newpassword": (commands.privileged.cmd_newpassword, ("genperms.manage_players")),
"@password": (commands.general.cmd_password, None), "@open": (commands.objmanip.cmd_open, ("genperms.builder")),
"@ps": (commands.info.cmd_ps, ("genperms.process_control")), "@password": (commands.general.cmd_password, None),
"@reload": (commands.privileged.cmd_reload, ("genperms.process_control")), "@ps": (commands.info.cmd_ps, ("genperms.process_control")),
"@set": (commands.objmanip.cmd_set, None), "@reload": (commands.privileged.cmd_reload, ("genperms.process_control")),
"@shutdown": (commands.privileged.cmd_shutdown, ("genperms.process_control")), "@set": (commands.objmanip.cmd_set, None),
"@stats": (commands.info.cmd_stats, None), "@shutdown": (commands.privileged.cmd_shutdown, ("genperms.process_control")),
"@teleport": (commands.objmanip.cmd_teleport, ("genperms.builder")), "@stats": (commands.info.cmd_stats, None),
"@unlink": (commands.objmanip.cmd_unlink, ("genperms.builder")), "@teleport": (commands.objmanip.cmd_teleport, ("genperms.builder")),
"@wall": (commands.general.cmd_wall, ("genperms.announce")), "@unlink": (commands.objmanip.cmd_unlink, ("genperms.builder")),
"@wipe": (commands.objmanip.cmd_wipe, None), "@wall": (commands.general.cmd_wall, ("genperms.announce")),
"@wipe": (commands.objmanip.cmd_wipe, None),
} }
def return_cmdtuple(func_name, unlogged_cmd=False): def return_cmdtuple(func_name, unlogged_cmd=False):
""" """
Returns a reference to the command's tuple. If there are no matches, Returns a reference to the command's tuple. If there are no matches,
returns false. returns false.
""" """
if not unlogged_cmd: if not unlogged_cmd:
cfunc = ctable.get(func_name, False) cfunc = ctable.get(func_name, False)
else: else:
cfunc = uncon_ctable.get(func_name, False) cfunc = uncon_ctable.get(func_name, False)
return cfunc
return cfunc

View file

@ -12,486 +12,553 @@ Generic command module. Pretty much every command should go here for
now. now.
""" """
def cmd_password(cdat): def cmd_password(cdat):
""" """
Changes your own password. Changes your own password.
@newpass <Oldpass>=<Newpass> @newpass <Oldpass>=<Newpass>
""" """
session = cdat['session'] session = cdat['session']
pobject = session.get_pobject() pobject = session.get_pobject()
args = cdat['uinput']['splitted'][1:] args = cdat['uinput']['splitted'][1:]
eq_args = ' '.join(args).split('=') eq_args = ' '.join(args).split('=')
oldpass = ''.join(eq_args[0]) oldpass = ''.join(eq_args[0])
newpass = ''.join(eq_args[1:]) newpass = ''.join(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.")
elif len(newpass) == 0: elif len(newpass) == 0:
session.msg("You must provide your new password.") session.msg("You must provide your new password.")
else: else:
uaccount = pobject.get_user_account() uaccount = pobject.get_user_account()
if not uaccount.check_password(oldpass): if not uaccount.check_password(oldpass):
session.msg("The specified old password isn't correct.") session.msg("The specified old password isn't correct.")
elif len(newpass) < 3: elif len(newpass) < 3:
session.msg("Passwords must be at least three characters long.") session.msg("Passwords must be at least three characters long.")
return return
else: else:
uaccount.set_password(newpass) uaccount.set_password(newpass)
uaccount.save() uaccount.save()
session.msg("Password changed.") session.msg("Password changed.")
def cmd_emit(cdat): def cmd_emit(cdat):
""" """
Emits something to your location. Emits something to your location.
""" """
session = cdat['session'] session = cdat['session']
pobject = session.get_pobject() pobject = session.get_pobject()
uinput= cdat['uinput']['splitted'] uinput= cdat['uinput']['splitted']
message = ' '.join(uinput[1:]) message = ' '.join(uinput[1:])
if message == '': if message == '':
session.msg("Emit what?") session.msg("Emit what?")
else: else:
pobject.get_location().emit_to_contents(message) pobject.get_location().emit_to_contents(message)
def cmd_wall(cdat): def cmd_wall(cdat):
""" """
Announces a message to all connected players. Announces a message to all connected players.
""" """
session = cdat['session'] session = cdat['session']
wallstring = ' '.join(cdat['uinput']['splitted'][1:]) wallstring = ' '.join(cdat['uinput']['splitted'][1:])
pobject = session.get_pobject() pobject = session.get_pobject()
if wallstring == '': if 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)
functions_general.announce_all(message) functions_general.announce_all(message)
def cmd_idle(cdat): def cmd_idle(cdat):
""" """
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(cdat):
""" """
Shows a player's inventory. Shows a player's inventory.
""" """
session = cdat['session'] session = cdat['session']
pobject = session.get_pobject() pobject = session.get_pobject()
session.msg("You are carrying:") session.msg("You are carrying:")
for item in pobject.get_contents(): for item in pobject.get_contents():
session.msg(" %s" % (item.get_name(),)) session.msg(" %s" % (item.get_name(),))
money = int(pobject.get_attribute_value("MONEY", default=0)) money = int(pobject.get_attribute_value("MONEY", default=0))
if money == 1: if money == 1:
money_name = gameconf.get_configvalue("MONEY_NAME_SINGULAR") money_name = gameconf.get_configvalue("MONEY_NAME_SINGULAR")
else: else:
money_name = gameconf.get_configvalue("MONEY_NAME_PLURAL") money_name = gameconf.get_configvalue("MONEY_NAME_PLURAL")
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(cdat):
""" """
Handle looking at objects. Handle looking at objects.
""" """
session = cdat['session'] session = cdat['session']
pobject = session.get_pobject() pobject = session.get_pobject()
args = cdat['uinput']['splitted'][1:] args = cdat['uinput']['splitted'][1:]
if len(args) == 0: if len(args) == 0:
target_obj = pobject.get_location() target_obj = pobject.get_location()
else: else:
target_obj = functions_db.standard_plr_objsearch(session, ' '.join(args)) target_obj = functions_db.standard_plr_objsearch(session, ' '.join(args))
# 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
# SCRIPT: Get the item's appearance from the scriptlink. # SCRIPT: Get the item's appearance from the scriptlink.
session.msg(target_obj.get_scriptlink().return_appearance({ session.msg(target_obj.get_scriptlink().return_appearance({
"target_obj": target_obj, "target_obj": target_obj,
"pobject": pobject "pobject": pobject
})) }))
# SCRIPT: Call the object's script's a_desc() method. # SCRIPT: Call the object's script's a_desc() method.
target_obj.get_scriptlink().a_desc({ target_obj.get_scriptlink().a_desc({
"target_obj": pobject "target_obj": pobject
}) })
def cmd_get(cdat): def cmd_get(cdat):
""" """
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 = cdat['session']
pobject = session.get_pobject() pobject = session.get_pobject()
args = cdat['uinput']['splitted'][1:] args = cdat['uinput']['splitted'][1:]
plr_is_staff = pobject.is_staff() plr_is_staff = pobject.is_staff()
if len(args) == 0: if len(args) == 0:
session.msg("Get what?") session.msg("Get what?")
return return
else: else:
target_obj = functions_db.standard_plr_objsearch(session, ' '.join(args), search_contents=False) target_obj = functions_db.standard_plr_objsearch(session, ' '.join(args), 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
if pobject == target_obj: if pobject == target_obj:
session.msg("You can't get yourself.") session.msg("You can't get yourself.")
return return
if not plr_is_staff and (target_obj.is_player() or target_obj.is_exit()): if not plr_is_staff and (target_obj.is_player() or target_obj.is_exit()):
session.msg("You can't get that.") session.msg("You can't get that.")
return return
if target_obj.is_room() or target_obj.is_garbage() or target_obj.is_going(): if target_obj.is_room() or target_obj.is_garbage() or target_obj.is_going():
session.msg("You can't get that.") session.msg("You can't get that.")
return return
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.get_scriptlink().a_get({ target_obj.get_scriptlink().a_get({
"pobject": pobject "pobject": pobject
}) })
def cmd_drop(cdat): def cmd_drop(cdat):
""" """
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 = cdat['session']
pobject = session.get_pobject() pobject = session.get_pobject()
args = cdat['uinput']['splitted'][1:] args = cdat['uinput']['splitted'][1:]
plr_is_staff = pobject.is_staff() plr_is_staff = pobject.is_staff()
if len(args) == 0: if len(args) == 0:
session.msg("Drop what?") session.msg("Drop what?")
return return
else: else:
target_obj = functions_db.standard_plr_objsearch(session, ' '.join(args), search_location=False) target_obj = functions_db.standard_plr_objsearch(session, ' '.join(args), 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
if not pobject == target_obj.get_location(): if not pobject == target_obj.get_location():
session.msg("You don't appear to be carrying that.") session.msg("You don't appear to be carrying that.")
return return
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.get_scriptlink().a_drop({ target_obj.get_scriptlink().a_drop({
"pobject": pobject "pobject": pobject
}) })
def cmd_examine(cdat): def cmd_examine(cdat):
""" """
Detailed object examine command Detailed object examine command
""" """
session = cdat['session'] session = cdat['session']
pobject = session.get_pobject() pobject = session.get_pobject()
args = cdat['uinput']['splitted'][1:] args = cdat['uinput']['splitted'][1:]
attr_search = False attr_search = False
if len(args) == 0: if len(args) == 0:
# 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 = args[0].split("/")
# 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.
if len(attr_split) > 1: if len(attr_split) > 1:
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[0]
# Just in case there's a slash in an attribute name. # Just in case there's a slash in an attribute name.
attr_searchstr = '/'.join(attr_split[1:]) attr_searchstr = '/'.join(attr_split[1:])
else: else:
searchstr = ' '.join(args) searchstr = ' '.join(args)
target_obj = functions_db.standard_plr_objsearch(session, searchstr) target_obj = functions_db.standard_plr_objsearch(session, 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:
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())
else:
session.msg("No matching attributes found.")
# End attr_search if()
else:
session.msg("%s\r\n%s" % (
target_obj.get_name(fullname=True),
target_obj.get_description(no_parsing=True),
))
session.msg("Type: %s Flags: %s" % (target_obj.get_type(), target_obj.get_flags()))
session.msg("Owner: %s " % (target_obj.get_owner(),))
session.msg("Zone: %s" % (target_obj.get_zone(),))
for attribute in target_obj.get_all_attributes():
session.msg(attribute.get_attrline()) session.msg(attribute.get_attrline())
else:
session.msg("No matching attributes found.")
# End attr_search if()
else:
session.msg("%s\r\n%s" % (
target_obj.get_name(fullname=True),
target_obj.get_description(no_parsing=True),
))
session.msg("Type: %s Flags: %s" % (target_obj.get_type(), target_obj.get_flags()))
session.msg("Owner: %s " % (target_obj.get_owner(),))
session.msg("Zone: %s" % (target_obj.get_zone(),))
for attribute in target_obj.get_all_attributes(): con_players = []
session.msg(attribute.get_attrline()) con_things = []
con_exits = []
con_players = [] for obj in target_obj.get_contents():
con_things = [] if obj.is_player():
con_exits = [] con_players.append(obj)
elif obj.is_exit():
con_exits.append(obj)
elif obj.is_thing():
con_things.append(obj)
for obj in target_obj.get_contents(): if con_players or con_things:
if obj.is_player(): session.msg("%sContents:%s" % (ansi.ansi["hilite"], ansi.ansi["normal"],))
con_players.append(obj) for player in con_players:
elif obj.is_exit(): session.msg('%s' % (player.get_name(fullname=True),))
con_exits.append(obj) for thing in con_things:
elif obj.is_thing(): session.msg('%s' % (thing.get_name(fullname=True),))
con_things.append(obj)
if con_players or con_things: if con_exits:
session.msg("%sContents:%s" % (ansi.ansi["hilite"], ansi.ansi["normal"],)) session.msg("%sExits:%s" % (ansi.ansi["hilite"], ansi.ansi["normal"],))
for player in con_players: for exit in con_exits:
session.msg('%s' % (player.get_name(fullname=True),)) session.msg('%s' %(exit.get_name(fullname=True),))
for thing in con_things:
session.msg('%s' % (thing.get_name(fullname=True),))
if con_exits: if not target_obj.is_room():
session.msg("%sExits:%s" % (ansi.ansi["hilite"], ansi.ansi["normal"],)) if target_obj.is_exit():
for exit in con_exits: session.msg("Destination: %s" % (target_obj.get_home(),))
session.msg('%s' %(exit.get_name(fullname=True),)) else:
session.msg("Home: %s" % (target_obj.get_home(),))
if not target_obj.is_room(): session.msg("Location: %s" % (target_obj.get_location(),))
if target_obj.is_exit():
session.msg("Destination: %s" % (target_obj.get_home(),))
else:
session.msg("Home: %s" % (target_obj.get_home(),))
session.msg("Location: %s" % (target_obj.get_location(),))
def cmd_page(cdat): def cmd_page(cdat):
""" """
Send a message to target user (if online). Send a message to target user (if online).
""" """
session = cdat['session'] session = cdat['session']
pobject = session.get_pobject() pobject = session.get_pobject()
server = cdat['server'] server = cdat['server']
args = cdat['uinput']['splitted'][1:] 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 functions_db.is_dbref(dbref):
raise ValueError
last_paged_object = functions_db.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 len(args) == 0: # If they don't give a target, or any data to send to the target
session.msg("Page who/what?") # then tell them who they last paged if they paged someone, if not
return # 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
# Combine the arguments into one string, split it by equal signs into # Build a list of targets
# victim (entry 0 in the list), and message (entry 1 and above). # If there are no targets, then set the targets to the last person they
eq_args = ' '.join(args).split('=') # 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 = functions_db.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 functions_db.is_dbref(target):
session.msg("Is dbref.")
matched_object = functions_db.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 = functions_db.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"
# If no equal sign is in the passed arguments, see if the player has # We build a list of target_names for the sender_message later
# a LASTPAGED attribute. If they do, default the page to them, if not, target_names = []
# don't touch anything and error out. for target in targets.keys():
if len(eq_args) == 1 and pobject.has_attribute("LASTPAGED"): # Check to make sure they're connected, or a player
eq_args.insert(0, "#%s" % (pobject.get_attribute_value("LASTPAGED"),)) 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(eq_args) > 1: if len(target_names) > 0:
target = functions_db.player_search(pobject, eq_args[0]) target_names_string = ', '.join(target_names)
message = ' '.join(eq_args[1:]) try:
session.msg(sender_message % (target_names_string, sender_name, data))
if len(target) == 0: except TypeError:
session.msg("I don't recognize \"%s\"." % (eq_args[0].capitalize(),)) session.msg(sender_message % (target_names_string, data))
return # Now set the LASTPAGED attribute
elif len(message) == 0: pobject.set_attribute("LASTPAGED", ','.join(
session.msg("I need a message to deliver.") ["#%d" % (x.id) for x in targets.keys()]))
return
elif len(target) > 1:
session.msg("Try a more unique spelling of their name.")
return
else:
if target[0].is_connected_plr():
target[0].emit_to("%s pages: %s" %
(pobject.get_name(show_dbref=False), message))
session.msg("You paged %s with '%s'." %
(target[0].get_name(show_dbref=False), message))
pobject.set_attribute("LASTPAGED", target[0].id)
else:
session.msg("Player %s does not exist or is not online." %
(target[0].get_name(show_dbref=False),))
else:
session.msg("Page who?")
return
def cmd_quit(cdat): 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 = cdat['session']
session.msg("Quitting!") session.msg("Quitting!")
session.handle_close() session.handle_close()
def cmd_who(cdat): def cmd_who(cdat):
""" """
Generic WHO command. Generic WHO command.
""" """
session_list = session_mgr.get_session_list() session_list = session_mgr.get_session_list()
session = cdat['session'] session = cdat['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")
# Only those with the see_session_data or superuser status can see # Only those with the see_session_data or superuser status can see
# session details. # session details.
if show_session_data: if show_session_data:
retval = "Player Name On For Idle Room Cmds Host\n\r" retval = "Player Name On For Idle Room Cmds Host\n\r"
else: else:
retval = "Player Name On For Idle\n\r" retval = "Player Name On For Idle\n\r"
for player in session_list: for player in session_list:
if not player.logged_in: if not player.logged_in:
continue continue
delta_cmd = time.time() - player.cmd_last_visible delta_cmd = time.time() - player.cmd_last_visible
delta_conn = time.time() - player.conn_time delta_conn = time.time() - player.conn_time
plr_pobject = player.get_pobject() plr_pobject = player.get_pobject()
if show_session_data: if show_session_data:
retval += '%-16s%9s %4s%-3s#%-6d%5d%3s%-25s\r\n' % \ retval += '%-16s%9s %4s%-3s#%-6d%5d%3s%-25s\r\n' % \
(plr_pobject.get_name(show_dbref=False)[:25].ljust(27), \ (plr_pobject.get_name(show_dbref=False)[:25].ljust(27), \
# On-time # On-time
functions_general.time_format(delta_conn,0), \ functions_general.time_format(delta_conn,0), \
# Idle time # Idle time
functions_general.time_format(delta_cmd,1), \ functions_general.time_format(delta_cmd,1), \
# Flags # Flags
'', \ '', \
# Location # Location
plr_pobject.get_location().id, \ plr_pobject.get_location().id, \
player.cmd_total, \ player.cmd_total, \
# More flags? # More flags?
'', \ '', \
player.address[0]) player.address[0])
else: else:
retval += '%-16s%9s %4s%-3s\r\n' % \ retval += '%-16s%9s %4s%-3s\r\n' % \
(plr_pobject.get_name(show_dbref=False)[:25].ljust(27), \ (plr_pobject.get_name(show_dbref=False)[:25].ljust(27), \
# On-time # On-time
functions_general.time_format(delta_conn,0), \ functions_general.time_format(delta_conn,0), \
# Idle time # Idle time
functions_general.time_format(delta_cmd,1), \ functions_general.time_format(delta_cmd,1), \
# Flags # Flags
'') '')
retval += '%d Players logged in.' % (len(session_list),) retval += '%d Players logged in.' % (len(session_list),)
session.msg(retval) session.msg(retval)
def cmd_say(cdat): def cmd_say(cdat):
""" """
Room-based speech command. Room-based speech command.
""" """
session = cdat['session'] session = cdat['session']
if not functions_general.cmd_check_num_args(session, cdat['uinput']['splitted'], 1, errortext="Say what?"): if not functions_general.cmd_check_num_args(session, cdat['uinput']['splitted'], 1, errortext="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 = ' '.join(cdat['uinput']['splitted'][1:])
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]
retval = "You say, '%s'" % (speech,) retval = "You say, '%s'" % (speech,)
for player in players_present: for player in players_present:
player.msg("%s says, '%s'" % (pobject.get_name(show_dbref=False), speech,)) player.msg("%s says, '%s'" % (pobject.get_name(show_dbref=False), speech,))
session.msg(retval) session.msg(retval)
def cmd_pose(cdat): def cmd_pose(cdat):
""" """
Pose/emote command. Pose/emote command.
""" """
session = cdat['session'] session = cdat['session']
pobject = session.get_pobject() pobject = session.get_pobject()
switches = cdat['uinput']['root_chunk'][1:] switches = cdat['uinput']['root_chunk'][1:]
if not functions_general.cmd_check_num_args(session, cdat['uinput']['splitted'], 1, errortext="Do what?"): if not functions_general.cmd_check_num_args(session, cdat['uinput']['splitted'], 1, errortext="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 = ' '.join(cdat['uinput']['splitted'][1:])
if "nospace" in switches: if "nospace" in switches:
sent_msg = "%s%s" % (pobject.get_name(show_dbref=False), speech) sent_msg = "%s%s" % (pobject.get_name(show_dbref=False), speech)
else: else:
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()]
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(cdat):
""" """
Help system commands. Help system commands.
""" """
session = cdat['session'] session = cdat['session']
pobject = session.get_pobject() pobject = session.get_pobject()
topicstr = ' '.join(cdat['uinput']['splitted'][1:]) topicstr = ' '.join(cdat['uinput']['splitted'][1:])
if len(topicstr) == 0: if len(topicstr) == 0:
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.")
return return
topics = functions_help.find_topicmatch(pobject, topicstr) topics = functions_help.find_topicmatch(pobject, topicstr)
if len(topics) == 0: if len(topics) == 0:
session.msg("No matching topics found, please refine your search.") session.msg("No matching topics found, please refine your search.")
suggestions = functions_help.find_topicsuggestions(pobject, topicstr) suggestions = functions_help.find_topicsuggestions(pobject, topicstr)
if len(suggestions) > 0: if len(suggestions) > 0:
session.msg("Matching similarly named topics:") session.msg("Matching similarly named topics:")
for result in suggestions: for result in suggestions:
session.msg(" %s" % (result,)) session.msg(" %s" % (result,))
session.msg("You may type 'help <#>' to see any of these topics.") session.msg("You may type 'help <#>' to see any of these topics.")
elif len(topics) > 1: elif len(topics) > 1:
session.msg("More than one match found:") session.msg("More than one match found:")
for result in topics: for result in topics:
session.msg("%3d. %s" % (result.id, result.get_topicname())) session.msg("%3d. %s" % (result.id, result.get_topicname()))
session.msg("You may type 'help <#>' to see any of these topics.") session.msg("You may type 'help <#>' to see any of these topics.")
else: else:
topic = topics[0] topic = topics[0]
session.msg("\r\n%s%s%s" % (ansi.ansi["hilite"], topic.get_topicname(), ansi.ansi["normal"])) session.msg("\r\n%s%s%s" % (ansi.ansi["hilite"], topic.get_topicname(), ansi.ansi["normal"]))
session.msg(topic.get_entrytext_ingame()) session.msg(topic.get_entrytext_ingame())
def cmd_version(cdat): def cmd_version(cdat):
""" """
Version info command. Version info command.
""" """
session = cdat['session'] session = cdat['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 += "-"*50 retval += "-"*50
session.msg(retval) session.msg(retval)
def cmd_time(cdat): def cmd_time(cdat):
""" """
Server local time. Server local time.
""" """
session = cdat['session'] session = cdat['session']
session.msg('Current server time : %s' % (time.strftime('%a %b %d %H:%M %Y (%Z)', time.localtime(),))) session.msg('Current server time : %s' % (time.strftime('%a %b %d %H:%M %Y (%Z)', time.localtime(),)))
def cmd_uptime(cdat): def cmd_uptime(cdat):
""" """
Server uptime and stats. Server uptime and stats.
""" """
session = cdat['session'] session = cdat['session']
server = cdat['server'] server = cdat['server']
start_delta = time.time() - server.start_time start_delta = time.time() - server.start_time
loadavg = os.getloadavg() 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' % (time.strftime('%a %b %d %H:%M %Y (%Z)', time.localtime(),)))
session.msg('Server start time : %s' % (time.strftime('%a %b %d %H:%M %Y', time.localtime(server.start_time),))) session.msg('Server start time : %s' % (time.strftime('%a %b %d %H:%M %Y', time.localtime(server.start_time),)))
session.msg('Server uptime : %s' % functions_general.time_format(start_delta, style=2)) session.msg('Server uptime : %s' % functions_general.time_format(start_delta, style=2))
session.msg('Server load (1 min) : %.2f' % loadavg[0]) session.msg('Server load (1 min) : %.2f' % loadavg[0])

View file

@ -3,540 +3,540 @@ import session_mgr
import functions_db import functions_db
def cmd_teleport(cdat): def cmd_teleport(cdat):
""" """
Teleports an object somewhere. Teleports an object somewhere.
""" """
session = cdat['session'] session = cdat['session']
pobject = session.get_pobject() pobject = session.get_pobject()
server = cdat['server'] server = cdat['server']
args = cdat['uinput']['splitted'][1:] args = cdat['uinput']['splitted'][1:]
if len(args) == 0: if len(args) == 0:
session.msg("Teleport where/what?") session.msg("Teleport where/what?")
return return
eq_args = args[0].split('=') eq_args = args[0].split('=')
search_str = ''.join(args) search_str = ''.join(args)
# 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
# a direct teleport, @tel <destination>. # a direct teleport, @tel <destination>.
if len(eq_args) > 1: if len(eq_args) > 1:
# Equal sign teleport. # Equal sign teleport.
victim = functions_db.standard_plr_objsearch(session, eq_args[0]) victim = functions_db.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 victim: if not victim:
return return
destination = functions_db.standard_plr_objsearch(session, eq_args[1]) destination = functions_db.standard_plr_objsearch(session, eq_args[1])
# 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
if victim.is_room(): if victim.is_room():
session.msg("You can't teleport a room.") session.msg("You can't teleport a room.")
return return
if victim == destination: if victim == destination:
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)
# This is somewhat kludgy right now, we'll have to find a better way # 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 # 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 # session list matching the object we're teleporting, force it to
# look. This is going to typically be a player. # look. This is going to typically be a player.
victim_session = session_mgr.session_from_object(victim) victim_session = session_mgr.session_from_object(victim)
if victim_session: if victim_session:
victim_session.execute_cmd("look") victim_session.execute_cmd("look")
else: else:
# Direct teleport (no equal sign) # Direct teleport (no equal sign)
target_obj = functions_db.standard_plr_objsearch(session, search_str) target_obj = functions_db.standard_plr_objsearch(session, search_str)
# 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 target_obj == pobject: if target_obj == pobject:
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) pobject.move_to(target_obj)
session.execute_cmd("look") session.execute_cmd("look")
def cmd_stats(cdat): def cmd_stats(cdat):
""" """
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 = cdat['session']
stats_dict = functions_db.object_totals() stats_dict = functions_db.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(cdat):
""" """
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 = cdat['session']
pobject = session.get_pobject() pobject = session.get_pobject()
args = cdat['uinput']['splitted'][1:] args = cdat['uinput']['splitted'][1:]
if len(args) == 0: if len(args) == 0:
session.msg("Alias whom?") session.msg("Alias whom?")
return return
# Resplit the args on = to check for an almost-required = # Resplit the args on = to check for an almost-required =
eq_args = ' '.join(args).split('=') 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 = functions_db.standard_plr_objsearch(session, eq_args[0]) target = functions_db.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: if not target:
session.msg("Alias whom?") session.msg("Alias whom?")
return return
duplicates = functions_db.alias_search(pobject, eq_args[1]) duplicates = functions_db.alias_search(pobject, eq_args[1])
if duplicates: if duplicates:
session.msg("Alias '%s' already exists." % (eq_args[1],)) session.msg("Alias '%s' already exists." % (eq_args[1],))
return return
else: else:
if pobject.controls_other(target): if pobject.controls_other(target):
target.set_attribute('ALIAS', eq_args[1]) target.set_attribute('ALIAS', eq_args[1])
session.msg("Alias '%s' set for %s." % (eq_args[1], target.get_name())) session.msg("Alias '%s' set for %s." % (eq_args[1], 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(),))
def cmd_wipe(cdat): def cmd_wipe(cdat):
""" """
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 = cdat['session']
pobject = session.get_pobject() pobject = session.get_pobject()
args = cdat['uinput']['splitted'][1:] args = cdat['uinput']['splitted'][1:]
attr_search = False attr_search = False
if len(args) == 0: if len(args) == 0:
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 = args[0].split("/")
# 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.
if len(attr_split) > 1: if len(attr_split) > 1:
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[0]
# Just in case there's a slash in an attribute name. # Just in case there's a slash in an attribute name.
attr_searchstr = '/'.join(attr_split[1:]) attr_searchstr = '/'.join(attr_split[1:])
else: else:
searchstr = ' '.join(args) searchstr = ' '.join(args)
target_obj = functions_db.standard_plr_objsearch(session, searchstr) target_obj = functions_db.standard_plr_objsearch(session, 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:
# 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(attr_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())
session.msg("%s - %d attributes wiped." % (target_obj.get_name(), len(attr_matches)))
else:
session.msg("No matching attributes found.")
else:
# User didn't specify a wild-card string, wipe entire object.
attr_matches = target_obj.attribute_namesearch("*", exclude_noset=True)
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:
session.msg("No matching attributes found.")
else:
# User didn't specify a wild-card string, wipe entire object.
attr_matches = target_obj.attribute_namesearch("*", exclude_noset=True)
for attr in attr_matches:
target_obj.clear_attribute(attr.get_name())
session.msg("%s - %d attributes wiped." % (target_obj.get_name(), len(attr_matches)))
def cmd_set(cdat): def cmd_set(cdat):
""" """
Sets flags or attributes on objects. Sets flags or attributes on objects.
""" """
session = cdat['session'] session = cdat['session']
pobject = session.get_pobject() pobject = session.get_pobject()
server = cdat['server'] server = cdat['server']
args = cdat['uinput']['splitted'][1:] args = cdat['uinput']['splitted'][1:]
if len(args) == 0: if len(args) == 0:
session.msg("Set what?") session.msg("Set what?")
return return
# There's probably a better way to do this. Break the arguments (minus # There's probably a better way to do this. Break the arguments (minus
# the root command) up so we have two items in the list, 0 being the victim, # the root command) up so we have two items in the list, 0 being the victim,
# 1 being the list of flags or the attribute/value pair. # 1 being the list of flags or the attribute/value pair.
eq_args = ' '.join(args).split('=') eq_args = ' '.join(args).split('=')
if len(eq_args) < 2: if len(eq_args) < 2:
session.msg("Set what?") session.msg("Set what?")
return return
victim = functions_db.standard_plr_objsearch(session, eq_args[0]) victim = functions_db.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 victim: if not victim:
return return
if not pobject.controls_other(victim): if not pobject.controls_other(victim):
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(':')
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()
splicenum = eq_args[1].find(':') + 1 splicenum = eq_args[1].find(':') + 1
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 functions_db.is_modifiable_attrib(attrib_name) and not pobject.is_superuser(): if not functions_db.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
if attrib_value: if attrib_value:
# An attribute value was specified, create or set the attribute. # An attribute value was specified, create or set the attribute.
verb = 'set' verb = 'set'
victim.set_attribute(attrib_name, attrib_value) victim.set_attribute(attrib_name, attrib_value)
else: else:
# No value was given, this means we delete the attribute. # No value was given, this means we delete the attribute.
verb = 'cleared' verb = 'cleared'
victim.clear_attribute(attrib_name) victim.clear_attribute(attrib_name)
session.msg("%s - %s %s." % (victim.get_name(), attrib_name, verb)) session.msg("%s - %s %s." % (victim.get_name(), attrib_name, verb))
else: else:
# Flag manipulation form. # Flag manipulation form.
flag_list = eq_args[1].split() flag_list = eq_args[1].split()
for flag in flag_list: for flag in flag_list:
flag = flag.upper() flag = flag.upper()
if flag[0] == '!': if flag[0] == '!':
# We're un-setting the flag. # We're un-setting the flag.
flag = flag[1:] flag = flag[1:]
if not functions_db.is_modifiable_flag(flag): if not functions_db.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:
session.msg('%s - %s cleared.' % (victim.get_name(), flag.upper(),))
victim.set_flag(flag, False)
else: else:
session.msg('%s - %s cleared.' % (victim.get_name(), flag.upper(),)) # We're setting the flag.
victim.set_flag(flag, False) if not functions_db.is_modifiable_flag(flag):
else: session.msg("You can't set/unset the flag - %s." % (flag,))
# We're setting the flag. else:
if not functions_db.is_modifiable_flag(flag): session.msg('%s - %s set.' % (victim.get_name(), flag.upper(),))
session.msg("You can't set/unset the flag - %s." % (flag,)) victim.set_flag(flag, True)
else:
session.msg('%s - %s set.' % (victim.get_name(), flag.upper(),))
victim.set_flag(flag, True)
def cmd_find(cdat): def cmd_find(cdat):
""" """
Searches for an object of a particular name. Searches for an object of a particular name.
""" """
session = cdat['session'] session = cdat['session']
server = cdat['server'] server = cdat['server']
searchstring = ' '.join(cdat['uinput']['splitted'][1:]) 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 searchstring == '':
session.msg("No search pattern given.") session.msg("No search pattern given.")
return return
results = functions_db.global_object_name_search(searchstring) results = functions_db.global_object_name_search(searchstring)
if len(results) > 0: if len(results) > 0:
session.msg("Name matches for: %s" % (searchstring,)) session.msg("Name matches for: %s" % (searchstring,))
for result in results: for result in results:
session.msg(" %s" % (result.get_name(fullname=True),)) session.msg(" %s" % (result.get_name(fullname=True),))
session.msg("%d matches returned." % (len(results),)) session.msg("%d matches returned." % (len(results),))
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(cdat):
""" """
Creates a new object of type 'THING'. Creates a new object of type 'THING'.
""" """
session = cdat['session'] session = cdat['session']
server = session.server server = session.server
pobject = session.get_pobject() pobject = session.get_pobject()
uinput= cdat['uinput']['splitted'] uinput= cdat['uinput']['splitted']
thingname = ' '.join(uinput[1:]) thingname = ' '.join(uinput[1:])
if thingname == '': if thingname == '':
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} odat = {"name": thingname, "type": 3, "location": pobject, "owner": pobject}
new_object = functions_db.create_object(odat) new_object = functions_db.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(cdat):
""" """
Returns the next free object number. Returns the next free object number.
""" """
session = cdat['session'] session = cdat['session']
nextfree = functions_db.get_nextfree_dbnum() nextfree = functions_db.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(cdat):
""" """
Handle the opening of exits. Handle the opening of exits.
Forms: Forms:
@open <Name> @open <Name>
@open <Name>=<Dbref> @open <Name>=<Dbref>
@open <Name>=<Dbref>,<Name> @open <Name>=<Dbref>,<Name>
""" """
session = cdat['session'] session = cdat['session']
pobject = session.get_pobject() pobject = session.get_pobject()
server = cdat['server'] server = cdat['server']
args = cdat['uinput']['splitted'][1:] args = cdat['uinput']['splitted'][1:]
if len(args) == 0: if len(args) == 0:
session.msg("Open an exit to where?") session.msg("Open an exit to where?")
return return
eq_args = ' '.join(args).split('=') eq_args = ' '.join(args).split('=')
exit_name = eq_args[0] exit_name = eq_args[0]
if len(exit_name) == 0: if len(exit_name) == 0:
session.msg("You must supply an exit name.") session.msg("You must supply an exit name.")
return return
# 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 @open <Name>=<Dbref>[,<Name>]. If not, we're doing # then we're doing a @open <Name>=<Dbref>[,<Name>]. If not, we're doing
# 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(',')
destination = functions_db.standard_plr_objsearch(session, comma_split[0]) destination = functions_db.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
if destination.is_exit(): if destination.is_exit():
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 = functions_db.create_object(odat) new_object = functions_db.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 = functions_db.create_object(odat) new_object = functions_db.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 = functions_db.create_object(odat) new_object = functions_db.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(cdat):
""" """
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 = cdat['session']
pobject = session.get_pobject() pobject = session.get_pobject()
server = cdat['server'] server = cdat['server']
args = cdat['uinput']['splitted'][1:] args = cdat['uinput']['splitted'][1:]
if len(args) == 0: if len(args) == 0:
session.msg("Link what?") session.msg("Link what?")
return return
eq_args = args[0].split('=') eq_args = args[0].split('=')
target_name = eq_args[0] target_name = eq_args[0]
dest_name = '='.join(eq_args[1:]) dest_name = '='.join(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?")
return return
if len(eq_args) > 1: if len(eq_args) > 1:
target_obj = functions_db.standard_plr_objsearch(session, target_name) target_obj = functions_db.standard_plr_objsearch(session, target_name)
# 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 not pobject.controls_other(target_obj): if not pobject.controls_other(target_obj):
session.msg(defines_global.NOCONTROL_MSG) session.msg(defines_global.NOCONTROL_MSG)
return return
# If we do something like "@link blah=", we unlink the object. # If we do something like "@link blah=", we unlink the object.
if len(dest_name) == 0: if len(dest_name) == 0:
target_obj.set_home(None) target_obj.set_home(None)
session.msg("You have unlinked %s." % (target_obj,)) session.msg("You have unlinked %s." % (target_obj,))
return return
destination = functions_db.standard_plr_objsearch(session, dest_name) destination = functions_db.standard_plr_objsearch(session, dest_name)
# 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
target_obj.set_home(destination) target_obj.set_home(destination)
session.msg("You link %s to %s." % (target_obj,destination)) session.msg("You link %s to %s." % (target_obj,destination))
else: else:
# We haven't provided a target. # We haven't provided a target.
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(cdat):
""" """
Unlinks an object. Unlinks an object.
""" """
session = cdat['session'] session = cdat['session']
pobject = session.get_pobject() pobject = session.get_pobject()
args = cdat['uinput']['splitted'][1:] args = cdat['uinput']['splitted'][1:]
if len(args) == 0: if len(args) == 0:
session.msg("Unlink what?") session.msg("Unlink what?")
return return
else: else:
target_obj = functions_db.standard_plr_objsearch(session, ' '.join(args)) target_obj = functions_db.standard_plr_objsearch(session, ' '.join(args))
# 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 not pobject.controls_other(target_obj): if not pobject.controls_other(target_obj):
session.msg(defines_global.NOCONTROL_MSG) session.msg(defines_global.NOCONTROL_MSG)
return return
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(cdat):
""" """
Creates a new object of type 'ROOM'. Creates a new object of type 'ROOM'.
""" """
session = cdat['session'] session = cdat['session']
pobject = session.get_pobject() pobject = session.get_pobject()
uinput= cdat['uinput']['splitted'] uinput= cdat['uinput']['splitted']
roomname = ' '.join(uinput[1:]) roomname = ' '.join(uinput[1:])
if roomname == '': if 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 = functions_db.create_object(odat) new_object = functions_db.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(cdat):
""" """
Handle naming an object. Handle naming an object.
""" """
session = cdat['session'] session = cdat['session']
pobject = session.get_pobject() pobject = session.get_pobject()
args = cdat['uinput']['splitted'][1:] args = cdat['uinput']['splitted'][1:]
eq_args = ' '.join(args).split('=') eq_args = ' '.join(args).split('=')
searchstring = ''.join(eq_args[0]) searchstring = ''.join(eq_args[0])
if len(args) == 0: if len(args) == 0:
session.msg("What do you want to name?") session.msg("What do you want to name?")
elif len(eq_args) < 2: elif len(eq_args) < 2:
session.msg("What would you like to name that object?") session.msg("What would you like to name that object?")
else: else:
target_obj = functions_db.standard_plr_objsearch(session, searchstring) target_obj = functions_db.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
if len(eq_args[1]) == 0: if len(eq_args[1]) == 0:
session.msg("What would you like to name that object?") session.msg("What would you like to name that object?")
else: else:
newname = '='.join(eq_args[1:]) newname = '='.join(eq_args[1:])
session.msg("You have renamed %s to %s." % (target_obj, ansi.parse_ansi(newname, strip_formatting=True))) session.msg("You have renamed %s to %s." % (target_obj, ansi.parse_ansi(newname, strip_formatting=True)))
target_obj.set_name(newname) target_obj.set_name(newname)
def cmd_description(cdat): def cmd_description(cdat):
""" """
Set an object's description. Set an object's description.
""" """
session = cdat['session'] session = cdat['session']
pobject = session.get_pobject() pobject = session.get_pobject()
args = cdat['uinput']['splitted'][1:] args = cdat['uinput']['splitted'][1:]
eq_args = ' '.join(args).split('=') eq_args = ' '.join(args).split('=')
searchstring = ''.join(eq_args[0]) searchstring = ''.join(eq_args[0])
if len(args) == 0: if len(args) == 0:
session.msg("What do you want to describe?") session.msg("What do you want to describe?")
elif len(eq_args) < 2: elif len(eq_args) < 2:
session.msg("How would you like to describe that object?") session.msg("How would you like to describe that object?")
else: else:
target_obj = functions_db.standard_plr_objsearch(session, searchstring) target_obj = functions_db.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
if not pobject.controls_other(target_obj): if not pobject.controls_other(target_obj):
session.msg(defines_global.NOCONTROL_MSG) session.msg(defines_global.NOCONTROL_MSG)
return return
new_desc = '='.join(eq_args[1:]) new_desc = '='.join(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(cdat):
""" """
Destroy an object. Destroy an object.
""" """
session = cdat['session'] session = cdat['session']
pobject = session.get_pobject() pobject = session.get_pobject()
args = cdat['uinput']['splitted'][1:] args = cdat['uinput']['splitted'][1:]
switches = cdat['uinput']['root_chunk'][1:] switches = cdat['uinput']['root_chunk'][1:]
switch_override = False switch_override = False
if "override" in switches: if "override" in switches:
switch_override = True switch_override = True
if len(args) == 0: if len(args) == 0:
session.msg("Destroy what?") session.msg("Destroy what?")
return return
else: else:
target_obj = functions_db.standard_plr_objsearch(session, ' '.join(args)) target_obj = functions_db.standard_plr_objsearch(session, ' '.join(args))
# 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
if target_obj.is_player():
if pobject.id == target_obj.id:
session.msg("You can't destroy yourself.")
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(),)) if target_obj.is_player():
target_obj.destroy() if pobject.id == target_obj.id:
session.msg("You can't destroy yourself.")
return
if not switch_override:
session.msg("You must use @destroy/override on players.")
return
if target_obj.is_superuser():
session.msg("You can't destroy a superuser.")
return
elif target_obj.is_going() or target_obj.is_garbage():
session.msg("That object is already destroyed.")
return
session.msg("You destroy %s." % (target_obj.get_name(),))
target_obj.destroy()

View file

@ -1,91 +1,98 @@
from django.contrib.auth.models import User from django.contrib.auth.models import User
from apps.objects.models import Attribute, Object
import functions_db import functions_db
import functions_general import functions_general
import defines_global
""" """
Commands that are available from the connect screen. Commands that are available from the connect screen.
""" """
def cmd_connect(cdat): def cmd_connect(cdat):
""" """
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 = cdat['session']
# Argument check. # Argument check.
if not functions_general.cmd_check_num_args(session, cdat['uinput']['splitted'], 2): if not functions_general.cmd_check_num_args(session, cdat['uinput']['splitted'], 2):
return return
uemail = cdat['uinput']['splitted'][1] uemail = cdat['uinput']['splitted'][1]
password = cdat['uinput']['splitted'][2] password = cdat['uinput']['splitted'][2]
# Match an email address to an account. # Match an email address to an account.
email_matches = functions_db.get_user_from_email(uemail) email_matches = functions_db.get_user_from_email(uemail)
autherror = "Specified email does not match any accounts!" 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(autherror)
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(autherror)
else: else:
uname = user.username uname = user.username
session.login(user) session.login(user)
def cmd_create(cdat): def cmd_create(cdat):
""" """
Handle the creation of new accounts. Handle the creation of new accounts.
""" """
session = cdat['session'] session = cdat['session']
# Argument check. # Argument check.
if not functions_general.cmd_check_num_args(session, cdat['uinput']['splitted'], 2): if not functions_general.cmd_check_num_args(session, cdat['uinput']['splitted'], 2):
return return
server = session.server server = session.server
quote_split = ' '.join(cdat['uinput']['splitted']).split("\"") quote_split = ' '.join(cdat['uinput']['splitted']).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.")
return return
uname = quote_split[1] uname = quote_split[1]
lastarg_split = quote_split[2].split() lastarg_split = quote_split[2].split()
if len(lastarg_split) != 2: if len(lastarg_split) != 2:
session.msg("You must specify an email address, followed by a password!") session.msg("You must specify an email address, followed by a password!")
return return
email = lastarg_split[0] email = lastarg_split[0]
password = lastarg_split[1] password = lastarg_split[1]
# Search for a user object with the specified username. # Search for a user object with the specified username.
account = User.objects.filter(username=uname) account = User.objects.filter(username=uname)
# Match an email address to an account. # Match an email address to an account.
email_matches = functions_db.get_user_from_email(email) email_matches = functions_db.get_user_from_email(email)
# Look for any objects with an 'Alias' attribute that matches
# the requested username
alias_matches = Object.objects.filter(attribute__attr_name__exact="ALIAS",
attribute__attr_value__iexact=uname).filter(
type=defines_global.OTYPE_PLAYER)
if not account.count() == 0: if not account.count() == 0 or not alias_matches.count() == 0:
session.msg("There is already a player with that name!") session.msg("There is already a player with that name!")
elif not email_matches.count() == 0: elif not email_matches.count() == 0:
session.msg("There is already a player with that email address!") session.msg("There is already a player with that email address!")
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:
functions_db.create_user(cdat, uname, email, password) functions_db.create_user(cdat, uname, email, password)
def cmd_quit(cdat): def cmd_quit(cdat):
""" """
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 = cdat['session']
session.msg("Disconnecting...") session.msg("Disconnecting...")
session.handle_close() session.handle_close()

View file

@ -4,341 +4,372 @@ from datetime import datetime, timedelta
from django.db import connection from django.db import connection
from django.contrib.auth.models import User from django.contrib.auth.models import User
from apps.objects.models import Object, Attribute from apps.objects.models import Object, Attribute
import defines_global as defines_global import defines_global
import gameconf import gameconf
from django.db.models import Q
""" """
Common database functions. Common database functions.
""" """
def num_total_players(): def num_total_players():
""" """
Returns the total number of registered players. Returns the total number of registered players.
""" """
return User.objects.count() return User.objects.count()
def get_connected_players(): def get_connected_players():
""" """
Returns the a QuerySet containing the currently connected players. Returns the a QuerySet containing the currently connected players.
""" """
return Object.objects.filter(nosave_flags__contains="CONNECTED") return Object.objects.filter(nosave_flags__contains="CONNECTED")
def get_recently_created_players(days=7): def get_recently_created_players(days=7):
""" """
Returns a QuerySet containing the player User accounts that have been Returns a QuerySet containing the player User accounts that have been
connected within the last <days> days. connected within the last <days> days.
""" """
end_date = datetime.now() end_date = datetime.now()
tdelta = timedelta(days) tdelta = timedelta(days)
start_date = end_date - tdelta start_date = end_date - tdelta
return User.objects.filter(date_joined__range=(start_date, end_date)) return User.objects.filter(date_joined__range=(start_date, end_date))
def get_recently_connected_players(days=7): def get_recently_connected_players(days=7):
""" """
Returns a QuerySet containing the player User accounts that have been Returns a QuerySet containing the player User accounts that have been
connected within the last <days> days. connected within the last <days> days.
""" """
end_date = datetime.now() end_date = datetime.now()
tdelta = timedelta(days) tdelta = timedelta(days)
start_date = end_date - tdelta start_date = end_date - tdelta
return User.objects.filter(last_login__range=(start_date, end_date)).order_by('-last_login') return User.objects.filter(last_login__range=(start_date, end_date)).order_by('-last_login')
def is_unsavable_flag(flagname): def is_unsavable_flag(flagname):
""" """
Returns TRUE if the flag is an unsavable flag. Returns TRUE if the flag is an unsavable flag.
""" """
return flagname.upper() in defines_global.NOSAVE_FLAGS return flagname.upper() in defines_global.NOSAVE_FLAGS
def is_modifiable_flag(flagname): def is_modifiable_flag(flagname):
""" """
Check to see if a particular flag is modifiable. Check to see if a particular flag is modifiable.
""" """
if flagname.upper() not in defines_global.NOSET_FLAGS: if flagname.upper() not in defines_global.NOSET_FLAGS:
return True return True
else: else:
return False return False
def is_modifiable_attrib(attribname): def is_modifiable_attrib(attribname):
""" """
Check to see if a particular attribute is modifiable. Check to see if a particular attribute is modifiable.
attribname: (string) An attribute name to check. attribname: (string) An attribute name to check.
""" """
if attribname.upper() not in defines_global.NOSET_ATTRIBS: if attribname.upper() not in defines_global.NOSET_ATTRIBS:
return True return True
else: else:
return False return False
def get_nextfree_dbnum(): def get_nextfree_dbnum():
""" """
Figure out what our next free database reference number is. Figure out what our next free database reference number is.
If we need to recycle a GARBAGE object, return the object to recycle If we need to recycle a GARBAGE object, return the object to recycle
Otherwise, return the first free dbref. Otherwise, return the first free dbref.
""" """
# First we'll see if there's an object of type 6 (GARBAGE) that we # First we'll see if there's an object of type 6 (GARBAGE) that we
# can recycle. # can recycle.
nextfree = Object.objects.filter(type__exact=defines_global.OTYPE_GARBAGE) nextfree = Object.objects.filter(type__exact=defines_global.OTYPE_GARBAGE)
if nextfree: if nextfree:
# We've got at least one garbage object to recycle. # We've got at least one garbage object to recycle.
return nextfree.id return nextfree.id
else: else:
# No garbage to recycle, find the highest dbnum and increment it # No garbage to recycle, find the highest dbnum and increment it
# for our next free. # for our next free.
return int(Object.objects.order_by('-id')[0].id + 1) return int(Object.objects.order_by('-id')[0].id + 1)
def global_object_name_search(ostring, exact_match=False): def global_object_name_search(ostring, exact_match=False):
""" """
Searches through all objects for a name match. Searches through all objects for a name match.
""" """
if exact_match: if exact_match:
return Object.objects.filter(name__iexact=ostring).exclude(type=defines_global.OTYPE_GARBAGE) return Object.objects.filter(name__iexact=ostring).exclude(type=defines_global.OTYPE_GARBAGE)
else: else:
return Object.objects.filter(name__icontains=ostring).exclude(type=defines_global.OTYPE_GARBAGE) return Object.objects.filter(name__icontains=ostring).exclude(type=defines_global.OTYPE_GARBAGE)
def list_search_object_namestr(searchlist, ostring, dbref_only=False, limit_types=False, match_type="fuzzy"): def list_search_object_namestr(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.
searchlist: (List of Objects) The objects to perform name comparisons on. searchlist: (List of Objects) The objects to perform name comparisons on.
ostring: (string) The string to match against. ostring: (string) The string to match against.
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.
""" """
if dbref_only: if dbref_only:
if limit_types: if limit_types:
return [prospect for prospect in searchlist if prospect.dbref_match(ostring) and prospect.type in limit_types] return [prospect for prospect in searchlist if prospect.dbref_match(ostring) and prospect.type in limit_types]
else: else:
return [prospect for prospect in searchlist if prospect.dbref_match(ostring)] return [prospect for prospect in searchlist if prospect.dbref_match(ostring)]
else: else:
if limit_types: if limit_types:
return [prospect for prospect in searchlist if prospect.name_match(ostring, match_type=match_type) and prospect.type in limit_types] return [prospect for prospect in searchlist if prospect.name_match(ostring, match_type=match_type) and prospect.type in limit_types]
else: else:
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 player_search(searcher, ostring):
"""
Combines an alias and local/global search for a player's name. If there are
no alias matches, do a global search limiting by type PLAYER.
searcher: (Object) The object doing the searching.
ostring: (string) The alias string to search for.
"""
alias_results = alias_search(searcher, ostring)
if len(alias_results) > 0:
return alias_results
else:
return local_and_global_search(searcher, ostring, limit_types=[defines_global.OTYPE_PLAYER])
def standard_plr_objsearch(session, ostring, search_contents=True, search_location=True, dbref_only=False, limit_types=False): def standard_plr_objsearch(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.
session: (SessionProtocol) Reference to the player's session. session: (SessionProtocol) Reference to the player's session.
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 = local_and_global_search(pobject, ostring, search_contents=search_contents, search_location=search_location, dbref_only=dbref_only, limit_types=limit_types) results = 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):")
for result in results: for result in results:
session.msg(" %s" % (result.get_name(),)) session.msg(" %s" % (result.get_name(),))
return False return False
elif len(results) == 0: elif len(results) == 0:
session.msg("I don't see that here.") session.msg("I don't see that here.")
return False return False
else: else:
return results[0] return results[0]
def object_totals(): def object_totals():
""" """
Returns a dictionary with database object totals. Returns a dictionary with database object totals.
""" """
dbtotals = {} dbtotals = {}
dbtotals["objects"] = Object.objects.count() dbtotals["objects"] = Object.objects.count()
dbtotals["things"] = Object.objects.filter(type=defines_global.OTYPE_THING).count() dbtotals["things"] = Object.objects.filter(type=defines_global.OTYPE_THING).count()
dbtotals["exits"] = Object.objects.filter(type=defines_global.OTYPE_EXIT).count() dbtotals["exits"] = Object.objects.filter(type=defines_global.OTYPE_EXIT).count()
dbtotals["rooms"] = Object.objects.filter(type=defines_global.OTYPE_ROOM).count() dbtotals["rooms"] = Object.objects.filter(type=defines_global.OTYPE_ROOM).count()
dbtotals["garbage"] = Object.objects.filter(type=defines_global.OTYPE_GARBAGE).count() dbtotals["garbage"] = Object.objects.filter(type=defines_global.OTYPE_GARBAGE).count()
dbtotals["players"] = Object.objects.filter(type=defines_global.OTYPE_PLAYER).count() dbtotals["players"] = Object.objects.filter(type=defines_global.OTYPE_PLAYER).count()
return dbtotals return dbtotals
def alias_search(searcher, ostring): def alias_search(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" attribute
exactly (not case-sensitive) matches ostring. 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) search_query = ''.join(ostring)
results = Attribute.objects.select_related().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()]
def player_name_search(search_string):
"""
Combines an alias and global search for a player's name. If there are
no alias matches, do a global search limiting by type PLAYER.
search_string: (string) The name string to search for.
"""
# Handle the case where someone might have started the search_string
# with a *
if search_string.startswith('*') is True:
search_string = search_string[1:]
# Use Q objects to build complex OR query to look at either
# the player name or ALIAS attribute
player_filter = Q(name__iexact=search_string)
alias_filter = Q(attribute__attr_name__exact="ALIAS") & \
Q(attribute__attr_value__iexact=search_string)
player_matches = Object.objects.filter(
player_filter | alias_filter).filter(
type=defines_global.OTYPE_PLAYER).distinct()
try:
return player_matches[0]
except IndexError:
return None
def dbref_search(dbref_string, limit_types=False):
"""
Searches for a given dbref.
dbref_number: (string) The dbref to search for
limit_types: (list of int) A list of Object type numbers to filter by.
"""
if not is_dbref(dbref_string):
return None
dbref_string = dbref_string[1:]
dbref_matches = Object.objects.filter(id=dbref_string).exclude(
type=defines_global.OTYPE_GARBAGE)
# Check for limiters
if limit_types is not False:
for limiter in limit_types:
dbref_matches.filter(type=limiter)
try:
return dbref_matches[0]
except IndexError:
return None
def local_and_global_search(searcher, ostring, search_contents=True, search_location=True, dbref_only=False, limit_types=False): def local_and_global_search(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.
searcher: (Object) The object performing the search. searcher: (Object) The object performing the search.
ostring: (string) The string to compare names against. ostring: (string) The string to compare names against.
search_contents: (bool) While true, check the contents of the searcher. search_contents: (bool) While true, check the contents of the searcher.
search_location: (bool) While true, check the searcher's surroundings. search_location: (bool) While true, check the searcher's surroundings.
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 = ''.join(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 is_dbref(ostring) and search_contents and search_location: if is_dbref(ostring):
search_num = search_query[1:] search_num = search_query[1:]
dbref_results = Object.objects.filter(id=search_num).exclude(type=6) dbref_match = dbref_search(search_num, limit_types)
if dbref_match is not None:
return [dbref_match]
# If there is a type limiter in, filter by it. # If the search string is one of the following, return immediately with
if limit_types: # the appropriate result.
for limiter in limit_types: if searcher.get_location().dbref_match(ostring) or ostring == 'here':
dbref_results.filter(type=limiter) return [searcher.get_location()]
elif ostring == 'me' and searcher:
return [searcher]
dbref_match = list(dbref_results) if search_query[0] == "*":
if len(dbref_match) > 0: # Player search- gotta search by name or alias
return dbref_match search_target = search_query[1:]
player_match = player_name_search(search_target)
if player_match is not None:
return [player_match]
# If the search string is one of the following, return immediately with local_matches = []
# the appropriate result. # Handle our location/contents searches. list_search_object_namestr() does
if searcher.get_location().dbref_match(ostring) or ostring == 'here': # name and dbref comparisons against search_query.
return [searcher.get_location()] if search_contents:
elif ostring == 'me' and searcher: local_matches += list_search_object_namestr(searcher.get_contents(), search_query, limit_types)
return [searcher] if search_location:
local_matches += list_search_object_namestr(searcher.get_location().get_contents(), search_query, limit_types=limit_types)
local_matches = [] return local_matches
# Handle our location/contents searches. list_search_object_namestr() does
# name and dbref comparisons against search_query.
if search_contents:
local_matches += list_search_object_namestr(searcher.get_contents(), search_query, limit_types)
if search_location:
local_matches += list_search_object_namestr(searcher.get_location().get_contents(), search_query, limit_types=limit_types)
return local_matches
def is_dbref(dbstring): def is_dbref(dbstring):
""" """
Is the input a well-formed dbref number? Is the input a well-formed dbref number?
""" """
try: try:
number = int(dbstring[1:]) number = int(dbstring[1:])
except ValueError: except ValueError:
return False return False
if not dbstring.startswith("#"):
if dbstring[0] != '#': return False
return False elif number < 1:
elif number < 1: return False
return False else:
else: return True
return True
def get_user_from_email(uemail): def get_user_from_email(uemail):
""" """
Returns a player's User object when given an email address. Returns a player's User object when given an email address.
""" """
return User.objects.filter(email__iexact=uemail) return User.objects.filter(email__iexact=uemail)
def get_object_from_dbref(dbref): def get_object_from_dbref(dbref):
""" """
Returns an object when given a dbref. Returns an object when given a dbref.
""" """
return Object.objects.get(id=dbref) return Object.objects.get(id=dbref)
def create_object(odat): def create_object(odat):
""" """
Create a new object. odat is a dictionary that contains the following keys. Create a new object. odat is a dictionary that contains the following keys.
REQUIRED KEYS: REQUIRED KEYS:
* type: Integer representing the object's type. * type: Integer representing the object's type.
* name: The name of the new object. * name: The name of the new object.
* location: Reference to another object for the new object to reside in. * location: Reference to another object for the new object to reside in.
* owner: The creator of the object. * owner: The creator of the object.
OPTIONAL KEYS: OPTIONAL KEYS:
* 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 = get_nextfree_dbnum()
new_object = Object() new_object = Object()
new_object.id = next_dbref new_object.id = next_dbref
new_object.type = odat["type"] new_object.type = odat["type"]
new_object.set_name(odat["name"]) new_object.set_name(odat["name"])
# If this is a player, we don't want him owned by anyone. # If this is a player, we don't want him owned by anyone.
# The get_owner() function will return that the player owns # The get_owner() function will return that the player owns
# himself. # himself.
if odat["type"] == 1: if odat["type"] == 1:
new_object.owner = None new_object.owner = None
new_object.zone = None new_object.zone = None
else: else:
new_object.owner = odat["owner"] new_object.owner = odat["owner"]
if new_object.get_owner().get_zone(): if new_object.get_owner().get_zone():
new_object.zone = new_object.get_owner().get_zone() new_object.zone = new_object.get_owner().get_zone()
# If we have a 'home' key, use that for our home value. Otherwise use # If we have a 'home' key, use that for our home value. Otherwise use
# the location key. # the location key.
if odat.has_key("home"): if odat.has_key("home"):
new_object.home = odat["home"] new_object.home = odat["home"]
else: else:
if new_object.is_exit(): if new_object.is_exit():
new_object.home = None new_object.home = None
else: else:
new_object.home = odat["location"] new_object.home = odat["location"]
new_object.save() new_object.save()
# Rooms have a NULL location. # Rooms have a NULL location.
if not new_object.is_room(): if not new_object.is_room():
new_object.move_to(odat['location']) new_object.move_to(odat['location'])
return new_object return new_object
def create_user(cdat, uname, email, password): def create_user(cdat, uname, email, password):
""" """
Handles the creation of new users. Handles the creation of new users.
""" """
session = cdat['session'] session = cdat['session']
server = cdat['server'] server = cdat['server']
start_room = int(gameconf.get_configvalue('player_dbnum_start')) start_room = int(gameconf.get_configvalue('player_dbnum_start'))
start_room_obj = get_object_from_dbref(start_room) start_room_obj = 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 = get_nextfree_dbnum()
print 'UID', uid 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 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.
user.save() user.save()
# We can't use the user model to change the id because of the way keys # We can't use the user model to change the id because of the way keys
# are handled, so we actually need to fall back to raw SQL. Boo hiss. # are handled, so we actually need to fall back to raw SQL. Boo hiss.
cursor = connection.cursor() cursor = connection.cursor()
cursor.execute("UPDATE auth_user SET id=%d WHERE id=%d" % (uid, user.id)) cursor.execute("UPDATE auth_user SET id=%d WHERE id=%d" % (uid, user.id))
# Grab the user object again since we've changed it and the old reference # Grab the user object again since we've changed it and the old reference
# is no longer valid. # is no longer valid.
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, "name": uname, "type": 1, "location": start_room_obj, "owner": None}
user_object = create_object(odat) user_object = 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)
print 'Registration: %s' % (session,) print 'Registration: %s' % (session,)
session.msg("Welcome to %s, %s.\n\r" % (gameconf.get_configvalue('site_name'), session.get_pobject().get_name(show_dbref=False),)) session.msg("Welcome to %s, %s.\n\r" % (gameconf.get_configvalue('site_name'), session.get_pobject().get_name(show_dbref=False),))

View file

@ -6,132 +6,138 @@ default. It will have the necessary outline for developers to sub-class and over
import ansi import ansi
class BasicObject: class BasicObject:
def __init__(self, source_obj): def __init__(self, source_obj):
""" """
Get our ducks in a row. Get our ducks in a row.
source_obj: (Object) A reference to the object being scripted (the child). source_obj: (Object) A reference to the object being scripted (the child).
""" """
self.source_obj = source_obj self.source_obj = source_obj
def a_desc(self, values): def a_desc(self, values):
""" """
Perform this action when someone uses the LOOK command on the object. Perform this action when someone uses the LOOK command on the object.
values: (Dict) Script arguments with keys: values: (Dict) Script arguments with keys:
* pobject: The object requesting the action. * pobject: The object requesting the action.
""" """
# Un-comment the line below for an example # Un-comment the line below for an example
#print "SCRIPT TEST: %s looked at %s." % (values["pobject"], self.source_obj) #print "SCRIPT TEST: %s looked at %s." % (values["pobject"], self.source_obj)
pass pass
def return_appearance(self, values): def return_appearance(self, values):
""" """
Returns a string representation of an object's appearance when LOOKed at. Returns a string representation of an object's appearance when LOOKed at.
values: (Dict) Script arguments with keys: values: (Dict) Script arguments with keys:
* pobject: The object requesting the action. * pobject: The object requesting the action.
""" """
target_obj = self.source_obj target_obj = self.source_obj
pobject = values["pobject"] pobject = values["pobject"]
retval = "\r\n%s\r\n%s" % ( description = target_obj.get_description()
target_obj.get_name(), if description is not None:
target_obj.get_description(), retval = "%s\r\n%s" % (
) target_obj.get_name(),
target_obj.get_description(),
)
else:
retval = "%s" % (
target_obj.get_name(),
)
con_players = [] con_players = []
con_things = [] con_things = []
con_exits = [] con_exits = []
for obj in target_obj.get_contents(): for obj in target_obj.get_contents():
if obj.is_player(): if obj.is_player():
if obj != pobject and obj.is_connected_plr(): if obj != pobject and obj.is_connected_plr():
con_players.append(obj) con_players.append(obj)
elif obj.is_exit(): elif obj.is_exit():
con_exits.append(obj) con_exits.append(obj)
else: else:
con_things.append(obj) con_things.append(obj)
if con_players: if not con_players == []:
retval += "\n\r%sPlayers:%s" % (ansi.ansi["hilite"], ansi.ansi["normal"],) retval += "\n\r%sPlayers:%s" % (ansi.ansi["hilite"], ansi.ansi["normal"],)
for player in con_players: for player in con_players:
retval +='\n\r%s' %(player.get_name(),) retval +='\n\r%s' %(player.get_name(),)
if con_things: if not con_things == []:
retval += "\n\r%sContents:%s" % (ansi.ansi["hilite"], ansi.ansi["normal"],) retval += "\n\r%sContents:%s" % (ansi.ansi["hilite"], ansi.ansi["normal"],)
for thing in con_things: for thing in con_things:
retval += '\n\r%s' %(thing.get_name(),) retval += '\n\r%s' %(thing.get_name(),)
if con_exits: if not con_exits == []:
retval += "\n\r%sExits:%s" % (ansi.ansi["hilite"], ansi.ansi["normal"],) retval += "\n\r%sExits:%s" % (ansi.ansi["hilite"], ansi.ansi["normal"],)
for exit in con_exits: for exit in con_exits:
retval += '\n\r%s' %(exit.get_name(),) retval += '\n\r%s' %(exit.get_name(),)
return retval return retval
def a_get(self, values): def a_get(self, values):
""" """
Perform this action when someone uses the GET command on the object. Perform this action when someone uses the GET command on the object.
values: (Dict) Script arguments with keys: values: (Dict) Script arguments with keys:
* pobject: The object requesting the action. * pobject: The object requesting the action.
""" """
# Un-comment the line below for an example # Un-comment the line below for an example
#print "SCRIPT TEST: %s got %s." % (values["pobject"], self.source_obj) #print "SCRIPT TEST: %s got %s." % (values["pobject"], self.source_obj)
pass pass
def a_drop(self, values): def a_drop(self, values):
""" """
Perform this action when someone uses the GET command on the object. Perform this action when someone uses the GET command on the object.
values: (Dict) Script arguments with keys: values: (Dict) Script arguments with keys:
* pobject: The object requesting the action. * pobject: The object requesting the action.
""" """
# Un-comment the line below for an example # Un-comment the line below for an example
#print "SCRIPT TEST: %s dropped %s." % (values["pobject"], self.source_obj) #print "SCRIPT TEST: %s dropped %s." % (values["pobject"], self.source_obj)
pass pass
def default_lock(self, values): def default_lock(self, values):
""" """
This method returns a True or False boolean value to determine whether This method returns a True or False boolean value to determine whether
the actor passes the lock. This is generally used for picking up the actor passes the lock. This is generally used for picking up
objects or traversing exits. objects or traversing exits.
values: (Dict) Script arguments with keys: values: (Dict) Script arguments with keys:
* pobject: The object requesting the action. * pobject: The object requesting the action.
""" """
# Assume everyone passes the default lock by default. # Assume everyone passes the default lock by default.
return True return True
def use_lock(self, values): def use_lock(self, values):
""" """
This method returns a True or False boolean value to determine whether This method returns a True or False boolean value to determine whether
the actor passes the lock. This is generally used for seeing whether the actor passes the lock. This is generally used for seeing whether
a player can use an object or any of its commands. a player can use an object or any of its commands.
values: (Dict) Script arguments with keys: values: (Dict) Script arguments with keys:
* pobject: The object requesting the action. * pobject: The object requesting the action.
""" """
# Assume everyone passes the use lock by default. # Assume everyone passes the use lock by default.
return True return True
def enter_lock(self, values): def enter_lock(self, values):
""" """
This method returns a True or False boolean value to determine whether This method returns a True or False boolean value to determine whether
the actor passes the lock. This is generally used for seeing whether the actor passes the lock. This is generally used for seeing whether
a player can enter another object. a player can enter another object.
values: (Dict) Script arguments with keys: values: (Dict) Script arguments with keys:
* pobject: The object requesting the action. * pobject: The object requesting the action.
""" """
# Assume everyone passes the enter lock by default. # Assume everyone passes the enter lock by default.
return True return True
def class_factory(source_obj): def class_factory(source_obj):
""" """
This method is called any script you retrieve (via the scripthandler). It This method is called any script you retrieve (via the scripthandler). It
creates an instance of the class and returns it transparently. I'm not creates an instance of the class and returns it transparently. I'm not
sure how well this will scale, but we'll find out. We may need to sure how well this will scale, but we'll find out. We may need to
re-factor this eventually. re-factor this eventually.
source_obj: (Object) A reference to the object being scripted (the child). source_obj: (Object) A reference to the object being scripted (the child).
""" """
return BasicObject(source_obj) return BasicObject(source_obj)