Further fixes to the system, still some issues remaining.
This commit is contained in:
parent
9eb1903f02
commit
20a57d4167
7 changed files with 119 additions and 69 deletions
|
|
@ -978,7 +978,7 @@ class CmdIC(MuxCommandOOC):
|
||||||
return
|
return
|
||||||
if caller.connect_character(new_character, sessid=sessid):
|
if caller.connect_character(new_character, sessid=sessid):
|
||||||
self.msg("\n{gYou become {c%s{n.\n" % new_character.name)
|
self.msg("\n{gYou become {c%s{n.\n" % new_character.name)
|
||||||
caller.db.last_puppet = old_character
|
caller.db._last_puppet = old_character
|
||||||
if not new_character.location:
|
if not new_character.location:
|
||||||
# this might be due to being hidden away at logout; check
|
# this might be due to being hidden away at logout; check
|
||||||
loc = new_character.db.prelogout_location
|
loc = new_character.db.prelogout_location
|
||||||
|
|
|
||||||
|
|
@ -106,11 +106,11 @@ class Object(TypeClass):
|
||||||
inside a deleted object are automatically moved to their <home>, they don't need to be removed here.
|
inside a deleted object are automatically moved to their <home>, they don't need to be removed here.
|
||||||
|
|
||||||
at_init() - called whenever typeclass is cached from memory, at least once every server restart/reload
|
at_init() - called whenever typeclass is cached from memory, at least once every server restart/reload
|
||||||
at_cmdset_get() - this is called just before the command handler requests a cmdset from this object
|
at_cmdset_get() - this is called just before the command handler requests a cmdset from this objecth
|
||||||
at_first_login() - (player-controlled objects only) called once, the very first time user logs in.
|
at_pre_puppet(player)- (player-controlled objects only) called just before puppeting
|
||||||
at_pre_login() - (player-controlled objects only) called every time the user connects, after they have identified, before other setup
|
at_post_puppet() - (player-controlled objects only) called just after completing connection player<->object
|
||||||
at_post_login() - (player-controlled objects only) called at the end of login, just before setting the player loose in the world.
|
at_pre_unpuppet() - (player-controlled objects only) called just before un-puppeting
|
||||||
at_disconnect() - (player-controlled objects only) called just before the user disconnects (or goes linkless)
|
at_post_unpuppet(player) - (player-controlled objects only) called just after disconnecting player<->object link
|
||||||
at_server_reload() - called before server is reloaded
|
at_server_reload() - called before server is reloaded
|
||||||
at_server_shutdown() - called just before server is fully shut down
|
at_server_shutdown() - called just before server is fully shut down
|
||||||
|
|
||||||
|
|
@ -458,33 +458,66 @@ class Object(TypeClass):
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def at_first_login(self):
|
def at_pre_puppet(self, player):
|
||||||
"""
|
"""
|
||||||
Only called once, the very first
|
Called just before a Player connects to this object
|
||||||
time the user logs in.
|
to puppet it.
|
||||||
"""
|
|
||||||
pass
|
player - connecting player object
|
||||||
def at_pre_login(self):
|
|
||||||
"""
|
|
||||||
Called every time the user logs in,
|
|
||||||
before they are actually logged in.
|
|
||||||
"""
|
|
||||||
pass
|
|
||||||
def at_post_login(self):
|
|
||||||
"""
|
|
||||||
Called at the end of the login
|
|
||||||
process, just before letting
|
|
||||||
them loose.
|
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def at_disconnect(self):
|
def at_post_puppet(self):
|
||||||
"""
|
"""
|
||||||
Called just before user
|
Called just after puppeting has been completed and
|
||||||
is disconnected.
|
all Player<->Object links have been established.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def at_pre_unpuppet(self):
|
||||||
|
"""
|
||||||
|
Called just before beginning to un-connect a puppeting
|
||||||
|
from this Player.
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
def at_post_unpuppet(self, player):
|
||||||
|
"""
|
||||||
|
Called just after the Player successfully disconnected
|
||||||
|
from this object, severing all connections.
|
||||||
|
|
||||||
|
player - the player object that just disconnected from
|
||||||
|
this object.
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
#def at_first_login(self):
|
||||||
|
# """
|
||||||
|
# Only called once, the very first
|
||||||
|
# time the user logs in.
|
||||||
|
# """
|
||||||
|
# pass
|
||||||
|
#def at_pre_login(self):
|
||||||
|
# """
|
||||||
|
# Called every time the user logs in,
|
||||||
|
# before they are actually logged in.
|
||||||
|
# """
|
||||||
|
# pass
|
||||||
|
#def at_post_login(self):
|
||||||
|
# """
|
||||||
|
# Called at the end of the login
|
||||||
|
# process, just before letting
|
||||||
|
# them loose.
|
||||||
|
# """
|
||||||
|
# pass
|
||||||
|
|
||||||
|
#def at_disconnect(self):
|
||||||
|
# """
|
||||||
|
# Called just before user
|
||||||
|
# is disconnected.
|
||||||
|
# """
|
||||||
|
# pass
|
||||||
|
|
||||||
def at_server_reload(self):
|
def at_server_reload(self):
|
||||||
"""
|
"""
|
||||||
This hook is called whenever the server is shutting down for restart/reboot.
|
This hook is called whenever the server is shutting down for restart/reboot.
|
||||||
|
|
@ -780,21 +813,12 @@ class Character(Object):
|
||||||
"Default is to look around after a move."
|
"Default is to look around after a move."
|
||||||
self.execute_cmd('look')
|
self.execute_cmd('look')
|
||||||
|
|
||||||
def at_disconnect(self):
|
def at_pre_puppet(self, player):
|
||||||
"""
|
"""
|
||||||
We stove away the character when logging off, otherwise the character object will
|
This recovers the character again after having been "stoved away" at the unpuppet
|
||||||
remain in the room also after the player logged off ("headless", so to say).
|
|
||||||
"""
|
"""
|
||||||
if self.location: # have to check, in case of multiple connections closing
|
print "object at_pre_puppet", self, player
|
||||||
self.location.msg_contents("%s has left the game." % self.name, exclude=[self])
|
|
||||||
self.db.prelogout_location = self.location
|
|
||||||
self.location = None
|
|
||||||
|
|
||||||
def at_post_login(self):
|
|
||||||
"""
|
|
||||||
This recovers the character again after having been "stoved away" at disconnect.
|
|
||||||
"""
|
|
||||||
print "char:at_post_login", self
|
|
||||||
if self.db.prelogout_location:
|
if self.db.prelogout_location:
|
||||||
# try to recover
|
# try to recover
|
||||||
self.location = self.db.prelogout_location
|
self.location = self.db.prelogout_location
|
||||||
|
|
@ -806,8 +830,24 @@ class Character(Object):
|
||||||
|
|
||||||
self.location.msg_contents("%s has entered the game." % self.name, exclude=[self])
|
self.location.msg_contents("%s has entered the game." % self.name, exclude=[self])
|
||||||
self.location.at_object_receive(self, self.location)
|
self.location.at_object_receive(self, self.location)
|
||||||
|
|
||||||
|
def at_post_puppet(self):
|
||||||
|
"Once puppeting is complete, make sure to view the location."
|
||||||
# call look
|
# call look
|
||||||
|
print "object at_post_puppet", self
|
||||||
self.execute_cmd("look")
|
self.execute_cmd("look")
|
||||||
|
|
||||||
|
def at_post_unpuppet(self, player):
|
||||||
|
"""
|
||||||
|
We stove away the character when the player goes ooc/logs off, otherwise the character object will
|
||||||
|
remain in the room also after the player logged off ("headless", so to say).
|
||||||
|
"""
|
||||||
|
print "at_post_unpuppet", player
|
||||||
|
if self.location: # have to check, in case of multiple connections closing
|
||||||
|
self.location.msg_contents("%s has left the game." % self.name, exclude=[self])
|
||||||
|
self.db.prelogout_location = self.location
|
||||||
|
self.location = None
|
||||||
|
|
||||||
#
|
#
|
||||||
# Base Room object
|
# Base Room object
|
||||||
#
|
#
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ from django.utils.encoding import smart_str
|
||||||
from src.server.caches import get_field_cache, set_field_cache, del_field_cache
|
from src.server.caches import get_field_cache, set_field_cache, del_field_cache
|
||||||
from src.server.caches import get_prop_cache, set_prop_cache, del_prop_cache
|
from src.server.caches import get_prop_cache, set_prop_cache, del_prop_cache
|
||||||
from src.players import manager
|
from src.players import manager
|
||||||
|
from src.scripts.models import ScriptDB
|
||||||
from src.typeclasses.models import Attribute, TypedObject, TypeNick, TypeNickHandler
|
from src.typeclasses.models import Attribute, TypedObject, TypeNick, TypeNickHandler
|
||||||
from src.typeclasses.typeclass import TypeClass
|
from src.typeclasses.typeclass import TypeClass
|
||||||
from src.commands.cmdsethandler import CmdSetHandler
|
from src.commands.cmdsethandler import CmdSetHandler
|
||||||
|
|
@ -364,8 +365,6 @@ class PlayerDB(TypedObject):
|
||||||
data - dictionary of optional data
|
data - dictionary of optional data
|
||||||
sessid - session sending this data
|
sessid - session sending this data
|
||||||
"""
|
"""
|
||||||
if _MULTISESSION_MODE < 2:
|
|
||||||
sessid = None
|
|
||||||
character = _GA(self, "get_character")(sessid=sessid)
|
character = _GA(self, "get_character")(sessid=sessid)
|
||||||
if character:
|
if character:
|
||||||
# execute command on character
|
# execute command on character
|
||||||
|
|
@ -406,15 +405,18 @@ class PlayerDB(TypedObject):
|
||||||
"""
|
"""
|
||||||
sessions = self.get_session_from_sessid(sessid)
|
sessions = self.get_session_from_sessid(sessid)
|
||||||
for session in make_iter(sessions):
|
for session in make_iter(sessions):
|
||||||
|
# this will also trigger disconnection of character(s)
|
||||||
session.sessionhandler.disconnect(session)
|
session.sessionhandler.disconnect(session)
|
||||||
|
|
||||||
def connect_session_to_character(self, sessid, character, force=False):
|
def connect_session_to_character(self, sessid, character, force=False, call_hooks=True):
|
||||||
"""
|
"""
|
||||||
Connect the given session to a character through this player.
|
Connect the given session to a character through this player.
|
||||||
Note that this assumes the character has previously been
|
Note that this assumes the character has previously been
|
||||||
linked to the player using self.connect_character().
|
linked to the player using self.connect_character().
|
||||||
|
|
||||||
force - drop existing connection to other character
|
force - drop existing connection to other character
|
||||||
|
call_hooks - call puppet/unpuppet hooks. This is not wanted e.g. if
|
||||||
|
server is reloading
|
||||||
|
|
||||||
Returns True if connection was successful, False otherwise
|
Returns True if connection was successful, False otherwise
|
||||||
"""
|
"""
|
||||||
|
|
@ -425,24 +427,21 @@ class PlayerDB(TypedObject):
|
||||||
_GA(self, "disconnect_session_from_character")(sessid)
|
_GA(self, "disconnect_session_from_character")(sessid)
|
||||||
else:
|
else:
|
||||||
return
|
return
|
||||||
|
# pre-puppet hook
|
||||||
|
if call_hooks:
|
||||||
|
# if e.g. server reloads we don't want to call any hooks anew
|
||||||
|
_GA(character.typeclass, "at_pre_puppet")(self.typeclass)
|
||||||
# do the connection
|
# do the connection
|
||||||
character.sessid = sessid
|
character.sessid = sessid
|
||||||
# update cache
|
# update cache
|
||||||
cache = get_prop_cache(self, "_characters") or {}
|
cache = get_prop_cache(self, "_characters") or {}
|
||||||
cache[sessid] = character
|
cache[sessid] = character
|
||||||
set_prop_cache(self, "_characters", cache)
|
set_prop_cache(self, "_characters", cache)
|
||||||
# call hooks
|
# start/validate (persistent) scripts on this object
|
||||||
character.at_init()
|
ScriptDB.objects.validate(obj=character)
|
||||||
if character:
|
# post-puppet hook
|
||||||
# start (persistent) scripts on this object
|
if call_hooks:
|
||||||
#ScriptDB.objects.validate(obj=character)
|
_GA(character.typeclass, "at_post_puppet")()
|
||||||
pass
|
|
||||||
if character.db._first_login:
|
|
||||||
character.at_first_login()
|
|
||||||
del character.db._first_login
|
|
||||||
character.at_pre_login()
|
|
||||||
print "player: calling at_post_login on char"
|
|
||||||
character.at_post_login()
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def disconnect_session_from_character(self, sessid):
|
def disconnect_session_from_character(self, sessid):
|
||||||
|
|
@ -451,21 +450,26 @@ class PlayerDB(TypedObject):
|
||||||
connection to the Player)
|
connection to the Player)
|
||||||
returns the newly disconnected character, if it existed
|
returns the newly disconnected character, if it existed
|
||||||
"""
|
"""
|
||||||
|
print "player disconnect_session_from_character", sessid
|
||||||
if not sessid:
|
if not sessid:
|
||||||
return
|
return
|
||||||
char = _GA(self, "get_character")(sessid=sessid, return_dbobj=True)
|
char = _GA(self, "get_character")(sessid=sessid, return_dbobj=True)
|
||||||
|
print char
|
||||||
if char:
|
if char:
|
||||||
# call hook before disconnecting
|
# call hook before disconnecting
|
||||||
_GA(char.typeclass, "at_disconnect")()
|
_GA(char.typeclass, "at_pre_unpuppet")()
|
||||||
del char.sessid
|
del char.sessid
|
||||||
# update cache
|
# update cache
|
||||||
cache = get_prop_cache(self, "_characters") or {}
|
cache = get_prop_cache(self, "_characters") or {}
|
||||||
if sessid in cache:
|
if sessid in cache:
|
||||||
del cache[sessid]
|
del cache[sessid]
|
||||||
set_prop_cache(self, "_characters", cache)
|
set_prop_cache(self, "_characters", cache)
|
||||||
|
# call post-unpuppet hook
|
||||||
|
_GA(char.typeclass, "at_post_unpuppet")(self.typeclass)
|
||||||
|
print "... leaving player disconnect_session_from_character", sessid
|
||||||
return char
|
return char
|
||||||
|
|
||||||
def reconnect_session_to_character(self, sessid):
|
def server_reconnect_session_to_character(self, sessid):
|
||||||
"""
|
"""
|
||||||
Auto-re-connect a session to a character. This is called by the sessionhandler
|
Auto-re-connect a session to a character. This is called by the sessionhandler
|
||||||
during a server reload. It goes through the characters stored in this player's
|
during a server reload. It goes through the characters stored in this player's
|
||||||
|
|
@ -478,19 +482,20 @@ class PlayerDB(TypedObject):
|
||||||
char = _GA(self, "get_character")(sessid=sessid, return_dbobj=True)
|
char = _GA(self, "get_character")(sessid=sessid, return_dbobj=True)
|
||||||
if not char:
|
if not char:
|
||||||
return
|
return
|
||||||
_GA(self, "connect_session_to_character")(sessid, char, force=True)
|
_GA(self, "connect_session_to_character")(sessid, char, force=True, call_hooks=False)
|
||||||
|
|
||||||
|
|
||||||
def get_character(self, sessid=None, character=None, return_dbobj=False):
|
def get_character(self, sessid=None, character=None, return_dbobj=False):
|
||||||
"""
|
"""
|
||||||
Get the character connected to this player and sessid
|
Get the character connected to this player and sessid. This is the main
|
||||||
|
method for retrieving the character from the player's end.
|
||||||
|
|
||||||
sessid - return character connected to this sessid,
|
sessid - return character connected to this sessid,
|
||||||
character - return character if connected to this player, else None.
|
character - return character if connected to this player, else None.
|
||||||
|
|
||||||
Combining both keywords will check the entire connection - if the
|
Combining both keywords will check the entire connection - if the
|
||||||
given session is currently connected to the given char. If no
|
given session is currently connected to the given char. If no
|
||||||
keywords are given, returns all connected characters.
|
keywords are given, returns all connected characters as a list.
|
||||||
"""
|
"""
|
||||||
cache = get_prop_cache(self, "_characters") or {}
|
cache = get_prop_cache(self, "_characters") or {}
|
||||||
if sessid:
|
if sessid:
|
||||||
|
|
|
||||||
|
|
@ -296,9 +296,10 @@ class Player(TypeClass):
|
||||||
|
|
||||||
def at_pre_login(self):
|
def at_pre_login(self):
|
||||||
"""
|
"""
|
||||||
Called every time the user logs in,
|
Called every time the user logs in, just before the actual
|
||||||
before they are actually logged in.
|
login-state is set.
|
||||||
"""
|
"""
|
||||||
|
print "player at_pre_login", self
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def _send_to_connect_channel(self, message):
|
def _send_to_connect_channel(self, message):
|
||||||
|
|
@ -322,6 +323,7 @@ class Player(TypeClass):
|
||||||
them loose. This is called before an eventual Character's
|
them loose. This is called before an eventual Character's
|
||||||
at_post_login hook.
|
at_post_login hook.
|
||||||
"""
|
"""
|
||||||
|
print "player at_post_login", self
|
||||||
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 == 2 or not self.get_all_characters():
|
if _MULTISESSION_MODE == 2 or not self.get_all_characters():
|
||||||
|
|
@ -331,10 +333,11 @@ class Player(TypeClass):
|
||||||
|
|
||||||
def at_disconnect(self, reason=None):
|
def at_disconnect(self, reason=None):
|
||||||
"""
|
"""
|
||||||
Called just before user
|
Called just before user is disconnected.
|
||||||
is disconnected.
|
|
||||||
"""
|
"""
|
||||||
self._send_to_connect_channel("{R%s disconnected{n" % self.key)
|
print "player at_disconnect", self
|
||||||
|
reason = reason and "(%s)" % reason or ""
|
||||||
|
self._send_to_connect_channel("{R%s disconnected %s{n" % (self.key, reason))
|
||||||
|
|
||||||
def at_message_receive(self, message, from_obj=None):
|
def at_message_receive(self, message, from_obj=None):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ def create_objects():
|
||||||
|
|
||||||
god_character.save()
|
god_character.save()
|
||||||
god_character.set_attribute("_superuser_character", True)
|
god_character.set_attribute("_superuser_character", True)
|
||||||
gor_character.set_attribute("_first_login", True)
|
god_character.set_attribute("_first_login", True)
|
||||||
|
|
||||||
# Limbo is the default "nowhere" starting room
|
# Limbo is the default "nowhere" starting room
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -272,7 +272,7 @@ class Evennia(object):
|
||||||
yield [(o.typeclass, o.at_server_shutdown()) for o in ObjectDB.get_all_cached_instances()]
|
yield [(o.typeclass, o.at_server_shutdown()) for o in ObjectDB.get_all_cached_instances()]
|
||||||
else: # shutdown
|
else: # shutdown
|
||||||
yield [_SA(p, "is_connected", False) for p in PlayerDB.get_all_cached_instances()]
|
yield [_SA(p, "is_connected", False) for p in PlayerDB.get_all_cached_instances()]
|
||||||
yield [(o.typeclass, o.at_disconnect(), o.at_server_shutdown()) for o in ObjectDB.get_all_cached_instances()]
|
yield [(o.typeclass, o.at_server_shutdown()) for o in ObjectDB.get_all_cached_instances()]
|
||||||
|
|
||||||
yield [(p.typeclass, p.at_server_shutdown()) for p in PlayerDB.get_all_cached_instances()]
|
yield [(p.typeclass, p.at_server_shutdown()) for p in PlayerDB.get_all_cached_instances()]
|
||||||
yield [(s.typeclass, s.at_server_shutdown()) for s in ScriptDB.get_all_cached_instances()]
|
yield [(s.typeclass, s.at_server_shutdown()) for s in ScriptDB.get_all_cached_instances()]
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ from src.commands import cmdhandler, cmdsethandler
|
||||||
from src.server.session import Session
|
from src.server.session import Session
|
||||||
|
|
||||||
IDLE_COMMAND = settings.IDLE_COMMAND
|
IDLE_COMMAND = settings.IDLE_COMMAND
|
||||||
|
_GA = object.__getattribute__
|
||||||
|
|
||||||
# load optional out-of-band function module
|
# load optional out-of-band function module
|
||||||
OOB_FUNC_MODULE = settings.OOB_FUNC_MODULE
|
OOB_FUNC_MODULE = settings.OOB_FUNC_MODULE
|
||||||
|
|
@ -57,7 +58,7 @@ class ServerSession(Session):
|
||||||
self.cmdset.update(init_mode=True)
|
self.cmdset.update(init_mode=True)
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
self.player.reconnect_session_to_character(self.sessid)
|
self.player.server_reconnect_session_to_character(self.sessid)
|
||||||
|
|
||||||
def at_login(self, player):
|
def at_login(self, player):
|
||||||
"""
|
"""
|
||||||
|
|
@ -83,17 +84,18 @@ class ServerSession(Session):
|
||||||
if self.logged_in:
|
if self.logged_in:
|
||||||
sessid = self.sessid
|
sessid = self.sessid
|
||||||
player = self.player
|
player = self.player
|
||||||
if player.get_character(sessid):
|
print "session at_disconnect", self
|
||||||
player.disconnect_session_from_character(sessid)
|
_GA(player.dbobj, "disconnect_session_from_character")(sessid)
|
||||||
uaccount = player.user
|
uaccount = _GA(player.dbobj, "user")
|
||||||
uaccount.last_login = datetime.now()
|
uaccount.last_login = datetime.now()
|
||||||
uaccount.save()
|
uaccount.save()
|
||||||
|
# calling player hook
|
||||||
|
_GA(player.typeclass, "at_disconnect")()
|
||||||
self.logged_in = False
|
self.logged_in = False
|
||||||
if not self.sessionhandler.sessions_from_player(player):
|
if not self.sessionhandler.sessions_from_player(player):
|
||||||
# no more sessions connected to this player
|
# no more sessions connected to this player
|
||||||
player.is_connected = False
|
player.is_connected = False
|
||||||
|
|
||||||
|
|
||||||
def get_player(self):
|
def get_player(self):
|
||||||
"""
|
"""
|
||||||
Get the player associated with this session
|
Get the player associated with this session
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue