Example #1
0
    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}
Example #2
0
    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}
Example #3
0
    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)
Example #4
0
    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"]}
Example #5
0
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
            )
        )
    )
Example #6
0
    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
Example #7
0
    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"]
        }
Example #8
0
    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}
Example #9
0
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": ""
        }
    )
Example #10
0
    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
Example #11
0
    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"],
            )
Example #12
0
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)
Example #14
0
 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
Example #15
0
 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