Added api functions for implementing protocols sending out-of-band data between server and portal (e.g. like GMCP)
This commit is contained in:
parent
3e8b43d222
commit
bced571805
6 changed files with 164 additions and 16 deletions
|
|
@ -34,10 +34,6 @@ SERVER_RESTART = os.path.join(settings.GAME_DIR, "server.restart")
|
||||||
# i18n
|
# i18n
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
|
|
||||||
# Signals
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def get_restart_mode(restart_file):
|
def get_restart_mode(restart_file):
|
||||||
"""
|
"""
|
||||||
|
|
@ -141,6 +137,24 @@ class MsgServer2Portal(amp.Command):
|
||||||
errors = [(Exception, 'EXCEPTION')]
|
errors = [(Exception, 'EXCEPTION')]
|
||||||
response = []
|
response = []
|
||||||
|
|
||||||
|
class OOBPortal2Server(amp.Command):
|
||||||
|
"""
|
||||||
|
OOB data portal -> server
|
||||||
|
"""
|
||||||
|
arguments = [('sessid', amp.Integer()),
|
||||||
|
('data', amp.String())]
|
||||||
|
errors = [(Exception, "EXCEPTION")]
|
||||||
|
response = []
|
||||||
|
|
||||||
|
class OOBServer2Portal(amp.Command):
|
||||||
|
"""
|
||||||
|
OOB data server -> portal
|
||||||
|
"""
|
||||||
|
arguments = [('sessid', amp.Integer()),
|
||||||
|
('data', amp.String())]
|
||||||
|
errors = [(Exception, "EXCEPTION")]
|
||||||
|
response = []
|
||||||
|
|
||||||
class ServerAdmin(amp.Command):
|
class ServerAdmin(amp.Command):
|
||||||
"""
|
"""
|
||||||
Portal -> Server
|
Portal -> Server
|
||||||
|
|
@ -168,6 +182,8 @@ class PortalAdmin(amp.Command):
|
||||||
errors = [(Exception, 'EXCEPTION')]
|
errors = [(Exception, 'EXCEPTION')]
|
||||||
response = []
|
response = []
|
||||||
|
|
||||||
|
dumps = lambda data: utils.to_str(pickle.dumps(data, pickle.HIGHEST_PROTOCOL))
|
||||||
|
loads = lambda data: pickle.loads(utils.to_str(data))
|
||||||
|
|
||||||
#------------------------------------------------------------
|
#------------------------------------------------------------
|
||||||
# Core AMP protocol for communication Server <-> Portal
|
# Core AMP protocol for communication Server <-> Portal
|
||||||
|
|
@ -220,7 +236,7 @@ class AMPProtocol(amp.AMP):
|
||||||
Relays message to server. This method is executed on the Server.
|
Relays message to server. This method is executed on the Server.
|
||||||
"""
|
"""
|
||||||
#print "msg portal -> server (server side):", sessid, msg
|
#print "msg portal -> server (server side):", sessid, msg
|
||||||
self.factory.server.sessions.data_in(sessid, msg, pickle.loads(utils.to_str(data)))
|
self.factory.server.sessions.data_in(sessid, msg, loads(data))
|
||||||
return {}
|
return {}
|
||||||
MsgPortal2Server.responder(amp_msg_portal2server)
|
MsgPortal2Server.responder(amp_msg_portal2server)
|
||||||
|
|
||||||
|
|
@ -232,7 +248,7 @@ class AMPProtocol(amp.AMP):
|
||||||
self.callRemote(MsgPortal2Server,
|
self.callRemote(MsgPortal2Server,
|
||||||
sessid=sessid,
|
sessid=sessid,
|
||||||
msg=msg,
|
msg=msg,
|
||||||
data=utils.to_str(pickle.dumps(data))).addErrback(self.errback, "MsgPortal2Server")
|
data=dumps(data)).addErrback(self.errback, "MsgPortal2Server")
|
||||||
|
|
||||||
# Server -> Portal message
|
# Server -> Portal message
|
||||||
|
|
||||||
|
|
@ -241,7 +257,7 @@ class AMPProtocol(amp.AMP):
|
||||||
Relays message to Portal. This method is executed on the Portal.
|
Relays message to Portal. This method is executed on the Portal.
|
||||||
"""
|
"""
|
||||||
#print "msg server->portal (portal side):", sessid, msg
|
#print "msg server->portal (portal side):", sessid, msg
|
||||||
self.factory.portal.sessions.data_out(sessid, msg, pickle.loads(utils.to_str(data)))
|
self.factory.portal.sessions.data_out(sessid, msg, loads(data))
|
||||||
return {}
|
return {}
|
||||||
MsgServer2Portal.responder(amp_msg_server2portal)
|
MsgServer2Portal.responder(amp_msg_server2portal)
|
||||||
|
|
||||||
|
|
@ -253,8 +269,50 @@ class AMPProtocol(amp.AMP):
|
||||||
self.callRemote(MsgServer2Portal,
|
self.callRemote(MsgServer2Portal,
|
||||||
sessid=sessid,
|
sessid=sessid,
|
||||||
msg=utils.to_str(msg),
|
msg=utils.to_str(msg),
|
||||||
data=utils.to_str(pickle.dumps(data))).addErrback(self.errback, "MsgServer2Portal")
|
data=dumps(data)).addErrback(self.errback, "OOBServer2Portal")
|
||||||
|
|
||||||
|
# OOB Portal -> Server
|
||||||
|
|
||||||
|
# Portal -> Server Msg
|
||||||
|
|
||||||
|
def amp_oob_portal2server(self, sessid, data):
|
||||||
|
"""
|
||||||
|
Relays out-of-band data to server. This method is executed on the Server.
|
||||||
|
"""
|
||||||
|
#print "oob portal -> server (server side):", sessid, loads(data)
|
||||||
|
self.factory.server.sessions.oob_data_in(sessid, loads(data))
|
||||||
|
return {}
|
||||||
|
OOBPortal2Server.responder(amp_oob_portal2server)
|
||||||
|
|
||||||
|
def call_remote_OOBPortal2Server(self, sessid, data=""):
|
||||||
|
"""
|
||||||
|
Access method called by the Portal and executed on the Portal.
|
||||||
|
"""
|
||||||
|
#print "oob portal->server (portal side):", sessid, data
|
||||||
|
self.callRemote(OOBPortal2Server,
|
||||||
|
sessid=sessid,
|
||||||
|
data=dumps(data)).addErrback(self.errback, "OOBPortal2Server")
|
||||||
|
|
||||||
|
# Server -> Portal message
|
||||||
|
|
||||||
|
def amp_oob_server2portal(self, sessid, data):
|
||||||
|
"""
|
||||||
|
Relays out-of-band data to Portal. This method is executed on the Portal.
|
||||||
|
"""
|
||||||
|
#print "oob server->portal (portal side):", sessid, data
|
||||||
|
self.factory.portal.sessions.oob_data_out(sessid, loads(data))
|
||||||
|
return {}
|
||||||
|
OOBServer2Portal.responder(amp_oob_server2portal)
|
||||||
|
|
||||||
|
def call_remote_OOBServer2Portal(self, sessid, data=""):
|
||||||
|
"""
|
||||||
|
Access method called by the Server and executed on the Server.
|
||||||
|
"""
|
||||||
|
#print "oob server->portal (server side):", sessid, data
|
||||||
|
self.callRemote(OOBServer2Portal,
|
||||||
|
sessid=sessid,
|
||||||
|
data=dumps(data)).addErrback(self.errback, "OOBServer2Portal")
|
||||||
|
|
||||||
|
|
||||||
# Server administration from the Portal side
|
# Server administration from the Portal side
|
||||||
|
|
||||||
|
|
@ -264,7 +322,7 @@ class AMPProtocol(amp.AMP):
|
||||||
operations on the server. This is executed on the Server.
|
operations on the server. This is executed on the Server.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
data = pickle.loads(utils.to_str(data))
|
data = loads(data)
|
||||||
|
|
||||||
#print "serveradmin (server side):", sessid, operation, data
|
#print "serveradmin (server side):", sessid, operation, data
|
||||||
|
|
||||||
|
|
@ -315,7 +373,7 @@ class AMPProtocol(amp.AMP):
|
||||||
Access method called by the Portal and Executed on the Portal.
|
Access method called by the Portal and Executed on the Portal.
|
||||||
"""
|
"""
|
||||||
#print "serveradmin (portal side):", sessid, operation, data
|
#print "serveradmin (portal side):", sessid, operation, data
|
||||||
data = utils.to_str(pickle.dumps(data))
|
data = dumps(data)
|
||||||
|
|
||||||
self.callRemote(ServerAdmin,
|
self.callRemote(ServerAdmin,
|
||||||
sessid=sessid,
|
sessid=sessid,
|
||||||
|
|
@ -329,7 +387,7 @@ class AMPProtocol(amp.AMP):
|
||||||
This allows the server to perform admin
|
This allows the server to perform admin
|
||||||
operations on the portal. This is executed on the Portal.
|
operations on the portal. This is executed on the Portal.
|
||||||
"""
|
"""
|
||||||
data = pickle.loads(utils.to_str(data))
|
data = loads(data)
|
||||||
|
|
||||||
#print "portaladmin (portal side):", sessid, operation, data
|
#print "portaladmin (portal side):", sessid, operation, data
|
||||||
if operation == 'SLOGIN': # 'server_session_login'
|
if operation == 'SLOGIN': # 'server_session_login'
|
||||||
|
|
@ -376,7 +434,7 @@ class AMPProtocol(amp.AMP):
|
||||||
Access method called by the server side.
|
Access method called by the server side.
|
||||||
"""
|
"""
|
||||||
#print "portaladmin (server side):", sessid, operation, data
|
#print "portaladmin (server side):", sessid, operation, data
|
||||||
data = utils.to_str(pickle.dumps(data))
|
data = dumps(data)
|
||||||
|
|
||||||
self.callRemote(PortalAdmin,
|
self.callRemote(PortalAdmin,
|
||||||
sessid=sessid,
|
sessid=sessid,
|
||||||
|
|
|
||||||
|
|
@ -12,12 +12,16 @@ from datetime import datetime
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from src.scripts.models import ScriptDB
|
from src.scripts.models import ScriptDB
|
||||||
from src.comms.models import Channel
|
from src.comms.models import Channel
|
||||||
from src.utils import logger
|
from src.utils import logger, utils
|
||||||
from src.commands import cmdhandler, cmdsethandler
|
from src.commands import cmdhandler, cmdsethandler
|
||||||
|
from src.server.session import Session
|
||||||
|
|
||||||
IDLE_COMMAND = settings.IDLE_COMMAND
|
IDLE_COMMAND = settings.IDLE_COMMAND
|
||||||
|
|
||||||
from src.server.session import Session
|
# load optional out-of-band function module
|
||||||
|
OOB_FUNC_MODULE = settings.OOB_FUNC_MODULE
|
||||||
|
if OOB_FUNC_MODULE:
|
||||||
|
OOB_FUNC_MODULE = utils.mod_import(settings.OOB_FUNC_MODULE)
|
||||||
|
|
||||||
# i18n
|
# i18n
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
|
|
@ -208,6 +212,44 @@ class ServerSession(Session):
|
||||||
"""
|
"""
|
||||||
self.sessionhandler.data_out(self, msg, data)
|
self.sessionhandler.data_out(self, msg, data)
|
||||||
|
|
||||||
|
|
||||||
|
def oob_data_in(self, data):
|
||||||
|
"""
|
||||||
|
This receives out-of-band data from the Portal.
|
||||||
|
|
||||||
|
This method parses the data input (a dict) and uses
|
||||||
|
it to launch correct methods from those plugged into
|
||||||
|
the system.
|
||||||
|
|
||||||
|
data = {funcname: ( [args], {kwargs]),
|
||||||
|
funcname: ( [args], {kwargs}), ...}
|
||||||
|
|
||||||
|
example:
|
||||||
|
data = {"get_hp": ([], {}),
|
||||||
|
"update_counter", (["counter1"], {"now":True}) }
|
||||||
|
"""
|
||||||
|
|
||||||
|
print "server: "
|
||||||
|
outdata = {}
|
||||||
|
|
||||||
|
for funcname, argtuple in data.items():
|
||||||
|
# loop through the data, calling available functions.
|
||||||
|
func = OOB_FUNC_MODULE.__dict__.get(funcname, None)
|
||||||
|
if func:
|
||||||
|
outdata[funcname] = func(*argtuple[0], **argtuple[1])
|
||||||
|
else:
|
||||||
|
logger.log_errmsg("oob_data_in error: funcname '%s' not found in OOB_FUNC_MODULE." % funcname)
|
||||||
|
if outdata:
|
||||||
|
self.oob_data_out(outdata)
|
||||||
|
|
||||||
|
|
||||||
|
def oob_data_out(self, data):
|
||||||
|
"""
|
||||||
|
This sends data from Server to the Portal across the AMP connection.
|
||||||
|
"""
|
||||||
|
self.sessionhandler.oob_data_out(self, data)
|
||||||
|
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
return self.address == other.address
|
return self.address == other.address
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -123,3 +123,20 @@ class Session(object):
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def oob_data_out(self, data):
|
||||||
|
"""
|
||||||
|
for Portal, this receives out-of-band data from Server across the AMP.
|
||||||
|
for Server, this sends out-of-band data to Portal.
|
||||||
|
|
||||||
|
data is a dictionary
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
def oob_data_in(self, data):
|
||||||
|
"""
|
||||||
|
for Portal, this sends out-of-band requests to Server over the AMP.
|
||||||
|
for Server, this receives data from Portal.
|
||||||
|
|
||||||
|
data is a dictionary
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
|
||||||
|
|
@ -295,6 +295,20 @@ class ServerSessionHandler(SessionHandler):
|
||||||
# to put custom effects on the server due to data input, e.g.
|
# to put custom effects on the server due to data input, e.g.
|
||||||
# from a custom client.
|
# from a custom client.
|
||||||
|
|
||||||
|
def oob_data_in(self, sessid, data):
|
||||||
|
"""
|
||||||
|
OOB (Out-of-band) Data Portal -> Server
|
||||||
|
"""
|
||||||
|
session = self.sessions.get(sessid, None)
|
||||||
|
if session:
|
||||||
|
session.oob_data_in(data)
|
||||||
|
|
||||||
|
def oob_data_out(self, session, data):
|
||||||
|
"""
|
||||||
|
OOB (Out-of-band) Data Server -> Portal
|
||||||
|
"""
|
||||||
|
self.server.amp_protocol.call_remote_OOBServer2Portal(session.sessid,
|
||||||
|
data=data)
|
||||||
|
|
||||||
#------------------------------------------------------------
|
#------------------------------------------------------------
|
||||||
# Portal-SessionHandler class
|
# Portal-SessionHandler class
|
||||||
|
|
@ -392,5 +406,20 @@ class PortalSessionHandler(SessionHandler):
|
||||||
if session:
|
if session:
|
||||||
session.data_out(string, data=data)
|
session.data_out(string, data=data)
|
||||||
|
|
||||||
|
def oob_data_in(self, session, data):
|
||||||
|
"""
|
||||||
|
OOB (Out-of-band) data Portal -> Server
|
||||||
|
"""
|
||||||
|
self.portal.amp_protocol.call_remote_OOBPortal2Server(session.sessid,
|
||||||
|
data=data)
|
||||||
|
|
||||||
|
def oob_data_out(self, sessid, data):
|
||||||
|
"""
|
||||||
|
OOB (Out-of-band) data Server -> Portal
|
||||||
|
"""
|
||||||
|
session = self.sessions.get(sessid, None)
|
||||||
|
if session:
|
||||||
|
session.oob_data_out(data)
|
||||||
|
|
||||||
SESSIONS = ServerSessionHandler()
|
SESSIONS = ServerSessionHandler()
|
||||||
PORTAL_SESSIONS = PortalSessionHandler()
|
PORTAL_SESSIONS = PortalSessionHandler()
|
||||||
|
|
|
||||||
|
|
@ -253,6 +253,8 @@ PERMISSION_PLAYER_DEFAULT = "Players"
|
||||||
# Tuple of modules implementing lock functions. All callable functions
|
# Tuple of modules implementing lock functions. All callable functions
|
||||||
# inside these modules will be available as lock functions.
|
# inside these modules will be available as lock functions.
|
||||||
LOCK_FUNC_MODULES = ("src.locks.lockfuncs",)
|
LOCK_FUNC_MODULES = ("src.locks.lockfuncs",)
|
||||||
|
# Module holding server-side functions for out-of-band protocols to call.
|
||||||
|
OOB_FUNC_MODULE = ""
|
||||||
|
|
||||||
|
|
||||||
###################################################
|
###################################################
|
||||||
|
|
|
||||||
|
|
@ -542,7 +542,7 @@ def has_parent(basepath, obj):
|
||||||
|
|
||||||
def mod_import(mod_path, propname=None):
|
def mod_import(mod_path, propname=None):
|
||||||
"""
|
"""
|
||||||
Takes filename of a module, converts it to a python path
|
Takes filename of a module (a python path or a full pathname)
|
||||||
and imports it. If property is given, return the named
|
and imports it. If property is given, return the named
|
||||||
property from this module instead of the module itself.
|
property from this module instead of the module itself.
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue