First steps towards a full account system (multiple Character with one Player); added the Player-level methods.

This commit is contained in:
Griatch 2013-01-26 21:20:31 +01:00
parent 91281e6bb8
commit 261454ff0a
2 changed files with 90 additions and 10 deletions

View file

@ -163,6 +163,7 @@ class PlayerDB(TypedObject):
# Use the property 'obj' to access. # Use the property 'obj' to access.
db_obj = models.ForeignKey("objects.ObjectDB", null=True, blank=True, db_obj = models.ForeignKey("objects.ObjectDB", null=True, blank=True,
verbose_name="character", help_text='In-game object.') verbose_name="character", help_text='In-game object.')
db_objs = models.ManyToManyField("objects.ObjectDB", null=True, verbose_name="characters", help_text="In-game objects.")
# store a connected flag here too, not just in sessionhandler. # store a connected flag here too, not just in sessionhandler.
# This makes it easier to track from various out-of-process locations # This makes it easier to track from various out-of-process locations
db_is_connected = models.BooleanField(default=False, verbose_name="is_connected", help_text="If player is connected to game or not") db_is_connected = models.BooleanField(default=False, verbose_name="is_connected", help_text="If player is connected to game or not")
@ -224,7 +225,7 @@ class PlayerDB(TypedObject):
#@property #@property
def character_get(self): def character_get(self):
"Getter. Allows for value = self.character" "Getter. Allows for value = self.character"
return get_field_cache(self, "obj") return get_field_cache(self, "obj)
#@character.setter #@character.setter
def character_set(self, character): def character_set(self, character):
"Setter. Allows for self.character = value" "Setter. Allows for self.character = value"
@ -236,6 +237,7 @@ class PlayerDB(TypedObject):
"Deleter. Allows for del self.character" "Deleter. Allows for del self.character"
del_field_cache(self, "obj") del_field_cache(self, "obj")
character = property(character_get, character_set, character_del) character = property(character_get, character_set, character_del)
# cmdset_storage property # cmdset_storage property
# This seems very sensitive to caching, so leaving it be for now /Griatch # This seems very sensitive to caching, so leaving it be for now /Griatch
#@property #@property
@ -358,26 +360,101 @@ class PlayerDB(TypedObject):
# PlayerDB class access methods # PlayerDB class access methods
# #
def msg(self, outgoing_string, from_obj=None, data=None): def msg(self, outgoing_string, from_obj=None, data=None, sessid=None):
""" """
Evennia -> User Evennia -> User
This is the main route for sending data back to the user from the server. This is the main route for sending data back to the user from the server.
""" """
if from_obj: if from_obj:
# call hook
try: try:
_GA(from_obj, "at_msg_send")(outgoing_string, to_obj=self, data=data) _GA(from_obj, "at_msg_send")(outgoing_string, to_obj=self, data=data)
except Exception: except Exception:
pass pass
if (_GA(self, "character") and not
_GA(self, "character").at_msg_receive(outgoing_string, from_obj=from_obj, data=data)):
# the at_msg_receive() hook may block receiving of certain messages
return
outgoing_string = utils.to_str(outgoing_string, force_string=True) outgoing_string = utils.to_str(outgoing_string, force_string=True)
for session in _GA(self, 'sessions'): session = None
if sessid:
session = _GA(self, "get_session")(sessid)
if session:
char = _GA(self, "get_character")(sessid)
if char and not char.at_msg_receive(outgoing_string, from_obj=from_obj, data=data)):
# if hook returns false, cancel send
return
session.msg(outgoing_string, data) session.msg(outgoing_string, data)
else:
# if no session was specified, send to them all
for sess in _GA(self, 'get_sessions'):
sess.msg(outgoing_string, data)
def inmsg(self, ingoing_string, data, session):
"""
This is the reverse of msg - used by sessions to relay
messages/data back into the game. It is normally not called
from inside game code but only by the serversessions directly.
ingoing_string - text string (i.e. command string)
data - dictionary of optional data
sessid - session sending this data
"""
character = _GA(self, "get_character")(session.sessid)
if character:
# execute command on character
character.execute_cmd(ingoing_string)
else:
# a non-character session; this goes to player directly
self.execute_cmd(ingoing_message)
def get_sessions(self, sessid=None):
"""
Return session with given sessid connected to this player. If sessid is
not given, return all connected sessions.
Note that this method will always return a list, even if it only has one
(or zero) element(s).
"""
return SESSIONS.get_session_from_player(self, sessid=sessid)
def get_character(self, sessid):
"""
Get the character connected through this sessid, if any
"""
if not sessid: # sessid is always > 0
return None
try:
char = get_prop_cache(self, "_characters").get(sessid)
except AttributeError:
set_prop_cache(self, "_characters", {})
char = None
if not char:
char = self.db_objs.filter(player=self, sessid=sessid)
if char.count():
chars_cache = get_prop_cache(self, "_characters")
chars_cache[sessid] = char[0]
set_prop_cache(self, "_characters")
return char
def connect_character(self, character, sessid):
"""
Use the Player to connect a Character to a session. Note
that we don't do any access checks at this point.
"""
character = character.dbobj
character.player = self
character.sessid = sessid
self.db_objs.add(character)
self.save()
def disconnect_character(self, character):
"""
Disconnect a character from this player.
"""
character = character.dbobj
if self.db_objs.filter(id=_GA(character,"id")):
self.db_objs.remove(character)
character.player = None
character.sessid = None
self.save()
def swap_character(self, new_character, delete_old_character=False): def swap_character(self, new_character, delete_old_character=False):
""" """

View file

@ -228,12 +228,15 @@ class ServerSessionHandler(SessionHandler):
""" """
return len(set(session.uid for session in self.sessions.values() if session.logged_in)) return len(set(session.uid for session in self.sessions.values() if session.logged_in))
def sessions_from_player(self, player): def sessions_from_player(self, player, sessid=None):
""" """
Given a player, return any matching sessions. Given a player, return any matching sessions.
""" """
uid = player.uid uid = player.uid
return [session for session in self.sessions.values() if session.logged_in and session.uid == uid] if sessid:
return [session for session in self.sessions.values() if session.logged_in and session.sessid == sessid and session.uid == uid]
else
return [session for session in self.sessions.values() if session.logged_in and session.uid == uid]
def sessions_from_character(self, character): def sessions_from_character(self, character):
""" """