def send_message(self, queue, message): data = construct_message(queue, message) try: self.transport.write(data) except Exception: self.transport.close()
def notify_all(self, game, message): """ Sends a message to every not DISCONNECTED Player in game. :param game: game object :param message: the message list """ print('Notify all in game {} with msg: {}'.format(game, message)) game_exchange = game.game_exchange for player in game.player_list: print('notifying player', player) if player.mode != DISCONNECTED: print('player not disconnected') self.channel.basic_publish(exchange=game_exchange, routing_key=player.user_name, body=construct_message(message)) self.channel.basic_publish(exchange=game.spec_exchange, routing_key='placeholder', body=construct_message(message))
def send_boards(self, game): """ Sends every not DISCONNECTED Player in game main board and tracking board """ print('Sending all boards') game_exchange = game.game_exchange # print('main board', json.dumps(player.main_board)) # if not json.dumps(player.main_board): # return for player in game.player_list: if player.mode != DISCONNECTED and player.main_board: self.channel.basic_publish(exchange=game_exchange, routing_key=player.user_name, body=construct_message([BOARDS, json.dumps(player.main_board), \ json.dumps(player.tracking_board)]))
def notify_spectators(self, game, shooter, hits): response = '' print('notify spec: hits, ', hits) print('notify spec: shooter, ', shooter) print('notify spec:game, ', game) for hit in hits: response += '%s hit %s\n' % (shooter, hit) for player in game.player_list: response += "%s's board:\n %s\n\n" % ( player.user_name, json.dumps(player.main_board)) self.channel.basic_publish(exchange=game.spec_exchange, routing_key='placeholder', body=construct_message( [SPECTATOR_ANNOUNCEMENT, response]))
def join_game(self, user_name, game_name): player = self.online_clients[user_name] game = self.games[game_name] # print('game.can_join') # print(game.can_join) if game.can_join_check(user_name): game_exchange = game.join(player) game_owner = game.owner.user_name print('Sending login user info to %s' % game_owner) self.channel.basic_publish(exchange=game_exchange, routing_key=game_owner, body=construct_message( [USER_JOINED, user_name])) return game_exchange else: return NOK
def create_game(self, board_size): """ Sends params for game creation to game server. Connects client to exchanges and stores the joined game key :param user_name: Necessary for server to know who's creating the game :param server_key: Game_server where the game is created :param board_size: gameboard size :return """ response = self.message_direct( self.server_key, construct_message([CREATE_GAME, self.user_name, board_size])) response = decode_message(response) game_exchange = response[0] self.current_exchange = game_exchange game_id = response[1] # print(game_exchange) self.current_game = game_id self.channel.queue_bind(exchange=game_exchange, queue=self.incoming_queue, routing_key=self.user_name) self.channel.basic_consume(self.on_info, queue=self.incoming_queue) print('Joined to a game. Incoming queue registered to game exchange.')
def remove_user(self, user_name): print('Removing %s from game' % user_name) return self.message_game( construct_message( [REMOVE_USER, self.user_name, self.current_game, user_name]))
def leave_game(self): print('User {} leaving game {}'.format(self.user_name, self.current_game)) return self.message_game( construct_message([LEAVE_GAME, self.user_name, self.current_game]))
def shoot(self, x, y): print('Shooting at %s, %s' % (x, y)) return self.message_game( construct_message([SHOOT, self.user_name, self.current_game, x, y]))
def start_game(self): print('Starting game!') return self.message_game( construct_message([START_GAME, self.user_name, self.current_game]))
def join_game_server(self, user_name, reconnect=False): self.user_name = user_name return self.message_direct( self.server_key, construct_message([JOIN_SERVER, user_name, reconnect]))
def get_game_list(self): return self.message_direct( self.server_key, construct_message([LIST_GAMES, self.user_name]))
def send_message(self, queue, message): data = construct_message(queue, message) self.transport.write(data)
def on_request(self, ch, method, props, body): body = decode_message(body) print 'Received request', body if body[0] == LIST_GAMES: game_list = [] query_from_user = body[1] print('query_from_user', query_from_user) for game_key, game in self.games.iteritems(): # players_in_game = [player.user_name for player in game.player_list] # print(game_key, players_in_game) # if query_from_user in players_in_game: # print('player already in this game, must be a reconnect') # if game.can_join or query_from_user in players_in_game: if game.can_join_check(query_from_user): game_list.append(game_key) response = json.dumps(game_list, ensure_ascii=False) elif body[0] == JOIN_SERVER: if (body[1]) not in self.online_clients: # Create a player instance with the name player = Player(body[1]) self.online_clients[body[1]] = player response = json.dumps(self.games.keys(), ensure_ascii=False) else: # print('player name exist, but is it reconnect?', body[2]) if body[2] == 'True': print('Player {} is reconnecting'.format(body[1])) response = json.dumps(OK, ensure_ascii=False) else: print('Player name {} is taken'.format(body[1])) # response = json.dumps(self.games.keys(), ensure_ascii=False) response = json.dumps(NOK, ensure_ascii=False) elif body[0] == CREATE_GAME: game_exchange, game_name = self.create_game(body[1], body[2]) response = construct_message([game_exchange, game_name]) elif body[0] == JOIN_GAME: game_exchange = self.join_game(body[1], body[2]) game = self.games[body[2]] current_player = game.shooting_player.user_name if game.shooting_player else 'Unknown' response = construct_message([game_exchange, current_player]) elif body[0] == START_GAME: self.start_game(body[1], body[2]) return elif body[0] == REFRESH_BOARD: self.refresh_boards(body[1]) return elif body[0] == SHOOT: self.shoot(body[1], body[2], body[3], body[4]) return elif body[0] == LEAVE_GAME: self.leave_game(body[1], body[2]) return else: response = UNKNOWN_REQUEST if response is not None: ch.basic_publish(exchange='', routing_key=props.reply_to, properties=pika.BasicProperties(correlation_id= \ props.correlation_id), body=str(response)) ch.basic_ack(delivery_tag=method.delivery_tag)
def shoot(self, user_name, game_name, x, y): """ Handles a shoot: updates every not DISCONNECTED users' board, notifies shooter, notifies suffering player, notifies next shooter :param game_name: Name of the game as provided by the user :param user_name: shooting user """ player = self.online_clients[user_name] game = self.games[game_name] game_exchange = game.game_exchange # Check shooting user if game.shooting_player.user_name == user_name: shot_results = game.shoot(user_name, x, y) hits = shot_results['hits'] sunk_ships = shot_results['sunk_ships'] self.send_boards(game) # Notify shooter if there was a hit self.channel.basic_publish(exchange=game_exchange, routing_key=user_name, body=construct_message( [YOUR_HITS, json.dumps(hits)])) # Notify users that shooter hit them. Don't loop if hits is None if hits: print('hits', hits) for user in hits: self.channel.basic_publish(exchange=game_exchange, routing_key=user, body=construct_message( [HIT, user_name])) print('shoot: notify spectators') self.notify_spectators(game, user_name, hits) else: self.channel.basic_publish( exchange=game.spec_exchange, routing_key='placeholder', body=construct_message([ SPECTATOR_ANNOUNCEMENT, '{} shot but missed!'.format(user_name) ])) if sunk_ships: print('some sunk ships') for ship in sunk_ships: ship_owner = ship[1].user_name self.notify_all( game, [SHIP_SUNK_ANNOUNCEMENT, user_name, ship_owner]) print(self.online_clients[ship_owner].all_ships_sunk()) print(self.online_clients[ship_owner]) print(self.online_clients) if self.online_clients[ship_owner].all_ships_sunk(): self.online_clients[ship_owner].mode = SPECTATOR self.channel.basic_publish(exchange=game_exchange, routing_key=ship_owner, body=construct_message([ YOU_DEAD, game.spec_exchange ])) if not game.end_session(): # Notify next shooter if not game.is_game_over(): next_shooter = game.get_next_shooter() self.channel.basic_publish( exchange=game_exchange, routing_key=next_shooter.user_name, body=YOUR_TURN) # Notify all users that game is over else: # TODO: probably need to so something more print('game_server GAME OVER CHECK') self.notify_all(game, [GAME_OVER, game.get_winner()]) else: # TODO: probably need to so something more self.channel.basic_publish(exchange=game.spec_exchange, routing_key='placeholder', body=SESSION_END)