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
"""
flags = session.protocol_flags
old_flags = session.protocol_flags
if not kwargs or kwargs.get("get", False):
# 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",
"UTF-8", "SCREENREADER", "ENCODING",
"MCCP", "SCREENHEIGHT",
@ -189,6 +189,7 @@ def client_options(session, *args, **kwargs):
return True if val.lower() in ("true", "on", "1") else False
return bool(val)
flags = {}
for key, value in kwargs.iteritems():
key = key.lower()
if key == "client":
@ -230,9 +231,11 @@ def client_options(session, *args, **kwargs):
err = _ERROR_INPUT.format(
name="client_settings", session=session, inp=key)
session.msg(text=err)
session.protocol_flags = flags
# we must update the portal as well
session.sessionhandler.session_portal_sync(session)
session.protocol_flags.update(flags)
# 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

View file

@ -72,7 +72,7 @@ class TelnetProtocol(Telnet, StatefulTelnetProtocol, Session):
# timeout the handshakes in case the client doesn't reply at all
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
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.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.
When all have reported, a sync with the server is performed.
The system will force-call this sync after a small time to handle
clients that don't reply to handshakes at all.
"""
if self.handshakes > 0:
if force:
if timeout:
if self.handshakes > 0:
self.handshakes = 0
self.sessionhandler.sync(self)
return
else:
self.handshakes -= 1
if self.handshakes <= 0:
# do the sync

View file

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

View file

@ -118,7 +118,13 @@ class Session(object):
"""
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):
"""

View file

@ -538,6 +538,22 @@ class ServerSessionHandler(SessionHandler):
sessiondata=sessdata,
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."):
"""
Cleanly disconnect all of the connected sessions.