def create_objects(): """ Creates the #1 player and Limbo room. """ logger.log_info("Creating objects (Player #1 and Limbo room) ...") # Set the initial User's account object's username on the #1 object. # This object is pure django and only holds name, email and password. god_player = get_god_player() # Create a Player 'user profile' object to hold eventual # mud-specific settings for the PlayerDB object. player_typeclass = settings.BASE_PLAYER_TYPECLASS # run all creation hooks on god_player (we must do so manually # since the manage.py command does not) god_player.swap_typeclass(player_typeclass, clean_attributes=True) god_player.basetype_setup() god_player.at_player_creation() god_player.locks.add("examine:perm(Immortals);edit:false();delete:false();boot:false();msg:all()") # this is necessary for quelling to work correctly. god_player.permissions.add("Immortals") # Limbo is the default "nowhere" starting room # Create the in-game god-character for player #1 and set # it to exist in Limbo. character_typeclass = settings.BASE_CHARACTER_TYPECLASS god_character = create.create_object(character_typeclass, key=god_player.username, nohome=True) god_character.id = 1 god_character.save() god_character.db.desc = _("This is User #1.") god_character.locks.add("examine:perm(Immortals);edit:false();delete:false();boot:false();msg:all();puppet:false()") god_character.permissions.add("Immortals") god_player.attributes.add("_first_login", True) god_player.attributes.add("_last_puppet", god_character) try: god_player.db._playable_characters.append(god_character) except AttributeError: god_player.db_playable_characters = [god_character] room_typeclass = settings.BASE_ROOM_TYPECLASS limbo_obj = create.create_object(room_typeclass, _("Limbo"), nohome=True) limbo_obj.id = 2 limbo_obj.save() limbo_obj.db.desc = LIMBO_DESC.strip() limbo_obj.save() # Now that Limbo exists, try to set the user up in Limbo (unless # the creation hooks already fixed this). if not god_character.location: god_character.location = limbo_obj if not god_character.home: god_character.home = limbo_obj
def func(self): usage = "@raise lat,lon = Room Name" caller = self.caller if "," in self.lhs: for coord in self.lhslist: try: int(coord) except ValueError: usage = "\nOnly integers allowed" usage += " for lat, lon.\n" usage += " For example: @raise -17,177 = Fiji" caller.msg(usage) return lat, lon = self.lhslist # `self.lhs` split into list by comma. else: caller.msg(usage) return # convert coordinates to int coordinates = (int(lat), int(lon)) # search for matching coordinates in db conflict = search.search_object_attribute(key="coordinates", value=coordinates) if conflict: report = "There is already a room at %s: %s" report += "\n%s is accessible as %s" report = report % (coordinates, conflict, conflict[0].name, conflict[0].dbref) caller.msg(report) return # choose the typeclass if "inland" in self.switches: typeclass = "rooms.DryLandRoom" room = "Inland" else: typeclass = "rooms.CoastalRoom" room = "Coastline" # over write the default name if name was provided if self.rhs: room = self.rhs # create a room lockstring = "control:id(%s) or perm(Immortals); delete:id(%s)" lockstring += " or perm(Wizards); edit:id(%s) or perm(Wizards)" lockstring = lockstring % (caller.dbref, caller.dbref, caller.dbref) new_room = create.create_object(typeclass, room, report_to=caller) new_room.locks.add(lockstring) new_room.db.coordinates = coordinates # save those coordinates room_string = "Created room %s(%s) of type %s." % (new_room, new_room.dbref, typeclass) caller.msg(room_string) if new_room and ('teleport' in self.switches or "tel" in self.switches): caller.move_to(new_room)
def new_room(room_name): """ print("-----") print("New Room creation details.") print("Name: %s" % room['name']) print("Alises: %s" % room['aliases']) print("Type: %s" % typeclass) print("Lock: %s" % lockstring) print("=====") """ if not account.check_permstring('Builders'): you.msg("You must have |wBuilders|n or higher access to create a new room.") return None name, aliases = '', [] if ';' in room_name: # Parse aliases out of room_name. name, aliases = room_name.strip().split(';', 1) aliases = aliases.split(';') else: # No aliases provided; aliases remain empty. name = room_name.strip() typeclass = settings.BASE_ROOM_TYPECLASS room = {'name': name, 'aliases': aliases} lockstring = "control:pid({0}) or perm(Immortals); delete:pid({0})" \ " or perm(Wizards); edit:pid({0}) or perm(Wizards); get:false()"\ .format(account.id) r = create.create_object(typeclass, room['name'], aliases=room['aliases'], report_to=you) r.locks.add(lockstring) alias_string = room['aliases'] if r.aliases.all(): alias_string = " |w(|c%s|w)|n" % "|n, |c".join(r.aliases.all()) account.msg("|gCreated room %s%s of type |m%s." % (r.get_display_name(account), alias_string, typeclass)) return r or None
def create_exit(self, mush_exit): typeclass = settings.BASE_EXIT_TYPECLASS lockstring = "control:id(%s) or perm(Immortals); delete:id(%s) or perm(Wizards); edit:id(%s) or perm(Wizards)" lockstring = lockstring % (self.caller.id, self.caller.id, self.caller.id) try: dest = mush_exit.destination dest = dest.obj except: dest = None try: loc = mush_exit.location loc = loc.obj except: loc = None alias = mush_exit.mushget('alias') if alias: alias = alias.split(';') else: alias = None new_exit = create.create_object(typeclass, mush_exit.name, location=loc, aliases=alias, locks=lockstring, destination=dest) mush_exit.obj = new_exit mush_exit.save() return new_exit
def convert_board(self, new_board): old_board = new_board.mush old_posts = new_board.mush.lattr('~`*') old_dict = dict() for old_post in old_posts: post_details = old_board.mushget(old_post + '`DETAILS').split('|') poster_name = post_details[0] poster_objid = post_details[1] poster_obj = objmatch(poster_objid) if poster_obj: owner = poster_obj.obj else: owner = create.create_object(typeclass='classes.characters.BaseCharacter', key=poster_name) dbref, csecs = poster_objid.split(':', 1) cdate = from_unixtimestring(csecs) MushObject.objects.create(objid=poster_objid, dbref=dbref, created=cdate, type=8, recreated=1, obj=owner) post_date = from_unixtimestring(post_details[2]) text = old_board.mushget(old_post) timeout_secs = int(old_board.mushget(old_post + '`TIMEOUT')) new_timeout = datetime.timedelta(0, timeout_secs, 0, 0, 0, 0, 0) subject = old_board.mushget(old_post + '`HDR') old_dict[old_post] = {'subject': subject, 'owner': owner, 'timeout': new_timeout, 'creation_date': post_date, 'text': text} for num, old_post in enumerate(sorted(old_posts, key=lambda old: old_dict[old]['creation_date'])): old_data = old_dict[old_post] new_board.posts.create(subject=old_data['subject'], owner=old_data['owner'], creation_date=old_data['creation_date'], timeout=old_data['timeout'], text=old_data['text'], order=num+1)
def _create_character(name, player): """Create a new character. Args: name: the name of the character to be created player: the player owning the character. Return: The newly-created character. """ # Look for default values permissions = settings.PERMISSION_PLAYER_DEFAULT typeclass = settings.BASE_CHARACTER_TYPECLASS home = ObjectDB.objects.get_id(settings.DEFAULT_HOME) # Create the character character = create.create_object(typeclass, key=name, home=home, permissions=permissions) # Set playable character list player.db._playable_characters.append(character) # Allow only the character itself and the player to puppet it. character.locks.add("puppet:id(%i) or pid(%i) or perm(Immortals) " \ "or pperm(Immortals)" % (character.id, player.id)) # If no description is set, set a default description if not character.db.desc: character.db.desc = "" # We need to set this to have @ic auto-connect to this character. player.db._last_puppet = character return character
def func(self): "create the new character" player = self.player if not self.args: self.msg("Usage: @charcreate <charname> [= description]") return key = self.lhs desc = self.rhs if not player.is_superuser and \ (player.db._playable_characters and len(player.db._playable_characters) >= MAX_NR_CHARACTERS): self.msg("You may only create a maximum of %i characters." % MAX_NR_CHARACTERS) return # create the character from evennia.objects.models import ObjectDB start_location = ObjectDB.objects.get_id(settings.START_LOCATION) default_home = ObjectDB.objects.get_id(settings.DEFAULT_HOME) typeclass = settings.BASE_CHARACTER_TYPECLASS permissions = settings.PERMISSION_PLAYER_DEFAULT new_character = create.create_object(typeclass, key=key, location=start_location, home=default_home, permissions=permissions) # only allow creator (and immortals) to puppet this char new_character.locks.add("puppet:id(%i) or pid(%i) or perm(Immortals) or pperm(Immortals)" % (new_character.id, player.id)) player.db._playable_characters.append(new_character) if desc: new_character.db.desc = desc elif not new_character.db.desc: new_character.db.desc = "This is a Player." self.msg("Created new character %s. Use {w@ic %s{n to enter the game as this character." % (new_character.key, new_character.key))
def creating(request): user = request.user if request.method == 'POST': form = AppForm(request.POST) if form.is_valid(): name = form.cleaned_data['name'] background = form.cleaned_data['background'] applied_date = datetime.now() submitted = True if 'save' in request.POST: submitted = False app = CharApp(char_name=name, background=background, date_applied=applied_date, player_id=user.id, submitted=submitted) app.save() if submitted: # Create the actual character object typeclass = settings.BASE_CHARACTER_TYPECLASS home = ObjectDB.objects.get_id(settings.DEFAULT_HOME) # turn the permissionhandler to a string perms = str(user.permissions) # create the character char = create.create_object(typeclass=typeclass, key=name, home=home, permissions=perms) user.db._playable_characters.append(char) # add the right locks for the character so the player can # puppet it char.locks.add("puppet:id(%i) or pid(%i) or perm(Immortals) " "or pperm(Immortals)" % (char.id, user.id)) char.db.background = background # set the character background return HttpResponseRedirect('/chargen') else: form = AppForm() return render(request, 'chargen/create.html', {'form': form})
def _create_character(character_key, level, session, new_player, typeclass, home, permissions, nickname): """ Helper function, creates a character based on a player's name. This is meant for Guest and MULTISESSION_MODE < 2 situations. """ try: new_character = create.create_object(typeclass, key=new_player.key, home=home, permissions=permissions) # set character info new_character.set_data_info(character_key) new_character.set_level(level) # set playable character list new_player.db._playable_characters.append(new_character) # allow only the character itself and the player to puppet this character (and Immortals). new_character.locks.add("puppet:id(%i) or pid(%i) or perm(Immortals) or pperm(Immortals)" % (new_character.id, new_player.id)) # If no description is set, set a default description if not new_character.db.desc: new_character.db.desc = "This is a Player." # Add nickname if not nickname: nickname = character_key new_character.set_nickname(nickname) # We need to set this to have @ic auto-connect to this character new_player.db._last_puppet = new_character except Exception, e: session.msg("There was an error creating the Character:\n%s\n If this problem persists, contact an admin." % e) logger.log_trace() return False
def setUp(self): """ Sets up testing environment """ self.player = create.create_player("TestPlayer", email="*****@*****.**", password="******", typeclass=self.player_typeclass) self.player2 = create.create_player("TestPlayer2", email="*****@*****.**", password="******", typeclass=self.player_typeclass) self.room1 = create.create_object(self.room_typeclass, key="Room", nohome=True) self.room1.db.desc = "room_desc" settings.DEFAULT_HOME = "#%i" % self.room1.id # we must have a default home self.room2 = create.create_object(self.room_typeclass, key="Room2") self.exit = create.create_object(self.exit_typeclass, key='out', location=self.room1, destination=self.room2) self.obj1 = create.create_object(self.object_typeclass, key="Obj", location=self.room1, home=self.room1) self.obj2 = create.create_object(self.object_typeclass, key="Obj2", location=self.room1, home=self.room1) self.char1 = create.create_object(self.character_typeclass, key="Char", location=self.room1, home=self.room1) self.char1.permissions.add("Immortals") self.char2 = create.create_object(self.character_typeclass, key="Char2", location=self.room1, home=self.room1) self.char1.player = self.player self.player.db._last_puppet = self.char1 self.char2.player = self.player2 self.player2.db._last_puppet = self.char2 self.script = create.create_script(self.script_typeclass, key="Script") self.player.permissions.add("Immortals") # set up a fake session session = ServerSession() session.init_session("telnet", ("localhost", "testmode"), SESSIONS) session.sessid = 1 SESSIONS.portal_connect(session.get_sync_data()) SESSIONS.login(SESSIONS.session_from_sessid(1), self.player, testmode=True) self.session = session
def setUp(self): """ Sets up testing environment """ self.account = create.create_account("TestAccount", email="*****@*****.**", password="******", typeclass=self.account_typeclass) self.account2 = create.create_account("TestAccount2", email="*****@*****.**", password="******", typeclass=self.account_typeclass) self.room1 = create.create_object(self.room_typeclass, key="Room", nohome=True) self.room1.db.desc = "room_desc" settings.DEFAULT_HOME = "#%i" % self.room1.id # we must have a default home # Set up fake prototype module for allowing tests to use named prototypes. settings.PROTOTYPE_MODULES = "evennia.utils.tests.data.prototypes_example" self.room2 = create.create_object(self.room_typeclass, key="Room2") self.exit = create.create_object(self.exit_typeclass, key='out', location=self.room1, destination=self.room2) self.obj1 = create.create_object(self.object_typeclass, key="Obj", location=self.room1, home=self.room1) self.obj2 = create.create_object(self.object_typeclass, key="Obj2", location=self.room1, home=self.room1) self.char1 = create.create_object(self.character_typeclass, key="Char", location=self.room1, home=self.room1) self.char1.permissions.add("Developer") self.char2 = create.create_object(self.character_typeclass, key="Char2", location=self.room1, home=self.room1) self.char1.account = self.account self.account.db._last_puppet = self.char1 self.char2.account = self.account2 self.account2.db._last_puppet = self.char2 self.script = create.create_script(self.script_typeclass, key="Script") self.account.permissions.add("Developer") # set up a fake session dummysession = ServerSession() dummysession.init_session("telnet", ("localhost", "testmode"), SESSIONS) dummysession.sessid = 1 SESSIONS.portal_connect(dummysession.get_sync_data()) # note that this creates a new Session! session = SESSIONS.session_from_sessid(1) # the real session SESSIONS.login(session, self.account, testmode=True) self.session = session
def create_room(self, mush_room): typeclass = settings.BASE_ROOM_TYPECLASS lockstring = "control:id(%s) or perm(Immortals); delete:id(%s) or perm(Wizards); edit:id(%s) or perm(Wizards)" lockstring = lockstring % (self.caller.id, self.caller.id, self.caller.id) new_room = create.create_object(typeclass, key=mush_room.name) new_room.locks.add(lockstring) mush_room.obj = new_room mush_room.save() return new_room
def func(self): "Create the shop rooms" if not self.args: self.msg("Usage: @buildshop <storename>") return # create the shop and storeroom super(CmdBuildShop, self).parse() for objdef in self.lhs_objs: shopname = objdef['name'] aliases = objdef['aliases'] shop = create_object(NPCShop, key=shopname, location=None, nohome=True) shop.at_object_creation() storeroom = create_object(StoreRoom, key="%s-storage" % shopname, location=None, nohome=True) storeroom.at_object_creation() shop.db.storeroom = storeroom # create a door between the two storeroom_entrance = create_object(Exit, key="back door", aliases=["storage", "store room", "storeroom", "back"], location=shop, destination=storeroom, home=shop) storeroom_exit = create_object(Exit, key="shop", aliases=["exit", "back", "out", "door", "o"], location=storeroom, destination=shop, home=storeroom) shop_entrance = create_object(Exit, key=shopname, location=self.caller.location, destination=shop, aliases=aliases, home=self.caller.location) shop_exit = create_object(Exit, key="front door", aliases=["front", "exit", "out", "o"], location=shop, destination=self.caller.location, home=shop) # make a key for accessing the store room storeroom_key_name = "%s-storekey" % shopname storeroom_key = create_object(DefaultObject, key=storeroom_key_name, location=self.caller, aliases=["key"], home=self.caller) # only allow chars with this key to enter the store room storeroom_entrance.locks.add("traverse:holds(%s)" % storeroom_key_name) # inform the builder about progress self.caller.msg("The shop %s was created!" % shop)
def character(key, player): from athanor.core.config import GLOBAL_SETTINGS key = sanitize_string(key, strip_ansi=True) typeclass = settings.BASE_CHARACTER_TYPECLASS home = GLOBAL_SETTINGS['character_home'] if key.upper() in SPEECH_FACTORY.upper(): raise ValueError("That character name is already in use!") char = create_object(typeclass=typeclass, key=key, location=home, home=home) player.account.bind_character(char) SPEECH_FACTORY.update(char) return char
def switch_accounts(self): char_typeclass = settings.BASE_CHARACTER_TYPECLASS accounts = cobj(abbr='accounts').children.all() for acc_obj in sorted(accounts, key=lambda acc: int(acc.name.split(' ')[1])): name = 'MushAcc %s' % acc_obj.name.split(' ')[1] password = str(random.randrange(5000000,1000000000)) email = acc_obj.mushget('email') or None new_player = create.create_player(name, email, password) new_player.db._import_ready = True new_player.db._reset_username = True if new_player.email == '*****@*****.**': new_player.db._reset_email = True objids = acc_obj.mushget('characters').split(' ') mush_chars = MushObject.objects.filter(objid__in=objids) for char in mush_chars: new_char = create.create_object(typeclass=char_typeclass, key=char.name) new_char.db.prelogout_location = char.location.obj char.obj = new_char char.save(update_fields=['obj']) new_player.bind_character(new_char) new_char.db._import_ready = True unbound = MushObject.objects.filter(type=8, obj=None) if unbound: name = 'Lost and Found' password = str(random.randrange(5000000,1000000000)) email = None new_player = create.create_player(name, email, password) new_player.db._lost_and_found = True for char in unbound: new_char = create.create_object(typeclass=char_typeclass, key=char.name) new_char.db.prelogout_location = char.location.obj char.obj = new_char char.save(update_fields=['obj']) new_player.bind_character(new_char) new_char.db._import_ready = True self.sys_msg("Finished importing characters!")
def setUp(self): settings.PROTOTYPE_MODULES = ainneve_settings.PROTOTYPE_MODULES self.character_typeclass = Character self.object_typeclass = NPC self.room_typeclass = Room self.script_typeclass = CombatHandler super(AinneveCombatTest, self).setUp() # create weapons for the fight self.melee = spawn({'prototype': 'SHORT_SWORD', 'location': self.room1}, prototype_modules=('world.content.prototypes_weapons',))[0] self.reach = spawn({'prototype': 'PIKE_POLEARM', 'location': self.room1}, prototype_modules=('world.content.prototypes_weapons',))[0] self.ranged = spawn({'prototype': 'LONG_BOW', 'location': self.room1}, prototype_modules=('world.content.prototypes_weapons',))[0] self.arrows = spawn({'prototype': 'ARROW_BUNDLE', 'location': self.room1}, prototype_modules=('world.content.prototypes_weapons',))[0] # set up chars sample_char(self.char1, 'warrior', 'human', 'cunning') self.char1.traits.ATKM.base = self.char1.traits.ATKR.base = self.char1.traits.ATKU.base = 5 sample_char(self.char2, 'warrior', 'human', 'cunning') self.char2.traits.HP.base = self.char2.traits.HP.current = 10 # one additional NPC self.obj3 = create.create_object(self.object_typeclass, key="Obj3", location=self.room1, home=self.room1) # set sdescs to key for testing self.char1.sdesc.add(self.char1.key) self.char2.sdesc.add(self.char2.key) self.obj1.sdesc.add(self.obj1.key) self.obj2.sdesc.add(self.obj2.key) self.obj3.sdesc.add(self.obj3.key) # use mock msg methods self.char1.msg = Mock() self.char2.msg = Mock() self.obj1.msg = Mock() self.obj2.msg = Mock() self.obj3.msg = Mock() # add combatants self.script.add_character(self.char1) self.script.add_character(self.char2) self.script.add_character(self.obj1) self.script.add_character(self.obj2) self.script.add_character(self.obj3)
def func(self): "create the new character" player = self.player if not self.args: self.msg("Usage: @charcreate <charname> [= description]") return key = self.lhs desc = self.rhs charmax = _MAX_NR_CHARACTERS if _MULTISESSION_MODE > 1 else 1 if not player.is_superuser and \ (player.db._playable_characters and len(player.db._playable_characters) >= charmax): self.msg("You may only create a maximum of %i characters." % charmax) return from evennia.objects.models import ObjectDB typeclass = settings.BASE_CHARACTER_TYPECLASS if ObjectDB.objects.filter(db_typeclass_path=typeclass, db_key__iexact=key): # check if this Character already exists. Note that we are only # searching the base character typeclass here, not any child # classes. self.msg("{rA character named '{w%s{r' already exists.{n" % key) return # create the character start_location = ObjectDB.objects.get_id(settings.START_LOCATION) default_home = ObjectDB.objects.get_id(settings.DEFAULT_HOME) permissions = settings.PERMISSION_PLAYER_DEFAULT new_character = create.create_object(typeclass, key=key, location=start_location, home=default_home, permissions=permissions) # only allow creator (and immortals) to puppet this char new_character.locks.add("puppet:id(%i) or pid(%i) or perm(Immortals) or pperm(Immortals)" % (new_character.id, player.id)) player.db._playable_characters.append(new_character) if desc: new_character.db.desc = desc elif not new_character.db.desc: new_character.db.desc = "This is a Player." self.msg("Created new character %s. Use {w@ic %s{n to enter the game as this character." % (new_character.key, new_character.key))
def _create_character(session, new_account, typeclass, home, permissions): """ Helper function, creates a character based on an account's name. This is meant for Guest and MULTISESSION_MODE < 2 situations. """ try: new_character = create.create_object(typeclass, key=new_account.key, home=home, permissions=permissions) # set playable character list new_account.db._playable_characters.append(new_character) # allow only the character itself and the account to puppet this character (and Developers). new_character.locks.add("puppet:id(%i) or pid(%i) or perm(Developer) or pperm(Developer)" % (new_character.id, new_account.id)) # If no description is set, set a default description if not new_character.db.desc: new_character.db.desc = "This is an Account." # We need to set this to have @ic auto-connect to this character new_account.db._last_puppet = new_character except Exception as e: session.msg("There was an error creating the Character:\n%s\n If this problem persists, contact an admin." % e) logger.log_trace()
def test_exit(self): """Test the callbacks of an exit.""" self.char1.key = "char1" code = dedent(""" if character.key == "char1": character.msg("You can leave.") else: character.msg("You cannot leave.") deny() """.strip("\n")) # Enforce self.exit.destination since swapping typeclass lose it self.exit.destination = self.room2 # Try the can_traverse callback self.handler.add_callback(self.exit, "can_traverse", code, author=self.char1, valid=True) # Have char1 move through the exit self.call(ExitCommand(), "", "You can leave.", obj=self.exit) self.assertIs(self.char1.location, self.room2) # Have char2 move through this exit self.call(ExitCommand(), "", "You cannot leave.", obj=self.exit, caller=self.char2) self.assertIs(self.char2.location, self.room1) # Try the traverse callback self.handler.del_callback(self.exit, "can_traverse", 0) self.handler.add_callback(self.exit, "traverse", "character.msg('Fine!')", author=self.char1, valid=True) # Have char2 move through the exit self.call(ExitCommand(), "", obj=self.exit, caller=self.char2) self.assertIs(self.char2.location, self.room2) self.handler.del_callback(self.exit, "traverse", 0) # Move char1 and char2 back self.char1.location = self.room1 self.char2.location = self.room1 # Test msg_arrive and msg_leave code = 'message = "{character} goes out."' self.handler.add_callback(self.exit, "msg_leave", code, author=self.char1, valid=True) # Have char1 move through the exit old_msg = self.char2.msg try: self.char2.msg = Mock() self.call(ExitCommand(), "", obj=self.exit) stored_msg = [args[0] if args and args[0] else kwargs.get("text",utils.to_str(kwargs, force_string=True)) for name, args, kwargs in self.char2.msg.mock_calls] # Get the first element of a tuple if msg received a tuple instead of a string stored_msg = [smsg[0] if isinstance(smsg, tuple) else smsg for smsg in stored_msg] returned_msg = ansi.parse_ansi("\n".join(stored_msg), strip_ansi=True) self.assertEqual(returned_msg, "char1 goes out.") finally: self.char2.msg = old_msg # Create a return exit back = create_object("evennia.objects.objects.DefaultExit", key="in", location=self.room2, destination=self.room1) code = 'message = "{character} goes in."' self.handler.add_callback(self.exit, "msg_arrive", code, author=self.char1, valid=True) # Have char1 move through the exit old_msg = self.char2.msg try: self.char2.msg = Mock() self.call(ExitCommand(), "", obj=back) stored_msg = [args[0] if args and args[0] else kwargs.get("text",utils.to_str(kwargs, force_string=True)) for name, args, kwargs in self.char2.msg.mock_calls] # Get the first element of a tuple if msg received a tuple instead of a string stored_msg = [smsg[0] if isinstance(smsg, tuple) else smsg for smsg in stored_msg] returned_msg = ansi.parse_ansi("\n".join(stored_msg), strip_ansi=True) self.assertEqual(returned_msg, "char1 goes in.") finally: self.char2.msg = old_msg
def copy_object(self, original_object, new_key=None, new_location=None, new_home=None, new_permissions=None, new_locks=None, new_aliases=None, new_destination=None): """ Create and return a new object as a copy of the original object. All will be identical to the original except for the arguments given specifically to this method. original_object (obj) - the object to make a copy from. new_key (str) - name the copy differently from the original. new_location (obj) - if not `None`, change the location. new_home (obj) - if not `None`, change the Home. new_aliases (list of strings) - if not `None`, change object aliases. new_destination (obj) - if not `None`, change destination. """ # get all the object's stats typeclass_path = original_object.typeclass_path if not new_key: new_key = original_object.key if not new_location: new_location = original_object.location if not new_home: new_home = original_object.home if not new_aliases: new_aliases = original_object.aliases.all() if not new_locks: new_locks = original_object.db_lock_storage if not new_permissions: new_permissions = original_object.permissions.all() if not new_destination: new_destination = original_object.destination # create new object from evennia.utils import create from evennia.scripts.models import ScriptDB new_object = create.create_object(typeclass_path, key=new_key, location=new_location, home=new_home, permissions=new_permissions, locks=new_locks, aliases=new_aliases, destination=new_destination) if not new_object: return None # copy over all attributes from old to new. for attr in original_object.attributes.all(): new_object.attributes.add(attr.key, attr.value) # copy over all cmdsets, if any for icmdset, cmdset in enumerate(original_object.cmdset.all()): if icmdset == 0: new_object.cmdset.add_default(cmdset) else: new_object.cmdset.add(cmdset) # copy over all scripts, if any for script in original_object.scripts.all(): ScriptDB.objects.copy_script(script, new_obj=new_object) return new_object
try: # Get record. model_obj = get_model(settings.WORLD_DATA_APP, model_name) record = model_obj.objects.get(key=obj_key) except Exception, e: ostring = "Can not load record %s:%s %s" % (model_name, obj_key, e) print(ostring) print(traceback.print_exc()) if caller: caller.msg(ostring) return # Create object. try: obj = create.create_object(record.typeclass, record.name) except Exception, e: ostring = "Can not create obj %s: %s" % (obj_key, e) print(ostring) print(traceback.print_exc()) if caller: caller.msg(ostring) return try: # Set data info. obj.set_data_info(record.key) except Exception, e: ostring = "Can not set data info to obj %s: %s" % (obj_key, e) print(ostring) print(traceback.print_exc())
def func(self): "Do checks and create account" session = self.caller try: playername, email, password = self.playerinfo except ValueError: string = "\n\r Usage (without <>): create \"<playername>\" <email> <password>" session.msg(string) return if not re.findall('^[\w. @+-]+$', playername) or not (0 < len(playername) <= 30): session.msg("\n\r Playername can be max 30 characters, or less. Letters, spaces, dig\ its and @/./+/-/_ only.") # this echoes the restrictions made by django's auth module. return if not email or not password: session.msg("\n\r You have to supply an e-mail address followed by a password." ) return if not utils.validate_email_address(email): # check so the email at least looks ok. session.msg("'%s' is not a valid e-mail address." % email) return # Run sanity and security checks if PlayerDB.objects.filter(username=playername): # player already exists session.msg("Sorry, there is already a player with the name '%s'." % playername) return if PlayerDB.objects.get_player_from_email(email): # email already set on a player session.msg("Sorry, there is already a player with that email address.") return if len(password) < 3: # too short password string = "Your password must be at least 3 characters or longer." string += "\n\rFor best security, make it at least 8 characters long, " string += "avoid making it a real word and mix numbers into it." session.msg(string) return # everything's ok. Create the new player account. try: default_home = ObjectDB.objects.get_id(settings.DEFAULT_HOME) typeclass = settings.BASE_CHARACTER_TYPECLASS permissions = settings.PERMISSION_PLAYER_DEFAULT try: new_player = create.create_player(playername, email, password, permissions=permissions) except Exception, e: session.msg("There was an error creating the default Player/Character:\n%s\n If this problem persists, contact an admin." % e) logger.log_trace() return # This needs to be called so the engine knows this player is # logging in for the first time. (so it knows to call the right # hooks during login later) utils.init_new_player(new_player) # join the new player to the public channel pchanneldef = settings.CHANNEL_PUBLIC if pchanneldef: pchannel = ChannelDB.objects.get_channel(pchanneldef[0]) if not pchannel.connect(new_player): string = "New player '%s' could not connect to public channel!" % new_player.key logger.log_errmsg(string) if MULTISESSION_MODE < 2: # if we only allow one character, create one with the same name as Player # (in mode 2, the character must be created manually once logging in) new_character = create.create_object(typeclass, key=playername, location=default_home, home=default_home, permissions=permissions) # set playable character list new_player.db._playable_characters.append(new_character) # allow only the character itself and the player to puppet this character (and Immortals). new_character.locks.add("puppet:id(%i) or pid(%i) or perm(Immortals) or pperm(Immortals)" % (new_character.id, new_player.id)) # If no description is set, set a default description if not new_character.db.desc: new_character.db.desc = "This is a Player." # We need to set this to have @ic auto-connect to this character new_player.db._last_puppet = new_character # tell the caller everything went well. string = "A new account '%s' was created. Welcome!" if " " in playername: string += "\n\nYou can now log in with the command 'connect %s <your password>'." else: string += "\n\nYou can now log with the command 'connect %s <your password>'." session.msg(string % (playername, email))
def setUp(self): super(TestEquipmentMixins, self).setUp() from evennia.utils import create from typeclasses.wearable.wearable import Wearable, WearableContainer from typeclasses.disguises.disguises import Mask from typeclasses.wearable.wieldable import Wieldable from typeclasses.wearable.decorative_weapon import DecorativeWieldable from world.dominion.models import ( Organization, AssetOwner, ) from world.crafting.models import ( CraftingRecipe, CraftingMaterialType, ) wearable_typeclass = Wearable purse_typeclass = WearableContainer weapon_typeclass = Wieldable hairpin_typeclass = DecorativeWieldable mask_typeclass = Mask self.org = Organization.objects.create(name="Orgtest") AssetOwner.objects.create(organization_owner=self.org) self.org.members.create(player=self.dompc) self.mat1 = CraftingMaterialType.objects.create(name="Mat1", value=100) self.recipe1 = CraftingRecipe.objects.create( name="Top 1 Slot", ability="tailor", level=5, slot="chest", slot_limit=1, base_value=1, armor_penalty=2, ) self.recipe2 = CraftingRecipe.objects.create( name="Top 2 Slot", ability="leatherworker", level=6, slot="chest", slot_limit=2, ) self.recipe3 = CraftingRecipe.objects.create( name="Bag", ability="leatherworker", level=5, slot="bag", slot_limit=2, base_value=40, ) self.recipe4 = CraftingRecipe.objects.create( name="Small Weapon", ability="weaponsmith", level=4, base_value=1, weapon_skill="small wpn", ) self.recipe5 = CraftingRecipe.objects.create( name="Hairpins", ability="weaponsmith", level=4, slot="hair", slot_limit=2, base_value=4, ) self.recipe6 = CraftingRecipe.objects.create( name="Mask", ability="apothecary", level=4, slot="face", slot_limit=1, fashion_mult=6, ) self.recipe7 = CraftingRecipe.objects.create( name="Medium Weapon", ability="weaponsmith", level=4, base_value=5, ) self.test_recipes = [ self.recipe1, self.recipe2, self.recipe3, self.recipe4, self.recipe5, self.recipe6, self.recipe7, ] for recipe in self.test_recipes: recipe.locks.add("learn:all();teach:all()") recipe.required_materials.create(amount=recipe.level, type=self.mat1) recipe.save() # Top1 is a wearable object with no recipe or crafter designated self.top1 = create.create_object(wearable_typeclass, key="Top1", location=self.room1, home=self.room1) self.top1.item_data.quality_level = 6 # Top2 is a 1-slot_limit chest Wearable made by non-staff char2 self.top2 = create.create_object(wearable_typeclass, key="Top2", location=self.char2, home=self.room1) self.top2.item_data.quality_level = 6 self.top2.item_data.recipe = 1 self.top2.item_data.crafted_by = self.char2 # Slinkity1 is chest 2-slot_limit, so can stack once with chest-wearables. Also has adorns self.catsuit1 = create.create_object(wearable_typeclass, key="Slinkity1", location=self.char2, home=self.room1) self.catsuit1.item_data.quality_level = 11 self.catsuit1.item_data.recipe = 2 self.catsuit1.item_data.crafted_by = self.char2 self.catsuit1.item_data.add_adorn(1, 200) # Purse1 is a wearable container; baseval is their capacity self.purse1 = create.create_object(purse_typeclass, key="Purse1", location=self.char2, home=self.room1) self.purse1.item_data.quality_level = 4 self.purse1.item_data.recipe = 3 self.purse1.item_data.crafted_by = self.char2 # Imps leer when they lick a knife self.knife1 = create.create_object(weapon_typeclass, key="Lickyknife1", location=self.char2, home=self.room1) self.knife1.item_data.quality_level = 11 self.knife1.item_data.recipe = 4 self.knife1.item_data.crafted_by = self.char2 self.knife1.item_data.attack_skill = ( self.knife1.item_data.recipe.weapon_skill or "medium wpn") # A larger weapon self.sword1 = create.create_object(weapon_typeclass, key="Sword1", location=self.char2, home=self.room1) self.sword1.item_data.quality_level = 6 self.sword1.item_data.recipe = 7 self.sword1.item_data.crafted_by = self.char2 self.sword1.item_data.attack_skill = ( self.sword1.item_data.recipe.weapon_skill or "medium wpn") # Masks change wearer identity and are restricted from being worn by 0 quality self.mask1 = create.create_object(mask_typeclass, key="A Fox Mask", location=self.char2, home=self.room1) self.mask1.item_data.quality_level = 0 self.mask1.item_data.recipe = 6 # mask also has fashion_mult:6 self.mask1.item_data.crafted_by = self.char2 self.mask1.item_data.mask_desc = "A very Slyyyy Fox..." self.mask1.item_data.add_adorn(1, 20) # Hairpins1 is a decorative weapon and should always show as 'worn' rather than 'sheathed' self.hairpins1 = create.create_object(hairpin_typeclass, key="Hairpins1", location=self.char2, home=self.room1) self.hairpins1.item_data.quality_level = 4 self.hairpins1.item_data.recipe = 5 self.hairpins1.item_data.crafted_by = self.char2 self.hairpins1.item_data.attack_skill = ( self.hairpins1.item_data.recipe.weapon_skill or "small wpn")
def copy_object(self, original_object, new_key=None, new_location=None, new_home=None, new_permissions=None, new_locks=None, new_aliases=None, new_destination=None): """ Create and return a new object as a copy of the original object. All will be identical to the original except for the arguments given specifically to this method. Args: original_object (Object): The object to make a copy from. new_key (str, optional): Name of the copy, if different from the original. new_location (Object, optional): Alternate location. new_home (Object, optional): Change the home location new_aliases (list, optional): Give alternate object aliases as a list of strings. new_destination (Object, optional): Used only by exits. Returns: copy (Object or None): The copy of `original_object`, optionally modified as per the ingoing keyword arguments. `None` if an error was encountered. """ # get all the object's stats typeclass_path = original_object.typeclass_path if not new_key: new_key = original_object.key if not new_location: new_location = original_object.location if not new_home: new_home = original_object.home if not new_aliases: new_aliases = original_object.aliases.all() if not new_locks: new_locks = original_object.db_lock_storage if not new_permissions: new_permissions = original_object.permissions.all() if not new_destination: new_destination = original_object.destination # create new object from evennia.utils import create from evennia.scripts.models import ScriptDB new_object = create.create_object(typeclass_path, key=new_key, location=new_location, home=new_home, permissions=new_permissions, locks=new_locks, aliases=new_aliases, destination=new_destination) if not new_object: return None # copy over all attributes from old to new. for attr in original_object.attributes.all(): new_object.attributes.add(attr.key, attr.value) # copy over all cmdsets, if any for icmdset, cmdset in enumerate(original_object.cmdset.all()): if icmdset == 0: new_object.cmdset.add_default(cmdset) else: new_object.cmdset.add(cmdset) # copy over all scripts, if any for script in original_object.scripts.all(): ScriptDB.objects.copy_script(script, new_obj=new_object) return new_object
def func(self): "create the new character" player = self.player session = self.session if not self.args: self.msg("Usage: @charcreate <charname>") return key = self.args.strip() charmax = _MAX_NR_CHARACTERS if _MULTISESSION_MODE > 1 else 1 if not player.is_superuser and \ (player.db._playable_characters and len(player.db._playable_characters) >= charmax): self.msg( "You may only create a maximum of {} characters.".format( charmax)) return # create the character from evennia.objects.models import ObjectDB start_location = ObjectDB.objects.get_id(settings.START_LOCATION) default_home = ObjectDB.objects.get_id(settings.DEFAULT_HOME) typeclass = settings.BASE_CHARACTER_TYPECLASS permissions = settings.PERMISSION_PLAYER_DEFAULT # check whether a character already exists new_character = None candidates = search.objects(key, typeclass='typeclasses.characters.Character') if candidates: for c in candidates: if c.access(player, 'puppet'): new_character = c break startnode = "menunode_welcome_archetypes" if not new_character: new_character = create.create_object(typeclass, key=key, location=None, home=default_home, permissions=permissions) # only allow creator (and immortals) to puppet this char new_character.locks.add( ("puppet:id({}) or pid({}) " "or perm(Immortals) or pperm(Immortals)").format( new_character.id, player.id )) player.db._playable_characters.append(new_character) else: if new_character.db.chargen_complete: self.msg(("{name} has already completed character " "generation. Use @ic {name} to puppet.").format( name=new_character.key if ' ' not in new_character.key else '"{}"'.format(new_character.key))) return if new_character.db.archetype: startnode = "menunode_allocate_traits" if (new_character.db.focus or (not new_character.db.focus and validate_primary_traits(new_character.traits)[0])): startnode = "menunode_races" if new_character.db.race: startnode = "menunode_allocate_mana" if (new_character.traits.BM.base + new_character.traits.WM.base == new_character.traits.MAG.actual and len(new_character.skills.all) > 0): startnode = "menunode_allocate_skills" if ('escape' in new_character.skills.all and not hasattr(new_character.skills.escape, 'minus')): startnode = "menunode_equipment_cats" session.new_char = new_character def finish_char_callback(session, menu): char = session.new_char if char.db.chargen_complete: char.location = start_location player.puppet_object(session, char) EvMenu(session, "world.chargen", startnode=startnode, allow_quit=False, cmd_on_quit=finish_char_callback)
def create_character(new_player, nickname, permissions=None, character_key=None, level=1, typeclass=None, location=None, home=None): """ Helper function, creates a character based on a player's name. """ if not character_key: character_key = GAME_SETTINGS.get("default_player_character_key") if not typeclass: typeclass = settings.BASE_PLAYER_CHARACTER_TYPECLASS if not permissions: permissions = settings.PERMISSION_ACCOUNT_DEFAULT if not home: home = settings.DEFAULT_HOME try: default_home_key = GAME_SETTINGS.get("default_player_home_key") if default_home_key: rooms = utils.search_obj_data_key(default_home_key) home = rooms[0] except: pass if not location: location = home try: start_location_key = GAME_SETTINGS.get("start_location_key") if start_location_key: rooms = utils.search_obj_data_key(start_location_key) location = rooms[0] except: pass new_character = create.create_object(typeclass, key=new_player.key, location=location, home=home, permissions=permissions) # set character info new_character.set_data_key(character_key) new_character.set_level(level) # set playable character list new_player.db._playable_characters.append(new_character) # allow only the character itself and the player to puppet this character (and Immortals). new_character.locks.add("puppet:id(%i) or pid(%i) or perm(Immortals) or pperm(Immortals)" % (new_character.id, new_player.id)) # If no description is set, set a default description if not new_character.db.desc: new_character.db.desc = "This is a Player." # Add nickname if not nickname: nickname = character_key new_character.set_nickname(nickname) # We need to set this to have @ic auto-connect to this character new_player.db._last_puppet = new_character return new_character
def test_exit(self): """Test the callbacks of an exit.""" self.char1.key = "char1" code = dedent( """ if character.key == "char1": character.msg("You can leave.") else: character.msg("You cannot leave.") deny() """.strip( "\n" ) ) # Enforce self.exit.destination since swapping typeclass lose it self.exit.destination = self.room2 # Try the can_traverse callback self.handler.add_callback(self.exit, "can_traverse", code, author=self.char1, valid=True) # Have char1 move through the exit self.call(ExitCommand(), "", "You can leave.", obj=self.exit) self.assertIs(self.char1.location, self.room2) # Have char2 move through this exit self.call(ExitCommand(), "", "You cannot leave.", obj=self.exit, caller=self.char2) self.assertIs(self.char2.location, self.room1) # Try the traverse callback self.handler.del_callback(self.exit, "can_traverse", 0) self.handler.add_callback( self.exit, "traverse", "character.msg('Fine!')", author=self.char1, valid=True ) # Have char2 move through the exit self.call(ExitCommand(), "", obj=self.exit, caller=self.char2) self.assertIs(self.char2.location, self.room2) self.handler.del_callback(self.exit, "traverse", 0) # Move char1 and char2 back self.char1.location = self.room1 self.char2.location = self.room1 # Test msg_arrive and msg_leave code = 'message = "{character} goes out."' self.handler.add_callback(self.exit, "msg_leave", code, author=self.char1, valid=True) # Have char1 move through the exit old_msg = self.char2.msg try: self.char2.msg = Mock() self.call(ExitCommand(), "", obj=self.exit) stored_msg = [ args[0] if args and args[0] else kwargs.get("text", utils.to_str(kwargs)) for name, args, kwargs in self.char2.msg.mock_calls ] # Get the first element of a tuple if msg received a tuple instead of a string stored_msg = [smsg[0] if isinstance(smsg, tuple) else smsg for smsg in stored_msg] returned_msg = ansi.parse_ansi("\n".join(stored_msg), strip_ansi=True) self.assertEqual(returned_msg, "char1 goes out.") finally: self.char2.msg = old_msg # Create a return exit back = create_object( "evennia.objects.objects.DefaultExit", key="in", location=self.room2, destination=self.room1, ) code = 'message = "{character} goes in."' self.handler.add_callback(self.exit, "msg_arrive", code, author=self.char1, valid=True) # Have char1 move through the exit old_msg = self.char2.msg try: self.char2.msg = Mock() self.call(ExitCommand(), "", obj=back) stored_msg = [ args[0] if args and args[0] else kwargs.get("text", utils.to_str(kwargs)) for name, args, kwargs in self.char2.msg.mock_calls ] # Get the first element of a tuple if msg received a tuple instead of a string stored_msg = [smsg[0] if isinstance(smsg, tuple) else smsg for smsg in stored_msg] returned_msg = ansi.parse_ansi("\n".join(stored_msg), strip_ansi=True) self.assertEqual(returned_msg, "char1 goes in.") finally: self.char2.msg = old_msg
def func(self): "Create the shop rooms" if not self.args: self.msg("Usage: @buildshop <storename>") return # create the shop and storeroom super(CmdBuildShop, self).parse() for objdef in self.lhs_objs: shopname = objdef['name'] aliases = objdef['aliases'] shop = create_object(NPCShop, key=shopname, location=None, nohome=True) shop.at_object_creation() storeroom = create_object(StoreRoom, key="%s-storage" % shopname, location=None, nohome=True) storeroom.at_object_creation() shop.db.storeroom = storeroom # create a door between the two storeroom_entrance = create_object( Exit, key="back door", aliases=["storage", "store room", "storeroom", "back"], location=shop, destination=storeroom, home=shop) storeroom_exit = create_object( Exit, key="shop", aliases=["exit", "back", "out", "door", "o"], location=storeroom, destination=shop, home=storeroom) shop_entrance = create_object(Exit, key=shopname, location=self.caller.location, destination=shop, aliases=aliases, home=self.caller.location) shop_exit = create_object(Exit, key="front door", aliases=["front", "exit", "out", "o"], location=shop, destination=self.caller.location, home=shop) # make a key for accessing the store room storeroom_key_name = "%s-storekey" % shopname storeroom_key = create_object(DefaultObject, key=storeroom_key_name, location=self.caller, aliases=["key"], home=self.caller) # only allow chars with this key to enter the store room storeroom_entrance.locks.add("traverse:holds(%s)" % storeroom_key_name) # inform the builder about progress self.caller.msg("The shop %s was created!" % shop)
def create_objects(): """ Creates the #1 account and Limbo room. """ logger.log_info( "Initial setup: Creating objects (Account #1 and Limbo room) ...") # Set the initial User's account object's username on the #1 object. # This object is pure django and only holds name, email and password. god_account = get_god_account() # Create an Account 'user profile' object to hold eventual # mud-specific settings for the AccountDB object. account_typeclass = settings.BASE_ACCOUNT_TYPECLASS # run all creation hooks on god_account (we must do so manually # since the manage.py command does not) god_account.swap_typeclass(account_typeclass, clean_attributes=True) god_account.basetype_setup() god_account.at_account_creation() god_account.locks.add( "examine:perm(Developer);edit:false();delete:false();boot:false();msg:all()" ) # this is necessary for quelling to work correctly. god_account.permissions.add("Developer") # Limbo is the default "nowhere" starting room # Create the in-game god-character for account #1 and set # it to exist in Limbo. character_typeclass = settings.BASE_CHARACTER_TYPECLASS god_character = create.create_object(character_typeclass, key=god_account.username, nohome=True) god_character.id = 1 god_character.save() god_character.db.desc = _("This is User #1.") god_character.locks.add( "examine:perm(Developer);edit:false();delete:false();boot:false();msg:all();puppet:false()" ) # we set this low so that quelling is more useful god_character.permissions.add("Player") god_account.attributes.add("_first_login", True) god_account.attributes.add("_last_puppet", god_character) try: god_account.db._playable_characters.append(god_character) except AttributeError: god_account.db_playable_characters = [god_character] room_typeclass = settings.BASE_ROOM_TYPECLASS limbo_obj = create.create_object(room_typeclass, _("Limbo"), nohome=True) limbo_obj.id = 2 limbo_obj.save() limbo_obj.db.desc = LIMBO_DESC.strip() limbo_obj.save() # Now that Limbo exists, try to set the user up in Limbo (unless # the creation hooks already fixed this). if not god_character.location: god_character.location = limbo_obj if not god_character.home: god_character.home = limbo_obj
def arrive_at(self, position): """ # The following code moves an object to a new position and room that # matches that position. """ vessel = self # Check the arguments to make sure vessel is a vessel and # position is a position # Look up room in teh entier DB if position: room = search.search_object_attribute(key="coordinates", value=position) else: string = "position: %s" % str(position) self.msg_contents(string) return # move to room if room: # If the destination room exists, we go there. vessel.msg_contents("%s already exists." % room) room = room[0] # TODO: fix this^ throw on multimatch rooms there should only # ever be one room per coordinates # unless it is dry land if inherits_from(room, "typeclasses.rooms.DryLandRoom"): vessel.msg_contents("It's dry land so cancelling move.") return # but if not dry land # ... lets get on with it and move else: vessel.msg_contents("Moving to %s" % room) vessel.move_to(room) return elif vessel.location.is_typeclass("rooms.DynamicRoom") and len(vessel.location.contents) == 1: # This means we are in a dynamic room alone vessel.msg_contents("updating room coordinates to %s" % str(position)) vessel.location.db.coordinates = position # have to update vessel position to match rooms new position vessel.db.position = position return else: # Assume the current room is occupied or not dynamic # create the room vessel.msg_contents("Creating new room at %s" % str(position)) room = create_object(typeclass="rooms.DynamicRoom", key="The Open Ocean", location=None) room.db.coordinates = position vessel.msg_contents("Moving to %s" % room) vessel.move_to(room) return def make_way(self, course): old_position = self.db.position position = move_vector(old_position, course) self.msg_contents("New position = %s" % str(position)) self.arrive_at(self, position) def at_tick(self): """ All floating objects move every tick unless anchored/moored. So at tick, we calculate course and make_way """ pass
def copy_object( self, original_object, new_key=None, new_location=None, new_home=None, new_permissions=None, new_locks=None, new_aliases=None, new_destination=None, ): """ Create and return a new object as a copy of the original object. All will be identical to the original except for the arguments given specifically to this method. Object contents will not be copied. Args: original_object (Object): The object to make a copy from. new_key (str, optional): Name of the copy, if different from the original. new_location (Object, optional): Alternate location. new_home (Object, optional): Change the home location new_aliases (list, optional): Give alternate object aliases as a list of strings. new_destination (Object, optional): Used only by exits. Returns: copy (Object or None): The copy of `original_object`, optionally modified as per the ingoing keyword arguments. `None` if an error was encountered. """ # get all the object's stats typeclass_path = original_object.typeclass_path if not new_key: new_key = original_object.key if not new_location: new_location = original_object.location if not new_home: new_home = original_object.home if not new_aliases: new_aliases = original_object.aliases.all() if not new_locks: new_locks = original_object.db_lock_storage if not new_permissions: new_permissions = original_object.permissions.all() if not new_destination: new_destination = original_object.destination # create new object from evennia.utils import create from evennia.scripts.models import ScriptDB new_object = create.create_object( typeclass_path, key=new_key, location=new_location, home=new_home, permissions=new_permissions, locks=new_locks, aliases=new_aliases, destination=new_destination, ) if not new_object: return None # copy over all attributes from old to new. attrs = ((a.key, a.value, a.category, a.lock_storage) for a in original_object.attributes.all()) new_object.attributes.batch_add(*attrs) # copy over all cmdsets, if any for icmdset, cmdset in enumerate(original_object.cmdset.all()): if icmdset == 0: new_object.cmdset.add_default(cmdset) else: new_object.cmdset.add(cmdset) # copy over all scripts, if any for script in original_object.scripts.all(): ScriptDB.objects.copy_script(script, new_obj=new_object) # copy over all tags, if any tags = ((t.db_key, t.db_category, t.db_data) for t in original_object.tags.all(return_objs=True)) new_object.tags.batch_add(*tags) return new_object
def switch_jobs(self): # Step one is importing all of the Job Categories from the MUSH data. Each category is a THING object # So we don't need mysql just yet. cat_dict = dict() old_categories = cobj('jobdb').children.all() for old_cat in old_categories: new_cat, created = JobCategory.objects.get_or_create(key=old_cat.name) if created: new_cat.setup() cat_dict[old_cat.objid] = new_cat # Establishing Mysql Connection! from commands.mysql import sql_dict db = MySQLdb.connect(host=sql_dict['site'], user=sql_dict['username'], passwd=sql_dict['password'], db=sql_dict['database'], cursorclass=cursors.DictCursor) c = db.cursor() # Our next order of business is retrieving all of the players who've ever posted jobs. # This section searches the database by OBJID and creates a dictionary that links the old jobsys player_id # to the new communications.ObjectStub, creating them if necessary. c.execute("""SELECT * from jobsys_players""") old_players = c.fetchall() char_dict = dict() for old_player in old_players: match = objmatch(old_player['objid']) if match: char = match.obj else: key = old_player['player_name'] char = create.create_object(typeclass='classes.characters.BaseCharacter', key=key) objid = old_player['objid'] dbref, csecs = objid.split(':', 1) cdate = from_unixtimestring(csecs) MushObject.objects.create(objid=objid, dbref=dbref, created=cdate, type=8, recreated=1, obj=char) char_dict[old_player['player_id']] = char # Now that we have the Player ID->Stub dictionary, we can begin the process of actually importing job data! # we only want the jobs from categories that actually exist. Probably rare that any of them wouldn't be, but # just in case... cat_list = ', '.join("'%s'" % cat for cat in cat_dict.keys()) c.execute("""SELECT * from jobsys_jobs WHERE job_objid IN (%s) ORDER BY job_id""" % cat_list) old_jobs = c.fetchall() for row in old_jobs: job_id = row['job_id'] if row['close_date']: close_date = row['close_date'].replace(tzinfo=pytz.utc) else: close_date = None if row['due_date']: due_date = row['due_date'].replace(tzinfo=pytz.utc) else: due_date = None if row['submit_date']: submit_date = row['submit_date'].replace(tzinfo=pytz.utc) else: submit_date = None title = row['job_title'] status = row['job_status'] owner = char_dict[row['player_id']] text = penn_substitutions(row['job_text']) category = cat_dict[row['job_objid']] handler_dict = dict() # We have our job row data prepped! Now to create the job and its opening comment as well as the owner-handler. new_job = category.jobs.create(title=title, submit_date=submit_date, due_date=due_date, close_date=close_date, status=status) new_owner = new_job.characters.create(character=owner, is_owner=True, check_date=utcnow()) new_owner.comments.create(text=text, date_made=submit_date) handler_dict[row['player_id']] = new_owner # Here it's time to import all of the job's claims, handlers, watchers, and create JobHandler rows for them. c.execute("""SELECT * from jobsys_claim WHERE job_id=%s""", (job_id,)) claim_data = c.fetchall() for old_claim in claim_data: stub = char_dict[old_claim['player_id']] new_handler, created = new_job.characters.get_or_create(character=stub, check_date=utcnow()) if old_claim['claim_mode'] == 0: new_handler.is_handler = True if old_claim['claim_mode'] == 1: new_handler.is_helper = True new_handler.save() handler_dict[old_claim['player_id']] = new_handler # Unfortunately it's also possible that people who didn't claim it might also need JobHandler entries so... c.execute("""SELECT DISTINCT player_id from jobsys_comments WHERE job_id=%s""", (job_id,)) all_speakers = c.fetchall() for speaker in all_speakers: if speaker['player_id'] not in handler_dict: new_handler, created = new_job.characters.get_or_create(character=char_dict[speaker['player_id']], check_date=utcnow()) handler_dict[speaker['player_id']] = new_handler # And another round. This time it's a matter of importing handlers for anyone who ever CHECKED a job. # Here we'll also import everyone's 'last date they checked the job'. c.execute("""SELECT * FROM jobsys_check WHERE job_id=%s""", (job_id,)) old_checks = c.fetchall() for check in old_checks: if check['player_id'] not in handler_dict: handler, created = new_job.characters.get_or_create(character=char_dict[check['player_id']], check_date=utcnow()) handler_dict[check['player_id']] = new_handler else: handler = handler_dict[check['player_id']] handler.check_date = check['check_date'].replace(tzinfo=pytz.utc) handler.save(update_fields=['check_date']) # Now to import all of the comments and replies. c.execute("""SELECT * from jobsys_comments WHERE job_id=%s ORDER BY comment_id""", (job_id,)) old_comments = c.fetchall() for old_com in old_comments: handler = handler_dict[old_com['player_id']] comment_text = penn_substitutions(old_com['comment_text']) comment_date = old_com['comment_date'].replace(tzinfo=pytz.utc) private = old_com['comment_type'] handler.comments.create(text=comment_text, date_made=comment_date, is_private=private) db.close()
def switch_scenes(self): # Establishing Mysql Connection! from commands.mysql import sql_dict db = MySQLdb.connect(host=sql_dict['site'], user=sql_dict['username'], passwd=sql_dict['password'], db=sql_dict['database'], cursorclass=cursors.DictCursor) c = db.cursor() # Just like with jobs, we need to create Stubs for everyone who has ever used SceneSys and link them to their # Scene IDs! Same code, believe it or not. c.execute("""SELECT * from scene_players""") old_players = c.fetchall() char_dict = dict() for old_player in old_players: match = objmatch(old_player['objid']) if match: char = match.obj else: key = old_player['player_name'] char = create.create_object(typeclass='classes.characters.BaseCharacter', key=key) objid = old_player['objid'] dbref, csecs = objid.split(':', 1) cdate = from_unixtimestring(csecs) new_mush = MushObject.objects.create(objid=objid, dbref=dbref, created=cdate, type=8, recreated=1, obj=char) new_mush.save() char_dict[old_player['player_id']] = char # Convert plots! This one's pretty easy. c.execute("""SELECT * FROM scene_plots ORDER BY plot_id""") old_plots = c.fetchall() plot_dict = dict() for old_plot in old_plots: if old_plot['start_date']: start_date = old_plot['start_date'].replace(tzinfo=pytz.utc) else: start_date = None if old_plot['end_date']: end_date = old_plot['end_date'].replace(tzinfo=pytz.utc) else: end_date = None owner = char_dict[old_plot['player_id']] description = penn_substitutions(old_plot['plot_desc']) plot_type = old_plot['plot_type'] title = old_plot['title'] new_plot = Plot.objects.create(owner=owner, description=description, title=title, date_start=start_date, date_end=end_date, type=plot_type) plot_dict[old_plot['plot_id']]= new_plot # Another easy one. Importing the Events calendar of scheduled scenes. event_dict = dict() c.execute("""SELECT * from scene_schedule ORDER BY schedule_id""") old_events = c.fetchall() for old_event in old_events: owner = char_dict[old_event['player_id']] schedule_date = old_event['schedule_date'].replace(tzinfo=pytz.utc) description = penn_substitutions(old_event['schedule_desc']) schedule_title = old_event['schedule_title'] plot = plot_dict.get(old_event['plot_id'], None) new_event = Event.objects.create(owner=owner, date_schedule=schedule_date, description=description, title=schedule_title, plot=plot) event_dict[old_event['schedule_id']] = new_event # Now we begin the process of importing scenes. This is a very involved process! scene_dict = dict() c.execute("""SELECT * FROM scene_scenes ORDER BY scene_id""") old_scenes = c.fetchall() for old_scene in old_scenes: owner = char_dict[old_scene['player_id']] scene_title = old_scene['scene_title'] scene_desc = old_scene['scene_desc'] scene_status = int(old_scene['scene_state']) creation_date = old_scene['creation_date'].replace(tzinfo=pytz.utc) if old_scene['finish_date']: finish_date = old_scene['finish_date'].replace(tzinfo=pytz.utc) else: finish_date = None plot = plot_dict.get(old_scene['plot_id'], None) room_objid = old_scene['room_objid'] old_loc = objmatch(room_objid) if old_loc.obj: location = old_loc.obj else: room_name = old_scene['room_name'] dbref, csecs = room_objid.split(':', 1) cdate = from_unixtimestring(csecs) location = create.create_object(typeclass='classes.rooms.BaseRoom', key=room_name) new_mush, created = MushObject.objects.get_or_create(objid=room_objid, dbref=dbref, type=1, created=cdate) new_mush.obj = location new_mush.save() new_scene = Scene.objects.create(owner=owner, title=scene_title, description=scene_desc, status=scene_status, date_created=creation_date, date_finished=finish_date, plot=plot) scene_dict[old_scene['scene_id']] = new_scene # In this section we'll be setting up the Participants for this scene and making an index dictionary # in preparation to import the poses. part_dict = dict() c.execute("""SELECT DISTINCT player_id FROM scene_poses WHERE scene_id=%s""", (old_scene['scene_id'],)) posers = c.fetchall() for poser in posers: new_part = new_scene.participants.create(character=char_dict[poser['player_id']]) part_dict[poser['player_id']] = new_part # Finally it's time to import the individual poses! pose_dict = dict() c.execute("""SELECT * from scene_poses WHERE scene_id=%s""", (old_scene['scene_id'],)) old_poses = c.fetchall() for pose in old_poses: parse_pose = pose['pose'].decode('utf-8',errors='ignore') owner = part_dict[pose['player_id']] pose_date = pose['pose_time'].replace(tzinfo=pytz.utc) ignore = bool(int(pose['pose_ignore'])) pose_text = penn_substitutions(parse_pose) new_pose = Pose.objects.create(owner=owner, ignore=ignore, text=pose_text, date_made=pose_date, location=location) pose_dict[pose['pose_id']] = new_pose db.close()
def func(self): caller = self.caller location = caller.location old_coord = location.db.coordinates # lat,lon of starting room if not old_coord: string = ("%s has no coordinates we cannot use 'walk' from here") string = string % location caller.msg(string) return "Implements the walk command" if not self.args or not self.lhs: string = "Usage: @walk[/switch] <direction> " string += "[= roomname]" self.caller.msg(string) return if self.lhs not in self.directions: string = "@walk only works in the following directions: %s." string = string % ",".join(sorted(self.directions.keys())) string += "\n(use @dig or @raise for more freedom)" self.caller.msg(string) return # retrieve all input and parse it sd = self.directions ex = self.lhs exname, back = sd[ex][0], sd[ex][1] backname = sd[back][0] string = "backname = %s" % backname vector = sd[ex][2] # caller.msg("Vector for %s is %s" % (ex, vector)) caller.msg(string) string = "" # calculate location of new_coord for new room new_coord = (old_coord[0] + vector[0], old_coord[1] + vector[1]) # search for matching coordinates in db conflict = search.search_object_attribute(key="coordinates", value=new_coord) if conflict: report = "There is already a room at %s: %s" report += "\n%s is accessible as %s" report = report % (new_coord, conflict, conflict[0].name, conflict[0].dbref) report += "\nSo you can delete it now then re-run this" report += "command, or just try to link to it.\n" report += "Automating this is on my todo list." caller.msg(report) return # find the backwards exit from the directions # backstring = ", %s;%s" % (backname, back) # choose the typeclass if "inland" in self.switches: typeclass_path = "rooms.DryLandRoom" roomname = "Inland" elif "coast" in self.switches: typeclass_path = "rooms.CoastalRoom" roomname = "Coastline" else: # no switches default type and name of start room # but name can be over written typeclass_path = location.typeclass_path roomname = location.name # name the new room if self.rhs: roomname = self.rhs # this may include aliases; that's fine. # create room lockstring = "control:id(%s) or perm(Immortals); delete:id(%s) " lockstring += "or perm(Wizards); edit:id(%s) or perm(Wizards)" lockstring = lockstring % (caller.dbref, caller.dbref, caller.dbref) new_room = create.create_object(typeclass_path, roomname, report_to=caller) # lock the room after creation new_room.locks.add(lockstring) # add the coordinates new_room.db.coordinates = new_coord room_string = "Created room %s(%s) of type %s." % ( new_room, new_room.dbref, typeclass_path) # create exit to room # Build the exit to the new room from the current one xtc = settings.BASE_EXIT_TYPECLASS new_to_exit = create.create_object(xtc, exname, location, aliases=ex[0], locks=lockstring, destination=new_room, report_to=caller) alias_string = "" exit_to_string = "\nCreated Exit from %s to %s: %s(%s)%s." exit_to_string = exit_to_string % (location.name, new_room.name, new_to_exit, new_to_exit.dbref, alias_string) # Create exit back from new room # Building the exit back to the current room if not location: exit_back_string = \ "\nYou cannot create an exit back to a None-location." else: typeclass = settings.BASE_EXIT_TYPECLASS new_back_exit = create.create_object(typeclass, backname, new_room, aliases=back, locks=lockstring, destination=location, report_to=caller) alias_string = "" exit_back_string = "\nCreated Exit back from %s to %s: %s(%s)%s." exit_back_string = exit_back_string % (new_room.name, location.name, new_back_exit, new_back_exit.dbref, alias_string) caller.msg("%s%s%s" % (room_string, exit_to_string, exit_back_string)) if new_room and ('still' not in self.switches): caller.move_to(new_room)
print(ostring) print(traceback.print_exc()) pass if not record or not typeclass: ostring = "Can not find the data of %s." % obj_key print(ostring) print(traceback.print_exc()) if caller: caller.msg(ostring) return # Create object. try: name = getattr(record, "name", "") obj = create.create_object(typeclass.path, name) except Exception, e: ostring = "Can not create obj %s: %s" % (obj_key, e) print(ostring) print(traceback.print_exc()) if caller: caller.msg(ostring) return try: # Set data info. obj.set_data_key(record.key, set_location=set_location) except Exception, e: ostring = "Can not set data info to obj %s: %s" % (obj_key, e) print(ostring) print(traceback.print_exc())
def func(self): "create the new character" player = self.player session = self.session if not self.args: self.msg("Usage: @charcreate <charname>") return key = self.args.strip() charmax = _MAX_NR_CHARACTERS if _MULTISESSION_MODE > 1 else 1 if not player.is_superuser and \ (player.db._playable_characters and len(player.db._playable_characters) >= charmax): self.msg( "You may only create a maximum of {} characters.".format( charmax)) return # create the character from evennia.objects.models import ObjectDB start_location = ObjectDB.objects.get_id(settings.START_LOCATION) default_home = ObjectDB.objects.get_id(settings.DEFAULT_HOME) typeclass = settings.BASE_CHARACTER_TYPECLASS permissions = settings.PERMISSION_PLAYER_DEFAULT # check whether a character already exists new_character = None candidates = search.objects(key, typeclass='typeclasses.characters.Character') if candidates: for c in candidates: if c.access(player, 'puppet'): new_character = c break startnode = "menunode_welcome_archetypes" if not new_character: new_character = create.create_object(typeclass, key=key, location=None, home=default_home, permissions=permissions) # only allow creator (and immortals) to puppet this char new_character.locks.add( ("puppet:id({}) or pid({}) " "or perm(Immortals) or pperm(Immortals)").format( new_character.id, player.id )) player.db._playable_characters.append(new_character) else: if new_character.db.chargen_complete: self.msg(("{name} has already completed character " "generation. Use @ic {name} to puppet.").format( name=new_character.key if ' ' not in new_character.key else '"{}"'.format(new_character.key))) return if new_character.db.archetype: startnode = "menunode_allocate_traits" if (new_character.db.focus or (not new_character.db.focus and validate_primary_traits(new_character.traits)[0])): startnode = "menunode_races" if new_character.db.race: startnode = "menunode_allocate_mana" if (new_character.traits.BM.base + new_character.traits.WM.base == new_character.traits.MAG.actual and len(new_character.skills.all) > 0): startnode = "menunode_allocate_skills" if ('escape' in new_character.skills.all and not hasattr(new_character.skills.escape, 'minus')): startnode = "menunode_equipment_cats" session.new_char = new_character def finish_char_callback(session, menu): char = session.new_char if char.db.chargen_complete: char.location = start_location player.puppet_object(session, char) EvMenu(session, "world.chargen", startnode=startnode, cmd_on_exit=finish_char_callback)