コード例 #1
0
ファイル: game.py プロジェクト: ChrisNolan1992/LivesPool
    def post(self):
        """
        POST the required parameters to register the pocketing/unpocketing of a ball

        * `ball`: The ball that was pocketed/unpocketed
        """
        gamemaster = self.get_current_user()
        ball = self.body['ball']
        game_id = get_player(self.db_conn, gamemaster)["current_game_id"]
        game = Game(self.db_conn, "game_id", game_id)

        res = {"game_id": game_id}

        # Authenticate
        api_assert(
            game["gamemaster"] == gamemaster,
            401,
            log_message="You are not the gamemaster of the current game"
        )

        # If ball is already sunk, retable it
        if ball not in get_balls_on_table(self.db_conn, game_id):
            game = Game(self.db_conn, "game_id", game_id)
            # Look for ball in game's set of unclaimed balls
            if ball in game["orig_unclaimed_balls"]:
                game["unclaimed_balls"] += [ball]
            # If it's not there, look for it from each player's set
            else:
                for pname in game["players"]:
                    p = Player(self.db_conn, "name", pname)
                    if ball in p["orig_balls"]:
                        p["balls"] += [ball]
                        break
            res['message'] = "Ball {} was retabled.".format(ball)
            return res

        # Otherwise, sink the ball
        # Look for it in players' first
        for pname in Game(self.db_conn, "game_id", game_id)["players"]:
            p = get_player(self.db_conn, pname)
            if ball in p["balls"]:
                p["balls"] = list(set(p["balls"]) - {ball})
                break
        else:
            # Remove ball from unclaimed
            g = Game(self.db_conn, "game_id", game_id)
            uballs = list(game["unclaimed_balls"])
            uballs.remove(ball)
            game["unclaimed_balls"] = uballs

        res["message"] = "Ball {} was sunk.".format(ball)
        return res
コード例 #2
0
ファイル: game.py プロジェクト: ChrisNolan1992/LivesPool
    def delete(self):
        """
        DELETE to end the game; this endpoint should only be triggered if
            GameState indicates there is a winner.
        """
        player_name = self.get_current_user()
        player = get_player(self.db_conn, player_name)
        game_id = player["current_game_id"]
        api_assert(game_id, 400, log_message="You are not currently in"
                   " a game.")
        game = get_game(self.db_conn, game_id)

        with DBLock():
            is_gamemaster = game["gamemaster"] == player_name
            gamemaster_has_closed = game["gamemaster"] is None

            winner_name = get_game_winner(self.db_conn, game_id)
            # If there is no current winner, return an error
            if not winner_name:
                raise APIError(
                    409,
                    log_message="The game currently has no winner."
                )
            # Otherwise, clean up everything
            else:
                # We want the gamemaster to FIRST to do the cleanup
                if is_gamemaster:
                    # Record the win for the player who won
                    winner = get_player(self.db_conn, winner_name)
                    winner["games_won"] += [game_id]
                    game["winner"] = winner_name
                    # Remove all players from game
                    for pname in game["players"]:
                        p = get_player(self.db_conn, pname)
                        p["balls"] = []
                        p["orig_balls"] = []
                    # Clear the game's "current" attributes
                    game["players"] = []
                    game["gamemaster"] = None
                    # Remove the gamemaster's current_game_id
                    player["current_game_id"] = None
                # Then the remainder of the players can truly leave the game
                #   so they have a chance to query who the winner was from GameState
                #   before having their current_game_id set to None
                elif gamemaster_has_closed:
                    player["current_game_id"] = None

                return "Game {} was completed; {} was the winner.".format(
                        game_id,
                        winner_name
                )
コード例 #3
0
    def post(self):
        """
        POST the required parameters to register the pocketing/unpocketing of a ball

        * `ball`: The ball that was pocketed/unpocketed
        """
        gamemaster = self.get_current_user()
        ball = self.body['ball']
        game_id = get_player(self.db_conn, gamemaster)["current_game_id"]
        game = Game(self.db_conn, "game_id", game_id)

        res = {"game_id": game_id}

        # Authenticate
        api_assert(
            game["gamemaster"] == gamemaster,
            401,
            log_message="You are not the gamemaster of the current game")

        # If ball is already sunk, retable it
        if ball not in get_balls_on_table(self.db_conn, game_id):
            game = Game(self.db_conn, "game_id", game_id)
            # Look for ball in game's set of unclaimed balls
            if ball in game["orig_unclaimed_balls"]:
                game["unclaimed_balls"] += [ball]
            # If it's not there, look for it from each player's set
            else:
                for pname in game["players"]:
                    p = Player(self.db_conn, "name", pname)
                    if ball in p["orig_balls"]:
                        p["balls"] += [ball]
                        break
            res['message'] = "Ball {} was retabled.".format(ball)
            return res

        # Otherwise, sink the ball
        # Look for it in players' first
        for pname in Game(self.db_conn, "game_id", game_id)["players"]:
            p = get_player(self.db_conn, pname)
            if ball in p["balls"]:
                p["balls"] = list(set(p["balls"]) - {ball})
                break
        else:
            # Remove ball from unclaimed
            g = Game(self.db_conn, "game_id", game_id)
            uballs = list(game["unclaimed_balls"])
            uballs.remove(ball)
            game["unclaimed_balls"] = uballs

        res["message"] = "Ball {} was sunk.".format(ball)
        return res
コード例 #4
0
    def delete(self):
        """
        DELETE to end the game; this endpoint should only be triggered if
            GameState indicates there is a winner.
        """
        player_name = self.get_current_user()
        player = get_player(self.db_conn, player_name)
        game_id = player["current_game_id"]
        api_assert(game_id,
                   400,
                   log_message="You are not currently in"
                   " a game.")
        game = get_game(self.db_conn, game_id)

        with DBLock():
            is_gamemaster = game["gamemaster"] == player_name
            gamemaster_has_closed = game["gamemaster"] is None

            winner_name = get_game_winner(self.db_conn, game_id)
            # If there is no current winner, return an error
            if not winner_name:
                raise APIError(409,
                               log_message="The game currently has no winner.")
            # Otherwise, clean up everything
            else:
                # We want the gamemaster to FIRST to do the cleanup
                if is_gamemaster:
                    # Record the win for the player who won
                    winner = get_player(self.db_conn, winner_name)
                    winner["games_won"] += [game_id]
                    game["winner"] = winner_name
                    # Remove all players from game
                    for pname in game["players"]:
                        p = get_player(self.db_conn, pname)
                        p["balls"] = []
                        p["orig_balls"] = []
                    # Clear the game's "current" attributes
                    game["players"] = []
                    game["gamemaster"] = None
                    # Remove the gamemaster's current_game_id
                    player["current_game_id"] = None
                # Then the remainder of the players can truly leave the game
                #   so they have a chance to query who the winner was from GameState
                #   before having their current_game_id set to None
                elif gamemaster_has_closed:
                    player["current_game_id"] = None

                return "Game {} was completed; {} was the winner.".format(
                    game_id, winner_name)
コード例 #5
0
ファイル: auth.py プロジェクト: ChrisNolan1992/LivesPool
    def post(self):
        """POST the required credentials to get back a cookie

        * `username`: Username
        * `password`: Password
        """
        player_name = self.body["username"]
        password = self.body["password"]
        player = get_player(self.db_conn, player_name, err_code=400)

        # Check if the given password hashed with the player's known
        #   salt matches the stored password
        password_match = bcrypt.hashpw(
            str(password), str(player["salt"])
        ) == player['password']
        if password_match:
            self.set_secure_cookie(
                "user", player_name, options.session_timeout_days
            )
            return {"username": player_name}
        else:
            raise APIError(
                400,
                log_message="Bad username/password combo"
            )
コード例 #6
0
ファイル: room.py プロジェクト: navSharma47/LivesPool
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
    """
    # Ensure that the following preconditions are met:
    #   * Correct password to room is give if required
    #   * The player is not already in a room
    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)
    )
    # If they are met, add the player to the room
    room["current_players"] += [player_name]
    player["current_room"] = room_name
コード例 #7
0
 def get(self):
     player = get_player(self.db_conn, self.get_current_user())
     if player["current_game_id"]:
         self.redirect("/room/game")
     elif player["current_room"]:
         self.redirect("/room/lobby")
     else:
         self.redirect("/room/join")
コード例 #8
0
ファイル: room.py プロジェクト: uservidya/LivesPool
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
            )
        )
    )
コード例 #9
0
ファイル: player.py プロジェクト: navSharma47/LivesPool
    def get(self):
        """
        GET to retrieve player info
        """
        player_name = self.get_current_user()
        player = get_player(self.db_conn, player_name)

        res = dict(player)
        res.pop("password")  # Redact password
        res.pop("salt")  # Redact salt
        res.pop("id")  # Players don't care about this
        # Make the following strings b/c the schema expects strings
        for k in ["current_game_id", "current_room"]:
            if not res[k]:
                res[k] = ""
        return res
コード例 #10
0
ファイル: room.py プロジェクト: navSharma47/LivesPool
def assert_non_tenant(db, player_name):
    """Assert that player ``player_name`` is not already in a room

    :type  player_name: str
    :raises APIError: If ``player_name`` is already in a room.
    """
    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
            )
        )
    )
コード例 #11
0
ファイル: auth.py プロジェクト: navSharma47/LivesPool
    def post(self):
        """POST the required credentials to get back a cookie

        * `username`: Username
        * `password`: Password
        """
        player_name = self.body["username"]
        password = self.body["password"]
        player = get_player(self.db_conn, player_name, err_code=400)

        # Check if the given password hashed with the player's known
        #   salt matches the stored password
        password_match = bcrypt.hashpw(str(password), str(
            player["salt"])) == player['password']
        if password_match:
            self.set_secure_cookie("user", player_name,
                                   options.session_timeout_days)
            return {"username": player_name}
        else:
            raise APIError(400, log_message="Bad username/password combo")
コード例 #12
0
ファイル: room.py プロジェクト: uservidya/LivesPool
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
コード例 #13
0
ファイル: game.py プロジェクト: ChrisNolan1992/LivesPool
    def post(self):
        """POST the required parameter to create a new game;
            only the owner of a room can make this request

        * `nbpp`: Number of balls per player
        """
        game_id = uuid.uuid4().hex
        gamemaster = self.get_current_user()
        player = get_player(self.db_conn, gamemaster)
        room_name = player["current_room"]
        room = get_room(self.db_conn, room_name)
        api_assert(room["owner"] == gamemaster, 403,
                   log_message="You must own a room to create a game.")

        player_names = room["current_players"]
        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.")
                   )

        # Create set of 15 balls, shuffle, and then match to players
        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
        self.db_conn["games"].insert(
            {
                "game_id": game_id,
                "players": stringify_list(players.keys()),
                "orig_players": stringify_list(players.keys()),
                "unclaimed_balls": stringify_list(unclaimed_balls),
                "orig_unclaimed_balls": stringify_list(unclaimed_balls),
                "gamemaster": gamemaster,
                "winner": None
            }
        )
        # Assign each player their set of balls, set game, leave room
        for name, balls in players.iteritems():
            p = get_player(self.db_conn, name)
            p["current_game_id"] = game_id
            p["balls"] = balls
            p["orig_balls"] = balls
            p["current_room"] = None
        # The room can be deleted
        self.db_conn["rooms"].delete(name=room_name)

        return {"game_id": game_id}
コード例 #14
0
    def post(self):
        """POST the required parameter to create a new game;
            only the owner of a room can make this request

        * `nbpp`: Number of balls per player
        """
        game_id = uuid.uuid4().hex
        gamemaster = self.get_current_user()
        player = get_player(self.db_conn, gamemaster)
        room_name = player["current_room"]
        room = get_room(self.db_conn, room_name)
        api_assert(room["owner"] == gamemaster,
                   403,
                   log_message="You must own a room to create a game.")

        player_names = room["current_players"]
        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."))

        # Create set of 15 balls, shuffle, and then match to players
        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
        self.db_conn["games"].insert({
            "game_id":
            game_id,
            "players":
            stringify_list(players.keys()),
            "orig_players":
            stringify_list(players.keys()),
            "unclaimed_balls":
            stringify_list(unclaimed_balls),
            "orig_unclaimed_balls":
            stringify_list(unclaimed_balls),
            "gamemaster":
            gamemaster,
            "winner":
            None
        })
        # Assign each player their set of balls, set game, leave room
        for name, balls in players.iteritems():
            p = get_player(self.db_conn, name)
            p["current_game_id"] = game_id
            p["balls"] = balls
            p["orig_balls"] = balls
            p["current_room"] = None
        # The room can be deleted
        self.db_conn["rooms"].delete(name=room_name)

        return {"game_id": game_id}