Run Migrate. Implemented a full separation between Player and Character - Players (OOC entities) can now also hold cmdsets and execute commands. This means that "disconnecting" from a Character becomes possible, putting the Player in an "OOC" state outside the game. This overall makes the game much more stable since there used to be issues if the character was destroyed. Having an OOC set also avoids the previous problem of @puppeting into an object that didn't have any cmdset of its own - you couldn't get back out! A new default OOC-Cmdset handles commands available to a player while OOC. Commands in this set are applied with a low priority, allowing "IC" mode to give precedence if desired.

This change meant several changes to the lock and permission functionality, since it becomes important if permissions are assigned on the Player or on their Character (lock functions pperm() and pid() etc check on Player rather than Character). This has the boon of allowing Admins to switch and play/test the game as a "Low access" character as they like.

Plenty of bug fixes and adjustments. Migrations should make sure to move over all data properly.
This commit is contained in:
Griatch 2011-04-23 11:54:08 +00:00
parent ce2a8e9ffe
commit 28fe2ad3f4
37 changed files with 1622 additions and 555 deletions

View file

@ -62,49 +62,81 @@ class CmdConnect(MuxCommand):
# We are logging in, get/setup the player object controlled by player
character = player.character
if not character:
# Create a new character object to tie the player to. This should
# usually not be needed unless the old character object was manually
# deleted.
default_home_id = ServerConfig.objects.conf("default_home")
default_home = ObjectDB.objects.get_id(default_home_id)
typeclass = settings.BASE_CHARACTER_TYPECLASS
character = create.create_object(typeclass=typeclass,
key=player.name,
location=default_home,
home=default_home,
player=player)
character.db.FIRST_LOGIN = "True"
# Getting ready to log the player in.
# Check if this is the first time the
# *player* connects
if player.db.FIRST_LOGIN:
player.at_first_login()
del player.db.FIRST_LOGIN
# check if this is the first time the *character*
# character (needs not be the first time the player
# does so, e.g. if the player has several characters)
if character.db.FIRST_LOGIN:
character.at_first_login()
del character.db.FIRST_LOGIN
# actually do the login, calling
# customization hooks before and after.
player.at_pre_login()
character.at_pre_login()
character = player.character
if character:
# this player has a character. Check if it's the
# first time *this character* logs in
if character.db.FIRST_LOGIN:
character.at_first_login()
del character.db.FIRST_LOGIN
# run character login hook
character.at_pre_login()
# actually do the login
session.session_login(player)
# post-login hooks
player.at_post_login()
if character:
character.at_post_login()
character.execute_cmd('look')
else:
player.execute_cmd('look')
player.at_post_login()
character.at_post_login()
# run look
#print "character:", character, character.scripts.all(), character.cmdset.current
character.execute_cmd('look')
#
# character = player.character
# if not character:
# # Create a new character object to tie the player to. This should
# # usually not be needed unless the old character object was manually
# # deleted.
# default_home_id = ServerConfig.objects.conf("default_home")
# default_home = ObjectDB.objects.get_id(default_home_id)
# typeclass = settings.BASE_CHARACTER_TYPECLASS
# character = create.create_object(typeclass=typeclass,
# key=player.name,
# location=default_home,
# home=default_home,
# player=player)
# character.db.FIRST_LOGIN = "True"
# # Getting ready to log the player in.
# # Check if this is the first time the
# # *player* connects
# if player.db.FIRST_LOGIN:
# player.at_first_login()
# del player.db.FIRST_LOGIN
# # check if this is the first time the *character*
# # character (needs not be the first time the player
# # does so, e.g. if the player has several characters)
# if character.db.FIRST_LOGIN:
# character.at_first_login()
# del character.db.FIRST_LOGIN
# # actually do the login, calling
# # customization hooks before and after.
# player.at_pre_login()
# character.at_pre_login()
# session.session_login(player)
# player.at_post_login()
# character.at_post_login()
# # run look
# #print "character:", character, character.scripts.all(), character.cmdset.current
# character.execute_cmd('look')
class CmdCreate(MuxCommand):
"""
@ -169,61 +201,69 @@ class CmdCreate(MuxCommand):
return
# Run sanity and security checks
if PlayerDB.objects.get_player_from_name(playername) or User.objects.filter(username=playername):
# player already exists
session.msg("Sorry, there is already a player with the name '%s'." % playername)
elif PlayerDB.objects.get_player_from_email(email):
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.")
elif len(password) < 3:
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)
else:
# everything's ok. Create the new player account
try:
default_home_id = ServerConfig.objects.conf("default_home")
default_home = ObjectDB.objects.get_id(default_home_id)
typeclass = settings.BASE_CHARACTER_TYPECLASS
permissions = settings.PERMISSION_PLAYER_DEFAULT
return
new_character = create.create_player(playername, email, password,
permissions=permissions,
location=default_home,
typeclass=typeclass,
home=default_home)
# character safety features
new_character.locks.delete("get")
new_character.locks.add("get:perm(Wizards)")
# everything's ok. Create the new player account.
try:
default_home_id = ServerConfig.objects.conf("default_home")
default_home = ObjectDB.objects.get_id(default_home_id)
# set a default description
new_character.db.desc = "This is a Player."
typeclass = settings.BASE_CHARACTER_TYPECLASS
permissions = settings.PERMISSION_PLAYER_DEFAULT
new_character.db.FIRST_LOGIN = True
new_player = new_character.player
new_player.db.FIRST_LOGIN = True
# join the new player to the public channel
pchanneldef = settings.CHANNEL_PUBLIC
if pchanneldef:
pchannel = Channel.objects.get_channel(pchanneldef[0])
if not pchannel.connect_to(new_player):
string = "New player '%s' could not connect to public channel!" % new_player.key
logger.log_errmsg(string)
new_character = create.create_player(playername, email, password,
permissions=permissions,
location=default_home,
typeclass=typeclass,
home=default_home)
new_player = new_character.player
# character safety features
new_character.locks.delete("get")
new_character.locks.add("get:perm(Wizards)")
# allow the character itself and the player to puppet this character.
new_character.locks.add("puppet:id(%i) or pid(%i) or perm(Immortals) or pperm(Immortals)" %
(new_character.id, new_player.id))
string = "A new account '%s' was created with the email address %s. Welcome!"
string += "\n\nYou can now log with the command 'connect %s <your password>'."
session.msg(string % (playername, email, email))
except Exception:
# we have to handle traceback ourselves at this point, if
# we don't, errors will give no feedback.
string = "%s\nThis is a bug. Please e-mail an admin if the problem persists."
session.msg(string % (traceback.format_exc()))
logger.log_errmsg(traceback.format_exc())
# set a default description
new_character.db.desc = "This is a Player."
new_character.db.FIRST_LOGIN = True
new_player = new_character.player
new_player.db.FIRST_LOGIN = True
# join the new player to the public channel
pchanneldef = settings.CHANNEL_PUBLIC
if pchanneldef:
pchannel = Channel.objects.get_channel(pchanneldef[0])
if not pchannel.connect_to(new_player):
string = "New player '%s' could not connect to public channel!" % new_player.key
logger.log_errmsg(string)
string = "A new account '%s' was created with the email address %s. Welcome!"
string += "\n\nYou can now log with the command 'connect %s <your password>'."
session.msg(string % (playername, email, email))
except Exception:
# We are in the middle between logged in and -not, so we have to handle tracebacks
# ourselves at this point. If we don't, we won't see any errors at all.
string = "%s\nThis is a bug. Please e-mail an admin if the problem persists."
session.msg(string % (traceback.format_exc()))
logger.log_errmsg(traceback.format_exc())
class CmdQuit(MuxCommand):
"""