Created setter inputfuncs for the basic GMCP handhakes. Also added
the possibility for the Server to sync a single Session with the Portal.
This commit is contained in:
parent
196306d914
commit
f3512971e3
4 changed files with 130 additions and 9 deletions
|
|
@ -559,7 +559,8 @@ class AMPProtocol(amp.AMP):
|
||||||
elif operation == SSYNC: # server_session_sync
|
elif operation == SSYNC: # server_session_sync
|
||||||
# server wants to save session data to the portal,
|
# server wants to save session data to the portal,
|
||||||
# maybe because it's about to shut down.
|
# maybe because it's about to shut down.
|
||||||
portal_sessionhandler.server_session_sync(kwargs.get("sessiondata"))
|
portal_sessionhandler.server_session_sync(kwargs.get("sessiondata"),
|
||||||
|
kwargs.get("clean", True))
|
||||||
# set a flag in case we are about to shut down soon
|
# set a flag in case we are about to shut down soon
|
||||||
self.factory.server_restart_mode = True
|
self.factory.server_restart_mode = True
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,19 @@
|
||||||
"""
|
"""
|
||||||
Handlers for input commands
|
Functions for processing input commands.
|
||||||
|
|
||||||
|
All global functions in this module whose name does not start with "_"
|
||||||
|
is considered an inputfunc. Each function must have the following
|
||||||
|
callsign:
|
||||||
|
|
||||||
|
inputfunc(session, *args, **kwargs)
|
||||||
|
|
||||||
|
There is one special function, the "default" function, which is called
|
||||||
|
on a no-match. It has this callsign:
|
||||||
|
|
||||||
|
default(session, cmdname, *args, **kwargs)
|
||||||
|
|
||||||
|
Evennia knows which modules to use for inputfuncs by
|
||||||
|
settings.INPUT_FUNC_MODULES.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
from future.utils import viewkeys
|
from future.utils import viewkeys
|
||||||
|
|
@ -9,11 +23,17 @@ from evennia.commands.cmdhandler import cmdhandler
|
||||||
from evennia.utils.logger import log_err
|
from evennia.utils.logger import log_err
|
||||||
from evennia.utils.utils import to_str
|
from evennia.utils.utils import to_str
|
||||||
|
|
||||||
|
|
||||||
_IDLE_COMMAND = settings.IDLE_COMMAND
|
_IDLE_COMMAND = settings.IDLE_COMMAND
|
||||||
_GA = object.__getattribute__
|
_GA = object.__getattribute__
|
||||||
_SA = object.__setattr__
|
_SA = object.__setattr__
|
||||||
_NA = lambda o: "N/A"
|
_NA = lambda o: "N/A"
|
||||||
|
|
||||||
|
_ERROR_INPUT = "Inputfunc {name}({session}): Wrong/unrecognized input: {inp}"
|
||||||
|
|
||||||
|
|
||||||
|
# All global functions are inputfuncs available to process inputs
|
||||||
|
|
||||||
def text(session, *args, **kwargs):
|
def text(session, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Main text input from the client. This will execute a command
|
Main text input from the client. This will execute a command
|
||||||
|
|
@ -51,11 +71,16 @@ def text(session, *args, **kwargs):
|
||||||
cmdhandler(session, text, callertype="session", session=session)
|
cmdhandler(session, text, callertype="session", session=session)
|
||||||
session.update_session_counters()
|
session.update_session_counters()
|
||||||
|
|
||||||
|
|
||||||
def echo(session, *args, **kwargs):
|
def echo(session, *args, **kwargs):
|
||||||
|
"""
|
||||||
|
Echo test function
|
||||||
|
"""
|
||||||
print "Inputfunc echo:", session, args, kwargs
|
print "Inputfunc echo:", session, args, kwargs
|
||||||
session.data_out(text="Echo returns: ")
|
session.data_out(text="Echo returns: ")
|
||||||
session.data_out(echo=(args, kwargs))
|
session.data_out(echo=(args, kwargs))
|
||||||
|
|
||||||
|
|
||||||
def default(session, cmdname, *args, **kwargs):
|
def default(session, cmdname, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Default catch-function. This is like all other input functions except
|
Default catch-function. This is like all other input functions except
|
||||||
|
|
@ -67,8 +92,89 @@ def default(session, cmdname, *args, **kwargs):
|
||||||
" args, kwargs: {args}, {kwargs}"
|
" args, kwargs: {args}, {kwargs}"
|
||||||
log_err(err.format(sessid=session.sessid, cmdname=cmdname, args=args, kwargs=kwargs))
|
log_err(err.format(sessid=session.sessid, cmdname=cmdname, args=args, kwargs=kwargs))
|
||||||
|
|
||||||
|
|
||||||
|
def client_settings(session, *args, **kwargs):
|
||||||
|
"""
|
||||||
|
This allows the client an OOB way to inform us about its name and capabilities.
|
||||||
|
This will be integrated into the session settings
|
||||||
|
|
||||||
|
Kwargs:
|
||||||
|
client (str): A client identifier, like "mushclient".
|
||||||
|
version (str): A client version
|
||||||
|
ansi (bool): Supports ansi colors
|
||||||
|
xterm256 (bool): Supports xterm256 colors or not
|
||||||
|
mxp (bool): Supports MXP or not
|
||||||
|
utf-8 (bool): Supports UTF-8 or not
|
||||||
|
screenreader (bool): Screen-reader mode on/off
|
||||||
|
mccp (bool): MCCP compression on/off
|
||||||
|
screenheight (int): Screen height in lines
|
||||||
|
screenwidth (int): Screen width in characters
|
||||||
|
|
||||||
|
"""
|
||||||
|
flags = session.protocol_flags
|
||||||
|
tflags = flags["TTYPE"]
|
||||||
|
for key, value in kwargs.iteritems():
|
||||||
|
key = key.lower()
|
||||||
|
if key == "client":
|
||||||
|
tflags["CLIENTNAME"] = to_str(value)
|
||||||
|
elif key == "version":
|
||||||
|
if "CLIENTNAME" in tflags:
|
||||||
|
tflags["CLIENTNAME"] = "%s %s" % (tflags["CLIENTNAME"], to_str(value))
|
||||||
|
elif key == "ansi":
|
||||||
|
tflags["ANSI"] = bool(value)
|
||||||
|
elif key == "xterm256":
|
||||||
|
tflags["256 COLORS"] = bool(value)
|
||||||
|
elif key == "mxp":
|
||||||
|
flags["MXP"] = bool(value)
|
||||||
|
elif key == "utf-8":
|
||||||
|
tflags["UTF-8"] = bool(value)
|
||||||
|
elif key == "screenreader":
|
||||||
|
flags["SCREENREADER"] = bool(value)
|
||||||
|
elif key == "mccp":
|
||||||
|
flags["MCCP"] = bool(value)
|
||||||
|
elif key == "screenheight":
|
||||||
|
flags["SCREENHEIGHT"] = int(value)
|
||||||
|
elif key == "screenwidth":
|
||||||
|
flags["SCREENWIDTH"] = int(value)
|
||||||
|
else:
|
||||||
|
err = _ERROR_INPUT.format(
|
||||||
|
name="client_settings", session=session, inp=key)
|
||||||
|
session.msg(text=err)
|
||||||
|
flags["TTYPE"] = tflags
|
||||||
|
session.protocol_flags = flags
|
||||||
|
# we must update the portal as well
|
||||||
|
session.sessionhandler.session_portal_sync(session)
|
||||||
|
|
||||||
|
|
||||||
|
def login(session, *args, **kwargs):
|
||||||
|
"""
|
||||||
|
Peform a login. This only works if session is currently not logged
|
||||||
|
in. This will also automatically throttle too quick attempts.
|
||||||
|
|
||||||
|
Kwargs:
|
||||||
|
name (str): Player name
|
||||||
|
password (str): Plain-text password
|
||||||
|
|
||||||
|
"""
|
||||||
|
if not session.logged_in and "name" in kwargs and "password" in kwargs:
|
||||||
|
from evennia.commands.default.unloggedin import create_normal_player
|
||||||
|
player = create_normal_player(session, kwargs["name"], kwargs["password"])
|
||||||
|
if player:
|
||||||
|
session.sessionhandler.login(session, player)
|
||||||
|
|
||||||
|
|
||||||
|
# aliases for GMCP
|
||||||
|
core_hello = client_settings # Core.Hello
|
||||||
|
core_supports_set = client_settings # Core.Supports.Set
|
||||||
|
char_login = login # Char.Login
|
||||||
|
|
||||||
|
|
||||||
#------------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#------------------------------------------------------------
|
#------------------------------------------------------------
|
||||||
# All OOB commands must be on the form
|
# All OOB commands must be on the form
|
||||||
# cmdname(session, *args, **kwargs)
|
# cmdname(session, *args, **kwargs)
|
||||||
|
|
|
||||||
|
|
@ -236,25 +236,27 @@ class PortalSessionHandler(SessionHandler):
|
||||||
"""
|
"""
|
||||||
session.load_sync_data(data)
|
session.load_sync_data(data)
|
||||||
|
|
||||||
def server_session_sync(self, serversessions):
|
def server_session_sync(self, serversessions, clean=True):
|
||||||
"""
|
"""
|
||||||
Server wants to save data to the portal, maybe because it's
|
Server wants to save data to the portal, maybe because it's
|
||||||
about to shut down. We don't overwrite any sessions here, just
|
about to shut down. We don't overwrite any sessions here, just
|
||||||
update them in-place and remove any that are out of sync
|
update them in-place.
|
||||||
(which should normally not be the case)
|
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
serversessions (dict): This is a dictionary
|
serversessions (dict): This is a dictionary
|
||||||
|
|
||||||
`{sessid:{property:value},...}` describing
|
`{sessid:{property:value},...}` describing
|
||||||
the properties to sync on all sessions.
|
the properties to sync on all sessions.
|
||||||
|
clean (bool): If True, remove any Portal sessions that are
|
||||||
|
not included in serversessions.
|
||||||
"""
|
"""
|
||||||
to_save = [sessid for sessid in serversessions if sessid in self]
|
to_save = [sessid for sessid in serversessions if sessid in self]
|
||||||
to_delete = [sessid for sessid in self if sessid not in to_save]
|
|
||||||
# save protocols
|
# save protocols
|
||||||
for sessid in to_save:
|
for sessid in to_save:
|
||||||
self[sessid].load_sync_data(serversessions[sessid])
|
self[sessid].load_sync_data(serversessions[sessid])
|
||||||
|
if clean:
|
||||||
# disconnect out-of-sync missing protocols
|
# disconnect out-of-sync missing protocols
|
||||||
|
to_delete = [sessid for sessid in self if sessid not in to_save]
|
||||||
for sessid in to_delete:
|
for sessid in to_delete:
|
||||||
self.server_disconnect(sessid)
|
self.server_disconnect(sessid)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -446,6 +446,18 @@ class ServerSessionHandler(SessionHandler):
|
||||||
operation=SSYNC,
|
operation=SSYNC,
|
||||||
sessiondata=sessdata)
|
sessiondata=sessdata)
|
||||||
|
|
||||||
|
def session_portal_sync(self, session):
|
||||||
|
"""
|
||||||
|
This is called by the server when it wants to sync a single session
|
||||||
|
with the Portal for whatever reason. Returns a deferred!
|
||||||
|
|
||||||
|
"""
|
||||||
|
sessdata = {session.sessid: session.get_sync_data()}
|
||||||
|
return self.server.amp_protocol.send_AdminServer2Portal(DUMMYSESSION,
|
||||||
|
operation=SSYNC,
|
||||||
|
sessiondata=sessdata,
|
||||||
|
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.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue