mirror of
https://github.com/evennia/evennia.git
synced 2026-03-31 13:07:16 +02:00
Cleaned up worst instability. Test suite does validate yet.
This commit is contained in:
parent
fa93c70e7f
commit
e36c7d5cc1
24 changed files with 134 additions and 300 deletions
|
|
@ -151,24 +151,6 @@ class MsgServer2Portal(amp.Command):
|
|||
errors = [(Exception, 'EXCEPTION')]
|
||||
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):
|
||||
"""
|
||||
Portal -> Server
|
||||
|
|
@ -289,7 +271,7 @@ class AMPProtocol(amp.AMP):
|
|||
msg=to_str(msg),
|
||||
ipart=icall,
|
||||
nparts=nmsglist,
|
||||
data=dumps(data)).addErrback(self.errback, "OOBServer2Portal")
|
||||
data=dumps(data)).addErrback(self.errback, "MsgServer2Portal")
|
||||
for icall, (msg, data) in enumerate(zip(msglist, datalist))]
|
||||
|
||||
# Message definition + helper methods to call/create each message type
|
||||
|
|
@ -317,11 +299,11 @@ class AMPProtocol(amp.AMP):
|
|||
data = "".join(t[2] for t in sorted(MSGBUFFER[sessid], key=lambda o:o[0]))
|
||||
del MSGBUFFER[sessid]
|
||||
# call session hook with the data
|
||||
self.factory.server.sessions.data_in(sessid, msg, loads(data))
|
||||
self.factory.server.sessions.data_in(sessid, text=msg, **loads(data))
|
||||
return {}
|
||||
MsgPortal2Server.responder(amp_msg_portal2server)
|
||||
|
||||
def call_remote_MsgPortal2Server(self, sessid, msg, data=""):
|
||||
def call_remote_MsgPortal2Server(self, sessid, msg, **kwargs):
|
||||
"""
|
||||
Access method called by the Portal and executed on the Portal.
|
||||
"""
|
||||
|
|
@ -332,10 +314,10 @@ class AMPProtocol(amp.AMP):
|
|||
msg=msg,
|
||||
ipart=0,
|
||||
nparts=1,
|
||||
data=dumps(data)).addErrback(self.errback, "MsgPortal2Server")
|
||||
data=dumps(kwargs)).addErrback(self.errback, "MsgPortal2Server")
|
||||
except amp.TooLong:
|
||||
# the msg (or data) was too long for AMP to send. We need to send in blocks.
|
||||
return self.send_split_msg(sessid, msg, data, MsgPortal2Server)
|
||||
return self.send_split_msg(sessid, msg, kwargs, MsgPortal2Server)
|
||||
|
||||
# Server -> Portal message
|
||||
|
||||
|
|
@ -357,11 +339,11 @@ class AMPProtocol(amp.AMP):
|
|||
data = "".join(t[2] for t in sorted(MSGBUFFER[sessid], key=lambda o:o[0]))
|
||||
del MSGBUFFER[sessid]
|
||||
# call session hook with the data
|
||||
self.factory.portal.sessions.data_out(sessid, msg, loads(data))
|
||||
self.factory.portal.sessions.data_out(sessid, text=msg, **loads(data))
|
||||
return {}
|
||||
MsgServer2Portal.responder(amp_msg_server2portal)
|
||||
|
||||
def call_remote_MsgServer2Portal(self, sessid, msg, data=""):
|
||||
def call_remote_MsgServer2Portal(self, sessid, msg, **kwargs):
|
||||
"""
|
||||
Access method called by the Server and executed on the Server.
|
||||
"""
|
||||
|
|
@ -372,52 +354,10 @@ class AMPProtocol(amp.AMP):
|
|||
msg=to_str(msg),
|
||||
ipart=0,
|
||||
nparts=1,
|
||||
data=dumps(data)).addErrback(self.errback, "OOBServer2Portal")
|
||||
data=dumps(kwargs)).addErrback(self.errback, "MsgServer2Portal")
|
||||
except amp.TooLong:
|
||||
# the msg (or data) was too long for AMP to send. We need to send in blocks.
|
||||
return self.send_split_msg(sessid, msg, data, MsgServer2Portal)
|
||||
|
||||
# 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")
|
||||
|
||||
# OOB 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 Portal.
|
||||
"""
|
||||
#print "oob server->portal (server side):", sessid, data
|
||||
return self.callRemote(OOBServer2Portal,
|
||||
sessid=sessid,
|
||||
data=dumps(data)).addErrback(self.errback, "OOBServer2Portal")
|
||||
return self.send_split_msg(sessid, msg, kwargs, MsgServer2Portal)
|
||||
|
||||
|
||||
# Server administration from the Portal side
|
||||
|
|
@ -501,21 +441,19 @@ class AMPProtocol(amp.AMP):
|
|||
return {}
|
||||
PortalAdmin.responder(amp_portal_admin)
|
||||
|
||||
def call_remote_PortalAdmin(self, sessid, operation="", data=""):
|
||||
def call_remote_PortalAdmin(self, sessid, operation="", **kwargs):
|
||||
"""
|
||||
Access method called by the server side.
|
||||
"""
|
||||
#print "portaladmin (server side):", sessid, ord(operation), data
|
||||
data = dumps(data)
|
||||
|
||||
return self.callRemote(PortalAdmin,
|
||||
sessid=sessid,
|
||||
operation=operation,
|
||||
data=data).addErrback(self.errback, "PortalAdmin")
|
||||
data=dumps(kwargs)).addErrback(self.errback, "PortalAdmin")
|
||||
|
||||
# Extra functions
|
||||
|
||||
def amp_function_call(self, module, function, args, kwargs):
|
||||
def amp_function_call(self, module, function, args, **kwargs):
|
||||
"""
|
||||
This allows Portal- and Server-process to call an arbitrary function
|
||||
in the other process. It is intended for use by plugin modules.
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ class PortalSessionHandler(SessionHandler):
|
|||
return [sess for sess in self.get_sessions(include_unloggedin=True)
|
||||
if hasattr(sess, 'suid') and sess.suid == suid]
|
||||
|
||||
def data_in(self, session, string="", data=""):
|
||||
def data_in(self, session, string="", **kwargs):
|
||||
"""
|
||||
Called by portal sessions for relaying data coming
|
||||
in from the protocol to the server. data is
|
||||
|
|
@ -130,7 +130,7 @@ class PortalSessionHandler(SessionHandler):
|
|||
#print "portal_data_in:", string
|
||||
self.portal.amp_protocol.call_remote_MsgPortal2Server(session.sessid,
|
||||
msg=string,
|
||||
data=data)
|
||||
data=kwargs)
|
||||
def announce_all(self, message):
|
||||
"""
|
||||
Send message to all connection sessions
|
||||
|
|
@ -138,30 +138,13 @@ class PortalSessionHandler(SessionHandler):
|
|||
for session in self.sessions.values():
|
||||
session.data_out(message)
|
||||
|
||||
def data_out(self, sessid, string="", data=""):
|
||||
def data_out(self, sessid, text=None, **kwargs):
|
||||
"""
|
||||
Called by server for having the portal relay messages and data
|
||||
to the correct session protocol.
|
||||
"""
|
||||
session = self.sessions.get(sessid, None)
|
||||
if session:
|
||||
session.data_out(string, data=data)
|
||||
|
||||
def oob_data_in(self, session, data):
|
||||
"""
|
||||
OOB (Out-of-band) data Portal -> Server
|
||||
"""
|
||||
print "portal_oob_data_in:", data
|
||||
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
|
||||
"""
|
||||
print "portal_oob_data_out:", data
|
||||
session = self.sessions.get(sessid, None)
|
||||
if session:
|
||||
session.oob_data_out(data)
|
||||
session.data_out(text=text, **kwargs)
|
||||
|
||||
PORTAL_SESSIONS = PortalSessionHandler()
|
||||
|
|
|
|||
|
|
@ -173,22 +173,22 @@ class SshProtocol(Manhole, session.Session):
|
|||
self.data_out(reason)
|
||||
self.connectionLost(reason)
|
||||
|
||||
def data_out(self, string, data=None):
|
||||
def data_out(self, text=None, **kwargs):
|
||||
"""
|
||||
Data Evennia -> Player access hook. 'data' argument is a dict parsed for string settings.
|
||||
|
||||
ssh flags:
|
||||
raw=True - leave all ansi markup and tokens unparsed
|
||||
nomarkup=True - remove all ansi markup
|
||||
|
||||
"""
|
||||
try:
|
||||
string = utils.to_str(string, encoding=self.encoding)
|
||||
text = utils.to_str(text if text else "", encoding=self.encoding)
|
||||
except Exception, e:
|
||||
self.lineSend(str(e))
|
||||
return
|
||||
nomarkup = False
|
||||
raw = False
|
||||
if type(data) == dict:
|
||||
# check if we want escape codes to go through unparsed.
|
||||
raw = data.get("raw", False)
|
||||
# check if we want to remove all markup
|
||||
nomarkup = data.get("nomarkup", False)
|
||||
raw = kwargs.get("raw", False)
|
||||
nomarkup = kwargs.get("nomarkup", False)
|
||||
if raw:
|
||||
self.lineSend(string)
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -141,28 +141,31 @@ class TelnetProtocol(Telnet, StatefulTelnetProtocol, Session):
|
|||
self.data_out(reason)
|
||||
self.connectionLost(reason)
|
||||
|
||||
def data_out(self, string, data=None):
|
||||
def data_out(self, text=None, **kwargs):
|
||||
"""
|
||||
generic hook method for engine to call in order to send data
|
||||
through the telnet connection.
|
||||
Data Evennia -> Player.
|
||||
data argument may contain a dict with output flags.
|
||||
|
||||
valid telnet kwargs:
|
||||
raw=True - pass string through without any ansi processing (i.e. include Evennia
|
||||
ansi markers but do not convert them into ansi tokens)
|
||||
nomarkup=True - strip all ansi markup
|
||||
|
||||
The telnet ttype negotiation flags, if any, are used if no kwargs are given.
|
||||
"""
|
||||
try:
|
||||
string = utils.to_str(string, encoding=self.encoding)
|
||||
text = utils.to_str(text if text else "", encoding=self.encoding)
|
||||
except Exception, e:
|
||||
self.sendLine(str(e))
|
||||
return
|
||||
ttype = self.protocol_flags.get('TTYPE', {})
|
||||
raw = kwargs.get("raw", False)
|
||||
nomarkup = not (ttype or ttype.get('256 COLORS') or ttype.get('ANSI') or not ttype.get("init_done"))
|
||||
raw = False
|
||||
if type(data) == dict:
|
||||
# check if we want escape codes to go through unparsed.
|
||||
raw = data.get("raw", False)
|
||||
# check if we want to remove all markup (TTYPE override)
|
||||
nomarkup = data.get("nomarkup", False)
|
||||
nomarkup = kwargs.get("nomarkup", nomarkup)
|
||||
if raw:
|
||||
self.sendLine(string)
|
||||
# no processing whatsoever
|
||||
self.sendLine(text)
|
||||
else:
|
||||
# we need to make sure to kill the color at the end in order to match the webclient output.
|
||||
self.sendLine(ansi.parse_ansi(_RE_N.sub("", string) + "{n", strip_ansi=nomarkup, xterm256=ttype.get('256 COLORS')))
|
||||
self.sendLine(ansi.parse_ansi(_RE_N.sub("", text) + "{n", strip_ansi=nomarkup, xterm256=ttype.get('256 COLORS')))
|
||||
|
|
|
|||
|
|
@ -224,33 +224,24 @@ class WebClientSession(session.Session):
|
|||
self.client.lineSend(self.suid, reason)
|
||||
self.client.client_disconnect(self.suid)
|
||||
|
||||
def data_out(self, string='', data=None):
|
||||
def data_out(self, text=None, **kwargs):
|
||||
"""
|
||||
Data Evennia -> Player access hook.
|
||||
|
||||
data argument may be used depending on
|
||||
the client-server implementation.
|
||||
webclient flags checked are
|
||||
raw=True - no parsing at all (leave ansi-to-html markers unparsed)
|
||||
nomarkup=True - clean out all ansi/html markers and tokens
|
||||
|
||||
"""
|
||||
|
||||
if data:
|
||||
# treat data?
|
||||
pass
|
||||
|
||||
# string handling is similar to telnet
|
||||
try:
|
||||
string = utils.to_str(string, encoding=self.encoding)
|
||||
|
||||
nomarkup = False
|
||||
raw = False
|
||||
if type(data) == dict:
|
||||
# check if we want escape codes to go through unparsed.
|
||||
raw = data.get("raw", False)
|
||||
# check if we want to remove all markup
|
||||
nomarkup = data.get("nomarkup", False)
|
||||
text = utils.to_str(text if text else "", encoding=self.encoding)
|
||||
raw = kwargs.get("raw", False)
|
||||
nomarkup = kwargs.get("nomarkup", False)
|
||||
if raw:
|
||||
self.client.lineSend(self.suid, string)
|
||||
self.client.lineSend(self.suid, text)
|
||||
else:
|
||||
self.client.lineSend(self.suid, parse_html(string, strip_ansi=nomarkup))
|
||||
self.client.lineSend(self.suid, parse_html(text, strip_ansi=nomarkup))
|
||||
return
|
||||
except Exception, e:
|
||||
except Exception:
|
||||
logger.log_trace()
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ from django.conf import settings
|
|||
from src.scripts.models import ScriptDB
|
||||
from src.comms.models import Channel
|
||||
from src.utils import logger, utils
|
||||
from src.utils.utils import make_iter
|
||||
from src.utils.utils import make_iter, to_str
|
||||
from src.commands import cmdhandler, cmdsethandler
|
||||
from src.server.session import Session
|
||||
|
||||
|
|
@ -162,25 +162,25 @@ class ServerSession(Session):
|
|||
# Player-visible idle time, not used in idle timeout calcs.
|
||||
self.cmd_last_visible = time.time()
|
||||
|
||||
def data_in(self, command_string):
|
||||
def data_in(self, text=None, **kwargs):
|
||||
"""
|
||||
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:
|
||||
self.update_session_counters(idle=True)
|
||||
return
|
||||
cmdhandler.cmdhandler(self, command_string, callertype="session", sessid=self.sessid)
|
||||
#if self.logged_in:
|
||||
# # the inmsg handler will relay to the right place
|
||||
# self.player.inmsg(command_string, self)
|
||||
#else:
|
||||
# # 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)
|
||||
self.update_session_counters()
|
||||
if text:
|
||||
# this is treated as a command input
|
||||
text = to_str(text)
|
||||
# handle the 'idle' command
|
||||
if text.strip() == IDLE_COMMAND:
|
||||
self.update_session_counters(idle=True)
|
||||
return
|
||||
cmdhandler.cmdhandler(self, text, callertype="session", sessid=self.sessid)
|
||||
self.update_session_counters()
|
||||
if "oob" in kwargs:
|
||||
# relay to OOB handler
|
||||
pass
|
||||
|
||||
execute_cmd = data_in # alias
|
||||
|
||||
def data_out(self, text=None, **kwargs):
|
||||
|
|
@ -189,58 +189,6 @@ class ServerSession(Session):
|
|||
"""
|
||||
self.sessionhandler.data_out(self, text=text, **kwargs)
|
||||
|
||||
def oob_data_in(self, data):
|
||||
"""
|
||||
This receives out-of-band data from the Portal.
|
||||
|
||||
OBS - preliminary. OOB not yet functional in Evennia. Don't use.
|
||||
|
||||
This method parses the data input (a dict) and uses
|
||||
it to launch correct methods from those plugged into
|
||||
the system.
|
||||
|
||||
data = {oobkey: (funcname, (args), {kwargs}),
|
||||
oobkey: (funcname, (args), {kwargs}), ...}
|
||||
|
||||
example:
|
||||
data = {"get_hp": ("oob_get_hp, [], {}),
|
||||
"update_counter", ("counter", ["counter1"], {"now":True}) }
|
||||
|
||||
All function names must be defined in settings.OOB_PLUGIN_MODULE. Each
|
||||
function will be called with the oobkey and a back-reference to this session
|
||||
as their first two arguments.
|
||||
"""
|
||||
|
||||
outdata = {}
|
||||
|
||||
for oobkey, functuple in data.items():
|
||||
# loop through the data, calling available functions.
|
||||
func = OOB_PLUGIN_MODULE.__dict__.get(functuple[0])
|
||||
if func:
|
||||
try:
|
||||
outdata[functuple[0]] = func(oobkey, self, *functuple[1], **functuple[2])
|
||||
except Exception:
|
||||
logger.log_trace()
|
||||
else:
|
||||
logger.log_errmsg("oob_data_in error: funcname '%s' not found in OOB_PLUGIN_MODULE." % functuple[0])
|
||||
if outdata:
|
||||
# we have a direct result - send it back right away
|
||||
self.oob_data_out(outdata)
|
||||
|
||||
|
||||
def oob_data_out(self, data):
|
||||
"""
|
||||
This sends data from Server to the Portal across the AMP connection.
|
||||
|
||||
OBS - preliminary. OOB not yet functional in Evennia. Don't use.
|
||||
|
||||
data = {oobkey: (funcname, (args), {kwargs}),
|
||||
oobkey: (funcname, (args), {kwargs}), ...}
|
||||
|
||||
"""
|
||||
self.sessionhandler.oob_data_out(self, data)
|
||||
|
||||
|
||||
def __eq__(self, other):
|
||||
return self.address == other.address
|
||||
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ class Session(object):
|
|||
"""
|
||||
pass
|
||||
|
||||
def data_out(self, msg, data=None):
|
||||
def data_out(self, text=None, **kwargs):
|
||||
"""
|
||||
generic hook for sending data out through the protocol. Server
|
||||
protocols can use this right away. Portal sessions
|
||||
|
|
@ -119,26 +119,9 @@ class Session(object):
|
|||
"""
|
||||
pass
|
||||
|
||||
def data_in(self, msg, data=None):
|
||||
def data_in(self, text=None, **kwargs):
|
||||
"""
|
||||
hook for protocols to send incoming data to the engine.
|
||||
"""
|
||||
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
|
||||
|
|
|
|||
|
|
@ -367,31 +367,13 @@ class ServerSessionHandler(SessionHandler):
|
|||
self.server.amp_protocol.call_remote_MsgServer2Portal(sessid=session.sessid,
|
||||
msg=text,
|
||||
data=kwargs)
|
||||
def data_in(self, sessid, text="", data=""):
|
||||
def data_in(self, sessid, text="", **kwargs):
|
||||
"""
|
||||
Data Portal -> Server
|
||||
"""
|
||||
session = self.sessions.get(sessid, None)
|
||||
if session:
|
||||
kwargs = data if data else {}
|
||||
session.data_in(text, **kwargs)
|
||||
session.data_in(text=text, **kwargs)
|
||||
|
||||
# ignore 'data' argument for now; this is otherwise the place
|
||||
# to put custom effects on the server due to data input, e.g.
|
||||
# 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)
|
||||
SESSIONS = ServerSessionHandler()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue