Heavily reworked the many-char system, cleaner and more consistent by not having any persistent links on the Object side once a player has unconnected.
This commit is contained in:
parent
5100a0561f
commit
26ced2cb90
8 changed files with 321 additions and 251 deletions
|
|
@ -268,13 +268,13 @@ class Evennia(object):
|
|||
|
||||
else:
|
||||
if mode == 'reset':
|
||||
# don't call disconnect hooks on reset
|
||||
# don't unset the is_connected flag on reset, otherwise same as shutdown
|
||||
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_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.unpuppet_all(), 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 ObjectDB.objects.clear_all_sessids()
|
||||
ServerConfig.objects.conf("server_restart_mode", "reset")
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ from src.server.session import Session
|
|||
|
||||
IDLE_COMMAND = settings.IDLE_COMMAND
|
||||
_GA = object.__getattribute__
|
||||
_ObjectDB = None
|
||||
|
||||
# load optional out-of-band function module
|
||||
OOB_FUNC_MODULE = settings.OOB_FUNC_MODULE
|
||||
|
|
@ -51,14 +52,19 @@ class ServerSession(Session):
|
|||
Since this is often called after a server restart we need to set up
|
||||
the session as it was.
|
||||
"""
|
||||
global _ObjectDB
|
||||
if not _ObjectDB:
|
||||
from src.objects.models import ObjectDB as _ObjectDB
|
||||
|
||||
if not self.logged_in:
|
||||
# assign the unloggedin-command set.
|
||||
self.cmdset = cmdsethandler.CmdSetHandler(self)
|
||||
self.cmdset_storage = [settings.CMDSET_UNLOGGEDIN]
|
||||
self.cmdset.update(init_mode=True)
|
||||
return
|
||||
else:
|
||||
self.player.server_reconnect_session_to_character(self.sessid)
|
||||
elif self.puid:
|
||||
self.puppet = None
|
||||
obj = _ObjectDB.objects.get(id=self.puid)
|
||||
self.player.puppet_object(self.sessid, obj, normal_mode=False)
|
||||
|
||||
def at_login(self, player):
|
||||
"""
|
||||
|
|
@ -72,6 +78,8 @@ class ServerSession(Session):
|
|||
self.uname = self.user.username
|
||||
self.logged_in = True
|
||||
self.conn_time = time.time()
|
||||
self.puid = None
|
||||
self.puppet = None
|
||||
|
||||
# Update account's last login time.
|
||||
self.user.last_login = datetime.now()
|
||||
|
|
@ -85,7 +93,7 @@ class ServerSession(Session):
|
|||
sessid = self.sessid
|
||||
player = self.player
|
||||
print "session at_disconnect", self
|
||||
_GA(player.dbobj, "disconnect_session_from_character")(sessid)
|
||||
_GA(player.dbobj, "unpuppet_object")(sessid)
|
||||
uaccount = _GA(player.dbobj, "user")
|
||||
uaccount.last_login = datetime.now()
|
||||
uaccount.save()
|
||||
|
|
@ -102,12 +110,13 @@ class ServerSession(Session):
|
|||
"""
|
||||
return self.logged_in and self.player
|
||||
|
||||
def get_character(self):
|
||||
def get_puppet(self):
|
||||
"""
|
||||
Returns the in-game character associated with this session.
|
||||
This returns the typeclass of the object.
|
||||
"""
|
||||
return self.logged_in and self.player.get_character(self.sessid) or None
|
||||
return self.logged_in and self.puppet
|
||||
get_character = get_puppet
|
||||
|
||||
def log(self, message, channel=True):
|
||||
"""
|
||||
|
|
@ -135,9 +144,11 @@ class ServerSession(Session):
|
|||
# Player-visible idle time, not used in idle timeout calcs.
|
||||
self.cmd_last_visible = time.time()
|
||||
|
||||
def execute_cmd(self, command_string):
|
||||
def data_in(self, command_string):
|
||||
"""
|
||||
Execute a command string on the server.
|
||||
Send Player->Evennia. This will in effect
|
||||
execute a command string on the server.
|
||||
Eventual extra data moves through oob_data_in
|
||||
"""
|
||||
# handle the 'idle' command
|
||||
if str(command_string).strip() == IDLE_COMMAND:
|
||||
|
|
@ -145,11 +156,12 @@ class ServerSession(Session):
|
|||
return
|
||||
if self.logged_in:
|
||||
# the inmsg handler will relay to the right place
|
||||
self.player.inmsg(command_string, sessid=self.sessid)
|
||||
self.player.inmsg(command_string, self)
|
||||
else:
|
||||
# we are not logged in. Use the session directly
|
||||
# we are not logged in. Execute cmd with the the session directly
|
||||
# (it uses the settings.UNLOGGEDIN cmdset)
|
||||
cmdhandler.cmdhandler(self, command_string, sessid=self.sessid)
|
||||
execute_cmd = data_in # alias
|
||||
|
||||
def data_out(self, msg, data=None):
|
||||
"""
|
||||
|
|
@ -157,6 +169,7 @@ class ServerSession(Session):
|
|||
"""
|
||||
self.sessionhandler.data_out(self, msg, data)
|
||||
|
||||
|
||||
def oob_data_in(self, data):
|
||||
"""
|
||||
This receives out-of-band data from the Portal.
|
||||
|
|
@ -249,7 +262,7 @@ class ServerSession(Session):
|
|||
self.data_out(string, data=data)
|
||||
|
||||
|
||||
# Dummy API hooks for use a non-loggedin operation
|
||||
# Dummy API hooks for use during non-loggedin operation
|
||||
|
||||
def at_cmdset_get(self):
|
||||
"dummy hook all objects with cmdsets need to have"
|
||||
|
|
|
|||
|
|
@ -34,9 +34,9 @@ class Session(object):
|
|||
|
||||
# names of attributes that should be affected by syncing.
|
||||
_attrs_to_sync = ('protocol_key', 'address', 'suid', 'sessid', 'uid', 'uname',
|
||||
'logged_in', 'cid', 'encoding',
|
||||
'logged_in', 'puid', 'encoding',
|
||||
'conn_time', 'cmd_last', 'cmd_last_visible', 'cmd_total',
|
||||
'server_data')
|
||||
'protocol_flags', 'server_data')
|
||||
|
||||
def init_session(self, protocol_key, address, sessionhandler):
|
||||
"""
|
||||
|
|
@ -63,15 +63,15 @@ class Session(object):
|
|||
# if user has authenticated already or not
|
||||
self.logged_in = False
|
||||
|
||||
# database id of character/object connected to this player session (if any)
|
||||
self.cid = None
|
||||
self.encoding = "utf-8"
|
||||
# database id of puppeted object (if any)
|
||||
self.puid = None
|
||||
|
||||
# session time statistics
|
||||
self.conn_time = time.time()
|
||||
self.cmd_last_visible = self.conn_time
|
||||
self.cmd_last = self.conn_time
|
||||
self.cmd_total = 0
|
||||
self.encoding = "utf-8"
|
||||
|
||||
self.protocol_flags = {}
|
||||
self.server_data = {}
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@ class ServerSessionHandler(SessionHandler):
|
|||
# validate all script
|
||||
_ScriptDB.objects.validate()
|
||||
self.sessions[sess.sessid] = sess
|
||||
sess.execute_cmd(CMD_LOGINSTART)
|
||||
sess.data_in(CMD_LOGINSTART)
|
||||
|
||||
def portal_disconnect(self, sessid):
|
||||
"""
|
||||
|
|
@ -196,7 +196,7 @@ class ServerSessionHandler(SessionHandler):
|
|||
Called from server side to remove session and inform portal
|
||||
of this fact.
|
||||
"""
|
||||
session = self.sessions.get(session.sessid, None)
|
||||
session = self.sessions.get(session.sessid)
|
||||
if session:
|
||||
session.at_disconnect()
|
||||
sessid = session.sessid
|
||||
|
|
@ -305,16 +305,19 @@ class ServerSessionHandler(SessionHandler):
|
|||
"""
|
||||
return len(set(session.uid for session in self.sessions.values() if session.logged_in))
|
||||
|
||||
def sessions_from_player(self, player, sessid=None):
|
||||
def session_from_player(self, player, sessid):
|
||||
"""
|
||||
Given a player, return any matching sessions.
|
||||
Given a player and a session id, return the actual session object
|
||||
"""
|
||||
session = self.sessions.get(sessid)
|
||||
return session and session.logged_in and player.uid == session.uid and session or None
|
||||
|
||||
def sessions_from_player(self, player):
|
||||
"""
|
||||
Given a player, return all matching sessions.
|
||||
"""
|
||||
uid = player.uid
|
||||
if sessid:
|
||||
session = self.sessions.get(sessid)
|
||||
return session and session.logged_in and session.uid == uid and session or None
|
||||
else:
|
||||
return [session for session in self.sessions.values() if session.logged_in and session.uid == uid]
|
||||
return [session for session in self.sessions.values() if session.logged_in and session.uid == uid]
|
||||
|
||||
def sessions_from_character(self, character):
|
||||
"""
|
||||
|
|
@ -345,7 +348,7 @@ class ServerSessionHandler(SessionHandler):
|
|||
"""
|
||||
session = self.sessions.get(sessid, None)
|
||||
if session:
|
||||
session.execute_cmd(string)
|
||||
session.data_in(string)
|
||||
|
||||
# ignore 'data' argument for now; this is otherwise the place
|
||||
# to put custom effects on the server due to data input, e.g.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue