def work(pubsub, channel): pubsub.subscribe('queue:' + channel) while True: message = pubsub.get_message() if message is not None: data = redisConnection.rpop('queue:' + channel + ":list") if data is not None: packet = packet_pb2.Packet() packet.ParseFromString(data) aes_key = redisConnection.get(packet.playerID) if aes_key is not None: reply = None if channel is "gamemessages": game_packet = client_pb2.ClientGameMessage() game_packet.ParseFromString( AESTool.decrypt(aes_key, packet.message)) print("Worker got GAME: ", game_packet) reply_packet = server_pb2.ServerGameMessage() # Here's where you would do the heavy tasks to calculate that data reply_packet.xPos = 12 reply_packet.yPos = 1032 reply_packet.zPos = 1 message = AESTool.encrypt( aes_key, reply_packet.SerializeToString()) reply = create_packet(packet_pb2.Packet.GAME, message, packet.playerID) elif channel is "datamessages": data_packet = client_pb2.ClientDataMessage() data_packet.ParseFromString( AESTool.decrypt(aes_key, packet.message)) print("Worker got DATA: ", data_packet) # Here's where you would do the heavy tasks to calculate that data reply_packet = server_pb2.ServerDataMessage() reply_packet.health = 12 reply_packet.coins = 1032 reply_packet.mana = 1 message = AESTool.encrypt( aes_key, reply_packet.SerializeToString()) reply = create_packet(packet_pb2.Packet.DATA, message, packet.playerID) reply.address = packet.address reply.port = packet.port redisConnection.publish('queue:packetreplies', reply.SerializeToString())
def start_heartbeat(self): """Starts the heartbeat""" player_id = "1111" while True: packet = create_packet(packet_pb2.Packet.HEARTBEAT, b"Ping", player_id) self.sock.sendto(packet.SerializeToString(), (self.server_host, self.server_port)) time.sleep(1)
def handle_packet(self, data, address): """Packer handler thread This is where the packet is checked for validity and put into the appropriate redis queue :param data: the data from the packet :address: a tuple with the (ip_address, port_number) """ packet = packet_pb2.Packet() packet.ParseFromString(data) if packet.type != packet_pb2.Packet.HEARTBEAT: print(packet) packet_crc = packet.crc packet.ClearField('crc') crc_data = packet.SerializePartialToString() crc = binascii.crc32(crc_data) & 0xFFFFFFFF if packet_crc != crc: print('Given CRC: {}'.format(packet.crc)) print('Calculated CRC: {}'.format( (binascii.crc32(crc_data) & 0xFFFFFFFF))) print("Dropped packet for bad checksum") return # put the crc back in there! packet.crc = packet_crc if packet.type == packet_pb2.Packet.HEARTBEAT: packet = create_packet(packet_pb2.Packet.HEARTBEAT, b"Pong") self.sock.sendto(packet.SerializeToString(), address) elif packet.type == packet_pb2.Packet.AUTH: decrypted_aes_key = self.rsa_key.decrypt(packet.message) print('DECRYPTED AES KEY:', [x for x in decrypted_aes_key]) print('PLAYER ID AUTH: ', packet.playerID) self.redis.set(packet.playerID, decrypted_aes_key) packet = create_packet(packet_pb2.Packet.HEARTBEAT, b"Pong") self.sock.sendto(packet.SerializeToString(), address) elif packet.type in PACKET_TYPE_TO_CHANNEL: packet.address = address[0] packet.port = address[1] self.forward_packet(packet, PACKET_TYPE_TO_CHANNEL[packet.type])
def data_thread(key, player_id): """The thread to create dummy data packets :param player_id: the player id """ while True: data_packet = client_pb2.ClientDataMessage() data_packet.lostHealth = 12 data_packet.usedCoins = 1032 data_packet.usedMana = 1 message = AESTool.encrypt(key, data_packet.SerializeToString()) packet = create_packet(packet_pb2.Packet.DATA, message, player_id) client_socket.send_to_server(packet) sleep_time = random.randint(300, 1500) time.sleep(sleep_time / 1000)
def main(): """The main client method""" # pylint: disable=global-statement # pylint: disable=invalid-name global client_socket # pylint: enable=invalid-name # pylint: enable=global-statement try: key = AESTool.create_key() client_socket = Client('127.0.0.1', 1234, key) client_socket.start() with open('public.key', 'r') as keyfile: rsa_key = PKCS1_OAEP.new(RSA.importKey(keyfile.read()), hashAlgo=Crypto.Hash.SHA256) # Apparently the encrypt message has a dummy second param and # second item in the return tuple that are to be ignored per the docs encrypted_key = rsa_key.encrypt(key) player_id = "1111" auth_packet = create_packet(packet_pb2.Packet.AUTH, encrypted_key, player_id) client_socket.send_to_server(auth_packet) while not client_socket.heartbeat_thread.is_alive(): time.sleep(0) print('starting game threads') threading.Thread(target=data_thread, args=( key, player_id, )).start() threading.Thread(target=game_thread, args=( key, player_id, )).start() except KeyboardInterrupt: client_socket.stop() client_socket.join(THREAD_TIMEOUT)
def game_thread(key, player_id): """The thread to create dummy game packets :param player_id: the player id """ count = 0 while count < 3: try: game_packet = client_pb2.ClientGameMessage() game_packet.xDelta = 2 game_packet.yDelta = -14 game_packet.zDelta = 0 message = AESTool.encrypt(key, game_packet.SerializeToString()) print('message len', len(message)) packet = create_packet(packet_pb2.Packet.GAME, message, player_id) client_socket.send_to_server(packet) sleep_time = random.randint(300, 1500) time.sleep(sleep_time / 1000) count += 1 # pylint: disable=broad-except except Exception as exception: # pylint: enable=broad-except print(exception)