Merge.
This commit is contained in:
commit
b50266623e
3 changed files with 127 additions and 11 deletions
|
|
@ -176,6 +176,9 @@ class ObjectDB(TypedObject):
|
||||||
# If this is a character object, the player is connected here.
|
# If this is a character object, the player is connected here.
|
||||||
db_player = models.ForeignKey("players.PlayerDB", blank=True, null=True, verbose_name='player',
|
db_player = models.ForeignKey("players.PlayerDB", blank=True, null=True, verbose_name='player',
|
||||||
help_text='a Player connected to this object, if any.')
|
help_text='a Player connected to this object, if any.')
|
||||||
|
# the session id associated with this player, if any
|
||||||
|
db_sessid = models.IntegerField(null=True, verbose_name="session id",
|
||||||
|
help_text="unique session id of connected Player, if any."
|
||||||
# The location in the game world. Since this one is likely
|
# The location in the game world. Since this one is likely
|
||||||
# to change often, we set this with the 'location' property
|
# to change often, we set this with the 'location' property
|
||||||
# to transparently handle Typeclassing.
|
# to transparently handle Typeclassing.
|
||||||
|
|
@ -191,7 +194,6 @@ class ObjectDB(TypedObject):
|
||||||
# database storage of persistant cmdsets.
|
# database storage of persistant cmdsets.
|
||||||
db_cmdset_storage = models.CharField('cmdset', max_length=255, null=True, blank=True,
|
db_cmdset_storage = models.CharField('cmdset', max_length=255, null=True, blank=True,
|
||||||
help_text="optional python path to a cmdset class.")
|
help_text="optional python path to a cmdset class.")
|
||||||
|
|
||||||
# Database manager
|
# Database manager
|
||||||
objects = ObjectManager()
|
objects = ObjectManager()
|
||||||
|
|
||||||
|
|
@ -260,6 +262,30 @@ class ObjectDB(TypedObject):
|
||||||
del_field_cache(self, "player")
|
del_field_cache(self, "player")
|
||||||
player = property(__player_get, __player_set, __player_del)
|
player = property(__player_get, __player_set, __player_del)
|
||||||
|
|
||||||
|
# sessid property (wraps db_sessid)
|
||||||
|
#@property
|
||||||
|
def __sessid_get(self):
|
||||||
|
"""
|
||||||
|
Getter. Allows for value = self.sessid. Since sessid
|
||||||
|
is directly related to self.player, we cannot have
|
||||||
|
a sessid without a player being connected (but the
|
||||||
|
opposite could be true).
|
||||||
|
"""
|
||||||
|
if not get_field_cache(self, "player"):
|
||||||
|
del_field_cache(self, "sessid")
|
||||||
|
return get_field_cache(self, "sessid")
|
||||||
|
|
||||||
|
#@player.setter
|
||||||
|
def __sessid_set(self, player):
|
||||||
|
"Setter. Allows for self.player = value"
|
||||||
|
if inherits_from(player, TypeClass):
|
||||||
|
player = player.dbobj
|
||||||
|
set_field_cache(self, "player", player)
|
||||||
|
#@player.deleter
|
||||||
|
def __player_del(self):
|
||||||
|
"Deleter. Allows for del self.player"
|
||||||
|
del_field_cache(self, "player")
|
||||||
|
player = property(__player_get, __player_set, __player_del)
|
||||||
# location property (wraps db_location)
|
# location property (wraps db_location)
|
||||||
#@property
|
#@property
|
||||||
def __location_get(self):
|
def __location_get(self):
|
||||||
|
|
|
||||||
|
|
@ -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,111 @@ 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, sessid):
|
||||||
|
"""
|
||||||
|
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
|
||||||
|
session - session sending this data
|
||||||
|
"""
|
||||||
|
character = _GA(self, "get_character")(sessid)
|
||||||
|
if character:
|
||||||
|
# execute command on character
|
||||||
|
_GA(character, "execute_cmd")(ingoing_string)
|
||||||
|
else:
|
||||||
|
# a non-character session; this goes to player directly
|
||||||
|
_GA(self, "execute_cmd")(ingoing_string)
|
||||||
|
|
||||||
|
def connect_session(self, sessid):
|
||||||
|
"""
|
||||||
|
Connect session to this player to a session through
|
||||||
|
its session id.
|
||||||
|
"""
|
||||||
|
|
||||||
|
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. Note that if the
|
||||||
|
game was fully restarted (including the Portal), this must be
|
||||||
|
used, since sessids will have changed as players reconnect.
|
||||||
|
"""
|
||||||
|
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 disconnect_all_characters(self):
|
||||||
|
for char in self.db_objs.all():
|
||||||
|
|
||||||
def swap_character(self, new_character, delete_old_character=False):
|
def swap_character(self, new_character, delete_old_character=False):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -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):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue