class Database(): ''' INFO: ALWAYS close the Instans to close the Connection ''' def __init__(self): self.log = Logging() self.log.debug('Database instance has been created') def initialize_data(self): pass #initialize_connection def get_connection(self): config = Config() config.initialize() try: connection = pymysql.connect( host=config.get_host(), port=config.get_port(), user=config.get_user(), password=config.get_pass(), db=config.get_database_name(), cursorclass=pymysql.cursors.DictCursor) return connection except pymysql.Error as Error: self.log.warning('Database - initialize_connection\n' + 'Config: ' + str(config.get_host()) + ' - ' + str(config.get_port()) + ' - ' + str(config.get_user()) + ' - ' + str(config.get_pass()) + ' - ' + str(config.get_database_name()) + '\nDatabase - inicon - Something went wrong: {}'. format(str(Error))) return False
class Database(): ''' INFO: ALWAYS close the Instans to close the Connection ''' def __init__(self): self.log = Logging() self.log.debug('Database instance has been created') def initialize_data(self): pass #initialize_connection def get_connection(self): config = Config() config.initialize() try: connection = mysql.connector.connect( host=config.get_world_db_host(), port=config.get_world_db_port(), user=config.get_world_db_user(), password=config.get_world_db_passwo(), db=config.get_world_db_name(), auth_plugin='mysql_native_password') return connection except mysql.connector.Error as Error: self.log.warning( 'Database - initialize_connection\n' + 'Config: ' + str(config.get_world_db_host()) + ' - ' + str(config.get_world_db_port()) + ' - ' + str(config.get_world_db_user()) + ' - ' + str(config.get_world_db_passwo()) + ' - ' + str(config.get_world_db_name()) + '\nDatabase - Something went wrong: {}'.format(str(Error))) return False
class ExchangeClient(): def __init__(self): self.log = Logging() def send(self, i): msg = bytes(i, 'utf-8') self.log.debug('[{}:{}][EX-SEND->] {}'.format(str(self.addr[0]), str(self.addr[1]), i)) self.IoSession.send(msg) def kick(self): self.log.info('[{}:{}] Exchange Client has disconnected'.format(str(self.addr[0]), str(self.addr[1]))) sys.exit(0) def set_addr(self, addr): self.addr = addr def get_addr(self): return self.addr def get_id(self): return self.id def set_id(self, i): self.id = i def get_io_session(self): return self.IoSession def set_io_session(self, s): self.IoSession = s
class Main: def __init__(self): self.log = Logging() self.config = Config() self.console = Console() self.console.clear() def start(self): # ====================================================== # start message def clear(): return os.system('cls') clear() def wel(): welmsg = [ 58 * '─', '| 0.01 |' + 12 * ' ' + 'pyCestra - World Server' + 11 * ' ' + '|', 58 * "─" ] for x in welmsg: print(bcolors.blue + x + bcolors.cend) wel() # ====================================================== # connection test self.log.info('Connection Test...') database = dataSource.Database() if database.get_connection(): self.log.info('Connection Successfully') else: self.log.warning('Connection ERROR') sys.exit(0) # ====================================================== # world class test world = World() world.createWorld() # ====================================================== # exchange client test exchangeTransferList = [] exClient = ExchangeClient() exClient.initialize(self.config.get_exchange_ip(), self.config.get_exchange_port(), exchangeTransferList) self.log.debug('Game Server Start') GameServer().initialize(self.config.get_world_ip(), self.config.get_world_port(), exchangeTransferList, world)
class LoginServer: def __init__(self, ip, port, gameClientDic, accountDataDic, hostList, ipBans): self.log = Logging() self.logoniIP = ip self.logonPort = port self.gameClientDic = gameClientDic self.accountDataDic = accountDataDic self.hostList = hostList self.ipBans = ipBans self.start() def start(self): threadName = 'Login-Server - ' + str(self.logonPort) try: t = threading.Thread(target=self.server, name=threadName, args=(self.logoniIP, self.logonPort, self.gameClientDic, self.accountDataDic, self.hostList, self.ipBans)) t.start() except threading.ThreadError as e: self.log.warning('Login Server could not be created: ' + str(e)) def server(self, logoniIP, logonPort, gameClientDic, accountDataDic, hostList, ipBans): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: s.bind((self.logoniIP, self.logonPort)) except socket.error: print('Login Socket - Binding faild') s.listen() self.log.info('Logon Socket is listening on Port: ' + str(self.logonPort)) while True: c, self.addr = s.accept() self.log.info('[{}:{}] Client Connected '.format( str(self.addr[0]), str(self.addr[1]))) self.session_created(c, self.addr) s.close() def session_created(self, soecket, addr): threadName = 'Client-Session ' + str(addr[0]) + ':' + str(addr[1]) try: t = threading.Thread(target=LoginHandler, name=threadName, args=(soecket, addr, self.gameClientDic, self.accountDataDic, self.hostList, self.ipBans)) t.start() except threading.ThreadError as e: self.log.debug('Created Session ' + str(addr[0]) + ':' + str(addr[1]) + ': ' + str(e))
class DatabaseUpdateService: def __init__(self): self.log = Logging() def start(self, accountDic, updateTime): threadName = 'Database-Update-Service' try: t = threading.Thread(target=DatabaseUpdateService.update_loop, name=threadName, args=(self, accountDic, updateTime)) t.start() self.log.info('Database-Update-Service Successfully') except: self.log.warning('Database-Update-Service could not be created') def update_loop(self, accountDic, updateTime): def string_builder(i): queryPart = ('UPDATE `accounts` SET ' '`pass` = \'{}\',' '`rank` = \'{}\',' '`nickname` = \'{}\',' '`lastConnectionDate` = \'{}\',' '`lastIP` = \'{}\',' '`friends` = \'{}\',' '`reload_needed` = \'{}\',' '`logged` = \'{}\',' '`subscribe` = \'{}\' ' 'WHERE (`id` = \'{}\');'.format( i["pass"], i["rank"], i["nickname"], i["lastConnectionDate"], i["lastIP"], i["friends"], i["reload_needed"], i["logged"], i["subscribe"], i["id"])) return queryPart dao = DAO() while True: time.sleep(updateTime) self.log.debug('[Database-Update-Service] - ' 'Data is send to the database') start = time.time() counter = 0 for i in accountDic: query = string_builder(i) dao.multi_update_data(query) del query counter = counter + 1 ende = time.time() self.log.debug('[Database-Update-Service] - Data was transferred ' '(query:{}, total time: {:5.3f}s)'.format( counter, ende - start))
class ExchangePacketHandler: def __init__(self): self.log = Logging() def parser(self, packet, exClient): if packet[0] == 'F': if packet[1] == '?': # F? # i = 50000 - Main.gameServer.getPlayerNumber() # exchangeClient.send("F" + i) return return elif packet[0] == 'S': if packet[1] == 'H': if packet[2] == 'K': # SHK self.log.debug( 'The Logon-Server validates the connection successfully.' ) return return elif packet[1] == 'K': if packet[2] == '?': # SK? i = 50000 - 0 # Main.gameServer.getPlayerNumber() # TODO Main.exchangeClient.send("SK" + Main.serverId + ";" + Main.key + ";" + i) ExchangePacketHandler().send(exClient, 'SK1;demo;' + str(i)) return elif packet[2] == 'K': # SKK self.log.debug( 'The Logon-Server has accepted the connection') # TODO Main.exchangeClient.send("SH" + Main.Ip + ";" + Main.gamePort) ExchangePacketHandler().send( exClient, 'SH' + '127.0.0.1' + ';' + '5555') return elif packet[2] == 'R': # SKR # self.log.debug('The login server refused the connection') # Main.stop() return return return elif packet[0] == 'W': # if (packet.split("W").length > 2) # magic ! if packet[1] == 'A': # WA return elif packet[1] == 'K': # WK return return elif packet[0] == 'M': if packet[1] == 'G': # MG return if packet[1] == 'F': # MF return if packet[1] == 'D': # MD return return def send(self, exClient, o): msg = bytes(o, 'utf-8') self.log.debug('[logon ip]' + '[EX-SEND->] ' + o) exClient.send(msg)
class HelloConnection(): def __init__(self, c, ipbans): self.log = Logging() client = c # We send the first package (HC + KEY + empty byte) client.write('HC' + client.get_key()) # We are waiting for the client version data = client.get_io_session().recv(2048) msg = data.decode() if not (msg == '1.30.9\n\x00' or msg == '1.29.1\n\x00' or msg == '1.30.0\n\x00' or msg == '1.31.2\n\x00'): self.log.debug('[' + str(client.get_address()[0]) + ':' + str(client.get_address()[1]) + '][' + str(client.get_status().name) + '] The client has the wrong version - ' + '(' + str(msg.split('\n')[0]) + ')') # TODO wrong text window is displayed "Invalid login or password." client.write('AlEf') sys.exit(0) for i in ipbans: if client.get_address()[0] == i['ip']: self.log.debug('[' + str(client.get_address()[0]) + ':' + str(client.get_address()[1]) + ']' + '[' + str(client.get_status().name) + '] ' + 'This IP is banned') client.write('AlEb') client.kick() self.log.debug('[' + str(client.get_address()[0]) + ':' + str(client.get_address()[1]) + '][' + str(client.get_status().name) + '] Version accepted ' + '(' + str(msg.split('\n')[0]) + ')') return
class GameServer: def __init__(self): self.log = Logging() def initialize(self, ip, port, exchangeTransferList, world): self.world = world threadName = 'Game-Server - ' + str(port) try: t = threading.Thread(target=self.server, name=threadName, args=(ip, port, exchangeTransferList)) t.start() except threading.ThreadError as e: self.log.warning('Game Server could not be created: ' + str(e)) def server(self, game_ip, game_port, exchangeTransferList): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: s.bind((game_ip, game_port)) except socket.error: self.log.warning('Game Socket - Binding faild') s.listen() self.log.info('Game Socket is listening on Port: ' + str(game_port)) while True: c, self.addr = s.accept() self.log.debug('[{}:{}] Client Connected '.format(str(self.addr[0]),str(self.addr[1]))) self.session_created(c, self.addr, exchangeTransferList) s.close() def session_created(self, socket, addr, exchangeTransferList): threadName = 'Game-Client-Session '+str(addr[0])+':'+ str(addr[1]) try: t = threading.Thread(target=GameHandler, name=threadName, args=(socket, addr, exchangeTransferList, self.world,)) t.start() except: self.log.warning('Game Client could not be created '+ str(addr[0])+':'+ str(addr[1]))
class LoginHandler: def __init__(self, soecket, addr, gameClientDic, accountDataDic, hostList, ipbans): self.log = Logging() self.gameClientDic = gameClientDic self.accountDataDic = accountDataDic self.hostList = hostList self.client = LoginClient(self.gameClientDic, self.accountDataDic) self.client.set_key(self.generate_key()) self.client.set_address(addr) self.client.set_status(Status(0)) self.client.set_io_session(soecket) self.log.debug('[' + str(addr[0]) + ':' + str(addr[1]) + '][' + str(self.client.get_status().name) + '] Client created - ' + self.client.get_key()) # the object is save in the global dictionary dict_str = addr[0] + ':' + str(addr[1]) self.gameClientDic[dict_str] = self.client HelloConnection(self.client, ipbans) self.recv_loop() def recv_loop(self): packetHandler = PacketHandler() while True: data = self.client.get_io_session().recv(2048) packet = data.decode() packetPrint = packet.replace('\n', '[n]') self.log.debug('[' + str(self.client.get_address()[0]) + ':' + str(self.client.get_address()[1]) + ']' + '[' + str(self.client.get_status().name) + '][<-RECV] ' + packetPrint) if not data: self.log.debug('[' + str(self.client.get_address()[0]) + ':' + str(self.client.get_address()[1]) + ']' + '[' + str(self.client.get_status().name) + '] PacketLoop no data') self.client.kick() break packetHandler.parser(self.client, packet, self.gameClientDic, self.accountDataDic, self.hostList) def send_to_all(self): pass def generate_key(self): key = '' alphabet = 'abcdefghijklmnopqrstuvwxyz' while len(key) < 32: char = random.choice(alphabet) key += char # key = key[:-1] return key
class ExchangeHandler: def __init__(self): self.log = Logging() def loop(self, exSocket): self.log.debug('Exchange-Receiver is started') while True: data = exSocket.recv(2048) packet = data.decode() packetLog = packet.replace('\n', '[]') self.log.debug('[logon ip][<-EX-RECV] ' + packetLog) if not data: self.log.debug('[logon ip] PacketLoop no data') # kick break ExchangePacketHandler().parser(packet, exSocket)
class ServerSelected(): def __init__(self, client, packet, accountDataDic, hostList): self.log = Logging() account = client.get_account() packet = packet.replace('\n\x00', '') packet = int(packet) server = None def get_free_server(hostList): msg = 'AXEf' for s in hostList: try: fp = s.get_free_places() except AttributeError: fp = 0 if s.get_sub() != 0 or fp > 0: continue msg += str(s.get_id()) + '|' return msg try: # server is searched from the host list for i in hostList: if i.get_id() == packet: server = i self.log.debug('[{}:{}][{}] Server {} has been selected'.format( str(client.get_address()[0]), str(client.get_address()[1]), str(client.get_status().name), packet)) # client is kicked if this server id does not exist if server is None: self.log.debug( '[{}:{}][{}] The selected server does not exist for the account' .format(str(client.get_address()[0]), str(client.get_address()[1]), str(client.get_status().name))) # clinet msg: You are not allowed to connect to this server. client.write('AXEr') return # the selected server is not in the correct status for the account if server.get_status() != 1: self.log.debug( '[{}:{}][{}] The status of the selected server is unavailable for the account' .format(str(client.get_address()[0]), str(client.get_address()[1]), str(client.get_status().name))) # clinet msg: The server you selected is unavailable at this time. client.write('AXEd') return # the selected server is only available to subscribers if account.is_subscribes() == 0 and server.get_sub() == 1: self.log.debug( '[{}:{}][{}] The selected server is full or you must be subscribed for the account' .format(str(client.get_address()[0]), str(client.get_address()[1]), str(client.get_status().name))) # clinet msg: Server:FULL Maximum number of players reached. # To get priority access, please becomme a full member by subscribing.. client.write(get_free_server(hostList)) ServerList().get_list(client) return account.set_server(server.get_id()) # all important account data are sent to the game server for __i in accountDataDic: if __i['id'] == account.get_id(): lastConnectionDate = __i['lastConnectionDate'] lastIP = __i['lastIP'] server.get_ex_client().send('WA#{}#{}#{}#{}#{}#{}#{}'.format( str(account.get_id()), account.get_nickname(), account.get_question(), account.get_reponse(), account.get_subscribe(), lastConnectionDate, lastIP)) # the address of the world server is sent to the client client.write('AYK{}:{};{}'.format(str(server.get_ip()), str(server.get_port()), str(account.get_id()))) # set client status to WAIT_VERSION account.set_state(0) self.log.info( '[{}:{}][{}] Client connects to World-Server:{}'.format( str(client.get_address()[0]), str(client.get_address()[1]), str(client.get_status().name), str(server.get_id()))) except Exception as e: self.log.warning( '[{}:{}][{}] The server selection failed\n{}'.format( str(client.get_address()[0]), str(client.get_address()[1]), str(client.get_status().name), e)) client.write('AXEr') client.kick() return
class PacketHandler: def __init__(self): self.log = Logging() def parser(self, client, packet, game_client_dic, accountDataDic, hostList): # client arrived here, the version has been checked if client.get_status().name == Status.WAIT_VERSION.name: # set client status to WAIT_ACCOUNT client.set_status(Status(2)) self.log.debug('[' + str(client.get_address()[0]) + ':' + str(client.get_address()[1]) + ']' + '[' + str(client.get_status().name) + '] Status change') if client.get_status().name == Status.WAIT_ACCOUNT.name: verifyAccountName = PacketHandler().verify_account_name( client, packet.split('\n')[0], accountDataDic) verifyPassword = PacketHandler().verify_password( client, packet.split('\n')[1]) if not (verifyAccountName and verifyPassword): self.log.debug('[' + str(client.get_address()[0]) + ':' + str(client.get_address()[1]) + ']' + '[' + str(client.get_status().name) + '] Login credentials incorrect') client.write('AlEf') if client.get_status().name == Status.WAIT_NICKNAME.name: ChooseNickName().verify(client, packet[:-2], accountDataDic, hostList) return if client.get_status().name == Status.SERVER.name: if (packet[0:2] == 'AF') or (packet[-4:-2] == 'AF'): # FriendServerList.get(client, packet) print('packet[0:2] == AF:') elif (packet[0:2] == 'AX') or (packet[-4:-2] == 'AX'): # ServerSelected.get() print('packet[0:2] == AX:') elif (packet[0:2] == 'Af') or (packet[-4:-2] == 'Af'): account = client.get_account() for game_client in game_client_dic.values(): if not game_client.get_key() == client.get_key(): dic_account = game_client.get_account() if dic_account.get_id() == account.get_id(): self.log.debug( '[' + str(client.get_address()[0]) + ':' + str(client.get_address()[1]) + ']' + '[' + str(client.get_status().name) + '] ' + 'this account is already logged in ...' + 'the other session is now closed') game_client.kick() AccountQueue().verify(client, accountDataDic, hostList) return elif (packet[0:2] == 'Ax') or (packet[-4:-2] == 'Ax'): ServerList().get_list(client) return client.kick() client.kick() def verify_account_name(self, client, name, accountDataDic): # accountDataDic is checked whether the account exists def load_from_result_set(resultSet): account = Account() account.set_id(resultSet['id']) account.set_name(resultSet['account']) account.set_pass(resultSet['pass']) account.set_nickname(resultSet['nickname']) account.set_question(resultSet['question']) account.set_state(resultSet['logged']) account.set_subscribe(resultSet['subscribe']) account.set_banned(resultSet['banned']) account.set_staff(resultSet['rank']) return account for i in accountDataDic: if i['account'] == name: account = load_from_result_set(i) client.set_account(account) break else: account = 0 if account == 0: return False client.get_account().set_client(client) # set client status to WAIT_PASSWORD client.set_status(Status(1)) self.log.debug('[' + str(client.get_address()[0]) + ':' + str(client.get_address()[1]) + ']' + '[' + str(client.get_status().name) + '] Status change') return True def verify_password(self, client, password): account = client.get_account() if account == 0: return False if not PacketHandler().decrypt_password( password[2:], client.get_key()) == account.get_pass(): return False # set client status to SERVER client.set_status(Status(4)) self.log.debug('[' + str(client.get_address()[0]) + ':' + str(client.get_address()[1]) + ']' + '[' + str(client.get_status().name) + '] Status change') return True def decrypt_password(self, passs, key): _Chaine = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_" _decrypted = "" for i in range(len(passs) // 2): _PKey = ord(key[i]) _ANB = _Chaine.index(passs[i * 2]) _ANB2 = _Chaine.index(passs[i * 2 + 1]) _somme1 = _ANB + len(_Chaine) _somme2 = _ANB2 + len(_Chaine) _APass = _somme1 - _PKey if _APass < 0: _APass += 64 _APass *= 16 _AKey = _somme2 - _PKey if _AKey < 0: _AKey += 64 _PPass = chr(_APass + _AKey) _decrypted = _decrypted + _PPass return _decrypted
class AccountQueue: def __init__(self): self.log = Logging() def verify(self, client, accountDataDic, hostList): account = client.get_account() if account.is_banned() == 1: self.log.debug('[' + str(client.get_address()[0]) + ':' + str(client.get_address()[1]) + ']' + '[' + str(client.get_status().name) + '] ' + 'The account is banned') client.write('AlEb') client.kick() return AccountQueue().send_information(client, account, accountDataDic, hostList) def send_information(self, client, account, accountDataDic, hostList): if account.get_nickname() == '': client.write('AlEr') # set client status to WAIT_NICKNAME client.set_status(Status(3)) self.log.debug('[' + str(client.get_address()[0]) + ':' + str(client.get_address()[1]) + ']' + '[' + str(client.get_status().name) + '] Status change') return self.log.debug('[' + str(client.get_address()[0]) + ':' + str(client.get_address()[1]) + ']' + '[' + str(client.get_status().name) + '] Sending account login information') # database.getPlayerData().load(account) client.write('Af0|0|0|1|-1') client.write('Ad' + account.get_nickname()) client.write('Ac0') # ----------------------------------------- # DEMO # client.write(Server.getHostList()) # AH ID ; STATUS ; 110 ; 1 | hostListStr = 'AH' for i in hostList: hostListStr += str(i.get_id()) + ';' + str( i.get_status()) + ';110;1|' client.write(hostListStr) # ----------------------------------------- client.write('AlK' + str(account.is_staff())) client.write('AQ' + account.get_question()) # ----------------------------------------- # Update lastConnectionDate and lastIP now = datetime.datetime.now() for i in accountDataDic: if i['id'] == account.get_id(): i['lastConnectionDate'] = now.strftime("%Y-%m-%d %H:%M:%S") i['lastIP'] = client.get_address()[0] i['logged'] = 1 self.log.debug('[' + str(client.get_address()[0]) + ':' + str(client.get_address()[1]) + ']' + '[' + str(client.get_status().name) + '] lastConnectionDate and lastIP update') self.log.debug('[' + str(client.get_address()[0]) + ':' + str(client.get_address()[1]) + ']' + '[' + str(client.get_status().name) + '] logged from 0 to 1 update')
class GameHandler: def __init__(self, socket, addr, exchangeTransferList, world): self.log = Logging() self.world = world self.gameClient = GameClient(socket, addr) self.exchangeTransferList = exchangeTransferList self.socketManager = SocketManager(self.gameClient) self.accId = None self.account = None self.socketManager.GAME_SEND_HELLOGAME_PACKET() self.loop() def loop(self): while True: data = self.gameClient.get_session().recv(2048) packet = data.decode() packetLog = packet.replace('\n\x00', '[n][x00]') self.log.debug('[{}][ACC:{}][<-RECV] {}'.format(str(self.gameClient.get_addr()[0]), str(self.acc_display_number()), str(packetLog))) if not data: self.log.debug('[{}][ACC:{}] PacketLoop no data'.format(str(self.gameClient.get_addr()[0]), str('X'))) self.gameClient.kick() break multiPacket = packet.split("\n\x00") if len(multiPacket) > 2: for p in multiPacket: if not p == '': self.parse(p) else: self.parse(packet.replace('\n\x00', '')) def acc_display_number(self): if type(self.accId) != int: if self.account == None: self.accId = 'X' else: self.accId = self.gameClient.get_account().get_id() return self.accId # -------------------------------------------------------------------- # PARSE ACCOUNT PACKET def add_character(self, packet): __packetList = packet[2:].split('|') __forbiddenWords = [r'[Aa][Dd][Mm][Ii][Nn]', r'[Mm][Oo][Dd][Oo]', r'[Gg][Mm]', r'[Gg][Aa][Mm][Ee]-?[Mm][Aa][Ss][Tt][Ee][Rr]'] __isValid = True # check existing character names for player in self.world.get_players(): if player.get_name() == __packetList[0]: self.socketManager.GAME_SEND_NAME_ALREADY_EXIST() return # check for forbidden words for __f in __forbiddenWords: if re.search(__f, __packetList[0]): __isValid = False # checking prohibited symbols for __i in __packetList[0]: nick = re.match(r'[a-zA-Z]?\x2D?', __i) if nick.group(0) == '': __isValid = False if __isValid == False: self.socketManager.GAME_SEND_NAME_ALREADY_EXIST() return # check available character slots if self.gameClient.get_account().get_number_of_characters() >= 5: self.socketManager.GAME_SEND_CREATE_PERSO_FULL() return try: self.world.create_player(self.gameClient.get_account().get_id(), __packetList[0],int(__packetList[1]),int(__packetList[2]), int(__packetList[3]),int(__packetList[4]),int(__packetList[5])) # # save changes in the account class __playerList = self.world.get_players_by_accid(self.gameClient.get_account().get_id()) if len(__playerList) != 0: self.gameClient.get_account().set_characters(__playerList) self.socketManager.GAME_SEND_CREATE_OK() # # broadcast of the current player list self.socketManager.GAME_SEND_PLAYER_LIST(self.gameClient.get_account().get_subscribe(), self.gameClient.get_account().get_number_of_characters(), self.gameClient.get_account().get_characters()) self.socketManager.GAME_SEND_cMK_PACKET_TO_MAP() except Exception as e: self.socketManager.GAME_SEND_CREATE_FAILED() self.log.warning('[{}][ACC:{}] GameHandler.add_character Exception: {}'.format(str(self.gameClient.get_addr()[0]), str(self.acc_display_number()), str(e))) def boost(self, packet): self.log.warning('boost') def delete_character(self, packet): try: __packetList = packet[2:].split('|') # determine the position of the character, save the character displayPosition = int(__packetList[0]) deletion_target = self.gameClient.get_account().get_characters().get(displayPosition) # check if the player is above level 19 and if the answer is correct if (deletion_target.get_level() >= 20 and __packetList[1] == self.gameClient.get_account().get_reponse()) or deletion_target.get_level() < 20: self.world.delete_player(deletion_target.get_id()) # save changes in the account class __playerList = self.world.get_players_by_accid(self.gameClient.get_account().get_id()) if len(__playerList) != 0: self.gameClient.get_account().set_characters(__playerList) # broadcast of the current player list self.socketManager.GAME_SEND_PLAYER_LIST(self.gameClient.get_account().get_subscribe(), self.gameClient.get_account().get_number_of_characters(), self.gameClient.get_account().get_characters()) else: self.socketManager.GAME_SEND_DELETE_PERSO_FAILED() except Exception as e: self.socketManager.GAME_SEND_DELETE_PERSO_FAILED() self.log.warning('[{}][ACC:{}] GameHandler.delete_character Exception: {}'.format(str(self.gameClient.get_addr()[0]), str(self.acc_display_number()), str(e))) def get_queue_position(self, packet): # placeholder ¯\_(ツ)_/¯ __queueID = 1 __position = 1 self.socketManager.MULTI_SEND_Af_PACKET(__position, 1, 1, "1", __queueID) def get_gifts(self, packet): self.log.warning('getGifts') def attribute_gift_to_character(self, packet): self.log.warning('attributeGiftToCharacter') def send_identity(self, packet): self.gameClient.get_account().set_key(packet[2:]) def get_characters(self, packet): # both objects refer to each other gameClient <-> account self.gameClient.get_account().set_game_client(self.gameClient) # TODO relog in the fight __playerList = self.world.get_players_by_accid(self.gameClient.get_account().get_id()) self.gameClient.get_account().set_characters(__playerList) self.socketManager.GAME_SEND_PLAYER_LIST(self.gameClient.get_account().get_subscribe(), self.gameClient.get_account().get_number_of_characters(), self.gameClient.get_account().get_characters()) def parse_migration(self, packet): self.log.warning('parseMigration') def set_character(self, packet): try: __listPosition = int(packet[2:]) self.gameClient.get_account().set_player(__listPosition) # both objects refer to each other account <-> player self.gameClient.get_account().get_player().set_account(self.gameClient.get_account(), self.socketManager) self.gameClient.get_account().get_player().join_game() except Exception as e: self.socketManager.GAME_SEND_PERSO_SELECTION_FAILED() self.log.warning('[{}][ACC:{}] GameHandler.set_character Exception: {}'.format(str(self.gameClient.get_addr()[0]), str(self.acc_display_number()), str(e))) self.gameClient.kick() def send_ticket(self, packet): __accId = packet[2:] __accIsAvailable = False __delCount = 0 for acc in self.exchangeTransferList: if str(acc.get_id()) == __accId: self.gameClient.set_account(acc) self.account = acc __accIsAvailable = True del self.exchangeTransferList[__delCount] __delCount += 1 if __accIsAvailable == True: self.socketManager.GAME_SEND_ATTRIBUTE_SUCCESS() else: self.socketManager.GAME_SEND_ATTRIBUTE_FAILED() self.gameClient.kick() # TODO In my opinion, the queue is sent here (Main.gameServer.getWaitingCompte(id)) # try: # try: # pass # this.compte = Main.gameServer.getWaitingCompte(id); # except Exception as e: # self.socketManager.GAME_SEND_ATTRIBUTE_FAILED() # self.log.warning(e) # self.gameClient.kick() # String ip = this.session.getRemoteAddress().toString().substring(1).split("\\:")[0]; # this.compte.setGameClient(this); # this.compte.setCurIP(ip); # Main.gameServer.delWaitingCompte(this.compte); # Database.getStatique().getPlayerData().loadByAccountId(this.compte.getGuid()); # self.socketManager.GAME_SEND_ATTRIBUTE_SUCCESS(this); # except Exception as e: # self.log.warning(e) # self.gameClient.kick() def request_regional_version(self, packet): self.socketManager.GAME_SEND_AV0() def realm_send_required_apk(self, packet): self.socketManager.REALM_SEND_REQUIRED_APK() # -------------------------------------------------------------------- # PARSE GAME PACKET parseBasicsPacket def get_date(self, packet): self.socketManager.GAME_SEND_SERVER_HOUR() # -------------------------------------------------------------------- # PARSE GAME PACKET parseGamePacket def send_actions(self, packet): self.log.warning('sendActions') def send_game_create(self, packet): self.gameClient.get_account().get_player().send_game_create() def delete_character_GD(self, packet): self.log.warning('deleteCharacter') def show_monster_target(self, packet): self.log.warning('showMonsterTarget') def set_flag(self, packet): self.log.warning('setFlag') def set_ghosts(self, packet): self.log.warning('setFlag') def get_extra_informations(self, packet): # EndFightAction are checked here self.log.warning('EndFightAction are checked here') self.get_extra_informations_two(packet) pass def get_extra_informations_two(self, packet): try: # if (perso.get_fight() != null) # SocketManager.GAME_SEND_MAP_GMS_PACKETS(this.perso.get_fight().getMap(), this.perso); # SocketManager.GAME_SEND_GDK_PACKET(this); # return # House.load # SocketManager.GAME_SEND_MAP_GMS_PACKETS # SocketManager.GAME_SEND_MAP_MOBS_GMS_PACKETS # SocketManager.GAME_SEND_MAP_NPCS_GMS_PACKETS # SocketManager.GAME_SEND_MAP_PERCO_GMS_PACKETS # SocketManager.GAME_SEND_MAP_OBJECTS_GDS_PACKETS self.socketManager.send('GDF|', 'GAME_SEND_MAP_OBJECTS_GDS_PACKETS (DEMO)') # SocketManager.GAME_SEND_GDK_PACKET # SocketManager.GAME_SEND_MAP_FIGHT_COUNT # SocketManager.SEND_GM_PRISME_TO_MAP # SocketManager.GAME_SEND_MERCHANT_LIST # Fight.FightStateAddFlag # SocketManager.GAME_SEND_Rp_PACKET # SocketManager.GAME_SEND_GDO_OBJECT_TO_MAP # SocketManager.GAME_SEND_GM_MOUNT # sendFloorItems # verifDoor # World.showPrismes # for (final Player player : this.perso.getCurMap().getPersos()) # player.send(String.valueOf(packet) + data) # this.perso.send(String.valueOf(packet) + data) pass except Exception as e: self.log.warning('[{}][ACC:{}] GameHandler.get_extra_informations_two Exception: {}'.format(str(self.gameClient.get_addr()[0]), str(self.acc_display_number()), str(e))) def action_ack(self, packet): self.log.warning('actionAck') def toggle_wings(self, packet): self.log.warning('toggleWings') def set_player_position(self, packet): self.log.warning('setPlayerPosition') def leave_fight(self, packet): self.log.warning('leaveFight') def ready_fight(self, packet): self.log.warning('readyFight') def get_fight_player_pass(self, packet): self.log.warning('get_fight().playerPass') # -------------------------------------------------------------------- def parse(self, recPacked): packetParse = { 'AA' : self.add_character, 'AB' : self.boost, 'AD' : self.delete_character, 'Af' : self.get_queue_position, 'Ag' : self.get_gifts, 'AG' : self.attribute_gift_to_character, 'Ai' : self.send_identity, 'AL' : self.get_characters, 'AM' : self.parse_migration, 'AS' : self.set_character, 'AT' : self.send_ticket, 'AV' : self.request_regional_version, 'AP' : self.realm_send_required_apk, 'BD' : self.get_date, 'GA' : self.send_actions, 'GC' : self.send_game_create, 'GD' : self.delete_character_GD, 'Gd' : self.show_monster_target, 'Gf' : self.set_flag, 'GF' : self.set_ghosts, 'GI' : self.get_extra_informations, 'GK' : self.action_ack, 'GP' : self.toggle_wings, 'Gp' : self.set_player_position, 'GQ' : self.leave_fight, 'GR' : self.ready_fight, 'Gt' : self.get_fight_player_pass, } try: packetParse[recPacked[:2]](recPacked) except KeyError: self.log.warning('UNKNOWN PACKAGE {}({})'.format(recPacked[:2],recPacked))
class ExchangeHandler(): def __init__(self): self.log = Logging() def recv_loop(self, exClient, hostList): while True: try: data = exClient.get_io_session().recv(2048) except ConnectionResetError: exClient.kick() packet = data.decode() packetPrint = packet.replace('\n', '[n]') self.log.debug('[{}:{}][<-EX-RECV] {}'.format( str(exClient.get_addr()[0]), str(exClient.get_addr()[1]), packetPrint)) if not data: self.log.debug('[SERVER-NAME] PacketLoop no data') exClient.kick() break ExchangeHandler().parse(exClient, packet, hostList) def parse(self, exClient, packet, hostList): if packet[0] == 'F': #F # org.cestra.exchange.ExchangePacketHandler @ parser # F + getPlayerNumber return elif packet[0] == 'S': if packet[1] == 'H': #SH # SH Ip ; Port s = packet[2:].split(';') ip = str(s[0]) port = int(s[1]) for i in hostList: if exClient.get_id() == i.get_id(): i.set_ip(ip) i.set_port(port) i.set_status(1) self.log.debug('[{}:{}] Status to 1'.format( str(exClient.get_addr()[0]), str(exClient.get_addr()[1]))) exClient.send('SHK') self.log.info( 'World-Server (ID:{}) has successfully registered'.format( exClient.get_id())) return elif packet[1] == 'K': #SK # 'SK id; key; freePlaces' s = packet[2:].split(';') id = int(s[0]) key = str(s[1]) freePlaces = int(s[2]) exClient.set_id(id) for serverObject in hostList: if serverObject.get_key() == key: serverObject.set_ex_client(exClient) serverObject.set_free_places(freePlaces) exClient.send('SKK') return exClient.send('SKR') exClient.kick() return elif packet[1] == 'S': #SS # org.cestra.game.GameServer @ setState # SS0 SS1 SS2 return elif packet[0] == 'M': if packet[1] == 'P': #MP # org.cestra.game.GameClient @ parseMigration # MP + GameClient.this.compte.getGuid return elif packet[1] == 'T': #MT # org.cestra.exchange.ExchangePacketHandler @ parser # MT" + account + "|" + server return elif packet[1] == 'D': #MD return elif packet[1] == 'O': #MO # org.cestra.game.GameClient @ parseMigration # MO + split[0] + "|" + server2 return self.log.warning('[' + str(exClient.get_id()) + '] Packet undefined: ' + packet) exClient.kick()
class SocketManager: def __init__(self, gameClient): self.log = Logging() self.nameGenerator = NameGenerator() # "world.join()" should quake it self.gameClient = gameClient self.account = None self.accId = None self.player = None def send(self, packet, name): __msg = bytes(packet + '\x00', 'utf-8') self.gameClient.get_session().send(__msg) if type(self.accId) != int: if self.account == None: self.accId = 'X' else: self.accId = self.account.get_id() self.log.debug('[{}][ACC:{}][SEND->] ({}) {}'.format( str(self.gameClient.get_addr()[0]), str(self.accId), name, str(packet))) def GAME_SEND_HELLOGAME_PACKET(self): __name = 'GAME_SEND_HELLOGAME_PACKET' __packet = 'HG' self.send(__packet, __name) def GAME_SEND_ATTRIBUTE_FAILED(self): __name = 'GAME_SEND_ATTRIBUTE_FAILED' __packet = 'ATE' self.send(__packet, __name) def GAME_SEND_ATTRIBUTE_SUCCESS(self): self.account = self.gameClient.get_account() __name = 'GAME_SEND_ATTRIBUTE_SUCCESS' __packet = 'ATK0' self.send(__packet, __name) def GAME_SEND_AV0(self): __name = 'GAME_SEND_AV0' __packet = 'AV0' self.send(__packet, __name) def MULTI_SEND_Af_PACKET(self, position, totalAbo, totalNonAbo, subscribe, queueID): __name = 'MULTI_SEND_Af_PACKET' __packet = ('Af{}|{}|{}|{}|{}'.format(str(position), str(totalAbo), str(totalNonAbo), str(subscribe), str(queueID))) self.send(__packet, __name) def GAME_SEND_PLAYER_LIST(self, sub, chrNum, palyerList): # ALK55751880000|1|1;pyCestra;1;80;-1;-1;-1;bc,96b,306,2593,2341;0;1;0;0; playerStr = '' for position, player in palyerList.items(): string = ( '|{};{};{};{};{};{};{};{},{},{},' '{},{};{};{};0;0;'.format( str(position), # player display position ; player.get_name(), # player name ; str(player.get_level()), # player level ; player.get_gfx(), # gfx ID ; player.get_color1(), # color 1 in hex ; player.get_color2(), # color 2 in hex ; player.get_color3(), # color 3 in hex ; '', # weapon ID in hex , '', # hat ID in hex , '', # cape ID in hex , '', # pet ID in hex , '', # shield ID in hex ; '0', # isShowSeller 0 ; '1', )) # server ID ; playerStr += string __name = 'GAME_SEND_PLAYER_LIST' __packet = 'ALK{}|{}{}'.format(str(sub), str(chrNum), playerStr) self.send(__packet, __name) def REALM_SEND_REQUIRED_APK(self): __name = 'GAME_SEND_APK' __packet = 'APK' __chName = self.nameGenerator.get_name() self.send(__packet + __chName, __name) def GAME_SEND_NAME_ALREADY_EXIST(self): __name = 'GAME_SEND_NAME_ALREADY_EXIST' __packet = 'AAEa' self.send(__packet, __name) def GAME_SEND_CREATE_FAILED(self): __name = 'GAME_SEND_CREATE_FAILED' __packet = 'AAEF' self.send(__packet, __name) def GAME_SEND_CREATE_PERSO_FULL(self): __name = 'GAME_SEND_CREATE_PERSO_FULL' __packet = 'AAEf' self.send(__packet, __name) def GAME_SEND_CREATE_OK(self): __name = 'GAME_SEND_CREATE_OK' __packet = 'AAK' self.send(__packet, __name) def GAME_SEND_cMK_PACKET_TO_MAP(self): __name = 'GAME_SEND_cMK_PACKET_TO_MAP' # cMK" + suffix + "|" + guid + "|" + name + "|" + msg __packet = 'cMK' self.send(__packet, __name) def GAME_SEND_PERSO_SELECTION_FAILED(self): __name = 'GAME_SEND_PERSO_SELECTION_FAILED' __packet = 'ASE' self.send(__packet, __name) def GAME_SEND_DELETE_PERSO_FAILED(self): __name = 'GAME_SEND_DELETE_PERSO_FAILED' __packet = 'ADE' self.send(__packet, __name) def GAME_SEND_Rx_PACKET(self): self.player = self.account.get_player() # Not sure where to put it yet __name = 'GAME_SEND_Rx_PACKET' __packet = 'Rx' + str(self.player.get_mountxpgive()) self.send(__packet, __name) def GAME_SEND_ASK(self, pId, name, level, morphClass, sex, gfxId, color1, color2, color3, itemToASK): __name = 'GAME_SEND_ASK' __packet = 'ASK|{}|{}|{}|{}|{}|{}|{}'.format(str(pId), str(name), str(level), str(morphClass), str(sex), str(gfxId), str(color1), str(color2), str(color3), str(itemToASK)) self.send(__packet, __name) def GAME_SEND_ALIGNEMENT(self, alignement): __name = 'GAME_SEND_ALIGNEMENT' __packet = 'ZS' + str(alignement) self.send(__packet, __name) def GAME_SEND_ADD_CANAL(self, chn): __name = 'GAME_SEND_ADD_CANAL' __packet = 'cC+' + str(chn) self.send(__packet, __name) def GAME_SEND_RESTRICTIONS(self): __name = 'GAME_SEND_RESTRICTIONS' __packet = 'AR6bk' self.send(__packet, __name) def GAME_SEND_GAME_CREATE(self, name): __name = 'GAME_SEND_GAME_CREATE' __packet = 'GCK|1|' + name self.send(__packet, __name) def GAME_SEND_STATS_PACKET(self, AsPacketString): __name = 'GAME_SEND_STATS_PACKET' self.GAME_SEND_Ow_PACKET() self.send(AsPacketString, __name) def GAME_SEND_Ow_PACKET(self): # pods - Ow + getPodUsed + | + getMaxPod __name = 'GAME_SEND_Ow_PACKET (DEMO)' __packet = 'Ow{}|{}'.format('0', '1000') self.send(__packet, __name) def GAME_SEND_SERVER_HOUR(self): tf = '%Y-%m-%d %H:%M' day00 = '3340-01-01 00:00' now = datetime.datetime.now() now = now.strftime(tf) now = datetime.datetime.strptime(now, tf) day00 = datetime.datetime.strptime(day00, tf) now_dofus = '{}-{}-{} {}:{}'.format('0' + str(now.year - 1370), str(now.month), str(now.day), str(now.hour), str(now.minute)) now_dofus = datetime.datetime.strptime(now_dofus, tf) mili_time = now_dofus - day00 mili_time = str((mili_time.total_seconds() * 1000) + 172800000) __name = 'GAME_SEND_SERVER_HOUR' __packet = 'BT' + mili_time self.send(__packet, __name)
class ChooseNickName: ''' information material: https://www.dofus.com/en/mmorpg/community/nicknames#\n https://www.python-kurs.eu/re.php ''' def __init__(self): self.log = Logging() def inspect(self, nickname): # Admin Modo GM Game Master forbiddenWords = [ r'[Aa][Dd][Mm][Ii][Nn]', r'[Mm][Oo][Dd][Oo]', r'[Gg][Mm]', r'[Gg][Aa][Mm][Ee]-?[Mm][Aa][Ss][Tt][Ee][Rr]', ] def forbidden_words_check(val): for x in forbiddenWords: if re.search(x, nickname): return False return True def forbidden_symbol(val): for i in nickname: nick = re.match(r'[a-z]?[A-Z]?[0-9]?\x2D?', i) if nick.group(0) == '': return False return True flag = 0 while True: # the nickname must be at least 3 symbol long if (len(nickname) < 3): flag = -1 break # the nickname may only consist of a-z, A-Z, 0-1 and - elif not forbidden_symbol(nickname): flag = -1 break # the nickname can not contain more than 4 "-" elif len(re.findall(r'\x2D', nickname)) >= 5: flag = -1 break # the nickname can not contain more than 2 numbers elif len(re.findall(r'[0-9]', nickname)) >= 3: flag = -1 break # The nickname can not be a forbidden word elif not forbidden_words_check(nickname): flag = -1 break else: flag = 0 return True if flag == -1: return False def verify(self, client, nickname, accountDataDic, hostList): # test if the nickname of the account is empty account = client.get_account() if not account.get_nickname() == '': client.kick() return # nickname must be different from your username if nickname.lower() == account.get_name().lower(): client.send("AlEr") return # the examination of the nickname string if not self.inspect(nickname): self.log.debug('[' + str(client.get_address()[0]) + ']' '[' + str(client.get_status().name) + '] This nickname is not available') # 'AlEs'= this nickname is not available. client.write("AlEs") return # is the nickname already taken? # AlEs = this nickname is not available. for i in accountDataDic: if i['nickname'] == nickname: self.log.debug('[' + str(client.get_address()[0]) + ']' '[' + str(client.get_status().name) + ']' + 'This nickname is already in use') client.write("AlEs") return account.set_nickname(nickname) account.set_state(0) # set client status to SERVER client.set_status(Status(4)) # update of the accountDataDic entry for i in accountDataDic: if i['id'] == account.get_id(): i['nickname'] = account.get_nickname() break AccountQueue().verify(client, accountDataDic, hostList)
class LoginClient: def __init__(self, game_client_dic, accountDataDic): self.game_client_dic = game_client_dic self.accountDataDic = accountDataDic self.log = Logging() def write(self, o): msg = bytes(o+'\x00', 'utf-8') self.log.debug('[' + str(self.address[0]) + ':' + str(self.address[1]) + '][' + str(self.status.name) + '][SEND->] ' + o) self.IoSession.send(msg) def kick(self): # ----------------------------------------- # update 'logged' to 0 for i in self.accountDataDic: if i['id'] == self.account.get_id(): i['logged'] = 0 # ----------------------------------------- # delete entries in 'game_client_dic' dict_str = self.address[0] + ':' + str(self.address[1]) self.IoSession.close() try: self.game_client_dic.pop(dict_str) except KeyError: self.log.warning('[' + str(self.address[0]) + ':' + str(self.address[1]) + '][' + str(self.status.name) + '] The request in "game_client_dic" has been incorrectly removed') # ----------------------------------------- self.log.info('[' + str(self.address[0]) + ':' + str(self.address[1]) + '][' + str(self.status.name) + '] Client kick') sys.exit(0) def get_address(self): return self.address def set_address(self, a): self.address = a def get_id(self): return self.id def set_id(self, Client_id): self.id = Client_id def get_io_session(self): return self.IoSession def set_io_session(self, s): self.IoSession = s def get_key(self): return self.key def set_key(self, k): self.key = k def get_status(self): return self.status def set_status(self, status): self.status = status def get_account(self): return self.account def set_account(self, account): self.account = account
class LoginHandler: def __init__(self): self.log = Logging() def login(self, soecket, key, addr, game_client_dic, accountDataDic, hostList, ipbans): client = LoginClient(game_client_dic, accountDataDic) client.set_key(key) client.set_address(addr) client.set_status(Status(0)) client.set_io_session(soecket) self.log.debug('[' + str(addr[0]) + ':' + str(addr[1]) + '][' + str(client.get_status().name) + '] Client created - ' + key) # the object is save in the global dictionary dict_str = addr[0] + ':' + str(addr[1]) game_client_dic[dict_str] = client HelloConnection(client, ipbans) LoginHandler().recv_loop(client, game_client_dic, accountDataDic, hostList) def recv_loop(self, client, game_client_dic, accountDataDic, hostList): while True: data = client.get_io_session().recv(2048) packet = data.decode() packetPrint = packet.replace('\n', '[n]') self.log.debug('[' + str(client.get_address()[0]) + ':' + str(client.get_address()[1]) + ']' + '[' + str(client.get_status().name) + '][<-RECV] ' + packetPrint) if not data: self.log.debug('[' + str(client.get_address()[0]) + ':' + str(client.get_address()[1]) + ']' + '[' + str(client.get_status().name) + '] PacketLoop no data') client.kick() break PacketHandler().parser(client, packet, game_client_dic, accountDataDic, hostList) def session_created(self, soecket, addr, game_client_dic, accountDataDic, hostList, ipbans): key = LoginHandler.generate_key(0) threadName = 'Client-Session ' + str(addr[0]) + ':' + str(addr[1]) try: t = threading.Thread(target=LoginHandler.login, name=threadName, args=(self, soecket, key, addr, game_client_dic, accountDataDic, hostList, ipbans)) t.start() except threading.ThreadError as e: self.log.debug('Created Session ' + str(addr[0]) + ':' + str(addr[1]) + ': ' + str(e)) def session_opened(self): pass def send_to_all(self): pass def generate_key(self): key = '' alphabet = 'abcdefghijklmnopqrstuvwxyz' while len(key) < 32: char = random.choice(alphabet) key += char # key = key[:-1] return key
class GameHandler: def __init__(self): self.log = Logging() def loop(self, gameClient): while True: data = gameClient.get_io_session().recv(2048) packet = data.decode() packetLog = packet.replace('\n', '[]') self.log.debug('[TODO client ip][<-GM-RECV] ' + packetLog) if not data: self.log.debug('[TODO client ip] PacketLoop no data') gameClient.kick() break GameHandler.parse(packet) def session_created(self, soecket, addr): threadName = 'Game-Client ' + str(addr[0]) + ':' + str(addr[1]) try: t = threading.Thread(target=GameClient, name=threadName, args=( soecket, addr, )) t.start() except: self.log.warning('Game Client could not be created ' + str(addr[0]) + ':' + str(addr[1])) def parse(self, packet): if packet[0] == 'A': print('parse_account_packet') return elif packet[0] == 'B': print('parseBasicsPacket') return elif packet[0] == 'C': print('parseConquestPacket') return elif packet[0] == 'c': print('parseChanelPacket') return elif packet[0] == 'D': print('parseDialogPacket') return elif packet[0] == 'd': print('parseDocumentPacket') return elif packet[0] == 'E': print('parseExchangePacket') return elif packet[0] == 'e': print('parseEnvironementPacket') return elif packet[0] == 'F': print('parseFrienDDacket') return elif packet[0] == 'f': print('parseFightPacket') return elif packet[0] == 'G': print('parseGamePacket') return elif packet[0] == 'g': print('parseGuildPacket') return elif packet[0] == 'h': print('parseHousePacket') return elif packet[0] == 'i': print('parseEnemyPacket') return elif packet[0] == 'J': print('parseJobOption') return elif packet[0] == 'K': print('parseHouseKodePacket') return elif packet[0] == 'O': print('parseObjectPacket') return elif packet[0] == 'P': print('parseGroupPacket') return elif packet[0] == 'R': print('parseMountPacket') return elif packet[0] == 'Q': print('parseQuestData') return elif packet[0] == 'S': print('parseSpellPacket') return elif packet[0] == 'T': print('parseFoireTroll') return elif packet[0] == 'W': print('parseWaypointPacket') return def parse_account_packet(self, packet): if packet[1] == 'A': print('addCharacter') return elif packet[1] == 'B': print('boost') return elif packet[1] == 'D': print('deleteCharacter') return elif packet[1] == 'f': print('getQueuePosition') return elif packet[1] == 'g': print('getGifts') return elif packet[1] == 'G': print('attributeGiftToCharacter') return elif packet[1] == 'i': print('sendIdentity') return elif packet[1] == 'L': print('getCharacters') return elif packet[1] == 'M': print('parseMigration') return elif packet[1] == 'S': print('setCharacter') return elif packet[1] == 'T': print('sendTicket') return elif packet[1] == 'V': print('requestRegionalVersion') return elif packet[1] == 'P': print('SocketManager.REALM_SEND_REQUIRED_APK') return