From 6ccbc8a55378660cd6bb79ccd6da80bf05d357b5 Mon Sep 17 00:00:00 2001 From: Ammar Askar Date: Tue, 4 Dec 2012 14:48:49 +0500 Subject: [PATCH] offline mode support --- networking/NetworkManager.py | 38 +++++++++++++++++++------------ start.py | 44 ++++++++++++++++++++++-------------- 2 files changed, 50 insertions(+), 32 deletions(-) diff --git a/networking/NetworkManager.py b/networking/NetworkManager.py index c5fb550..f646d11 100644 --- a/networking/NetworkManager.py +++ b/networking/NetworkManager.py @@ -18,12 +18,11 @@ EntityID = 0 class ServerConnection(threading.Thread): - def __init__(self, window, username, password, sessionID, server, port, options=None): + def __init__(self, window, username, sessionID, server, port, options=None): threading.Thread.__init__(self) self.options = options self.isConnected = False self.username = username - self.password = password self.sessionID = sessionID self.server = server self.port = port @@ -69,17 +68,16 @@ class ServerConnection(threading.Thread): #Generate a 16 byte (128 bit) shared secret self.sharedSecret = _UserFriendlyRNG.get_random_bytes(16) - #Grab the server id - sha1 = hashlib.sha1() - sha1.update(packetFD['ServerID']) - sha1.update(self.sharedSecret) - sha1.update(packetFD['Public Key']) - #lovely java style hex digest by barneygale - serverid = Utils.javaHexDigest(sha1) - #Authenticate the server from sessions.minecraft.net - if(serverid != '-'): + if(packetFD['ServerID'] != '-'): try: + #Grab the server id + sha1 = hashlib.sha1() + sha1.update(packetFD['ServerID']) + sha1.update(self.sharedSecret) + sha1.update(packetFD['Public Key']) + #lovely java style hex digest by barneygale + serverid = Utils.javaHexDigest(sha1) #Open up the url with the appropriate get parameters url = "http://session.minecraft.net/game/joinserver.jsp?user=" + self.username + "&sessionId=" + self.sessionID + "&serverId=" + serverid response = urllib2.urlopen(url).read() @@ -88,7 +86,7 @@ class ServerConnection(threading.Thread): print "Response from sessions.minecraft.net wasn't OK, it was " + response return False - #Success \o/ We can now begin sending our stuff to the server + #Success \o/ We can now begin sending our serverAddress to the server #Instantiate our main packet listener self.listener = PacketListener(self, self.window, self.socket, self.FileObject) @@ -106,7 +104,17 @@ class ServerConnection(threading.Thread): traceback.print_exc() else: print "Server is in offline mode" - #TODO: handle offline mod servers + #Instantiate our main packet listener + self.listener = PacketListener(self, self.window, self.socket, self.FileObject) + self.listener.start() + + #Encrypt the verification token from earlier along with our shared secret with the server's rsa key + self.RSACipher = PKCS1_v1_5.new(self.pubkey) + encryptedSanityToken = self.RSACipher.encrypt(str(packetFD['Token'])) + encryptedSharedSecret = self.RSACipher.encrypt(str(self.sharedSecret)) + + #Send out a a packet FC to the server + PacketSenderManager.sendFC(self.socket, encryptedSharedSecret, encryptedSanityToken) except Exception, e: print "Connection to server failed" traceback.print_exc() @@ -135,8 +143,8 @@ class EncryptedSocketObjectHandler(): self.socket = socket self.cipher = cipher - def send(self, stuff): - self.socket.send(self.cipher.encrypt(stuff)) + def send(self, serverAddress): + self.socket.send(self.cipher.encrypt(serverAddress)) def close(self): self.socket.close() diff --git a/start.py b/start.py index 475206b..2b048a8 100644 --- a/start.py +++ b/start.py @@ -24,6 +24,10 @@ if __name__ == "__main__": 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") + (options, args) = parser.parse_args() if(options.username != ""): @@ -32,29 +36,35 @@ if __name__ == "__main__": user = raw_input("Enter your username: ") if(options.password != ""): passwd = options.password - else: + elif(not options.offlineMode): passwd = getpass.getpass("Enter your password: ") - loginThread = Utils.MinecraftLoginThread(user, passwd) - loginThread.start() - loginThread.join() - derp = loginThread.getResponse() - if(derp['Response'] != "Good to go!"): - print derp['Response'] - sys.exit(1) - sessionid = derp['SessionID'] - print "Logged in as " + derp['Username'] + "! Your session id is: " + sessionid - if(options.server != ""): - stuff = options.server + + if (not options.offlineMode): + loginThread = Utils.MinecraftLoginThread(user, passwd) + loginThread.start() + loginThread.join() + loginResponse = loginThread.getResponse() + if(loginResponse['Response'] != "Good to go!"): + print loginResponse['Response'] + sys.exit(1) + sessionid = loginResponse['SessionID'] + user = loginResponse['Username'] + print "Logged in as " + loginResponse['Username'] + "! Your session id is: " + sessionid else: - stuff = raw_input("Enter host and port if any: ") - if ':' in stuff: - StuffEnteredIntoBox = stuff.split(":") + sessionid = None + + if(options.server != ""): + serverAddress = options.server + else: + serverAddress = raw_input("Enter host and port if any: ") + if ':' in serverAddress: + StuffEnteredIntoBox = serverAddress.split(":") host = StuffEnteredIntoBox[0] port = int(StuffEnteredIntoBox[1]) else: - host = stuff + host = serverAddress port = 25565 - connection = NetworkManager.ServerConnection(None, derp['Username'], passwd, sessionid, host, port, options) + connection = NetworkManager.ServerConnection(None, user, sessionid, host, port, options) connection.start() while True: try: