def delete(self): # Shorthand since we need to reference this multiple times db = self.db_conn.db # Get player and the game_id he's in player_name = self.get_current_user() player = Player(db, "name", player_name) game_id = player["current_game_id"] api_assert(game_id, 409, log_message="You are not currently in a game.") # Get game game = Game(db, "game_id", game_id) # Get remaining set of players rem_players = list(set(game["players"]) - {player_name}) # Set new gamemaster if not rem_players: game["gamemaster"] = None # If gamemaster is leaving, assign to a random player elif game["gamemaster"] == player_name: game["gamemaster"] = choice(rem_players) # Set remaining players in game and add players' balls to game's # unclaimed set game["players"] = rem_players game["unclaimed_balls"] = game["unclaimed_balls"] + player["balls"] # Set the player's game_id to None and his list of balls to empty player["current_game_id"] = None player["balls"] = [] return {"game_id": game_id}
def post(self): player_name = self.body["username"] password = self.body["password"] # Create player player_exists = self.db_conn.db['players'].find_one(name=player_name) api_assert(not player_exists, 409, log_message="{} is already registered.".format(player_name)) salt = bcrypt.gensalt(rounds=12) self.db_conn.db['players'].insert( { "name": player_name, "current_game_id": "", "current_room": "", "balls": "", "salt": salt, "password": bcrypt.hashpw(str(password), salt) } ) self.set_secure_cookie( "user", player_name, options.session_timeout_days ) return {"username": player_name}
def get(self): db = self.db_conn.db player_name = self.get_current_user() player = Player(db, "name", player_name) game_id = player["current_game_id"] api_assert(game_id, 400, log_message="You are not currently in" " a game.") return self.db_conn.get_balls_on_table(game_id)
def get(self): db = self.db_conn.db player_name = self.get_current_user() player = Player(db, "name", player_name) game_id = player["current_game_id"] api_assert(game_id, 400, log_message="You are not currently in" " a game.") game = Game(db, "game_id", game_id) return {"players": game["players"], "gamemaster": game["gamemaster"]}
def assert_non_tenant(db, player_name): player = get_player(db, player_name) player_room = player["current_room"] api_assert( not player_room, 409, log_message=( "{} is already in a room: `{}`. Leave current room" " to join a new one.".format( player_name, player_room ) ) )
def delete_room(self, player_name): ptable, player = self._get_player(player_name) room_name = player["current_room"] api_assert(room_name, 409, "`{}` is currently not in a room.".format(player_name)) rtable = self.db["rooms"] room = rtable.find_one(name=room_name) api_assert(room["owner"] == player_name, 403, log_message="You must own the room if you want to destroy it.") # Set each player's room to None, then delete the room for p in listify_string(str, room["current_players"]): ptable.update({"name": p, "current_room": None}, ["name"]) rtable.delete(name=room_name) return room_name
def get(self): db = self.db_conn.db # Get player player_name = self.get_current_user() player = Player(db, "name", player_name) room_name = player["current_room"] api_assert(room_name, 400, log_message="You are not currently in" " a room.") # Get room room = Room(db, "name", room_name) return { "players": room["current_players"], "owner": room["owner"] }
def post(self): """POST RequestHandler""" game_id = uuid.uuid4().hex gamemaster = self.get_current_user() room_name = self.db_conn.get_owned_room(gamemaster) api_assert(room_name, 403, log_message="You must own a room to create a game.") player_names = self.db_conn.get_players_in_room(room_name) nplayers = len(player_names) nbpp = self.body["nbpp"] # Make sure values make sense api_assert( nplayers <= nbpp * nplayers <= TOTAL_NUM_BALLS, 400, log_message=( "Your math seems to be a little off; " "please pick a `number of balls per player` " "such that each player has at least one ball " "and there are enough to go around for " "everyone." ), ) balls = generate_balls(TOTAL_NUM_BALLS) shuffle(balls) players = {} for i in xrange(nplayers): _balls = [] for i in xrange(nbpp): _balls.append(balls.pop()) pname = player_names.pop() players[pname] = _balls unclaimed_balls = balls[:] # Create game, then delete the room self.db_conn.create_game(game_id, players, unclaimed_balls, gamemaster) self.db_conn.delete_room(gamemaster) return {"game_id": game_id}
def create_room(db, room_name, password, owner): """Create a new room `room_name` Adds entry for room `room_name` to the database. :raises APIError: If a room with `room_name` has already been created. """ api_assert(not db["rooms"].find_one(name=room_name), 409, log_message="Room with name `{}` already exists.".format( room_name)) db["rooms"].insert( { "name": room_name, "password": password, "owner": owner, "current_players": "" } )
def post(self): db = self.db_conn.db gamemaster = self.get_current_user() ball = self.body["ball"] game_id = self.db_conn._get_player(gamemaster)[1]["current_game_id"] res = {"game_id": game_id} # Authenticate api_assert( self.db_conn.auth_game_update_request(game_id, gamemaster), 401, log_message="You are not the gamemaster of the current game", ) # If ball is already sunk, retable it if ball not in self.db_conn.get_balls_on_table(game_id): game = Game(db, "game_id", game_id) if ball in game["orig_unclaimed_balls"]: game["unclaimed_balls"] = game["unclaimed_balls"] + [ball] else: for pname in game["players"]: p = Player(db, "name", pname) if ball in p["orig_balls"]: p["balls"] = p["balls"] + [ball] break res["message"] = "Ball {} was retabled.".format(ball) return res # Otherwise, sink the ball for p in self.db_conn.get_players_for_game(game_id): if ball in self.db_conn.get_balls_for_player(p): self.db_conn.remove_ball_for_player(p, ball) break else: self.db_conn.remove_ball_from_unclaimed(game_id, ball) res["message"] = "Ball {} was sunk.".format(ball) return res
def create_game(self, game_id, players, unclaimed_balls, gamemaster): """Create game with game_id `game_id` Adds entry for a new game with given parameters to database, and updates players as well. :raises APIError: If any players are not already registered """ ptable = self.db["players"] all_players = [p["name"] for p in ptable] api_assert( all(p in all_players for p in players), 409, log_message="Your list of players contains unregistered" " names. Please register all players first.", ) table = self.db["games"] table.insert( { "game_id": game_id, "players": stringify_list(players.keys()), "unclaimed_balls": stringify_list(unclaimed_balls), "orig_unclaimed_balls": stringify_list(unclaimed_balls), "gamemaster": gamemaster, "status": "active", } ) table = self.db["players"] for name, balls in players.iteritems(): table.update( { "name": name, "current_game_id": game_id, "balls": stringify_list(balls), "orig_balls": stringify_list(balls), }, ["name"], )
def join_room(db, room_name, password, player_name): """Join room `room_name` Updates `current_players` entry for room `room_name` with player `player_name` to the database. :raises APIError: If a room with `room_name` does not exist; or if the password is incorrect for room `room_name`, or if player `player_name` does not exist """ room = get_room(db, room_name) api_assert(password == room['password'], 403, log_message="Bad password for room `{}`.".format(room_name)) player = get_player(db, player_name) api_assert( player_name not in room["current_players"], 409, log_message="Player `{}` already in room `{}`".format( player_name, room_name) ) room["current_players"] += [player_name] player["current_room"] = room_name
def test_api_assert(self): """Test utils.api_assert""" with pytest.raises(utils.APIError): utils.api_assert(False, 400) utils.api_assert(True, 400)
def _get_room(self, room_name): rtable, room = self.__get_room(room_name) api_assert(room, 409, log_message="No room {} exists".format(room_name)) return rtable, room
def _get_player(self, player_name): ptable, player = self.__get_player(player_name) api_assert(player, 409, log_message="No user {} exists.".format(player_name)) return ptable, player