diff --git a/cmdhandler.py b/cmdhandler.py index 3c38d398aa..28b3977f9b 100755 --- a/cmdhandler.py +++ b/cmdhandler.py @@ -2,10 +2,6 @@ from traceback import format_exc import time import defines_global -import commands_privileged -import commands_general -import commands_comsys -import commands_unloggedin import cmdtable import functions_db import functions_general @@ -163,7 +159,7 @@ def handle(cdat): if exit.get_home(): cdat['uinput'] = parsed_input pobject.move_to(exit.get_home()) - commands_general.cmd_look(cdat) + session.execute_cmd("look") else: session.msg("That exit leads to nowhere.") return diff --git a/cmdtable.py b/cmdtable.py index e8975f0e4c..bd2c003470 100644 --- a/cmdtable.py +++ b/cmdtable.py @@ -1,7 +1,9 @@ -import commands_unloggedin -import commands_general -import commands_privileged -import commands_comsys +import commands.general +import commands.privileged +import commands.comsys +import commands.unloggedin +import commands.info +import commands.objmanip """ Command Table Entries @@ -15,60 +17,62 @@ privilege checking in the command function), use None in place of the permissions tuple. """ -# Unlogged-in Command Table +# -- Unlogged-in Command Table -- +# Command Name Command Function Privilege Tuple uncon_ctable = { - "connect": (commands_unloggedin.cmd_connect, None), - "create": (commands_unloggedin.cmd_create, None), - "quit": (commands_unloggedin.cmd_quit, None), + "connect": (commands.unloggedin.cmd_connect, None), + "create": (commands.unloggedin.cmd_create, None), + "quit": (commands.unloggedin.cmd_quit, None), } -# Command Table +# -- Command Table -- +# Command Name Command Function Privilege Tuple ctable = { - "addcom": (commands_comsys.cmd_addcom, None), - "comlist": (commands_comsys.cmd_comlist, None), - "delcom": (commands_comsys.cmd_delcom, None), - "drop": (commands_general.cmd_drop, None), - "examine": (commands_general.cmd_examine, None), - "get": (commands_general.cmd_get, None), - "help": (commands_general.cmd_help, None), - "idle": (commands_general.cmd_idle, None), - "inventory": (commands_general.cmd_inventory, None), - "look": (commands_general.cmd_look, None), - "page": (commands_general.cmd_page, None), - "pose": (commands_general.cmd_pose, None), - "quit": (commands_general.cmd_quit, None), - "say": (commands_general.cmd_say, None), - "time": (commands_general.cmd_time, None), - "uptime": (commands_general.cmd_uptime, None), - "version": (commands_general.cmd_version, None), - "who": (commands_general.cmd_who, None), - "@ccreate": (commands_comsys.cmd_ccreate, ("objects.add_commchannel")), - "@cdestroy": (commands_comsys.cmd_cdestroy, ("objects.delete_commchannel")), - "@cemit": (commands_comsys.cmd_cemit, None), - "@clist": (commands_comsys.cmd_clist, None), - "@create": (commands_privileged.cmd_create, ("genperms.builder")), - "@describe": (commands_privileged.cmd_description, None), - "@destroy": (commands_privileged.cmd_destroy, ("genperms.builder")), - "@dig": (commands_privileged.cmd_dig, ("genperms.builder")), - "@emit": (commands_privileged.cmd_emit, ("genperms.announce")), - "@find": (commands_privileged.cmd_find, ("genperms.builder")), - "@link": (commands_privileged.cmd_link, ("genperms.builder")), - "@list": (commands_privileged.cmd_list, ("genperms.process_control")), - "@name": (commands_privileged.cmd_name, None), - "@nextfree": (commands_privileged.cmd_nextfree, ("genperms.builder")), - "@newpassword": (commands_privileged.cmd_newpassword, ("genperms.manage_players")), - "@open": (commands_privileged.cmd_open, ("genperms.builder")), - "@password": (commands_privileged.cmd_password, None), - "@ps": (commands_privileged.cmd_ps, ("genperms.process_control")), - "@reload": (commands_privileged.cmd_reload, ("genperms.process_control")), - "@set": (commands_privileged.cmd_set, None), - "@shutdown": (commands_privileged.cmd_shutdown, ("genperms.process_control")), - "@stats": (commands_privileged.cmd_stats, None), - "@teleport": (commands_privileged.cmd_teleport, ("genperms.builder")), - "@unlink": (commands_privileged.cmd_unlink, ("genperms.builder")), - "@wall": (commands_privileged.cmd_wall, ("genperms.announce")), - "@wipe": (commands_privileged.cmd_wipe, None), + "addcom": (commands.comsys.cmd_addcom, None), + "comlist": (commands.comsys.cmd_comlist, None), + "delcom": (commands.comsys.cmd_delcom, None), + "drop": (commands.general.cmd_drop, None), + "examine": (commands.general.cmd_examine, None), + "get": (commands.general.cmd_get, None), + "help": (commands.general.cmd_help, None), + "idle": (commands.general.cmd_idle, None), + "inventory": (commands.general.cmd_inventory, None), + "look": (commands.general.cmd_look, None), + "page": (commands.general.cmd_page, None), + "pose": (commands.general.cmd_pose, None), + "quit": (commands.general.cmd_quit, None), + "say": (commands.general.cmd_say, None), + "time": (commands.general.cmd_time, None), + "uptime": (commands.general.cmd_uptime, None), + "version": (commands.general.cmd_version, None), + "who": (commands.general.cmd_who, None), + "@ccreate": (commands.comsys.cmd_ccreate, ("objects.add_commchannel")), + "@cdestroy": (commands.comsys.cmd_cdestroy, ("objects.delete_commchannel")), + "@cemit": (commands.comsys.cmd_cemit, None), + "@clist": (commands.comsys.cmd_clist, None), + "@create": (commands.objmanip.cmd_create, ("genperms.builder")), + "@describe": (commands.objmanip.cmd_description, None), + "@destroy": (commands.objmanip.cmd_destroy, ("genperms.builder")), + "@dig": (commands.objmanip.cmd_dig, ("genperms.builder")), + "@emit": (commands.general.cmd_emit, ("genperms.announce")), + "@find": (commands.objmanip.cmd_find, ("genperms.builder")), + "@link": (commands.objmanip.cmd_link, ("genperms.builder")), + "@list": (commands.info.cmd_list, ("genperms.process_control")), + "@name": (commands.objmanip.cmd_name, None), + "@nextfree": (commands.objmanip.cmd_nextfree, ("genperms.builder")), + "@newpassword": (commands.privileged.cmd_newpassword, ("genperms.manage_players")), + "@open": (commands.objmanip.cmd_open, ("genperms.builder")), + "@password": (commands.general.cmd_password, None), + "@ps": (commands.info.cmd_ps, ("genperms.process_control")), + "@reload": (commands.privileged.cmd_reload, ("genperms.process_control")), + "@set": (commands.objmanip.cmd_set, None), + "@shutdown": (commands.privileged.cmd_shutdown, ("genperms.process_control")), + "@stats": (commands.info.cmd_stats, None), + "@teleport": (commands.objmanip.cmd_teleport, ("genperms.builder")), + "@unlink": (commands.objmanip.cmd_unlink, ("genperms.builder")), + "@wall": (commands.general.cmd_wall, ("genperms.announce")), + "@wipe": (commands.objmanip.cmd_wipe, None), } def return_cmdtuple(func_name, unlogged_cmd=False): @@ -80,5 +84,5 @@ def return_cmdtuple(func_name, unlogged_cmd=False): cfunc = ctable.get(func_name, False) else: cfunc = uncon_ctable.get(func_name, False) - + return cfunc diff --git a/commands/__init__.py b/commands/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/commands_comsys.py b/commands/comsys.py similarity index 99% rename from commands_comsys.py rename to commands/comsys.py index d1e5415ba0..bd1c2572bf 100644 --- a/commands_comsys.py +++ b/commands/comsys.py @@ -1,4 +1,3 @@ -import os import time import settings @@ -7,7 +6,6 @@ import functions_db import functions_help import functions_comsys import defines_global -import session_mgr import ansi """ Comsys command module. Pretty much every comsys command should go here for diff --git a/commands_general.py b/commands/general.py similarity index 89% rename from commands_general.py rename to commands/general.py index f45ecc8b76..0d7a50b466 100644 --- a/commands_general.py +++ b/commands/general.py @@ -1,16 +1,74 @@ +import os, time import settings -import time import functions_general import functions_db import functions_help -import defines_global as global_defines +import defines_global import session_mgr import ansi -import os """ Generic command module. Pretty much every command should go here for now. -""" +""" +def cmd_password(cdat): + """ + Changes your own password. + + @newpass = + """ + session = cdat['session'] + pobject = session.get_pobject() + args = cdat['uinput']['splitted'][1:] + eq_args = ' '.join(args).split('=') + oldpass = ''.join(eq_args[0]) + newpass = ''.join(eq_args[1:]) + + if len(oldpass) == 0: + session.msg("You must provide your old password.") + elif len(newpass) == 0: + session.msg("You must provide your new password.") + else: + uaccount = pobject.get_user_account() + + if not uaccount.check_password(oldpass): + session.msg("The specified old password isn't correct.") + elif len(newpass) < 3: + session.msg("Passwords must be at least three characters long.") + return + else: + uaccount.set_password(newpass) + uaccount.save() + session.msg("Password changed.") + +def cmd_emit(cdat): + """ + Emits something to your location. + """ + session = cdat['session'] + pobject = session.get_pobject() + uinput= cdat['uinput']['splitted'] + message = ' '.join(uinput[1:]) + + if message == '': + session.msg("Emit what?") + else: + pobject.get_location().emit_to_contents(message) + +def cmd_wall(cdat): + """ + Announces a message to all connected players. + """ + session = cdat['session'] + wallstring = ' '.join(cdat['uinput']['splitted'][1:]) + pobject = session.get_pobject() + + if wallstring == '': + session.msg("Announce what?") + return + + message = "%s shouts \"%s\"" % (session.get_pobject().get_name(show_dbref=False), wallstring) + functions_general.announce_all(message) + def cmd_idle(cdat): """ Returns nothing, this lets the player set an idle timer without spamming @@ -424,7 +482,7 @@ def cmd_version(cdat): """ session = cdat['session'] retval = "-"*50 +"\n\r" - retval += "Evennia %s\n\r" % (global_defines.EVENNIA_VERSION,) + retval += "Evennia %s\n\r" % (defines_global.EVENNIA_VERSION,) retval += "-"*50 session.msg(retval) diff --git a/commands/info.py b/commands/info.py new file mode 100644 index 0000000000..ca33b664de --- /dev/null +++ b/commands/info.py @@ -0,0 +1,62 @@ +import os, resource + +import functions_db +import scheduler + +def cmd_list(cdat): + """ + Shows some game related information. + """ + session = cdat['session'] + pobject = session.get_pobject() + args = cdat['uinput']['splitted'][1:] + argstr = ''.join(args) + + msg_invalid = "Unknown option. Use one of: commands, flags, process" + + if len(argstr) == 0: + session.msg(msg_invalid) + elif argstr == "commands": + session.msg('Commands: '+ ' '.join(session.server.command_list())) + elif argstr == "process": + loadvg = os.getloadavg() + psize = resource.getpagesize() + rusage = resource.getrusage(resource.RUSAGE_SELF) + session.msg("Process ID: %10d %10d bytes per page" % (os.getpid(), psize)) + session.msg("Time used: %10d user %10d sys" % (rusage[0],rusage[1])) + session.msg("Integral mem:%10d shared %10d private%10d stack" % (rusage[3], rusage[4], rusage[5])) + session.msg("Max res mem: %10d pages %10d bytes" % (rusage[2],rusage[2] * psize)) + session.msg("Page faults: %10d hard %10d soft %10d swapouts" % (rusage[7], rusage[6], rusage[8])) + session.msg("Disk I/O: %10d reads %10d writes" % (rusage[9], rusage[10])) + session.msg("Network I/O: %10d in %10d out" % (rusage[12], rusage[11])) + session.msg("Context swi: %10d vol %10d forced %10d sigs" % (rusage[14], rusage[15], rusage[13])) + elif argstr == "flags": + session.msg("Flags: "+" ".join(defines_global.SERVER_FLAGS)) + else: + session.msg(msg_invalid) + +def cmd_ps(cdat): + """ + Shows the process/event table. + """ + session = cdat['session'] + session.msg("-- Interval Events --") + for event in scheduler.schedule: + session.msg(" [%d/%d] %s" % (scheduler.get_event_nextfire(event), + scheduler.get_event_interval(event), + scheduler.get_event_description(event))) + session.msg("Totals: %d interval events" % (len(scheduler.schedule),)) + +def cmd_stats(cdat): + """ + Shows stats about the database. + 4012 objects = 144 rooms, 212 exits, 613 things, 1878 players. (1165 garbage) + """ + session = cdat['session'] + stats_dict = functions_db.object_totals() + session.msg("%d objects = %d rooms, %d exits, %d things, %d players. (%d garbage)" % (stats_dict["objects"], + stats_dict["rooms"], + stats_dict["exits"], + stats_dict["things"], + stats_dict["players"], + stats_dict["garbage"])) diff --git a/commands_privileged.py b/commands/objmanip.py similarity index 73% rename from commands_privileged.py rename to commands/objmanip.py index defd78c5b8..5a0bd4c4b3 100644 --- a/commands_privileged.py +++ b/commands/objmanip.py @@ -1,26 +1,69 @@ -import os -import resource - -from django.contrib.auth.models import User -from apps.objects.models import Object -import defines_global -import scheduler -import session_mgr -import functions_general -import functions_db -import commands_general import ansi +import session_mgr +import functions_db -""" -This file contains commands that require special permissions to use. These -are generally @-prefixed commands, but there are exceptions. -""" +def cmd_teleport(cdat): + """ + Teleports an object somewhere. + """ + session = cdat['session'] + pobject = session.get_pobject() + server = cdat['server'] + args = cdat['uinput']['splitted'][1:] -def cmd_alias(cdat): - """ - Assigns an alias to a player object for ease of paging, etc. - """ - pass + if len(args) == 0: + session.msg("Teleport where/what?") + return + + eq_args = args[0].split('=') + search_str = ''.join(args) + + # If we have more than one entry in our '=' delimited argument list, + # then we're doing a @tel =. If not, we're doing + # a direct teleport, @tel . + if len(eq_args) > 1: + # Equal sign teleport. + victim = functions_db.standard_plr_objsearch(session, eq_args[0]) + # Use standard_plr_objsearch to handle duplicate/nonexistant results. + if not victim: + return + + destination = functions_db.standard_plr_objsearch(session, eq_args[1]) + # Use standard_plr_objsearch to handle duplicate/nonexistant results. + if not destination: + return + + if victim.is_room(): + session.msg("You can't teleport a room.") + return + + if victim == destination: + session.msg("You can't teleport an object inside of itself!") + return + session.msg("Teleported.") + victim.move_to(destination) + + # This is somewhat kludgy right now, we'll have to find a better way + # to do it sometime else. If we can find a session in the server's + # session list matching the object we're teleporting, force it to + # look. This is going to typically be a player. + victim_session = session_mgr.session_from_object(victim) + if victim_session: + victim_session.execute_cmd("look") + + else: + # Direct teleport (no equal sign) + target_obj = functions_db.standard_plr_objsearch(session, search_str) + # Use standard_plr_objsearch to handle duplicate/nonexistant results. + if not target_obj: + return + + if target_obj == pobject: + session.msg("You can't teleport inside yourself!") + return + session.msg("Teleported.") + pobject.move_to(target_obj) + session.execute_cmd("look") def cmd_stats(cdat): """ @@ -36,251 +79,162 @@ def cmd_stats(cdat): stats_dict["players"], stats_dict["garbage"])) -def cmd_reload(cdat): +def cmd_alias(cdat): """ - Reloads all modules. + Assigns an alias to a player object for ease of paging, etc. """ - session = cdat['session'] - server = session.server.reload(session) + pass -def cmd_ps(cdat): +def cmd_wipe(cdat): """ - Shows the process/event table. - """ - session = cdat['session'] - session.msg("-- Interval Events --") - for event in scheduler.schedule: - session.msg(" [%d/%d] %s" % (scheduler.get_event_nextfire(event), - scheduler.get_event_interval(event), - scheduler.get_event_description(event))) - session.msg("Totals: %d interval events" % (len(scheduler.schedule),)) - - -def cmd_destroy(cdat): - """ - Destroy an object. + Wipes an object's attributes, or optionally only those matching a search + string. """ session = cdat['session'] pobject = session.get_pobject() args = cdat['uinput']['splitted'][1:] - switches = cdat['uinput']['root_chunk'][1:] - switch_override = False - - if "override" in switches: - switch_override = True - + attr_search = False + if len(args) == 0: - session.msg("Destroy what?") - return - else: - target_obj = functions_db.standard_plr_objsearch(session, ' '.join(args)) - # Use standard_plr_objsearch to handle duplicate/nonexistant results. - if not target_obj: - return - - if target_obj.is_player(): - if pobject.id == target_obj.id: - session.msg("You can't destroy yourself.") - return - if not switch_override: - session.msg("You must use @destroy/override on players.") - return - if target_obj.is_superuser(): - session.msg("You can't destroy a superuser.") - return - elif target_obj.is_going() or target_obj.is_garbage(): - session.msg("That object is already destroyed.") - return - - session.msg("You destroy %s." % (target_obj.get_name(),)) - target_obj.destroy() - -def cmd_list(cdat): - """ - Shows some game related information. - """ - session = cdat['session'] - pobject = session.get_pobject() - args = cdat['uinput']['splitted'][1:] - argstr = ''.join(args) - - msg_invalid = "Unknown option. Use one of: commands, flags, process" - - if len(argstr) == 0: - session.msg(msg_invalid) - elif argstr == "commands": - session.msg('Commands: '+ ' '.join(session.server.command_list())) - elif argstr == "process": - loadvg = os.getloadavg() - psize = resource.getpagesize() - rusage = resource.getrusage(resource.RUSAGE_SELF) - session.msg("Process ID: %10d %10d bytes per page" % (os.getpid(), psize)) - session.msg("Time used: %10d user %10d sys" % (rusage[0],rusage[1])) - session.msg("Integral mem:%10d shared %10d private%10d stack" % (rusage[3], rusage[4], rusage[5])) - session.msg("Max res mem: %10d pages %10d bytes" % (rusage[2],rusage[2] * psize)) - session.msg("Page faults: %10d hard %10d soft %10d swapouts" % (rusage[7], rusage[6], rusage[8])) - session.msg("Disk I/O: %10d reads %10d writes" % (rusage[9], rusage[10])) - session.msg("Network I/O: %10d in %10d out" % (rusage[12], rusage[11])) - session.msg("Context swi: %10d vol %10d forced %10d sigs" % (rusage[14], rusage[15], rusage[13])) - elif argstr == "flags": - session.msg("Flags: "+" ".join(defines_global.SERVER_FLAGS)) - else: - session.msg(msg_invalid) - -def cmd_description(cdat): - """ - Set an object's description. - """ - session = cdat['session'] - pobject = session.get_pobject() - args = cdat['uinput']['splitted'][1:] - eq_args = ' '.join(args).split('=') - searchstring = ''.join(eq_args[0]) - - if len(args) == 0: - session.msg("What do you want to describe?") - elif len(eq_args) < 2: - session.msg("How would you like to describe that object?") - else: - target_obj = functions_db.standard_plr_objsearch(session, searchstring) - # Use standard_plr_objsearch to handle duplicate/nonexistant results. - if not target_obj: - return - - if not pobject.controls_other(target_obj): - session.msg(defines_global.NOCONTROL_MSG) - return - - new_desc = '='.join(eq_args[1:]) - session.msg("%s - DESCRIPTION set." % (target_obj,)) - target_obj.set_description(new_desc) - -def cmd_newpassword(cdat): - """ - Set a player's password. - """ - session = cdat['session'] - pobject = session.get_pobject() - args = cdat['uinput']['splitted'][1:] - eq_args = ' '.join(args).split('=') - searchstring = ''.join(eq_args[0]) - newpass = ''.join(eq_args[1:]) - - if len(args) == 0: - session.msg("What player's password do you want to change") - return - if len(newpass) == 0: - session.msg("You must supply a new password.") + session.msg("Wipe what?") return - target_obj = functions_db.standard_plr_objsearch(session, searchstring) + # Look for a slash in the input, indicating an attribute wipe. + attr_split = args[0].split("/") + + # If the splitting by the "/" character returns a list with more than 1 + # entry, it's an attribute match. + if len(attr_split) > 1: + attr_search = True + # Strip the object search string from the input with the + # object/attribute pair. + searchstr = attr_split[0] + # Just in case there's a slash in an attribute name. + attr_searchstr = '/'.join(attr_split[1:]) + else: + searchstr = ' '.join(args) + + target_obj = functions_db.standard_plr_objsearch(session, searchstr) # Use standard_plr_objsearch to handle duplicate/nonexistant results. if not target_obj: return - if not target_obj.is_player(): - session.msg("You can only change passwords on players.") - elif not pobject.controls_other(target_obj): - session.msg("You do not control %s." % (target_obj.get_name(),)) - else: - uaccount = target_obj.get_user_account() - if len(newpass) == 0: - uaccount.set_password() + if attr_search: + # User has passed an attribute wild-card string. Search for name matches + # and wipe. + attr_matches = target_obj.attribute_namesearch(attr_searchstr, exclude_noset=True) + if attr_matches: + for attr in attr_matches: + target_obj.clear_attribute(attr.get_name()) + session.msg("%s - %d attributes wiped." % (target_obj.get_name(), len(attr_matches))) else: - uaccount.set_password(newpass) - uaccount.save() - session.msg("%s - PASSWORD set." % (target_obj.get_name(),)) - target_obj.emit_to("%s has changed your password." % (pobject.get_name(show_dbref=False),)) + 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_password(cdat): +def cmd_set(cdat): """ - Changes your own password. - - @newpass = + Sets flags or attributes on objects. """ session = cdat['session'] pobject = session.get_pobject() + server = cdat['server'] args = cdat['uinput']['splitted'][1:] + + if len(args) == 0: + session.msg("Set what?") + return + + # There's probably a better way to do this. Break the arguments (minus + # the root command) up so we have two items in the list, 0 being the victim, + # 1 being the list of flags or the attribute/value pair. eq_args = ' '.join(args).split('=') - oldpass = ''.join(eq_args[0]) - newpass = ''.join(eq_args[1:]) + + if len(eq_args) < 2: + session.msg("Set what?") + return - if len(oldpass) == 0: - session.msg("You must provide your old password.") - elif len(newpass) == 0: - session.msg("You must provide your new password.") - else: - uaccount = User.objects.get(id=pobject.id) + victim = functions_db.standard_plr_objsearch(session, eq_args[0]) + # Use standard_plr_objsearch to handle duplicate/nonexistant results. + if not victim: + return + + if not pobject.controls_other(victim): + session.msg(defines_global.NOCONTROL_MSG) + return + + attrib_args = eq_args[1].split(':') + + if len(attrib_args) > 1: + # We're dealing with an attribute/value pair. + attrib_name = attrib_args[0].upper() + splicenum = eq_args[1].find(':') + 1 + attrib_value = eq_args[1][splicenum:] - if not uaccount.check_password(oldpass): - session.msg("The specified old password isn't correct.") - elif len(newpass) < 3: - session.msg("Passwords must be at least three characters long.") - return - else: - uaccount.set_password(newpass) - uaccount.save() - session.msg("Password changed.") - -def cmd_name(cdat): - """ - Handle naming an object. - """ - session = cdat['session'] - pobject = session.get_pobject() - args = cdat['uinput']['splitted'][1:] - eq_args = ' '.join(args).split('=') - searchstring = ''.join(eq_args[0]) - - if len(args) == 0: - session.msg("What do you want to name?") - elif len(eq_args) < 2: - session.msg("What would you like to name that object?") - else: - target_obj = functions_db.standard_plr_objsearch(session, searchstring) - # Use standard_plr_objsearch to handle duplicate/nonexistant results. - if not target_obj: + # 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(): + session.msg("You can't modify that attribute.") return - if len(eq_args[1]) == 0: - session.msg("What would you like to name that object?") + if attrib_value: + # An attribute value was specified, create or set the attribute. + verb = 'set' + victim.set_attribute(attrib_name, attrib_value) else: - newname = '='.join(eq_args[1:]) - session.msg("You have renamed %s to %s." % (target_obj, ansi.parse_ansi(newname, strip_formatting=True))) - target_obj.set_name(newname) + # No value was given, this means we delete the attribute. + verb = 'cleared' + victim.clear_attribute(attrib_name) + session.msg("%s - %s %s." % (victim.get_name(), attrib_name, verb)) + else: + # Flag manipulation form. + flag_list = eq_args[1].split() + + for flag in flag_list: + flag = flag.upper() + if flag[0] == '!': + # We're un-setting the flag. + flag = flag[1:] + if not functions_db.is_modifiable_flag(flag): + session.msg("You can't set/unset the flag - %s." % (flag,)) + else: + session.msg('%s - %s cleared.' % (victim.get_name(), flag.upper(),)) + victim.set_flag(flag, False) + else: + # We're setting the flag. + if not functions_db.is_modifiable_flag(flag): + session.msg("You can't set/unset the flag - %s." % (flag,)) + else: + session.msg('%s - %s set.' % (victim.get_name(), flag.upper(),)) + victim.set_flag(flag, True) -def cmd_dig(cdat): +def cmd_find(cdat): """ - Creates a new object of type 'ROOM'. + Searches for an object of a particular name. """ session = cdat['session'] + server = cdat['server'] + searchstring = ' '.join(cdat['uinput']['splitted'][1:]) pobject = session.get_pobject() - uinput= cdat['uinput']['splitted'] - roomname = ' '.join(uinput[1:]) + can_find = pobject.user_has_perm("genperms.builder") + + if searchstring == '': + session.msg("No search pattern given.") + return - if roomname == '': - session.msg("You must supply a name!") + results = functions_db.global_object_name_search(searchstring) + + if len(results) > 0: + session.msg("Name matches for: %s" % (searchstring,)) + for result in results: + session.msg(" %s" % (result.get_name(fullname=True),)) + session.msg("%d matches returned." % (len(results),)) else: - # Create and set the object up. - odat = {"name": roomname, "type": 2, "location": None, "owner": pobject} - new_object = functions_db.create_object(odat) - - session.msg("You create a new room: %s" % (new_object,)) - -def cmd_emit(cdat): - """ - Emits something to your location. - """ - session = cdat['session'] - pobject = session.get_pobject() - uinput= cdat['uinput']['splitted'] - message = ' '.join(uinput[1:]) - - if message == '': - session.msg("Emit what?") - else: - pobject.get_location().emit_to_contents(message) - + session.msg("No name matches found for: %s" % (searchstring,)) + def cmd_create(cdat): """ Creates a new object of type 'THING'. @@ -449,241 +403,114 @@ def cmd_unlink(cdat): target_obj.set_home(None) session.msg("You have unlinked %s." % (target_obj.get_name(),)) -def cmd_teleport(cdat): +def cmd_dig(cdat): """ - Teleports an object somewhere. + Creates a new object of type 'ROOM'. """ session = cdat['session'] pobject = session.get_pobject() - server = cdat['server'] - args = cdat['uinput']['splitted'][1:] - - if len(args) == 0: - session.msg("Teleport where/what?") - return - - eq_args = args[0].split('=') - search_str = ''.join(args) - - # If we have more than one entry in our '=' delimited argument list, - # then we're doing a @tel =. If not, we're doing - # a direct teleport, @tel . - if len(eq_args) > 1: - # Equal sign teleport. - victim = functions_db.standard_plr_objsearch(session, eq_args[0]) - # Use standard_plr_objsearch to handle duplicate/nonexistant results. - if not victim: - return - - destination = functions_db.standard_plr_objsearch(session, eq_args[1]) - # Use standard_plr_objsearch to handle duplicate/nonexistant results. - if not destination: - return - - if victim == destination: - session.msg("You can't teleport an object inside of itself!") - return - session.msg("Teleported.") - victim.move_to(destination) - - # This is somewhat kludgy right now, we'll have to find a better way - # to do it sometime else. If we can find a session in the server's - # session list matching the object we're teleporting, force it to - # look. This is going to typically be a player. - victim_session = session_mgr.session_from_object(victim) - if victim_session: - # We need to form up a new cdat dictionary to pass with the command. - # Kinda yucky I guess. - cdat2 = {"server": server, "uinput": 'look', "session": victim_session} - cmdhandler.handle(cdat2) - + uinput= cdat['uinput']['splitted'] + roomname = ' '.join(uinput[1:]) + + if roomname == '': + session.msg("You must supply a name!") else: - # Direct teleport (no equal sign) - target_obj = functions_db.standard_plr_objsearch(session, search_str) + # Create and set the object up. + odat = {"name": roomname, "type": 2, "location": None, "owner": pobject} + new_object = functions_db.create_object(odat) + + session.msg("You create a new room: %s" % (new_object,)) + +def cmd_name(cdat): + """ + Handle naming an object. + """ + session = cdat['session'] + pobject = session.get_pobject() + args = cdat['uinput']['splitted'][1:] + eq_args = ' '.join(args).split('=') + searchstring = ''.join(eq_args[0]) + + if len(args) == 0: + session.msg("What do you want to name?") + elif len(eq_args) < 2: + session.msg("What would you like to name that object?") + else: + target_obj = functions_db.standard_plr_objsearch(session, searchstring) + # Use standard_plr_objsearch to handle duplicate/nonexistant results. + if not target_obj: + return + + if len(eq_args[1]) == 0: + session.msg("What would you like to name that object?") + else: + newname = '='.join(eq_args[1:]) + session.msg("You have renamed %s to %s." % (target_obj, ansi.parse_ansi(newname, strip_formatting=True))) + target_obj.set_name(newname) + +def cmd_description(cdat): + """ + Set an object's description. + """ + session = cdat['session'] + pobject = session.get_pobject() + args = cdat['uinput']['splitted'][1:] + eq_args = ' '.join(args).split('=') + searchstring = ''.join(eq_args[0]) + + if len(args) == 0: + session.msg("What do you want to describe?") + elif len(eq_args) < 2: + session.msg("How would you like to describe that object?") + else: + target_obj = functions_db.standard_plr_objsearch(session, searchstring) # Use standard_plr_objsearch to handle duplicate/nonexistant results. if not target_obj: return - if target_obj == pobject: - session.msg("You can't teleport inside yourself!") + if not pobject.controls_other(target_obj): + session.msg(defines_global.NOCONTROL_MSG) return - session.msg("Teleported.") - pobject.move_to(target_obj) - commands_general.cmd_look(cdat) -def cmd_wipe(cdat): + new_desc = '='.join(eq_args[1:]) + session.msg("%s - DESCRIPTION set." % (target_obj,)) + target_obj.set_description(new_desc) + +def cmd_destroy(cdat): """ - Wipes an object's attributes, or optionally only those matching a search - string. + Destroy an object. """ session = cdat['session'] pobject = session.get_pobject() args = cdat['uinput']['splitted'][1:] - attr_search = False - + switches = cdat['uinput']['root_chunk'][1:] + switch_override = False + + if "override" in switches: + switch_override = True + if len(args) == 0: - session.msg("Wipe what?") + session.msg("Destroy what?") return - - # Look for a slash in the input, indicating an attribute wipe. - attr_split = args[0].split("/") - - # If the splitting by the "/" character returns a list with more than 1 - # entry, it's an attribute match. - if len(attr_split) > 1: - attr_search = True - # Strip the object search string from the input with the - # object/attribute pair. - searchstr = attr_split[0] - # Just in case there's a slash in an attribute name. - attr_searchstr = '/'.join(attr_split[1:]) else: - searchstr = ' '.join(args) - - target_obj = functions_db.standard_plr_objsearch(session, searchstr) - # Use standard_plr_objsearch to handle duplicate/nonexistant results. - if not target_obj: - return - - if attr_search: - # User has passed an attribute wild-card string. Search for name matches - # and wipe. - attr_matches = target_obj.attribute_namesearch(attr_searchstr, exclude_noset=True) - if attr_matches: - for attr in attr_matches: - target_obj.clear_attribute(attr.get_name()) - session.msg("%s - %d attributes wiped." % (target_obj.get_name(), len(attr_matches))) - 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): - """ - Sets flags or attributes on objects. - """ - session = cdat['session'] - pobject = session.get_pobject() - server = cdat['server'] - args = cdat['uinput']['splitted'][1:] - - if len(args) == 0: - session.msg("Set what?") - return - - # There's probably a better way to do this. Break the arguments (minus - # the root command) up so we have two items in the list, 0 being the victim, - # 1 being the list of flags or the attribute/value pair. - eq_args = ' '.join(args).split('=') - - if len(eq_args) < 2: - session.msg("Set what?") - return - - victim = functions_db.standard_plr_objsearch(session, eq_args[0]) - # Use standard_plr_objsearch to handle duplicate/nonexistant results. - if not victim: - return - - if not pobject.controls_other(victim): - session.msg(defines_global.NOCONTROL_MSG) - return - - attrib_args = eq_args[1].split(':') - - if len(attrib_args) > 1: - # We're dealing with an attribute/value pair. - attrib_name = attrib_args[0].upper() - splicenum = eq_args[1].find(':') + 1 - attrib_value = eq_args[1][splicenum:] - - # 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(): - session.msg("You can't modify that attribute.") + target_obj = functions_db.standard_plr_objsearch(session, ' '.join(args)) + # Use standard_plr_objsearch to handle duplicate/nonexistant results. + if not target_obj: return - if attrib_value: - # An attribute value was specified, create or set the attribute. - verb = 'set' - victim.set_attribute(attrib_name, attrib_value) - else: - # No value was given, this means we delete the attribute. - verb = 'cleared' - victim.clear_attribute(attrib_name) - session.msg("%s - %s %s." % (victim.get_name(), attrib_name, verb)) - else: - # Flag manipulation form. - flag_list = eq_args[1].split() - - for flag in flag_list: - flag = flag.upper() - if flag[0] == '!': - # We're un-setting the flag. - flag = flag[1:] - if not functions_db.is_modifiable_flag(flag): - session.msg("You can't set/unset the flag - %s." % (flag,)) - else: - session.msg('%s - %s cleared.' % (victim.get_name(), flag.upper(),)) - victim.set_flag(flag, False) - else: - # We're setting the flag. - if not functions_db.is_modifiable_flag(flag): - session.msg("You can't set/unset the flag - %s." % (flag,)) - else: - session.msg('%s - %s set.' % (victim.get_name(), flag.upper(),)) - victim.set_flag(flag, True) - -def cmd_find(cdat): - """ - Searches for an object of a particular name. - """ - session = cdat['session'] - server = cdat['server'] - searchstring = ' '.join(cdat['uinput']['splitted'][1:]) - pobject = session.get_pobject() - can_find = pobject.user_has_perm("genperms.builder") - - if searchstring == '': - session.msg("No search pattern given.") - return + if target_obj.is_player(): + if pobject.id == target_obj.id: + session.msg("You can't destroy yourself.") + return + if not switch_override: + session.msg("You must use @destroy/override on players.") + return + if target_obj.is_superuser(): + session.msg("You can't destroy a superuser.") + return + elif target_obj.is_going() or target_obj.is_garbage(): + session.msg("That object is already destroyed.") + return - results = functions_db.global_object_name_search(searchstring) - - if len(results) > 0: - session.msg("Name matches for: %s" % (searchstring,)) - for result in results: - session.msg(" %s" % (result.get_name(fullname=True),)) - session.msg("%d matches returned." % (len(results),)) - else: - session.msg("No name matches found for: %s" % (searchstring,)) - -def cmd_wall(cdat): - """ - Announces a message to all connected players. - """ - session = cdat['session'] - wallstring = ' '.join(cdat['uinput']['splitted'][1:]) - pobject = session.get_pobject() - - if wallstring == '': - session.msg("Announce what?") - return - - message = "%s shouts \"%s\"" % (session.get_pobject().get_name(show_dbref=False), wallstring) - functions_general.announce_all(message) - -def cmd_shutdown(cdat): - """ - Shut the server down gracefully. - """ - session = cdat['session'] - server = cdat['server'] - pobject = session.get_pobject() - - session.msg('Shutting down...') - print 'Server shutdown by %s' % (pobject.get_name(show_dbref=False),) - server.shutdown() + session.msg("You destroy %s." % (target_obj.get_name(),)) + target_obj.destroy() \ No newline at end of file diff --git a/commands/privileged.py b/commands/privileged.py new file mode 100644 index 0000000000..9759baf067 --- /dev/null +++ b/commands/privileged.py @@ -0,0 +1,65 @@ +import defines_global +import functions_general +import functions_db +import ansi + +""" +This file contains commands that require special permissions to use. These +are generally @-prefixed commands, but there are exceptions. +""" + +def cmd_reload(cdat): + """ + Reloads all modules. + """ + session = cdat['session'] + server = session.server.reload(session) + +def cmd_newpassword(cdat): + """ + Set a player's password. + """ + session = cdat['session'] + pobject = session.get_pobject() + args = cdat['uinput']['splitted'][1:] + eq_args = ' '.join(args).split('=') + searchstring = ''.join(eq_args[0]) + newpass = ''.join(eq_args[1:]) + + if len(args) == 0: + session.msg("What player's password do you want to change") + return + if len(newpass) == 0: + session.msg("You must supply a new password.") + return + + target_obj = functions_db.standard_plr_objsearch(session, searchstring) + # Use standard_plr_objsearch to handle duplicate/nonexistant results. + if not target_obj: + return + + if not target_obj.is_player(): + session.msg("You can only change passwords on players.") + elif not pobject.controls_other(target_obj): + session.msg("You do not control %s." % (target_obj.get_name(),)) + else: + uaccount = target_obj.get_user_account() + if len(newpass) == 0: + uaccount.set_password() + else: + uaccount.set_password(newpass) + uaccount.save() + session.msg("%s - PASSWORD set." % (target_obj.get_name(),)) + target_obj.emit_to("%s has changed your password." % (pobject.get_name(show_dbref=False),)) + +def cmd_shutdown(cdat): + """ + Shut the server down gracefully. + """ + session = cdat['session'] + server = cdat['server'] + pobject = session.get_pobject() + + session.msg('Shutting down...') + print 'Server shutdown by %s' % (pobject.get_name(show_dbref=False),) + server.shutdown() diff --git a/commands_unloggedin.py b/commands/unloggedin.py similarity index 100% rename from commands_unloggedin.py rename to commands/unloggedin.py diff --git a/events.py b/events.py index 8c80be5752..13a5c63f4e 100644 --- a/events.py +++ b/events.py @@ -1,5 +1,3 @@ -import time -from twisted.internet import protocol, reactor, defer import session_mgr """ diff --git a/functions_comsys.py b/functions_comsys.py index 6282855a4f..0ee44558ac 100644 --- a/functions_comsys.py +++ b/functions_comsys.py @@ -1,6 +1,5 @@ import cPickle as pickle -import time -import datetime +import time, datetime from apps.objects.models import CommChannel, CommChannelMessage import session_mgr diff --git a/functions_db.py b/functions_db.py index 7bf399930d..43022db289 100644 --- a/functions_db.py +++ b/functions_db.py @@ -1,4 +1,5 @@ import sets + from django.db import connection from django.contrib.auth.models import User from apps.objects.models import Object, Attribute diff --git a/functions_general.py b/functions_general.py index fc42fc699e..700dcec54d 100644 --- a/functions_general.py +++ b/functions_general.py @@ -1,9 +1,6 @@ from twisted.python import log import session_mgr -import commands_privileged -import commands_general -import commands_unloggedin """ General commonly used functions. diff --git a/initial_setup.py b/initial_setup.py index 8d515c6986..a51305bcee 100644 --- a/initial_setup.py +++ b/initial_setup.py @@ -1,7 +1,5 @@ from django.contrib.auth.models import User, Group from apps.objects.models import Object -import functions_db -import functions_general import gameconf def handle_setup(): diff --git a/server.py b/server.py index 90cd0d59d9..3feee4ec4f 100755 --- a/server.py +++ b/server.py @@ -1,6 +1,5 @@ from traceback import format_exc -import time -import sys +import time, sys from twisted.application import internet, service from twisted.internet import protocol, reactor, defer @@ -96,8 +95,8 @@ class EvenniaService(service.Service): For changes to the scheduler, server, or session_mgr modules, a cold restart is needed. """ - reload_list = ['ansi', 'cmdhandler', 'commands_comsys', 'commands_general', - 'commands_privileged', 'commands_unloggedin', 'defines_global', + reload_list = ['ansi', 'cmdhandler', 'commands.comsys', 'commands.general', + 'commands.privileged', 'commands.unloggedin', 'defines_global', 'events', 'functions_db', 'functions_general', 'functions_comsys', 'functions_help', 'gameconf', 'session', 'apps.objects.models', 'apps.helpsys.models', 'apps.config.models'] diff --git a/session.py b/session.py index 6d00cb7f88..67add8e201 100755 --- a/session.py +++ b/session.py @@ -6,7 +6,6 @@ from twisted.conch.telnet import StatefulTelnetProtocol import cmdhandler from apps.objects.models import Object from django.contrib.auth.models import User -import commands_general import functions_db import functions_general import session_mgr @@ -82,6 +81,12 @@ class SessionProtocol(StatefulTelnetProtocol): # Stuff anything we need to pass in this dictionary. cdat = {"server": self.factory.server, "uinput": uinput, "session": self} cmdhandler.handle(cdat) + + def execute_cmd(self, cmdstr): + """ + Executes a command as this session. + """ + self.lineReceived(data=cmdstr) def handle_close(self): """ diff --git a/session_mgr.py b/session_mgr.py index d21d15ce46..4025f74c12 100644 --- a/session_mgr.py +++ b/session_mgr.py @@ -71,7 +71,8 @@ def remove_session(session): session_list.remove(session) functions_general.log_infomsg('Sessions active: %d' % (len(get_session_list()),)) except: - functions_general.log_errmsg("Unable to remove session: %s" % (session,)) + #functions_general.log_errmsg("Unable to remove session: %s" % (session,)) + pass def session_from_object(targobject):