Reworked the puppet-checking code into the puppet_object method.

This commit is contained in:
Griatch 2015-02-22 19:09:39 +01:00
parent 0fcf9501d2
commit 27d2b1ac42
2 changed files with 65 additions and 42 deletions

View file

@ -995,7 +995,7 @@ class DefaultObject(ObjectDB):
Called just after puppeting has been completed and Called just after puppeting has been completed and
all Player<->Object links have been established. all Player<->Object links have been established.
""" """
pass self.player.db._last_puppet = self
def at_pre_unpuppet(self): def at_pre_unpuppet(self):
""" """

View file

@ -164,8 +164,7 @@ class DefaultPlayer(PlayerDB):
def puppet_object(self, sessid, obj, normal_mode=True): def puppet_object(self, sessid, obj, normal_mode=True):
""" """
Use the given session to control (puppet) the given object (usually Use the given session to control (puppet) the given object (usually
a Character type). Note that we make no puppet checks here, that must a Character type).
have been done before calling this method.
sessid - session id of session to connect sessid - session id of session to connect
obj - the object to connect to obj - the object to connect to
@ -174,16 +173,41 @@ class DefaultPlayer(PlayerDB):
returns True if successful, False otherwise returns True if successful, False otherwise
""" """
# safety checks
if not obj:
return
session = self.get_session(sessid) session = self.get_session(sessid)
if not session: if not session:
return False return False
if self.get_puppet(sessid) == obj:
# already puppeting this object
return
if obj.player:
# object already puppeted
if obj.player == self:
if obj.sessid.count():
# we may take over another of our sessions
self.unpuppet_object(obj.sessid.get())
# output messages to the affected sessions
if _MULTISESSION_MODE in (1, 3):
txt1 = "{c%s{n{G is now shared from another of your sessions.{n"
txt2 = "Sharing {c%s{n with another of your sessions."
else:
txt1 = "{c%s{n{R is now acted from another of your sessions.{n"
txt2 = "Taking over {c%s{n from another of your sessions."
self.msg(txt1 % obj.name, sessid=obj.sessid.get())
self.msg(txt2 % obj.name, sessid=sessid)
elif obj.player.is_connected:
# controlled by another player
return
if not obj.access(self, 'puppet'):
# no access
return
# do the puppeting
if normal_mode and session.puppet: if normal_mode and session.puppet:
# cleanly unpuppet eventual previous object puppeted by this session # cleanly unpuppet eventual previous object puppeted by this session
self.unpuppet_object(sessid) self.unpuppet_object(sessid)
if obj.player and obj.player.is_connected and obj.player != self:
# we don't allow to puppet an object already controlled by an active
# player. To kick a player, call unpuppet_object on them explicitly.
return
# if we get to this point the character is ready to puppet or it # if we get to this point the character is ready to puppet or it
# was left with a lingering player/sessid reference from an unclean # was left with a lingering player/sessid reference from an unclean
# server kill or similar # server kill or similar
@ -504,7 +528,6 @@ class DefaultPlayer(PlayerDB):
lockstring = "attrread:perm(Admins);attredit:perm(Admins);attrcreate:perm(Admins)" lockstring = "attrread:perm(Admins);attredit:perm(Admins);attrcreate:perm(Admins)"
self.attributes.add("_playable_characters", [], lockstring=lockstring) self.attributes.add("_playable_characters", [], lockstring=lockstring)
# TODO - handle this in __init__ instead.
def at_init(self): def at_init(self):
""" """
This is always called whenever this object is initiated -- This is always called whenever this object is initiated --
@ -596,55 +619,55 @@ class DefaultPlayer(PlayerDB):
else: else:
logger.log_infomsg("[%s]: %s" % (now, message)) logger.log_infomsg("[%s]: %s" % (now, message))
def _go_ic_at_login(self, sessid=None): #def _go_ic_at_login(self, sessid=None):
new_character = self.db._last_puppet # new_character = self.db._last_puppet
# permission checks # # permission checks
if self.get_puppet(sessid) == new_character: # if self.get_puppet(sessid) == new_character:
return # return
if new_character.player: # if new_character.player:
# may not puppet an already puppeted character # # may not puppet an already puppeted character
if new_character.sessid.count() and new_character.player == self: # if new_character.sessid.count() and new_character.player == self:
# as a safeguard we allow "taking over" chars from your own sessions. # # as a safeguard we allow "taking over" chars from your own sessions.
if MULTISESSION_MODE in (1, 3): # if _MULTISESSION_MODE in (1, 3):
txt1 = "{c%s{n{G is now shared from another of your sessions.{n" # txt1 = "{c%s{n{G is now shared from another of your sessions.{n"
txt2 = "Sharing {c%s{n with another of your sessions." # txt2 = "Sharing {c%s{n with another of your sessions."
else: # else:
txt1 = "{c%s{n{R is now acted from another of your sessions.{n" # txt1 = "{c%s{n{R is now acted from another of your sessions.{n"
txt2 = "Taking over {c%s{n from another of your sessions." # txt2 = "Taking over {c%s{n from another of your sessions."
self.unpuppet_object(new_character.sessid.get()) # self.unpuppet_object(new_character.sessid.get())
self.msg(txt1 % new_character.name, sessid=new_character.sessid.get()) # self.msg(txt1 % new_character.name, sessid=new_character.sessid.get())
self.msg(txt2 % new_character.name, sessid=sessid) # self.msg(txt2 % new_character.name, sessid=sessid)
elif new_character.player != self and new_character.player.is_connected: # elif new_character.player != self and new_character.player.is_connected:
self.msg("{c%s{r is already acted by another player{n." % new_character.name, sessid=sessid) # self.msg("{c%s{r is already acted by another player{n." % new_character.name, sessid=sessid)
return # return
if not new_character.access(self, 'puppet'): # if not new_character.access(self, 'puppet'):
# main acccess check # # main acccess check
self.msg("{rYou may not become {C%s{n." % new_character.name, sessid=sessid) # self.msg("{rYou may not become {C%s{n." % new_character.name, sessid=sessid)
return # return
if self.puppet_object(sessid, new_character): # if self.puppet_object(sessid, new_character):
self.db._last_puppet = new_character # self.db._last_puppet = new_character
else: # else:
self.msg("{rYou cannot become {C%s{n." % new_character.name, sessid=sessid) # self.msg("{rYou cannot become {C%s{n." % new_character.name, sessid=sessid)
def at_post_login(self, sessid=None): def at_post_login(self, sessid=None):
""" """
Called at the end of the login process, just before letting Called at the end of the login process, just before letting
them loose. This is called before an eventual Character's the player loose. This is called before an eventual Character's
at_post_login hook. at_post_login hook.
""" """
self._send_to_connect_channel("{G%s connected{n" % self.key) self._send_to_connect_channel("{G%s connected{n" % self.key)
if _MULTISESSION_MODE == 0: if _MULTISESSION_MODE == 0:
# in this mode we should have only one character available. We # in this mode we should have only one character available. We
# try to auto-connect to it by calling _go_ic_at_login() # try to auto-connect to our last conneted object, if any
# (this relies on player.db._last_puppet being set). self.puppet_object(sessid, self.db._last_puppet)
self._go_ic_at_login(sessid=sessid)
elif _MULTISESSION_MODE == 1: elif _MULTISESSION_MODE == 1:
# in this mode the first session to connect acts like mode 0, # in this mode the first session to connect acts like mode 0,
# the following sessions "share" the same view and should # the following sessions "share" the same view and should
# not perform any actions # not perform any actions
if not self.get_all_puppets(): if not self.get_all_puppets():
self._go_ic_at_login(sessid=sessid) # we are first. Connect.
self.puppet_object(sessid, self.db._last_puppet)
elif _MULTISESSION_MODE in (2, 3): elif _MULTISESSION_MODE in (2, 3):
# In this mode we by default end up at a character selection # In this mode we by default end up at a character selection
# screen. We execute look on the player. # screen. We execute look on the player.