Allow options to partially update portal session, correctly relay late handshakes.

This commit is contained in:
Griatch 2017-12-31 23:16:16 +01:00
parent 9355b255ad
commit c8b1dfcd20
5 changed files with 38 additions and 12 deletions

View file

@ -160,10 +160,10 @@ def client_options(session, *args, **kwargs):
raw (bool): Turn off parsing raw (bool): Turn off parsing
""" """
flags = session.protocol_flags old_flags = session.protocol_flags
if not kwargs or kwargs.get("get", False): if not kwargs or kwargs.get("get", False):
# return current settings # return current settings
options = dict((key, flags[key]) for key in flags options = dict((key, old_flags[key]) for key in old_flags
if key.upper() in ("ANSI", "XTERM256", "MXP", if key.upper() in ("ANSI", "XTERM256", "MXP",
"UTF-8", "SCREENREADER", "ENCODING", "UTF-8", "SCREENREADER", "ENCODING",
"MCCP", "SCREENHEIGHT", "MCCP", "SCREENHEIGHT",
@ -189,6 +189,7 @@ def client_options(session, *args, **kwargs):
return True if val.lower() in ("true", "on", "1") else False return True if val.lower() in ("true", "on", "1") else False
return bool(val) return bool(val)
flags = {}
for key, value in kwargs.iteritems(): for key, value in kwargs.iteritems():
key = key.lower() key = key.lower()
if key == "client": if key == "client":
@ -230,9 +231,11 @@ def client_options(session, *args, **kwargs):
err = _ERROR_INPUT.format( err = _ERROR_INPUT.format(
name="client_settings", session=session, inp=key) name="client_settings", session=session, inp=key)
session.msg(text=err) session.msg(text=err)
session.protocol_flags = flags
# we must update the portal as well session.protocol_flags.update(flags)
session.sessionhandler.session_portal_sync(session) # we must update the protocol flags on the portal session copy as well
session.sessionhandler.session_portal_partial_sync(
{session.sessid: {"protocol_flags": flags}})
# GMCP alias # GMCP alias

View file

@ -72,7 +72,7 @@ class TelnetProtocol(Telnet, StatefulTelnetProtocol, Session):
# timeout the handshakes in case the client doesn't reply at all # timeout the handshakes in case the client doesn't reply at all
from evennia.utils.utils import delay from evennia.utils.utils import delay
delay(2, callback=self.handshake_done, force=True) delay(2, callback=self.handshake_done, timeout=True)
# TCP/IP keepalive watches for dead links # TCP/IP keepalive watches for dead links
self.transport.setTcpKeepAlive(1) self.transport.setTcpKeepAlive(1)
@ -100,17 +100,18 @@ class TelnetProtocol(Telnet, StatefulTelnetProtocol, Session):
self.nop_keep_alive = LoopingCall(self._send_nop_keepalive) self.nop_keep_alive = LoopingCall(self._send_nop_keepalive)
self.nop_keep_alive.start(30, now=False) self.nop_keep_alive.start(30, now=False)
def handshake_done(self, force=False): def handshake_done(self, timeout=False):
""" """
This is called by all telnet extensions once they are finished. This is called by all telnet extensions once they are finished.
When all have reported, a sync with the server is performed. When all have reported, a sync with the server is performed.
The system will force-call this sync after a small time to handle The system will force-call this sync after a small time to handle
clients that don't reply to handshakes at all. clients that don't reply to handshakes at all.
""" """
if self.handshakes > 0: if timeout:
if force: if self.handshakes > 0:
self.handshakes = 0
self.sessionhandler.sync(self) self.sessionhandler.sync(self)
return else:
self.handshakes -= 1 self.handshakes -= 1
if self.handshakes <= 0: if self.handshakes <= 0:
# do the sync # do the sync

View file

@ -66,7 +66,7 @@ class Ttype(object):
option (Option): Not used. option (Option): Not used.
""" """
self.protocol.protocol_flags['TTYPE'] = True self.protocol.protocol_flags['TTYPE'] = False
self.protocol.handshake_done() self.protocol.handshake_done()
def will_ttype(self, option): def will_ttype(self, option):

View file

@ -118,7 +118,13 @@ class Session(object):
""" """
for propname, value in sessdata.items(): for propname, value in sessdata.items():
setattr(self, propname, value) if (propname == "prototocol_flags" and isinstance(value, dict) and
hasattr(self, "protocol_flags") and
isinstance(self.protocol_flags.propname, dict)):
# special handling to allow partial update of protocol flags
self.protocol_flags.update(value)
else:
setattr(self, propname, value)
def at_sync(self): def at_sync(self):
""" """

View file

@ -538,6 +538,22 @@ class ServerSessionHandler(SessionHandler):
sessiondata=sessdata, sessiondata=sessdata,
clean=False) clean=False)
def session_portal_partial_sync(self, session_data):
"""
Call to make a partial update of the session, such as only a particular property.
Args:
session_data (dict): Store `{sessid: {property:value}, ...}` defining one or
more sessions in detail.
"""
return self.server.amp_protocol.send_AdminServer2Portal(DUMMYSESSION,
operation=SSYNC,
sessiondata=session_data,
clean=False)
def disconnect_all_sessions(self, reason="You have been disconnected."): def disconnect_all_sessions(self, reason="You have been disconnected."):
""" """
Cleanly disconnect all of the connected sessions. Cleanly disconnect all of the connected sessions.