From 7c1d5bdc397c2b14f72047ccf2ce427e1524a672 Mon Sep 17 00:00:00 2001 From: Ammar Askar Date: Fri, 26 Oct 2012 05:02:42 +0500 Subject: [PATCH] Command line interaction made much better, try start.py --help for details Bumped up protocol version Added packet dumping Handle disconnects more cleanly --- NoGUIstuff.py | 12 +-- networking/NetworkManager.py | 138 ++++++++++++++++-------------- networking/PacketSenderManager.py | 8 +- start.py | 56 +++++++++--- 4 files changed, 128 insertions(+), 86 deletions(-) diff --git a/NoGUIstuff.py b/NoGUIstuff.py index 5cf5555..b03bbed 100644 --- a/NoGUIstuff.py +++ b/NoGUIstuff.py @@ -1,5 +1,4 @@ import urllib2, urllib -from networking import PacketSenderManager def loginToMinecraft(username, password): try: @@ -14,14 +13,9 @@ def loginToMinecraft(username, password): response = opener.open(req, None, 10) response = response.read() except urllib2.URLError: - toReturn = {'Response' : "Can't connect to minecraft.net"} - return toReturn - if(response == "Bad login"): - toReturn = {'Response' : "Incorrect username/password"} - return toReturn - if(response == "Account migrated, use e-mail as username."): - toReturn = {'Response' : "Account migrated, use e-mail as username."} - return toReturn + return {'Response' : "Can't connect to minecraft.net"} + if(not "deprecated" in response.lower()): + return {'Response' : response} response = response.split(":") sessionid = response[3] toReturn = {'Response' : "Good to go!", diff --git a/networking/NetworkManager.py b/networking/NetworkManager.py index f7fd1a4..a9d057c 100644 --- a/networking/NetworkManager.py +++ b/networking/NetworkManager.py @@ -24,8 +24,9 @@ EntityID = 0 class ServerConnection(threading.Thread): - def __init__(self, window, username, password, sessionID, server, port): + def __init__(self, window, username, password, sessionID, server, port, options=None): threading.Thread.__init__(self) + self.options = options self.isConnected = False self.username = username self.password = password @@ -39,6 +40,7 @@ class ServerConnection(threading.Thread): self.window = window def disconnect(self): + PacketSenderManager.sendFF(self.socket, "Disconnected by user") self.listener.kill = True self.socket.close() @@ -198,6 +200,9 @@ 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 @@ -213,133 +218,136 @@ class PacketListener(threading.Thread): sys.exit() break if(response == "\x00"): - PacketListenerManager.handle00(self.FileObject, self.socket) + packet = PacketListenerManager.handle00(self.FileObject, self.socket) elif(response == "\x01"): - packet01 = PacketListenerManager.handle01(self.FileObject) - print "Logged in \o/ Received an entity id of " + str(packet01['EntityID']) + packet = PacketListenerManager.handle01(self.FileObject) + print "Logged in \o/ Received an entity id of " + str(packet['EntityID']) elif(response == "\x03"): - message = PacketListenerManager.handle03(self.FileObject) + packet = PacketListenerManager.handle03(self.FileObject) if(self.connection.NoGUI): # 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(message)) + filtered_string = filter(lambda x: x in string.printable + "\x1b", Utils.translate_escapes(packet)) #print message.replace(u'\xa7', '&') print filtered_string + packet = {'Message' : filtered_string} elif(self.window): - self.window.handleChat(message) + self.window.handleChat(packet) elif(response == "\x04"): - PacketListenerManager.handle04(self.FileObject) + packet = PacketListenerManager.handle04(self.FileObject) elif(response == "\x05"): - PacketListenerManager.handle05(self.FileObject) + packet = PacketListenerManager.handle05(self.FileObject) elif(response == "\x06"): - PacketListenerManager.handle06(self.FileObject) + packet = PacketListenerManager.handle06(self.FileObject) elif(response == "\x07"): - PacketListenerManager.handle07(self.FileObject) + packet = PacketListenerManager.handle07(self.FileObject) elif(response == "\x08"): - PacketListenerManager.handle08(self.FileObject) + packet = PacketListenerManager.handle08(self.FileObject) elif(response == "\x09"): - PacketListenerManager.handle09(self.FileObject) + packet = PacketListenerManager.handle09(self.FileObject) elif(response == "\x0D"): - PacketListenerManager.handle0D(self.FileObject) + packet = PacketListenerManager.handle0D(self.FileObject) elif(response == "\x11"): - PacketListenerManager.handle11(self.FileObject) + packet = PacketListenerManager.handle11(self.FileObject) elif(response == "\x12"): - PacketListenerManager.handle12(self.FileObject) + packet = PacketListenerManager.handle12(self.FileObject) elif(response == "\x14"): - PacketListenerManager.handle14(self.FileObject) + packet = PacketListenerManager.handle14(self.FileObject) elif(response == "\x15"): - PacketListenerManager.handle15(self.FileObject) + packet = PacketListenerManager.handle15(self.FileObject) elif(response == "\x16"): - PacketListenerManager.handle16(self.FileObject) + packet = PacketListenerManager.handle16(self.FileObject) elif(response == "\x17"): - PacketListenerManager.handle17(self.FileObject) + packet = PacketListenerManager.handle17(self.FileObject) elif(response == "\x18"): - PacketListenerManager.handle18(self.FileObject) + packet = PacketListenerManager.handle18(self.FileObject) elif(response == "\x19"): - PacketListenerManager.handle19(self.FileObject) + packet = PacketListenerManager.handle19(self.FileObject) elif(response == "\x1A"): - PacketListenerManager.handle1A(self.FileObject) + packet = PacketListenerManager.handle1A(self.FileObject) elif(response == "\x1C"): - PacketListenerManager.handle1C(self.FileObject) + packet = PacketListenerManager.handle1C(self.FileObject) elif(response == "\x1D"): - PacketListenerManager.handle1D(self.FileObject) + packet = PacketListenerManager.handle1D(self.FileObject) elif(response == "\x1E"): - PacketListenerManager.handle1E(self.FileObject) + packet = PacketListenerManager.handle1E(self.FileObject) elif(response == "\x1F"): - PacketListenerManager.handle1F(self.FileObject) + packet = PacketListenerManager.handle1F(self.FileObject) elif(response == "\x20"): - PacketListenerManager.handle20(self.FileObject) + packet = PacketListenerManager.handle20(self.FileObject) elif(response == "\x21"): - PacketListenerManager.handle21(self.FileObject) + packet = PacketListenerManager.handle21(self.FileObject) elif(response == "\x22"): - PacketListenerManager.handle22(self.FileObject) + packet = PacketListenerManager.handle22(self.FileObject) elif(response == "\x23"): - PacketListenerManager.handle23(self.FileObject) + packet = PacketListenerManager.handle23(self.FileObject) elif(response == "\x26"): - PacketListenerManager.handle26(self.FileObject) + packet = PacketListenerManager.handle26(self.FileObject) elif(response == "\x27"): - PacketListenerManager.handle27(self.FileObject) + packet = PacketListenerManager.handle27(self.FileObject) elif(response == "\x28"): - PacketListenerManager.handle28(self.FileObject) + packet = PacketListenerManager.handle28(self.FileObject) elif(response == "\x29"): - PacketListenerManager.handle29(self.FileObject) + packet = PacketListenerManager.handle29(self.FileObject) elif(response == "\x2A"): - PacketListenerManager.handle2A(self.FileObject) + packet = PacketListenerManager.handle2A(self.FileObject) elif(response == "\x2B"): - PacketListenerManager.handle2B(self.FileObject) + packet = PacketListenerManager.handle2B(self.FileObject) elif(response == "\x33"): PacketListenerManager.handle33(self.FileObject) + packet = {'PlaceHolder' : 0} elif(response == "\x34"): - PacketListenerManager.handle34(self.FileObject) + packet = PacketListenerManager.handle34(self.FileObject) elif(response == "\x35"): - PacketListenerManager.handle35(self.FileObject) + packet = PacketListenerManager.handle35(self.FileObject) elif(response == "\x36"): - PacketListenerManager.handle36(self.FileObject) + packet = PacketListenerManager.handle36(self.FileObject) elif(response == "\x37"): - PacketListenerManager.handle37(self.FileObject) + packet = PacketListenerManager.handle37(self.FileObject) elif(response == "\x38"): PacketListenerManager.handle38(self.FileObject) + packet = {'PlaceHolder' : 0} elif(response == "\x3C"): - PacketListenerManager.handle3C(self.FileObject) + packet = PacketListenerManager.handle3C(self.FileObject) elif(response == "\x3D"): - PacketListenerManager.handle3D(self.FileObject) + packet = PacketListenerManager.handle3D(self.FileObject) elif(response == "\x3E"): - PacketListenerManager.handle3E(self.FileObject) + packet = PacketListenerManager.handle3E(self.FileObject) elif(response == "\x46"): - PacketListenerManager.handle46(self.FileObject) + packet = PacketListenerManager.handle46(self.FileObject) elif(response == "\x47"): - PacketListenerManager.handle47(self.FileObject) + packet = PacketListenerManager.handle47(self.FileObject) elif(response == "\x64"): - PacketListenerManager.handle64(self.FileObject) + packet = PacketListenerManager.handle64(self.FileObject) elif(response == "\x65"): - PacketListenerManager.handle65(self.FileObject) + packet = PacketListenerManager.handle65(self.FileObject) elif(response == "\x67"): - PacketListenerManager.handle67(self.FileObject) + packet = PacketListenerManager.handle67(self.FileObject) elif(response == "\x68"): - PacketListenerManager.handle68(self.FileObject) + packet = PacketListenerManager.handle68(self.FileObject) elif(response == "\x69"): - PacketListenerManager.handle69(self.FileObject) + packet = PacketListenerManager.handle69(self.FileObject) elif(response == "\x6A"): - PacketListenerManager.handle6A(self.FileObject) + packet = PacketListenerManager.handle6A(self.FileObject) elif(response == "\x6B"): - PacketListenerManager.handle6B(self.FileObject) + packet = PacketListenerManager.handle6B(self.FileObject) elif(response == "\x82"): - PacketListenerManager.handle82(self.FileObject) + packet = PacketListenerManager.handle82(self.FileObject) elif(response == "\x83"): - PacketListenerManager.handle83(self.FileObject) + packet = PacketListenerManager.handle83(self.FileObject) elif(response == "\x84"): - PacketListenerManager.handle84(self.FileObject) + packet = PacketListenerManager.handle84(self.FileObject) elif(response == "\xC8"): - PacketListenerManager.handleC8(self.FileObject) + packet = PacketListenerManager.handleC8(self.FileObject) elif(response == "\xC9"): - PacketListenerManager.handleC9(self.FileObject) + packet = PacketListenerManager.handleC9(self.FileObject) elif(response == "\xCA"): - PacketListenerManager.handleCA(self.FileObject) + packet = PacketListenerManager.handleCA(self.FileObject) elif(response == "\xCB"): - PacketListenerManager.handleCB(self.FileObject) + packet = PacketListenerManager.handleCB(self.FileObject) elif(response == "\xFA"): - PacketListenerManager.handleFA(self.FileObject) + packet = PacketListenerManager.handleFA(self.FileObject) elif(response == "\xFC"): - PacketListenerManager.handleFC(self.FileObject) + packet = PacketListenerManager.handleFC(self.FileObject) if (not self.encryptedConnection): self.enableEncryption() self.connection.isConnected = True @@ -355,9 +363,15 @@ class PacketListener(threading.Thread): if(hasattr(self.window, 'Status')): self.window.Status.SetLabel("Disconnected: " + DisconMessage) self.socket.close() + sys.exit(1) break else: if(self.window == None): print "Protocol error: " + hex(ord(response)) self.socket.close() + if(f != None): + f.close() + sys.exit(1) break + if(self.connection.options != None and self.connection.options.dumpPackets): + f.write(hex(ord(response)) + " : " + str(packet) + '\n') diff --git a/networking/PacketSenderManager.py b/networking/PacketSenderManager.py index 05ea54a..5607ad2 100644 --- a/networking/PacketSenderManager.py +++ b/networking/PacketSenderManager.py @@ -6,7 +6,7 @@ def sendHandshake(socket, username, host, port): socket.send("\x02") #byte - protocol version - socket.send(struct.pack('!b', 39)) + socket.send(struct.pack('!b', 47)) #string - username socket.send(struct.pack('!h', username.__len__())) @@ -44,4 +44,8 @@ def sendFC(socket, secret, token): #token socket.send(struct.pack('!h', token.__len__())) #length - socket.send(token) \ No newline at end of file + socket.send(token) + +def sendFF(socket, reason): + socket.send(struct.pack('!h', reason.__len__())) #length + socket.send(reason.encode("utf-16be")) #message \ No newline at end of file diff --git a/start.py b/start.py index 814254b..00ec5de 100644 --- a/start.py +++ b/start.py @@ -2,10 +2,11 @@ import urllib import urllib2 import getpass import sys -from networking import PacketSenderManager, NetworkManager import NoGUIstuff import time import threading +from networking import PacketSenderManager, NetworkManager +from optparse import OptionParser wxImportError = False try: import wx @@ -97,21 +98,50 @@ class KeepConnectionAlive(threading.Thread): self.window.parent.loggedIn = True if __name__ == "__main__": - noGUI = False - if (len(sys.argv) > 1): - if (sys.argv.count("nogui") > 0) : - noGUI = True + + parser = OptionParser() + + parser.add_option("-n", "--nogui", + action="store_true", dest="noGUI", default=False, + help="don't use a GUI") + + parser.add_option("-u", "--username", dest="username", default="", + help="username to log in with (only with no gui mode)") + + parser.add_option("-p", "--password", dest="password", default="", + help="password to log in with (only with no gui mode)") + + parser.add_option("-s", "--server", dest="server", default="", + help="server to connect to (only with no gui mode)") + + 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") + + (options, args) = parser.parse_args() - if(noGUI or wxImportError): - user = raw_input("Enter your username: ") - passwd = getpass.getpass("Enter your password: ") + if(options.noGUI or wxImportError): + if(options.username != ""): + user = options.username + else: + user = raw_input("Enter your username: ") + if(options.password != ""): + passwd = options.password + else: + passwd = getpass.getpass("Enter your password: ") derp = NoGUIstuff.loginToMinecraft(user, passwd) - if(derp['Response'] == "Incorrect username/password" or derp['Response'] == "Can't connect to minecraft.net" or derp['Response'] == "Account migrated, use e-mail as username."): + if(derp['Response'] != "Good to go!"): print derp['Response'] - sys.exit() + sys.exit() sessionid = derp['SessionID'] print "Logged in as " + derp['Username'] + "! Your session id is: " + sessionid - stuff = raw_input("Enter host and port if any: ") + if(options.server != ""): + stuff = options.server + else: + stuff = raw_input("Enter host and port if any: ") if ':' in stuff: StuffEnteredIntoBox = stuff.split(":") host = StuffEnteredIntoBox[0] @@ -119,7 +149,7 @@ if __name__ == "__main__": else: host = stuff port = 25565 - connection = NetworkManager.ServerConnection(None, derp['Username'], passwd, sessionid, host, port) + connection = NetworkManager.ServerConnection(None, derp['Username'], passwd, sessionid, host, port, options) connection.start() while True: try: @@ -127,7 +157,7 @@ if __name__ == "__main__": if (connection.isConnected): PacketSenderManager.send03(connection.grabSocket(), chat_input) else: - pass + pass except KeyboardInterrupt, e: connection.disconnect() sys.exit(1)