mirror of
https://github.com/evennia/evennia.git
synced 2026-03-24 00:36:30 +01:00
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
|
||||
if caller.connect_character(new_character, sessid=sessid):
|
||||
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:
|
||||
# this might be due to being hidden away at logout; check
|
||||
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.
|
||||
|
||||
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_first_login() - (player-controlled objects only) called once, the very first time user logs in.
|
||||
at_pre_login() - (player-controlled objects only) called every time the user connects, after they have identified, before other setup
|
||||
at_post_login() - (player-controlled objects only) called at the end of login, just before setting the player loose in the world.
|
||||
at_disconnect() - (player-controlled objects only) called just before the user disconnects (or goes linkless)
|
||||
at_cmdset_get() - this is called just before the command handler requests a cmdset from this objecth
|
||||
at_pre_puppet(player)- (player-controlled objects only) called just before puppeting
|
||||
at_post_puppet() - (player-controlled objects only) called just after completing connection player<->object
|
||||
at_pre_unpuppet() - (player-controlled objects only) called just before un-puppeting
|
||||
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_shutdown() - called just before server is fully shut down
|
||||
|
||||
|
|
@ -458,33 +458,66 @@ class Object(TypeClass):
|
|||
"""
|
||||
pass
|
||||
|
||||
def at_first_login(self):
|
||||
def at_pre_puppet(self, player):
|
||||
"""
|
||||
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.
|
||||
Called just before a Player connects to this object
|
||||
to puppet it.
|
||||
|
||||
player - connecting player object
|
||||
"""
|
||||
pass
|
||||
|
||||
def at_disconnect(self):
|
||||
def at_post_puppet(self):
|
||||
"""
|
||||
Called just before user
|
||||
is disconnected.
|
||||
Called just after puppeting has been completed and
|
||||
all Player<->Object links have been established.
|
||||
"""
|
||||
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):
|
||||
"""
|
||||
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."
|
||||
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
|
||||
remain in the room also after the player logged off ("headless", so to say).
|
||||
This recovers the character again after having been "stoved away" at the unpuppet
|
||||
"""
|
||||
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
|
||||
print "object at_pre_puppet", self, player
|
||||
|
||||
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:
|
||||
# try to recover
|
||||
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.at_object_receive(self, self.location)
|
||||
|
||||
def at_post_puppet(self):
|
||||
"Once puppeting is complete, make sure to view the location."
|
||||
# call look
|
||||
print "object at_post_puppet", self
|
||||
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
|
||||
#
|
||||
|
|
|
|||
|
|
@ -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_prop_cache, set_prop_cache, del_prop_cache
|
||||
from src.players import manager
|
||||
from src.scripts.models import ScriptDB
|
||||
from src.typeclasses.models import Attribute, TypedObject, TypeNick, TypeNickHandler
|
||||
from src.typeclasses.typeclass import TypeClass
|
||||
from src.commands.cmdsethandler import CmdSetHandler
|
||||
|
|
@ -364,8 +365,6 @@ class PlayerDB(TypedObject):
|
|||
data - dictionary of optional data
|
||||
sessid - session sending this data
|
||||
"""
|
||||
if _MULTISESSION_MODE < 2:
|
||||
sessid = None
|
||||
character = _GA(self, "get_character")(sessid=sessid)
|
||||
if character:
|
||||
# execute command on character
|
||||
|
|
@ -406,15 +405,18 @@ class PlayerDB(TypedObject):
|
|||
"""
|
||||
sessions = self.get_session_from_sessid(sessid)
|
||||
for session in make_iter(sessions):
|
||||
# this will also trigger disconnection of character(s)
|
||||
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.
|
||||
Note that this assumes the character has previously been
|
||||
linked to the player using self.connect_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
|
||||
"""
|
||||
|
|
@ -425,24 +427,21 @@ class PlayerDB(TypedObject):
|
|||
_GA(self, "disconnect_session_from_character")(sessid)
|
||||
else:
|
||||
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
|
||||
character.sessid = sessid
|
||||
# update cache
|
||||
cache = get_prop_cache(self, "_characters") or {}
|
||||
cache[sessid] = character
|
||||
set_prop_cache(self, "_characters", cache)
|
||||
# call hooks
|
||||
character.at_init()
|
||||
if character:
|
||||
# start (persistent) scripts on this object
|
||||
#ScriptDB.objects.validate(obj=character)
|
||||
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()
|
||||
# start/validate (persistent) scripts on this object
|
||||
ScriptDB.objects.validate(obj=character)
|
||||
# post-puppet hook
|
||||
if call_hooks:
|
||||
_GA(character.typeclass, "at_post_puppet")()
|
||||
return True
|
||||
|
||||
def disconnect_session_from_character(self, sessid):
|
||||
|
|
@ -451,21 +450,26 @@ class PlayerDB(TypedObject):
|
|||
connection to the Player)
|
||||
returns the newly disconnected character, if it existed
|
||||
"""
|
||||
print "player disconnect_session_from_character", sessid
|
||||
if not sessid:
|
||||
return
|
||||
char = _GA(self, "get_character")(sessid=sessid, return_dbobj=True)
|
||||
print char
|
||||
if char:
|
||||
# call hook before disconnecting
|
||||
_GA(char.typeclass, "at_disconnect")()
|
||||
_GA(char.typeclass, "at_pre_unpuppet")()
|
||||
del char.sessid
|
||||
# update cache
|
||||
cache = get_prop_cache(self, "_characters") or {}
|
||||
if sessid in cache:
|
||||
del cache[sessid]
|
||||
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
|
||||
|
||||
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
|
||||
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)
|
||||
if not char:
|
||||
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):
|
||||
"""
|
||||
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,
|
||||
character - return character if connected to this player, else None.
|
||||
|
||||
Combining both keywords will check the entire connection - if the
|
||||
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 {}
|
||||
if sessid:
|
||||
|
|
|
|||
|
|
@ -296,9 +296,10 @@ class Player(TypeClass):
|
|||
|
||||
def at_pre_login(self):
|
||||
"""
|
||||
Called every time the user logs in,
|
||||
before they are actually logged in.
|
||||
Called every time the user logs in, just before the actual
|
||||
login-state is set.
|
||||
"""
|
||||
print "player at_pre_login", self
|
||||
pass
|
||||
|
||||
def _send_to_connect_channel(self, message):
|
||||
|
|
@ -322,6 +323,7 @@ class Player(TypeClass):
|
|||
them loose. This is called before an eventual Character's
|
||||
at_post_login hook.
|
||||
"""
|
||||
print "player at_post_login", self
|
||||
self._send_to_connect_channel("{G%s connected{n" % self.key)
|
||||
|
||||
if _MULTISESSION_MODE == 2 or not self.get_all_characters():
|
||||
|
|
@ -331,10 +333,11 @@ class Player(TypeClass):
|
|||
|
||||
def at_disconnect(self, reason=None):
|
||||
"""
|
||||
Called just before user
|
||||
is disconnected.
|
||||
Called just before user 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):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ def create_objects():
|
|||
|
||||
god_character.save()
|
||||
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
|
||||
|
||||
|
|
|
|||
|
|
@ -272,7 +272,7 @@ class Evennia(object):
|
|||
yield [(o.typeclass, o.at_server_shutdown()) for o in ObjectDB.get_all_cached_instances()]
|
||||
else: # shutdown
|
||||
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 [(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
|
||||
|
||||
IDLE_COMMAND = settings.IDLE_COMMAND
|
||||
_GA = object.__getattribute__
|
||||
|
||||
# load optional out-of-band function module
|
||||
OOB_FUNC_MODULE = settings.OOB_FUNC_MODULE
|
||||
|
|
@ -57,7 +58,7 @@ class ServerSession(Session):
|
|||
self.cmdset.update(init_mode=True)
|
||||
return
|
||||
else:
|
||||
self.player.reconnect_session_to_character(self.sessid)
|
||||
self.player.server_reconnect_session_to_character(self.sessid)
|
||||
|
||||
def at_login(self, player):
|
||||
"""
|
||||
|
|
@ -83,17 +84,18 @@ class ServerSession(Session):
|
|||
if self.logged_in:
|
||||
sessid = self.sessid
|
||||
player = self.player
|
||||
if player.get_character(sessid):
|
||||
player.disconnect_session_from_character(sessid)
|
||||
uaccount = player.user
|
||||
print "session at_disconnect", self
|
||||
_GA(player.dbobj, "disconnect_session_from_character")(sessid)
|
||||
uaccount = _GA(player.dbobj, "user")
|
||||
uaccount.last_login = datetime.now()
|
||||
uaccount.save()
|
||||
# calling player hook
|
||||
_GA(player.typeclass, "at_disconnect")()
|
||||
self.logged_in = False
|
||||
if not self.sessionhandler.sessions_from_player(player):
|
||||
# no more sessions connected to this player
|
||||
player.is_connected = False
|
||||
|
||||
|
||||
def get_player(self):
|
||||
"""
|
||||
Get the player associated with this session
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue