def mapConnect(self, conn): mapsocket=socket.socket(socket.AF_INET, socket.SOCK_STREAM) mapsocket.connect(conn.server.mapServer()); packet='\x9b\x00\x37\x00' + struct.pack('4s', conn.accountID) + '\x00' + struct.pack('I', conn.charID) + '\x65\x32\x39\x00' + struct.pack('4s', conn.sessionID1) + struct.pack('4s', util.getTickCount(3)) + conn.sex mapsocket.send(packet) mapsocket.setblocking(1) def initialHandler(socket): header = socket.recv(2) if header == '\x83\x02': #Eat the account ID data = socket.recv(4) event.setSocketHandler(socket, self.receiveData) conn.mapSocket = socket conn.addEvent(lambda: self.syncLoop(conn), 0) self.connections[socket] = conn self.sendMapAck(socket) self.eventHandlers[socket] = {} conn.startScripts() else: header = struct.unpack('H', data[0:2]) socket.close() event.removeSocket(socket) return event.addSocket(mapsocket, initialHandler)
def connect(self, connection): accountsocket=socket.socket(socket.AF_INET, socket.SOCK_STREAM) accountsocket.connect(connection.server.accountServer()); md5obj = md5.new() md5obj.update(connection.password) md5sum=md5obj.digest() prefix='\xdd\x01\x8c\xa9\x00\x00' packet=prefix + struct.pack("24s16sb", connection.username, md5sum, 0x10) accountsocket.send(packet); accountsocket.setblocking(1) def loginParser(socket): data = socket.recv(1024) (header,) = struct.unpack('H', data[0:2]) if header == 0x6a: log.info("Rejected from server") return elif header == 0x69: (length,) = struct.unpack('H', data[2:4]) numServers = (length-47)/32 connection.accountID =data[8:12]; connection.sessionID1=data[4:8]; connection.sessionID2=data[12:16]; log.info("AccountId: %s SessionId1: %s SessionId2 %s", connection.accountID, connection.sessionID1, connection.sessionID2) connection.sex = data[46] socket.close() event.removeSocket(socket) event.addEvent(lambda: self.charLogin(connection), 0) #add the login socket to the event manager event.addSocket(accountsocket, loginParser)
def charLogin(self, conn): log.info("Logging in %s", conn.username) charsocket=socket.socket(socket.AF_INET, socket.SOCK_STREAM) charsocket.connect(conn.server.charServer()); packet=struct.pack("bx4s4s4sxxc", 0x65, conn.accountID, conn.sessionID1, conn.sessionID2, conn.sex); print len(packet), util.toHex(packet) charsocket.send(packet); charsocket.setblocking(1) def charParser(socket): data = socket.recv(1024) print len(data) if len(data) < 4: log.error("Char login bad error") return if data.startswith(conn.accountID): data = data[4:] if len(data) == 0: return (header,) = struct.unpack('H', data[0:2]) if header == 0x6c: log.error("Char login denied") return elif header == 0x81: log.error("Already logged in") return elif header == 0x71: mapname = data[6:22].split('\x00\x00')[0] conn.mapname = mapname socket.close() event.removeSocket(socket) event.addEvent(lambda: self.mapConnect(conn), 0) elif header == 0x6b: (length,) = struct.unpack('H', data[2:4]) if (length - 24) % 108 == 0: charlen = 108 elif (length - 24) % 106 == 0: charlen = 106 numChars = (length - 24) / charlen log.info("Number of characters: %d",numChars) for i in range(0, numChars): offset = 24 + i * charlen res = struct.unpack('IIIIIIIIIIHHHHHHHHHHHHHHHHH24sBBBBBBH', data[offset:offset+106]) if conn.slot == res[34]: conn.charID = res[0] log.info('CharId: %s', util.toHex(struct.pack('I', conn.charID))) conn.baseExp = res[1] conn.zeny = res[2] conn.jobExp = res[3] conn.jobLevel = res[4] conn.hp = res[11] conn.maxhp = res[12] conn.sp = res[13] conn.maxsp = res[14] conn.charname = res[27].split('\x00')[0] socket.send('\x87\x01' + conn.accountID); socket.send(struct.pack('bxb', 0x66, conn.slot)); event.addSocket(charsocket, charParser)