Permalink
Browse files

Pass proto. ver. to MC3Plugin instances.

To correctly encode injected messages, instances of
MC3Plugin need to know the current protocol version.
We augment the PluginManager to extract this from the
handshake message, and pass it along during plugin
instantiation.

The tests have been updated to reflect that both login
request messages are now important.
  • Loading branch information...
1 parent ec6bacf commit 4d06fe46c842b95d7a890339690bb5b61b9eaece @mmcgill mmcgill committed Oct 28, 2011
Showing with 31 additions and 17 deletions.
  1. +21 −11 mc3p/plugins.py
  2. +10 −6 test_plugins.py
View
@@ -118,6 +118,9 @@ def __init__(self, config, cli_proxy, srv_proxy):
# True when a successful client-server handshake has completed.
self.__session_active = False
+ # Holds the protocol version number after successful handshake.
+ self.__proto_version = 0
+
# Stores handshake messages before handshake has completed,
# so they can be fed to plugins after initialization.
self.__msgbuf = []
@@ -195,7 +198,9 @@ def _instantiate_one(self, id, pname):
return
try:
logger.debug(" Instantiating plugin '%s' as '%s'" % (pname, id))
- inst = clazz(self.__from_client_q, self.__from_server_q)
+ inst = clazz(self.__proto_version,
+ self.__from_client_q,
+ self.__from_server_q)
inst.init(self.__config.argstr[id])
self.__instances[id] = inst
except Exception as e:
@@ -230,11 +235,16 @@ def filter(self, msg, source):
self.__msgbuf = None
return self._call_plugins(msg, source)
else:
- if 'server' == source and 0x01 == msg['msgtype']:
- logger.info('Handshake completed, loading plugins')
- self.__session_active = True
- self._load_plugins()
- self._instantiate_all()
+ if 0x01 == msg['msgtype']:
+ if 'client' == source:
+ self.__proto_version = msg['proto_version']
+ logger.debug('PluginManager detected proto version %d' %
+ self.__proto_version)
+ else:
+ logger.info('Handshake completed, loading plugins')
+ self.__session_active = True
+ self._load_plugins()
+ self._instantiate_all()
self.__msgbuf.append( (msg, source) )
return True
@@ -269,7 +279,8 @@ def wrapper(f):
class MC3Plugin(object):
"""Base class for mc3p plugins."""
- def __init__(self, from_client, from_server):
+ def __init__(self, proto_version, from_client, from_server):
+ self.__proto_version = proto_version
self.__to_client = from_server
self.__to_server = from_client
self.__hdlrs = {}
@@ -311,10 +322,9 @@ def _destroy(self):
self.destroy()
def __encode_msg(self, source, msg):
- if source == 'client':
- msg_spec = messages.cli_msgs
- else:
- msg_spec = messages.srv_msgs
+ cli_msgs, srv_msgs = messages.protocol[self.__proto_version]
+ msg_spec = cli_msgs if source == 'client' else srv_msgs
+
if not msg.has_key('msgtype'):
logger.error("Plugin %s tried to send message without msgtype."%\
self.plugin.__class__.__name__)
View
@@ -165,9 +165,11 @@ def testMultiplePluginClasses(self):
self.pmgr._instantiate_all()
self.assertEqual(0, len(mockplugin.instances))
- handshake_msg = {'msgtype':0x01, 'eid': 1, 'reserved': '',
- 'map_seed': 42, 'server_mode': 0, 'dimension': 0,
- 'difficulty': 2, 'world_height': 128, 'max_players': 16}
+ handshake_msg1 = {'msgtype':0x01, 'proto_version': 21, 'username': 'foo',
+ 'nu1': 0, 'nu2': 0, 'nu3': 0, 'nu4': 0, 'nu5': 0, 'nu6': 0}
+ handshake_msg2 = {'msgtype':0x01, 'eid': 1, 'reserved': '',
+ 'map_seed': 42, 'server_mode': 0, 'dimension': 0,
+ 'difficulty': 2, 'world_height': 128, 'max_players': 16}
def testLoadingPluginInPackage(self):
pkgname = os.path.basename(self.__class__.pkgdir)
@@ -185,7 +187,8 @@ def testInstantiationAfterSuccessfulHandshake(self):
self.pmgr = PluginManager(pcfg, self.cli_proxy, self.srv_proxy)
self.assertEqual(0, len(mockplugin.instances))
- self.pmgr.filter(self.__class__.handshake_msg, 'server')
+ self.pmgr.filter(self.__class__.handshake_msg1, 'client')
+ self.pmgr.filter(self.__class__.handshake_msg2, 'server')
self.assertEqual(2, len(mockplugin.instances))
def testMessageHandlerRegistration(self):
@@ -194,7 +197,7 @@ class A(MC3Plugin):
def hdlr1(self, msg, dir): pass
@msghdlr(0x04)
def hdlr2(self, msg, dir): pass
- a = A(None, None)
+ a = A(21, None, None)
hdlrs = getattr(a, '_MC3Plugin__hdlrs')
for msgtype in (0x01, 0x02, 0x03, 0x04):
self.assertTrue(msgtype in hdlrs)
@@ -205,7 +208,8 @@ def testMessageHandlerFiltering(self):
mockplugin = self._write_and_load('mockplugin', MOCK_PLUGIN_CODE)
pcfg = PluginConfig().add('mockplugin', 'p1').add('mockplugin', 'p2')
self.pmgr = PluginManager(pcfg, self.cli_proxy, self.srv_proxy)
- self.pmgr.filter(self.__class__.handshake_msg, 'server')
+ self.pmgr.filter(self.__class__.handshake_msg1, 'client')
+ self.pmgr.filter(self.__class__.handshake_msg2, 'server')
p1 = mockplugin.instances[0]
p2 = mockplugin.instances[1]
msg = {'msgtype': 0x03, 'chat_msg': 'foo!'}

0 comments on commit 4d06fe4

Please sign in to comment.