From 0e46a61c85d5d982f4f20fc8cd83e976f6c2881b Mon Sep 17 00:00:00 2001 From: Griatch Date: Sun, 27 Sep 2009 10:05:47 +0000 Subject: [PATCH] * Added copy_object() to the object manager * Added @copy command (builders only) * Moved the greeting for first-time logins into a hook in basicplayer * Fixed bug in @set to handle whitespace better * Added the /drop switch to @create /Griatch --- src/commands/objmanip.py | 89 ++++++++++++++++++++++++++++--- src/objects/managers/object.py | 60 ++++++++++++++++++--- src/objects/models.py | 1 - src/script_parents/basicplayer.py | 12 +++++ src/session.py | 4 +- 5 files changed, 150 insertions(+), 16 deletions(-) diff --git a/src/commands/objmanip.py b/src/commands/objmanip.py index e423bc79bf..1f0cc7b400 100644 --- a/src/commands/objmanip.py +++ b/src/commands/objmanip.py @@ -7,6 +7,7 @@ import src.flags from src import ansi from src.cmdtable import GLOBAL_CMD_TABLE from src import defines_global +from src import logger def cmd_teleport(command): """ @@ -182,7 +183,7 @@ def cmd_set(command): # Equal signs are not optional for @set. source_object.emit_to("Set what?") return - target_name = eq_args[0] + target_name = eq_args[0].strip() target = source_object.search_for_object(eq_args[0]) # Use search_for_object to handle duplicate/nonexistant results. if not target: @@ -196,7 +197,7 @@ def cmd_set(command): attrib_args = eq_args[1].split(':', 1) if len(attrib_args) > 1: # We're dealing with an attribute/value pair. - attrib_name = attrib_args[0] + attrib_name = attrib_args[0].strip() splicenum = eq_args[1].find(':') + 1 attrib_value = (eq_args[1][splicenum:]).strip() @@ -225,7 +226,7 @@ def cmd_set(command): flag_list = eq_args[1].split() s = "" for flag in flag_list: - flag = flag.upper() + flag = flag.upper().strip() if flag[0] == '!': # We're un-setting the flag. flag = flag[1:] @@ -425,7 +426,10 @@ def cmd_create(command): """ @create - Usage: @create objname [:parent] + Usage: @create[/drop] objname [:parent] + + switch: + drop - automatically drop the new object into your current location (this is not echoed) Creates a new object. If parent is given, the object is created as a child of this parent. The parent script is assumed to be located under game/gamesrc/parents @@ -437,7 +441,7 @@ def cmd_create(command): source_object = command.source_object if not command.command_argument: - source_object.emit_to("Usage: @create [:path_to_script_parent]") + source_object.emit_to("Usage: @create[/drop] [:path_to_script_parent]") return eq_args = command.command_argument.split(':', 1) @@ -464,10 +468,81 @@ def cmd_create(command): else: source_object.emit_to("You create a new thing: %s" % (new_object,)) + if "drop" in command.command_switches: + new_object.move_to(source_object.get_location(),quiet=True) + + + GLOBAL_CMD_TABLE.add_command("@create", cmd_create, - priv_tuple=("genperms.builder"),auto_help=True) + priv_tuple=("genperms.builder"),auto_help=True,staff_help=True) + +def cmd_copy(command): + """Usage: + @copy[/reset] [new_name] [, new_location] + + switch: + reset - make a 'clean' copy, without any changes that might have happened to the + original since it was first created. + + Create an identical copy of an object. + """ + source_object = command.source_object + args = command.command_argument + switches = command.command_switches + if not args: + source_object.emit_to("Usage: @copy [=new_name] [, new_location]") + return + reset = False + if "reset" in switches: + reset = True + + objname = None + new_objname = None + new_location = None + new_location_name = None + + arglist = args.split("=",1) + if len(arglist) == 1: + objname = args.strip() + else: + objname, args = arglist[0].strip(), arglist[1] + arglist = args.split(",",1) + if len(arglist) == 1: + new_objname = args.strip() + else: + new_objname, new_location_name = arglist[0].strip(), arglist[1].strip() + original_object = source_object.search_for_object(objname) + if not original_object: + return + if new_location_name: + new_location = source_object.search_for_object(new_location_name) + if not new_location: + return + if original_object.is_player(): + source_object.emit_to("You cannot copy a player.") + return + if not source_object.controls_other(original_object,builder_override=True): + source_object.emit_to("You don't have permission to do that.") + return + + #we are good to go, perform the copying. + new_object = Object.objects.copy_object(original_object, new_name=new_objname, + new_location=new_location, reset=reset) + name_text = "" + if new_objname: + name_text = " to '%s'" % new_objname + loc_text = "" + if new_location: + loc_text = " in %s" % new_location_name + reset_text = "" + if reset: + reset_text = " (using default attrs/flags)" + source_object.emit_to("Copied object '%s'%s%s%s." % (objname,name_text,loc_text,reset_text)) +GLOBAL_CMD_TABLE.add_command("@copy", cmd_copy, + priv_tuple=("genperms.builder"),auto_help=True,staff_help=True) + def cmd_nextfree(command): """Usage: @nextfree @@ -477,7 +552,7 @@ def cmd_nextfree(command): nextfree = Object.objects.get_nextfree_dbnum() command.source_object.emit_to("Next free object number: #%s" % nextfree) GLOBAL_CMD_TABLE.add_command("@nextfree", cmd_nextfree, - priv_tuple=("genperms.builder"),auto_help=True) + priv_tuple=("genperms.builder"),auto_help=True,staff_help=True) def cmd_open(command): """ diff --git a/src/objects/managers/object.py b/src/objects/managers/object.py index 3533a9047e..2dc4c20345 100644 --- a/src/objects/managers/object.py +++ b/src/objects/managers/object.py @@ -496,16 +496,62 @@ class ObjectManager(models.Manager): user_object.scriptlink.at_player_creation() # Activate the player's session and set them loose. - command.session.login(user) + command.session.login(user, first_login=True) logger.log_infomsg('Registration: %s' % user_object.get_name()) - - #Don't show the greeting; it messes with using the login hooks for - #making character creation wizards. /Griatch - #user_object.emit_to("Welcome to %s, %s.\n\r" % ( - # ConfigValue.objects.get_configvalue('site_name'), - # user_object.get_name(show_dbref=False))) # Add the user to all of the CommChannel objects that are flagged # is_joined_by_default. command.session.add_default_channels() + + # + # ObjectManager Copy method + # + + def copy_object(self, original_object, new_name=None, new_location=None, reset=False): + """ + Create and return a new object as a copy of the source object. All will + be identical to the original except for the dbref. Does not allow the + copying of Player objects. + + original_object (obj) - the object to make a copy from + new_location (obj) - if None, we create the new object in the same place as the old one. + reset (bool) - copy only the default attributes/flags set by the script_parent, ignoring + any changes to the original after it was originally created. + """ + if not original_object or original_object.is_player(): + return + + # get all the object's stats + if new_name: + name = new_name + else: + name = original_object.get_name(show_dbref=False,no_ansi=True) + otype = original_object.type + if new_location: + location = new_location + else: + location = original_object.get_location() + owner = original_object.get_owner() + home = original_object.get_home() + script_parent = original_object.get_script_parent() + + # create new object + new_object = self.create_object(name, otype, location, owner, home, + script_parent=script_parent) + if not new_object: + return + + if not reset: + # we make sure that the objects are identical by manually copying over all attributes and + # flags; this way we also get those that might have changed since the original was created. + + all_attribs = original_object.get_all_attributes() + for attr in all_attribs: + new_object.set_attribute(attr.get_name(), attr.get_value()) + + all_flags = original_object.get_flags() #this is a string + for flag in all_flags.split(): + new_object.set_flag(flag) + + return new_object diff --git a/src/objects/models.py b/src/objects/models.py index 261c7f0b10..2c84d7a057 100755 --- a/src/objects/models.py +++ b/src/objects/models.py @@ -430,7 +430,6 @@ class Object(models.Model): """ Returns an object's flag list. """ - # Holds the list of flags to display all_flags = [] if self.flags is not None: # Add saved flags to the display list diff --git a/src/script_parents/basicplayer.py b/src/script_parents/basicplayer.py index 531a4ed836..a00db76536 100644 --- a/src/script_parents/basicplayer.py +++ b/src/script_parents/basicplayer.py @@ -7,6 +7,7 @@ SCRIPT_DEFAULT_PLAYER variable in settings.py to point to the new class. """ import time from src import comsys +from src.config.models import ConfigValue class EvenniaBasicPlayer(object): def at_player_creation(self): @@ -32,6 +33,17 @@ class EvenniaBasicPlayer(object): pobject.set_attribute("Last", "%s" % (time.strftime("%a %b %d %H:%M:%S %Y", time.localtime()),)) pobject.set_attribute("Lastsite", "%s" % (session.address[0],)) pobject.set_flag("CONNECTED", True) + + def at_first_login(self, session): + """ + This hook is called only *once*, when the player is created and logs + in for first time. It is called after the user has logged in, but + before at_post_login() is called. + """ + pobject = self.scripted_obj + pobject.emit_to("Welcome to %s, %s.\n\r" % ( + ConfigValue.objects.get_configvalue('site_name'), + pobject.get_name(show_dbref=False))) def at_post_login(self, session): """ diff --git a/src/session.py b/src/session.py index b9857ef978..687d5a4b52 100755 --- a/src/session.py +++ b/src/session.py @@ -158,7 +158,7 @@ class SessionProtocol(StatefulTelnetProtocol): except: return False - def login(self, user): + def login(self, user, first_login=False): """ After the user has authenticated, handle logging him in. """ @@ -170,6 +170,8 @@ class SessionProtocol(StatefulTelnetProtocol): self.get_pobject() #session_mgr.disconnect_duplicate_session(self) + if first_login: + self.pobject.scriptlink.at_first_login(self) self.pobject.scriptlink.at_pre_login(self) logger.log_infomsg("Logged in: %s" % self)