Command line interaction made much better, try start.py --help for details

Bumped up protocol version
Added packet dumping
Handle disconnects more cleanly
This commit is contained in:
Ammar Askar 2012-10-26 05:02:42 +05:00
parent 2a09899634
commit 7c1d5bdc39
4 changed files with 128 additions and 86 deletions

View File

@ -1,5 +1,4 @@
import urllib2, urllib import urllib2, urllib
from networking import PacketSenderManager
def loginToMinecraft(username, password): def loginToMinecraft(username, password):
try: try:
@ -14,14 +13,9 @@ def loginToMinecraft(username, password):
response = opener.open(req, None, 10) response = opener.open(req, None, 10)
response = response.read() response = response.read()
except urllib2.URLError: except urllib2.URLError:
toReturn = {'Response' : "Can't connect to minecraft.net"} return {'Response' : "Can't connect to minecraft.net"}
return toReturn if(not "deprecated" in response.lower()):
if(response == "Bad login"): return {'Response' : response}
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
response = response.split(":") response = response.split(":")
sessionid = response[3] sessionid = response[3]
toReturn = {'Response' : "Good to go!", toReturn = {'Response' : "Good to go!",

View File

@ -24,8 +24,9 @@ EntityID = 0
class ServerConnection(threading.Thread): 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) threading.Thread.__init__(self)
self.options = options
self.isConnected = False self.isConnected = False
self.username = username self.username = username
self.password = password self.password = password
@ -39,6 +40,7 @@ class ServerConnection(threading.Thread):
self.window = window self.window = window
def disconnect(self): def disconnect(self):
PacketSenderManager.sendFF(self.socket, "Disconnected by user")
self.listener.kill = True self.listener.kill = True
self.socket.close() self.socket.close()
@ -198,6 +200,9 @@ class PacketListener(threading.Thread):
self.encryptedConnection = True self.encryptedConnection = True
def run(self): def run(self):
if(self.connection.options != None and self.connection.options.dumpPackets):
f = open(self.connection.options.filename, 'w')
while True: while True:
if (self.kill): if (self.kill):
break break
@ -213,133 +218,136 @@ class PacketListener(threading.Thread):
sys.exit() sys.exit()
break break
if(response == "\x00"): if(response == "\x00"):
PacketListenerManager.handle00(self.FileObject, self.socket) packet = PacketListenerManager.handle00(self.FileObject, self.socket)
elif(response == "\x01"): elif(response == "\x01"):
packet01 = PacketListenerManager.handle01(self.FileObject) packet = PacketListenerManager.handle01(self.FileObject)
print "Logged in \o/ Received an entity id of " + str(packet01['EntityID']) print "Logged in \o/ Received an entity id of " + str(packet['EntityID'])
elif(response == "\x03"): elif(response == "\x03"):
message = PacketListenerManager.handle03(self.FileObject) packet = PacketListenerManager.handle03(self.FileObject)
if(self.connection.NoGUI): if(self.connection.NoGUI):
# Add "\x1b" because it is essential for ANSI escapes emitted by translate_escapes # 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 message.replace(u'\xa7', '&')
print filtered_string print filtered_string
packet = {'Message' : filtered_string}
elif(self.window): elif(self.window):
self.window.handleChat(message) self.window.handleChat(packet)
elif(response == "\x04"): elif(response == "\x04"):
PacketListenerManager.handle04(self.FileObject) packet = PacketListenerManager.handle04(self.FileObject)
elif(response == "\x05"): elif(response == "\x05"):
PacketListenerManager.handle05(self.FileObject) packet = PacketListenerManager.handle05(self.FileObject)
elif(response == "\x06"): elif(response == "\x06"):
PacketListenerManager.handle06(self.FileObject) packet = PacketListenerManager.handle06(self.FileObject)
elif(response == "\x07"): elif(response == "\x07"):
PacketListenerManager.handle07(self.FileObject) packet = PacketListenerManager.handle07(self.FileObject)
elif(response == "\x08"): elif(response == "\x08"):
PacketListenerManager.handle08(self.FileObject) packet = PacketListenerManager.handle08(self.FileObject)
elif(response == "\x09"): elif(response == "\x09"):
PacketListenerManager.handle09(self.FileObject) packet = PacketListenerManager.handle09(self.FileObject)
elif(response == "\x0D"): elif(response == "\x0D"):
PacketListenerManager.handle0D(self.FileObject) packet = PacketListenerManager.handle0D(self.FileObject)
elif(response == "\x11"): elif(response == "\x11"):
PacketListenerManager.handle11(self.FileObject) packet = PacketListenerManager.handle11(self.FileObject)
elif(response == "\x12"): elif(response == "\x12"):
PacketListenerManager.handle12(self.FileObject) packet = PacketListenerManager.handle12(self.FileObject)
elif(response == "\x14"): elif(response == "\x14"):
PacketListenerManager.handle14(self.FileObject) packet = PacketListenerManager.handle14(self.FileObject)
elif(response == "\x15"): elif(response == "\x15"):
PacketListenerManager.handle15(self.FileObject) packet = PacketListenerManager.handle15(self.FileObject)
elif(response == "\x16"): elif(response == "\x16"):
PacketListenerManager.handle16(self.FileObject) packet = PacketListenerManager.handle16(self.FileObject)
elif(response == "\x17"): elif(response == "\x17"):
PacketListenerManager.handle17(self.FileObject) packet = PacketListenerManager.handle17(self.FileObject)
elif(response == "\x18"): elif(response == "\x18"):
PacketListenerManager.handle18(self.FileObject) packet = PacketListenerManager.handle18(self.FileObject)
elif(response == "\x19"): elif(response == "\x19"):
PacketListenerManager.handle19(self.FileObject) packet = PacketListenerManager.handle19(self.FileObject)
elif(response == "\x1A"): elif(response == "\x1A"):
PacketListenerManager.handle1A(self.FileObject) packet = PacketListenerManager.handle1A(self.FileObject)
elif(response == "\x1C"): elif(response == "\x1C"):
PacketListenerManager.handle1C(self.FileObject) packet = PacketListenerManager.handle1C(self.FileObject)
elif(response == "\x1D"): elif(response == "\x1D"):
PacketListenerManager.handle1D(self.FileObject) packet = PacketListenerManager.handle1D(self.FileObject)
elif(response == "\x1E"): elif(response == "\x1E"):
PacketListenerManager.handle1E(self.FileObject) packet = PacketListenerManager.handle1E(self.FileObject)
elif(response == "\x1F"): elif(response == "\x1F"):
PacketListenerManager.handle1F(self.FileObject) packet = PacketListenerManager.handle1F(self.FileObject)
elif(response == "\x20"): elif(response == "\x20"):
PacketListenerManager.handle20(self.FileObject) packet = PacketListenerManager.handle20(self.FileObject)
elif(response == "\x21"): elif(response == "\x21"):
PacketListenerManager.handle21(self.FileObject) packet = PacketListenerManager.handle21(self.FileObject)
elif(response == "\x22"): elif(response == "\x22"):
PacketListenerManager.handle22(self.FileObject) packet = PacketListenerManager.handle22(self.FileObject)
elif(response == "\x23"): elif(response == "\x23"):
PacketListenerManager.handle23(self.FileObject) packet = PacketListenerManager.handle23(self.FileObject)
elif(response == "\x26"): elif(response == "\x26"):
PacketListenerManager.handle26(self.FileObject) packet = PacketListenerManager.handle26(self.FileObject)
elif(response == "\x27"): elif(response == "\x27"):
PacketListenerManager.handle27(self.FileObject) packet = PacketListenerManager.handle27(self.FileObject)
elif(response == "\x28"): elif(response == "\x28"):
PacketListenerManager.handle28(self.FileObject) packet = PacketListenerManager.handle28(self.FileObject)
elif(response == "\x29"): elif(response == "\x29"):
PacketListenerManager.handle29(self.FileObject) packet = PacketListenerManager.handle29(self.FileObject)
elif(response == "\x2A"): elif(response == "\x2A"):
PacketListenerManager.handle2A(self.FileObject) packet = PacketListenerManager.handle2A(self.FileObject)
elif(response == "\x2B"): elif(response == "\x2B"):
PacketListenerManager.handle2B(self.FileObject) packet = PacketListenerManager.handle2B(self.FileObject)
elif(response == "\x33"): elif(response == "\x33"):
PacketListenerManager.handle33(self.FileObject) PacketListenerManager.handle33(self.FileObject)
packet = {'PlaceHolder' : 0}
elif(response == "\x34"): elif(response == "\x34"):
PacketListenerManager.handle34(self.FileObject) packet = PacketListenerManager.handle34(self.FileObject)
elif(response == "\x35"): elif(response == "\x35"):
PacketListenerManager.handle35(self.FileObject) packet = PacketListenerManager.handle35(self.FileObject)
elif(response == "\x36"): elif(response == "\x36"):
PacketListenerManager.handle36(self.FileObject) packet = PacketListenerManager.handle36(self.FileObject)
elif(response == "\x37"): elif(response == "\x37"):
PacketListenerManager.handle37(self.FileObject) packet = PacketListenerManager.handle37(self.FileObject)
elif(response == "\x38"): elif(response == "\x38"):
PacketListenerManager.handle38(self.FileObject) PacketListenerManager.handle38(self.FileObject)
packet = {'PlaceHolder' : 0}
elif(response == "\x3C"): elif(response == "\x3C"):
PacketListenerManager.handle3C(self.FileObject) packet = PacketListenerManager.handle3C(self.FileObject)
elif(response == "\x3D"): elif(response == "\x3D"):
PacketListenerManager.handle3D(self.FileObject) packet = PacketListenerManager.handle3D(self.FileObject)
elif(response == "\x3E"): elif(response == "\x3E"):
PacketListenerManager.handle3E(self.FileObject) packet = PacketListenerManager.handle3E(self.FileObject)
elif(response == "\x46"): elif(response == "\x46"):
PacketListenerManager.handle46(self.FileObject) packet = PacketListenerManager.handle46(self.FileObject)
elif(response == "\x47"): elif(response == "\x47"):
PacketListenerManager.handle47(self.FileObject) packet = PacketListenerManager.handle47(self.FileObject)
elif(response == "\x64"): elif(response == "\x64"):
PacketListenerManager.handle64(self.FileObject) packet = PacketListenerManager.handle64(self.FileObject)
elif(response == "\x65"): elif(response == "\x65"):
PacketListenerManager.handle65(self.FileObject) packet = PacketListenerManager.handle65(self.FileObject)
elif(response == "\x67"): elif(response == "\x67"):
PacketListenerManager.handle67(self.FileObject) packet = PacketListenerManager.handle67(self.FileObject)
elif(response == "\x68"): elif(response == "\x68"):
PacketListenerManager.handle68(self.FileObject) packet = PacketListenerManager.handle68(self.FileObject)
elif(response == "\x69"): elif(response == "\x69"):
PacketListenerManager.handle69(self.FileObject) packet = PacketListenerManager.handle69(self.FileObject)
elif(response == "\x6A"): elif(response == "\x6A"):
PacketListenerManager.handle6A(self.FileObject) packet = PacketListenerManager.handle6A(self.FileObject)
elif(response == "\x6B"): elif(response == "\x6B"):
PacketListenerManager.handle6B(self.FileObject) packet = PacketListenerManager.handle6B(self.FileObject)
elif(response == "\x82"): elif(response == "\x82"):
PacketListenerManager.handle82(self.FileObject) packet = PacketListenerManager.handle82(self.FileObject)
elif(response == "\x83"): elif(response == "\x83"):
PacketListenerManager.handle83(self.FileObject) packet = PacketListenerManager.handle83(self.FileObject)
elif(response == "\x84"): elif(response == "\x84"):
PacketListenerManager.handle84(self.FileObject) packet = PacketListenerManager.handle84(self.FileObject)
elif(response == "\xC8"): elif(response == "\xC8"):
PacketListenerManager.handleC8(self.FileObject) packet = PacketListenerManager.handleC8(self.FileObject)
elif(response == "\xC9"): elif(response == "\xC9"):
PacketListenerManager.handleC9(self.FileObject) packet = PacketListenerManager.handleC9(self.FileObject)
elif(response == "\xCA"): elif(response == "\xCA"):
PacketListenerManager.handleCA(self.FileObject) packet = PacketListenerManager.handleCA(self.FileObject)
elif(response == "\xCB"): elif(response == "\xCB"):
PacketListenerManager.handleCB(self.FileObject) packet = PacketListenerManager.handleCB(self.FileObject)
elif(response == "\xFA"): elif(response == "\xFA"):
PacketListenerManager.handleFA(self.FileObject) packet = PacketListenerManager.handleFA(self.FileObject)
elif(response == "\xFC"): elif(response == "\xFC"):
PacketListenerManager.handleFC(self.FileObject) packet = PacketListenerManager.handleFC(self.FileObject)
if (not self.encryptedConnection): if (not self.encryptedConnection):
self.enableEncryption() self.enableEncryption()
self.connection.isConnected = True self.connection.isConnected = True
@ -355,9 +363,15 @@ class PacketListener(threading.Thread):
if(hasattr(self.window, 'Status')): if(hasattr(self.window, 'Status')):
self.window.Status.SetLabel("Disconnected: " + DisconMessage) self.window.Status.SetLabel("Disconnected: " + DisconMessage)
self.socket.close() self.socket.close()
sys.exit(1)
break break
else: else:
if(self.window == None): if(self.window == None):
print "Protocol error: " + hex(ord(response)) print "Protocol error: " + hex(ord(response))
self.socket.close() self.socket.close()
if(f != None):
f.close()
sys.exit(1)
break break
if(self.connection.options != None and self.connection.options.dumpPackets):
f.write(hex(ord(response)) + " : " + str(packet) + '\n')

View File

@ -6,7 +6,7 @@ def sendHandshake(socket, username, host, port):
socket.send("\x02") socket.send("\x02")
#byte - protocol version #byte - protocol version
socket.send(struct.pack('!b', 39)) socket.send(struct.pack('!b', 47))
#string - username #string - username
socket.send(struct.pack('!h', username.__len__())) socket.send(struct.pack('!h', username.__len__()))
@ -44,4 +44,8 @@ def sendFC(socket, secret, token):
#token #token
socket.send(struct.pack('!h', token.__len__())) #length socket.send(struct.pack('!h', token.__len__())) #length
socket.send(token) socket.send(token)
def sendFF(socket, reason):
socket.send(struct.pack('!h', reason.__len__())) #length
socket.send(reason.encode("utf-16be")) #message

View File

@ -2,10 +2,11 @@ import urllib
import urllib2 import urllib2
import getpass import getpass
import sys import sys
from networking import PacketSenderManager, NetworkManager
import NoGUIstuff import NoGUIstuff
import time import time
import threading import threading
from networking import PacketSenderManager, NetworkManager
from optparse import OptionParser
wxImportError = False wxImportError = False
try: try:
import wx import wx
@ -97,21 +98,50 @@ class KeepConnectionAlive(threading.Thread):
self.window.parent.loggedIn = True self.window.parent.loggedIn = True
if __name__ == "__main__": if __name__ == "__main__":
noGUI = False
if (len(sys.argv) > 1): parser = OptionParser()
if (sys.argv.count("nogui") > 0) :
noGUI = True 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): if(options.noGUI or wxImportError):
user = raw_input("Enter your username: ") if(options.username != ""):
passwd = getpass.getpass("Enter your password: ") 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) 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'] print derp['Response']
sys.exit() sys.exit()
sessionid = derp['SessionID'] sessionid = derp['SessionID']
print "Logged in as " + derp['Username'] + "! Your session id is: " + 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: if ':' in stuff:
StuffEnteredIntoBox = stuff.split(":") StuffEnteredIntoBox = stuff.split(":")
host = StuffEnteredIntoBox[0] host = StuffEnteredIntoBox[0]
@ -119,7 +149,7 @@ if __name__ == "__main__":
else: else:
host = stuff host = stuff
port = 25565 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() connection.start()
while True: while True:
try: try:
@ -127,7 +157,7 @@ if __name__ == "__main__":
if (connection.isConnected): if (connection.isConnected):
PacketSenderManager.send03(connection.grabSocket(), chat_input) PacketSenderManager.send03(connection.grabSocket(), chat_input)
else: else:
pass pass
except KeyboardInterrupt, e: except KeyboardInterrupt, e:
connection.disconnect() connection.disconnect()
sys.exit(1) sys.exit(1)