Added plugins!

Moved packet dumping to its own plugin
Removed now unused font
This commit is contained in:
Ammar Askar 2012-12-17 18:40:49 +05:00
parent 43f86d09f5
commit 9f076a6f37
5 changed files with 113 additions and 24 deletions

View File

@ -18,8 +18,9 @@ EntityID = 0
class ServerConnection(threading.Thread):
def __init__(self, username, sessionID, server, port, options=None):
def __init__(self, pluginLoader, username, sessionID, server, port, options=None):
threading.Thread.__init__(self)
self.pluginLoader = pluginLoader
self.options = options
self.isConnected = False
self.username = username
@ -85,6 +86,7 @@ class ServerConnection(threading.Thread):
#Instantiate our main packet listener
self.listener = PacketListener(self, self.socket, self.FileObject)
self.listener.setDaemon(True)
self.listener.start()
#Encrypt the verification token from earlier along with our shared secret with the server's rsa key
@ -101,6 +103,7 @@ class ServerConnection(threading.Thread):
print "Server is in offline mode"
#Instantiate our main packet listener
self.listener = PacketListener(self, self.socket, self.FileObject)
self.listener.setDaemon(True)
self.listener.start()
#Encrypt the verification token from earlier along with our shared secret with the server's rsa key
@ -172,9 +175,6 @@ class PacketListener(threading.Thread):
self.encryptedConnection = True
def run(self):
if(self.connection.options != None and self.connection.options.dumpPackets):
f = open(self.connection.options.filename, 'w')
while True:
if (self.kill):
break
@ -198,9 +198,8 @@ class PacketListener(threading.Thread):
packet = PacketListenerManager.handle03(self.FileObject)
# Add "\x1b" because it is essential for ANSI escapes emitted by translate_escapes
filtered_string = filter(lambda x: x in string.printable + "\x1b", Utils.translate_escapes(packet['Message']))
#print message.replace(u'\xa7', '&')
print filtered_string
packet['Message'] = filter(lambda x: x in string.printable, packet['Message'])
elif(response == "\x04"):
packet = PacketListenerManager.handle04(self.FileObject)
elif(response == "\x05"):
@ -262,8 +261,7 @@ class PacketListener(threading.Thread):
elif(response == "\x2B"):
packet = PacketListenerManager.handle2B(self.FileObject)
elif(response == "\x33"):
PacketListenerManager.handle33(self.FileObject)
packet = {'ChunkPlaceHolder' : 0}
packet = PacketListenerManager.handle33(self.FileObject)
elif(response == "\x34"):
packet = PacketListenerManager.handle34(self.FileObject)
elif(response == "\x35"):
@ -273,8 +271,7 @@ class PacketListener(threading.Thread):
elif(response == "\x37"):
packet = PacketListenerManager.handle37(self.FileObject)
elif(response == "\x38"):
PacketListenerManager.handle38(self.FileObject)
packet = {'ChunkPlaceHolder' : 0}
packet = PacketListenerManager.handle38(self.FileObject)
elif(response == "\x3C"):
packet = PacketListenerManager.handle3C(self.FileObject)
elif(response == "\x3D"):
@ -324,17 +321,17 @@ class PacketListener(threading.Thread):
elif(response == "\xFF"):
packet = PacketListenerManager.handleFF(self.FileObject)
print "Disconnected: " + packet['Reason']
if(self.connection.options != None and self.connection.options.dumpPackets):
f.close()
self.connection.disconnect()
self.connection.pluginLoader.disablePlugins()
sys.exit(1)
break
else:
print "Protocol error: " + hex(ord(response))
self.connection.disconnect("Protocol error, invalid packet: " + hex(ord(response)))
if(f != None):
f.close()
self.connection.pluginLoader.disablePlugins()
sys.exit(1)
break
if(self.connection.options != None and self.connection.options.dumpPackets):
f.write(hex(ord(response)) + " : " + str(packet) + '\n')
# Invoke plugin listeners
for listener in self.connection.pluginLoader.getPacketListeners():
listener(response, packet)

54
pluginloader.py Normal file
View File

@ -0,0 +1,54 @@
import os
import imp
class PluginLoader():
path = ""
plugins = []
listeners = []
def __init__(self, path):
self.path = path
def loadPlugins(self, parser):
for root, dirs, files in os.walk(self.path):
for source in (s for s in files if s.endswith(".py")):
name = os.path.splitext(os.path.basename(source))[0]
full_name = os.path.splitext(source)[0].replace(os.path.sep, '.')
m = imp.load_module(full_name, *imp.find_module(name, [root]))
pluginClass = None
try:
pluginClass = getattr(m, name)()
self.plugins.append(pluginClass)
try:
pluginClass.onEnable(parser)
except AttributeError:
pass
try:
self.listeners.append(pluginClass.packetReceive)
except AttributeError:
pass
except AttributeError:
print "Plugin " + name + " is malformed"
def disablePlugins(self):
for plugin in self.plugins:
try:
plugin.onDisable()
except AttributeError:
pass
def notifyOptions(self, options):
for plugin in self.plugins:
try:
plugin.optionsParsed(options)
except AttributeError:
pass
def getPlugins(self):
return self.plugins
def getPacketListeners(self):
return self.listeners

36
plugins/PacketDumper.py Normal file
View File

@ -0,0 +1,36 @@
import string
import copy
class PacketDumper:
options = None
writeFile = None
def onEnable(self, parser):
parser.add_option("-d", "--dump-packets",
action="store_true", dest="dumpPackets", default=False,
help="run with this argument to dump packets")
parser.add_option("-o", "--out-file", dest="filename", default="dump.txt",
help="file to dump packets to")
def onDisable(self):
if (self.writeFile != None):
self.writeFile.close()
def optionsParsed(self, parsedOptions):
self.options = parsedOptions
if (self.options.dumpPackets):
self.writeFile = open(self.options.filename, 'w')
def packetReceive(self, packetID, receivedPacket):
packet = copy.deepcopy(receivedPacket)
if (self.writeFile != None):
if (packetID == "\x33" or packetID == "\x38"):
packet = {'ChunkPlaceHolder' : 0}
if (packetID == "\x03"):
packet['Message'] = filter(lambda x: x in string.printable, packet['Message'])
self.writeFile.write(hex(ord(packetID)) + " : " + str(packet) + '\n')

View File

@ -1,6 +1,7 @@
import getpass
import sys
import Utils
from pluginloader import PluginLoader
from networking import PacketSenderManager, NetworkManager
from optparse import OptionParser
@ -17,18 +18,17 @@ if __name__ == "__main__":
parser.add_option("-s", "--server", dest="server", default="",
help="server to connect to")
parser.add_option("-d", "--dump-packets",
action="store_true", dest="dumpPackets", default=False,
help="run with this argument to dump packets")
parser.add_option("-o", "--out-file", dest="filename", default="dump.txt",
help="file to dump packets to")
parser.add_option("-x", "--offline-mode", dest="offlineMode",
action="store_true", default=False,
help="run in offline mode i.e don't attempt to auth via minecraft.net")
# pluginLoader
pluginLoader = PluginLoader("plugins")
pluginLoader.loadPlugins(parser)
(options, args) = parser.parse_args()
pluginLoader.notifyOptions(options)
if(options.username != ""):
user = options.username
@ -64,7 +64,8 @@ if __name__ == "__main__":
else:
host = serverAddress
port = 25565
connection = NetworkManager.ServerConnection(user, sessionid, host, port, options)
connection = NetworkManager.ServerConnection(pluginLoader, user, sessionid, host, port, options)
connection.setDaemon(True)
connection.start()
while True:
try:
@ -75,4 +76,5 @@ if __name__ == "__main__":
pass
except KeyboardInterrupt, e:
connection.disconnect()
pluginLoader.disablePlugins()
sys.exit(1)