Fix merge conflicts

This commit is contained in:
Griatch 2017-03-19 18:10:06 +01:00
commit 08670008ad
9 changed files with 111 additions and 107 deletions

View file

@ -7,7 +7,7 @@ The separation works like this:
Portal - (AMP client) handles protocols. It contains a list of connected Portal - (AMP client) handles protocols. It contains a list of connected
sessions in a dictionary for identifying the respective player sessions in a dictionary for identifying the respective player
connected. If it looses the AMP connection it will automatically connected. If it loses the AMP connection it will automatically
try to reconnect. try to reconnect.
Server - (AMP server) Handles all mud operations. The server holds its own list Server - (AMP server) Handles all mud operations. The server holds its own list
@ -32,6 +32,7 @@ from twisted.internet import protocol
from twisted.internet.defer import Deferred from twisted.internet.defer import Deferred
from evennia.utils import logger from evennia.utils import logger
from evennia.utils.utils import to_str, variable_from_module from evennia.utils.utils import to_str, variable_from_module
import zlib # Used in Compressed class
DUMMYSESSION = namedtuple('DummySession', ['sessid'])(0) DUMMYSESSION = namedtuple('DummySession', ['sessid'])(0)
@ -58,7 +59,6 @@ BATCH_TIMEOUT = 0.5 # how often to poll to empty batch queue, in seconds
_SENDBATCH = defaultdict(list) _SENDBATCH = defaultdict(list)
_MSGBUFFER = defaultdict(list) _MSGBUFFER = defaultdict(list)
import zlib
def get_restart_mode(restart_file): def get_restart_mode(restart_file):
""" """
@ -323,9 +323,9 @@ dumps = lambda data: to_str(pickle.dumps(to_str(data), pickle.HIGHEST_PROTOCOL))
loads = lambda data: pickle.loads(to_str(data)) loads = lambda data: pickle.loads(to_str(data))
#------------------------------------------------------------ # -------------------------------------------------------------
# Core AMP protocol for communication Server <-> Portal # Core AMP protocol for communication Server <-> Portal
#------------------------------------------------------------ # -------------------------------------------------------------
class AMPProtocol(amp.AMP): class AMPProtocol(amp.AMP):
""" """
@ -385,7 +385,6 @@ class AMPProtocol(amp.AMP):
""" """
pass pass
# Error handling # Error handling
def errback(self, e, info): def errback(self, e, info):
@ -447,7 +446,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.
Args: Args:
sessid (int): Unique Session id. session (session): Session
kwargs (any, optional): Optional data. kwargs (any, optional): Optional data.
Returns: Returns:
@ -473,7 +472,6 @@ class AMPProtocol(amp.AMP):
self.factory.portal.sessions.data_out(session, **kwargs) self.factory.portal.sessions.data_out(session, **kwargs)
return {} return {}
def send_MsgServer2Portal(self, session, **kwargs): def send_MsgServer2Portal(self, session, **kwargs):
""" """
Access method - executed on the Server for sending data Access method - executed on the Server for sending data
@ -545,7 +543,7 @@ class AMPProtocol(amp.AMP):
""" """
return self.send_data(AdminPortal2Server, session.sessid, operation=operation, **kwargs) return self.send_data(AdminPortal2Server, session.sessid, operation=operation, **kwargs)
# Portal administraton from the Server side # Portal administration from the Server side
@AdminServer2Portal.responder @AdminServer2Portal.responder
def portal_receive_adminserver2portal(self, packed_data): def portal_receive_adminserver2portal(self, packed_data):
@ -562,7 +560,6 @@ class AMPProtocol(amp.AMP):
operation = kwargs.pop("operation") operation = kwargs.pop("operation")
portal_sessionhandler = self.factory.portal.sessions portal_sessionhandler = self.factory.portal.sessions
if operation == SLOGIN: # server_session_login if operation == SLOGIN: # server_session_login
# a session has authenticated; sync it. # a session has authenticated; sync it.
session = portal_sessionhandler.get(sessid) session = portal_sessionhandler.get(sessid)
@ -665,4 +662,5 @@ class AMPProtocol(amp.AMP):
module=modulepath, module=modulepath,
function=functionname, function=functionname,
args=dumps(args), args=dumps(args),
kwargs=dumps(kwargs)).addCallback(lambda r: loads(r["result"])).addErrback(self.errback, "FunctionCall") kwargs=dumps(kwargs)).addCallback(
lambda r: loads(r["result"])).addErrback(self.errback, "FunctionCall")

View file

@ -198,7 +198,7 @@ class IRCBot(irc.IRCClient, Session):
logger.log_info("IRC bot '%s' connected to %s at %s:%s." % (self.nickname, self.channel, logger.log_info("IRC bot '%s' connected to %s at %s:%s." % (self.nickname, self.channel,
self.network, self.port)) self.network, self.port))
def disconnect(self, reason=None): def disconnect(self, reason=""):
""" """
Called by sessionhandler to disconnect this protocol. Called by sessionhandler to disconnect this protocol.
@ -206,7 +206,7 @@ class IRCBot(irc.IRCClient, Session):
reason (str): Motivation for the disconnect. reason (str): Motivation for the disconnect.
""" """
self.sessionhandler.disconnect(self) self.sessionhandler.disconnect(self, reason=reason)
self.stopping = True self.stopping = True
self.transport.loseConnection() self.transport.loseConnection()

View file

@ -37,9 +37,9 @@ if os.name == 'nt':
# For Windows we need to handle pid files manually. # For Windows we need to handle pid files manually.
PORTAL_PIDFILE = os.path.join(settings.GAME_DIR, "server", 'portal.pid') PORTAL_PIDFILE = os.path.join(settings.GAME_DIR, "server", 'portal.pid')
#------------------------------------------------------------ # -------------------------------------------------------------
# Evennia Portal settings # Evennia Portal settings
#------------------------------------------------------------ # -------------------------------------------------------------
VERSION = get_evennia_version() VERSION = get_evennia_version()
@ -76,6 +76,8 @@ AMP_ENABLED = AMP_HOST and AMP_PORT and AMP_INTERFACE
# Maintenance function - this is called repeatedly by the portal. # Maintenance function - this is called repeatedly by the portal.
_IDLE_TIMEOUT = settings.IDLE_TIMEOUT _IDLE_TIMEOUT = settings.IDLE_TIMEOUT
def _portal_maintenance(): def _portal_maintenance():
""" """
The maintenance function handles repeated checks and updates that The maintenance function handles repeated checks and updates that
@ -97,9 +99,9 @@ if _IDLE_TIMEOUT > 0:
_maintenance_task.start(60) # called every minute _maintenance_task.start(60) # called every minute
#------------------------------------------------------------ # -------------------------------------------------------------
# Portal Service object # Portal Service object
#------------------------------------------------------------ # -------------------------------------------------------------
class Portal(object): class Portal(object):
""" """
@ -180,11 +182,11 @@ class Portal(object):
self.shutdown_complete = True self.shutdown_complete = True
reactor.callLater(0, reactor.stop) reactor.callLater(0, reactor.stop)
#------------------------------------------------------------ # -------------------------------------------------------------
# #
# Start the Portal proxy server and add all active services # Start the Portal proxy server and add all active services
# #
#------------------------------------------------------------ # -------------------------------------------------------------
# twistd requires us to define the variable 'application' so it knows # twistd requires us to define the variable 'application' so it knows
# what to execute from. # what to execute from.

View file

@ -283,7 +283,8 @@ class SshProtocol(Manhole, session.Session):
else: else:
# we need to make sure to kill the color at the end in order # we need to make sure to kill the color at the end in order
# to match the webclient output. # to match the webclient output.
linetosend = ansi.parse_ansi(_RE_N.sub("", text) + "|n", strip_ansi=nocolor, xterm256=xterm256, mxp=False) linetosend = ansi.parse_ansi(_RE_N.sub("", text) + ("|n" if text[-1] != "|" else "||n"),
strip_ansi=nocolor, xterm256=xterm256, mxp=False)
self.sendLine(linetosend) self.sendLine(linetosend)
def send_prompt(self, *args, **kwargs): def send_prompt(self, *args, **kwargs):

View file

@ -54,6 +54,7 @@ class SSLProtocol(TelnetProtocol):
super(SSLProtocol, self).__init__(*args, **kwargs) super(SSLProtocol, self).__init__(*args, **kwargs)
self.protocol_name = "ssl" self.protocol_name = "ssl"
def verify_SSL_key_and_cert(keyfile, certfile): def verify_SSL_key_and_cert(keyfile, certfile):
""" """
This function looks for RSA key and certificate in the current This function looks for RSA key and certificate in the current

View file

@ -141,7 +141,7 @@ class TelnetProtocol(Telnet, StatefulTelnetProtocol, Session):
enable (bool): If this option should be enabled. enable (bool): If this option should be enabled.
""" """
return (option == MCCP or option==ECHO) return option == MCCP or option == ECHO
def disableLocal(self, option): def disableLocal(self, option):
""" """
@ -189,7 +189,7 @@ class TelnetProtocol(Telnet, StatefulTelnetProtocol, Session):
# legacy clients. There should never be a reason to send a # legacy clients. There should never be a reason to send a
# lone NULL character so this seems to be a safe thing to # lone NULL character so this seems to be a safe thing to
# support for backwards compatibility. It also stops the # support for backwards compatibility. It also stops the
# NULL from continously popping up as an unknown command. # NULL from continuously popping up as an unknown command.
data = [_IDLE_COMMAND] data = [_IDLE_COMMAND]
else: else:
data = _RE_LINEBREAK.split(data) data = _RE_LINEBREAK.split(data)
@ -225,16 +225,16 @@ class TelnetProtocol(Telnet, StatefulTelnetProtocol, Session):
# Session hooks # Session hooks
def disconnect(self, reason=None): def disconnect(self, reason=""):
""" """
generic hook for the engine to call in order to generic hook for the engine to call in order to
disconnect this protocol. disconnect this protocol.
Args: Args:
reason (str): Reason for disconnecting. reason (str, optional): Reason for disconnecting.
""" """
self.data_out(text=((reason or "",), {})) self.data_out(text=((reason,), {}))
self.connectionLost(reason) self.connectionLost(reason)
def data_in(self, **kwargs): def data_in(self, **kwargs):
@ -306,9 +306,11 @@ class TelnetProtocol(Telnet, StatefulTelnetProtocol, Session):
if options.get("send_prompt"): if options.get("send_prompt"):
# send a prompt instead. # send a prompt instead.
prompt = text
if not raw: if not raw:
# processing # processing
prompt = ansi.parse_ansi(_RE_N.sub("", text) + "|n", strip_ansi=nocolor, xterm256=xterm256) prompt = ansi.parse_ansi(_RE_N.sub("", prompt) + ("|n" if prompt[-1] != "|" else "||n"),
strip_ansi=nocolor, xterm256=xterm256)
if mxp: if mxp:
prompt = mxp_parse(prompt) prompt = mxp_parse(prompt)
prompt = prompt.replace(IAC, IAC + IAC).replace('\n', '\r\n') prompt = prompt.replace(IAC, IAC + IAC).replace('\n', '\r\n')
@ -335,7 +337,8 @@ class TelnetProtocol(Telnet, StatefulTelnetProtocol, Session):
else: else:
# we need to make sure to kill the color at the end in order # we need to make sure to kill the color at the end in order
# to match the webclient output. # to match the webclient output.
linetosend = ansi.parse_ansi(_RE_N.sub("", text) + "|n", strip_ansi=nocolor, xterm256=xterm256, mxp=mxp) linetosend = ansi.parse_ansi(_RE_N.sub("", text) + ("|n" if text[-1] != "|" else "||n"),
strip_ansi=nocolor, xterm256=xterm256, mxp=mxp)
if mxp: if mxp:
linetosend = mxp_parse(linetosend) linetosend = mxp_parse(linetosend)
self.sendLine(linetosend) self.sendLine(linetosend)

View file

@ -51,11 +51,13 @@ force_str = lambda inp: to_str(inp, force_string=True)
# pre-compiled regexes # pre-compiled regexes
# returns 2-tuple # returns 2-tuple
msdp_regex_table = re.compile(r"%s\s*(\w*?)\s*%s\s*%s(.*?)%s" % (MSDP_VAR, MSDP_VAL, msdp_regex_table = re.compile(r"%s\s*(\w*?)\s*%s\s*%s(.*?)%s"
% (MSDP_VAR, MSDP_VAL,
MSDP_TABLE_OPEN, MSDP_TABLE_OPEN,
MSDP_TABLE_CLOSE)) MSDP_TABLE_CLOSE))
# returns 2-tuple # returns 2-tuple
msdp_regex_array = re.compile(r"%s\s*(\w*?)\s*%s\s*%s(.*?)%s" % (MSDP_VAR, MSDP_VAL, msdp_regex_array = re.compile(r"%s\s*(\w*?)\s*%s\s*%s(.*?)%s"
% (MSDP_VAR, MSDP_VAL,
MSDP_ARRAY_OPEN, MSDP_ARRAY_OPEN,
MSDP_ARRAY_CLOSE)) MSDP_ARRAY_CLOSE))
msdp_regex_var = re.compile(r"%s" % MSDP_VAR) msdp_regex_var = re.compile(r"%s" % MSDP_VAR)
@ -67,6 +69,7 @@ EVENNIA_TO_GMCP = {"client_options": "Core.Supports.Get",
"repeat": "Char.Repeat.Update", "repeat": "Char.Repeat.Update",
"monitor": "Char.Monitor.Update"} "monitor": "Char.Monitor.Update"}
# MSDP/GMCP communication handler # MSDP/GMCP communication handler
class TelnetOOB(object): class TelnetOOB(object):
@ -100,7 +103,7 @@ class TelnetOOB(object):
Client reports No msdp supported or wanted. Client reports No msdp supported or wanted.
Args: Args:
options (Option): Not used. option (Option): Not used.
""" """
# no msdp, check GMCP # no msdp, check GMCP
@ -173,7 +176,7 @@ class TelnetOOB(object):
if not (args or kwargs): if not (args or kwargs):
return msdp_cmdname return msdp_cmdname
#print "encode_msdp in:", cmdname, args, kwargs # print("encode_msdp in:", cmdname, args, kwargs) # DEBUG
msdp_args = '' msdp_args = ''
if args: if args:
@ -186,11 +189,10 @@ class TelnetOOB(object):
"{msdp_array_close}".format( "{msdp_array_close}".format(
msdp_array_open=MSDP_ARRAY_OPEN, msdp_array_open=MSDP_ARRAY_OPEN,
msdp_array_close=MSDP_ARRAY_CLOSE, msdp_array_close=MSDP_ARRAY_CLOSE,
msdp_args= "".join("%s%s" % ( msdp_args="".join("%s%s"
MSDP_VAL, json.dumps(val)) % (MSDP_VAL, json.dumps(val))
for val in args)) for val in args))
msdp_kwargs = "" msdp_kwargs = ""
if kwargs: if kwargs:
msdp_kwargs = msdp_cmdname msdp_kwargs = msdp_cmdname
@ -199,13 +201,14 @@ class TelnetOOB(object):
"{msdp_table_close}".format( "{msdp_table_close}".format(
msdp_table_open=MSDP_TABLE_OPEN, msdp_table_open=MSDP_TABLE_OPEN,
msdp_table_close=MSDP_TABLE_CLOSE, msdp_table_close=MSDP_TABLE_CLOSE,
msdp_kwargs = "".join("%s%s%s%s" % ( msdp_kwargs="".join("%s%s%s%s"
MSDP_VAR, key, MSDP_VAL, json.dumps(val)) % (MSDP_VAR, key, MSDP_VAL,
json.dumps(val))
for key, val in kwargs.iteritems())) for key, val in kwargs.iteritems()))
msdp_string = msdp_args + msdp_kwargs msdp_string = msdp_args + msdp_kwargs
#print "msdp_string:", msdp_string # print("msdp_string:", msdp_string) # DEBUG
return msdp_string return msdp_string
def encode_gmcp(self, cmdname, *args, **kwargs): def encode_gmcp(self, cmdname, *args, **kwargs):
@ -241,7 +244,7 @@ class TelnetOOB(object):
else: # only kwargs else: # only kwargs
gmcp_string = "%s %s" % (cmdname, json.dumps(kwargs)) gmcp_string = "%s %s" % (cmdname, json.dumps(kwargs))
#print "gmcp string", gmcp_string # print("gmcp string", gmcp_string) # DEBUG
return gmcp_string return gmcp_string
def decode_msdp(self, data): def decode_msdp(self, data):
@ -271,7 +274,7 @@ class TelnetOOB(object):
if hasattr(data, "__iter__"): if hasattr(data, "__iter__"):
data = "".join(data) data = "".join(data)
#print "decode_msdp in:", data # print("decode_msdp in:", data) # DEBUG
tables = {} tables = {}
arrays = {} arrays = {}
@ -279,7 +282,7 @@ class TelnetOOB(object):
# decode tables # decode tables
for key, table in msdp_regex_table.findall(data): for key, table in msdp_regex_table.findall(data):
tables[key] = {} if not key in tables else tables[key] tables[key] = {} if key not in tables else tables[key]
for varval in msdp_regex_var.split(table)[1:]: for varval in msdp_regex_var.split(table)[1:]:
var, val = msdp_regex_val.split(varval, 1) var, val = msdp_regex_val.split(varval, 1)
if var: if var:
@ -288,7 +291,7 @@ class TelnetOOB(object):
# decode arrays from all that was not a table # decode arrays from all that was not a table
data_no_tables = msdp_regex_table.sub("", data) data_no_tables = msdp_regex_table.sub("", data)
for key, array in msdp_regex_array.findall(data_no_tables): for key, array in msdp_regex_array.findall(data_no_tables):
arrays[key] = [] if not key in arrays else arrays[key] arrays[key] = [] if key not in arrays else arrays[key]
parts = msdp_regex_val.split(array) parts = msdp_regex_val.split(array)
if len(parts) == 2: if len(parts) == 2:
arrays[key].append(parts[1]) arrays[key].append(parts[1])
@ -326,10 +329,9 @@ class TelnetOOB(object):
for key, var in variables.iteritems(): for key, var in variables.iteritems():
cmds[key] = [[var], {}] cmds[key] = [[var], {}]
#print "msdp data in:", cmds # print("msdp data in:", cmds) # DEBUG
self.protocol.data_in(**cmds) self.protocol.data_in(**cmds)
def decode_gmcp(self, data): def decode_gmcp(self, data):
""" """
Decodes incoming GMCP data on the form 'varname <structure>'. Decodes incoming GMCP data on the form 'varname <structure>'.
@ -353,7 +355,7 @@ class TelnetOOB(object):
if hasattr(data, "__iter__"): if hasattr(data, "__iter__"):
data = "".join(data) data = "".join(data)
#print "decode_gmcp in:", data # print("decode_gmcp in:", data) # DEBUG
if data: if data:
try: try:
cmdname, structure = data.split(None, 1) cmdname, structure = data.split(None, 1)

View file

@ -27,6 +27,7 @@ MTTS = [(128, 'PROXY'),
(2, 'VT100'), (2, 'VT100'),
(1, 'ANSI')] (1, 'ANSI')]
class Ttype(object): class Ttype(object):
""" """
Handles ttype negotiations. Called and initiated by the Handles ttype negotiations. Called and initiated by the
@ -104,7 +105,6 @@ class Ttype(object):
# use name to identify support for xterm256. Many of these # use name to identify support for xterm256. Many of these
# only support after a certain version, but all support # only support after a certain version, but all support
# it since at least 4 years. We assume recent client here for now. # it since at least 4 years. We assume recent client here for now.
xterm256 = False
cupper = clientname.upper() cupper = clientname.upper()
if cupper.startswith("MUDLET"): if cupper.startswith("MUDLET"):
# supports xterm256 stably since 1.1 (2010?) # supports xterm256 stably since 1.1 (2010?)

View file

@ -32,8 +32,9 @@ from django.utils.translation import ugettext as _
# Handlers for Session.db/ndb operation # Handlers for Session.db/ndb operation
class NDbHolder(object): class NDbHolder(object):
"Holder for allowing property access of attributes" """Holder for allowing property access of attributes"""
def __init__(self, obj, name, manager_name='attributes'): def __init__(self, obj, name, manager_name='attributes'):
_SA(self, name, _GA(obj, manager_name)) _SA(self, name, _GA(obj, manager_name))
_SA(self, 'name', name) _SA(self, 'name', name)
@ -145,9 +146,9 @@ class NAttributeHandler(object):
return [key for key in self._store if not key.startswith("_")] return [key for key in self._store if not key.startswith("_")]
#------------------------------------------------------------ # -------------------------------------------------------------
# Server Session # Server Session
#------------------------------------------------------------ # -------------------------------------------------------------
class ServerSession(Session): class ServerSession(Session):
""" """
@ -160,7 +161,7 @@ class ServerSession(Session):
""" """
def __init__(self): def __init__(self):
"Initiate to avoid AttributeErrors down the line" """Initiate to avoid AttributeErrors down the line"""
self.puppet = None self.puppet = None
self.player = None self.player = None
self.cmdset_storage_string = "" self.cmdset_storage_string = ""
@ -264,7 +265,6 @@ class ServerSession(Session):
MONITOR_HANDLER.remove(player, "_saved_webclient_options", MONITOR_HANDLER.remove(player, "_saved_webclient_options",
self.sessid) self.sessid)
def get_player(self): def get_player(self):
""" """
Get the player associated with this session Get the player associated with this session
@ -364,7 +364,6 @@ class ServerSession(Session):
self.protocol_flags.update(kwargs) self.protocol_flags.update(kwargs)
self.sessionhandler.session_portal_sync(self) self.sessionhandler.session_portal_sync(self)
def data_out(self, **kwargs): def data_out(self, **kwargs):
""" """
Sending data from Evennia->Client Sending data from Evennia->Client
@ -437,7 +436,7 @@ class ServerSession(Session):
self.sessionhandler.data_in(self, **kwargs) self.sessionhandler.data_in(self, **kwargs)
def __eq__(self, other): def __eq__(self, other):
"Handle session comparisons" """Handle session comparisons"""
try: try:
return self.address == other.address return self.address == other.address
except AttributeError: except AttributeError:
@ -462,11 +461,9 @@ class ServerSession(Session):
return "%s%s@%s" % (self.uname, symbol, address) return "%s%s@%s" % (self.uname, symbol, address)
def __unicode__(self): def __unicode__(self):
"Unicode representation" """Unicode representation"""
return u"%s" % str(self) return u"%s" % str(self)
# Dummy API hooks for use during non-loggedin operation # Dummy API hooks for use during non-loggedin operation
def at_cmdset_get(self, **kwargs): def at_cmdset_get(self, **kwargs):
@ -518,7 +515,7 @@ class ServerSession(Session):
# @ndb.deleter # @ndb.deleter
def ndb_del(self): def ndb_del(self):
"Stop accidental deletion." """Stop accidental deletion."""
raise Exception("Cannot delete the ndb object!") raise Exception("Cannot delete the ndb object!")
ndb = property(ndb_get, ndb_set, ndb_del) ndb = property(ndb_get, ndb_set, ndb_del)
db = property(ndb_get, ndb_set, ndb_del) db = property(ndb_get, ndb_set, ndb_del)
@ -526,5 +523,5 @@ class ServerSession(Session):
# Mock access method for the session (there is no lock info # Mock access method for the session (there is no lock info
# at this stage, so we just present a uniform API) # at this stage, so we just present a uniform API)
def access(self, *args, **kwargs): def access(self, *args, **kwargs):
"Dummy method to mimic the logged-in API." """Dummy method to mimic the logged-in API."""
return True return True