示例#1
0
        def handle_player_leave():
            player = self.players_by_session.get(
                session.get("connection_id", None), None)
            requests_logger.debug(
                f"{session.get('connection_id', None)} disconnected from {self.lobby_name} "
                f"at /{self.lobby_slug}")
            if player:
                del self.players_by_session[session["connection_id"]]

                ####################
                def player_leave(self, p):
                    # NOTE: Backend will only make one copy per player for certain (except for reconnects)
                    if p in self.participants:
                        print('before:', self.participants)
                        self.participants.remove(p)
                        print('after:', self.participants)
                    else:
                        raise logic.Game.InvalidPlayer

                    if len(self.participants) == 0:
                        self.quit_game()

                    elif p == self.host:
                        self.host = self.participants[0]

                    if self.rules.finish_game_on_disconnect:
                        self.finish_game()
示例#2
0
 def vote_on_rules(json=None):
     player = self.players_by_session.get(
         session.get("connection_id", None), None)
     if player:
         requests_logger.debug(
             f'Player {player} is trying to vote on rules on {self.name_space}'
         )
         if json:
             if jsonschema.validate(json, schema.game_action_schema):
                 pass
             else:
                 return jsonify({
                     "Error": {
                         "type":
                         "schema_error",
                         "message":
                         "The json data provided does not match the required schema.",
                     }
                 })
         else:
             return jsonify({
                 "Error": {
                     "type": "data_missing",
                     "message": "You need to provide json data.",
                 }
             })
     else:
         requests_logger.debug(
             f'A foreign connection has tried to vote on rules on {self.name_space}'
         )
示例#3
0
 def handle_chat_message(json=None):
     player = self.players_by_session.get(
         session.get("connection_id", None), None)
     if json:
         if jsonschema.validate(json, schema.player_schema):
             pass
         else:
             return JSON.dumps({
                 "Error": {
                     "type":
                     "schema_error",
                     "message":
                     "The json data provided does not match the required schema."
                 }
             })
     else:
         return JSON.dumps({
             "Error": {
                 "type": "data_missing",
                 "message": "You need to provide json data."
             }
         })
     requests_logger.debug(
         f"A player has tried to send a chat message to game {self.lobby_name}"
     )
示例#4
0
        def handle_player_join(json=None):
            if "connection_id" not in session:
                session["connection_id"] = b64encode(os.urandom(2**5))
            requests_logger.debug(
                f"{session.get('connection_id', None)} connected to game {self.lobby_name} at /{self.lobby_slug}."
            )

            if json:
                if jsonschema.validate(json, schema.player_schema):
                    token_style_data = json["token_style"]
                    token_style = data.TokenStyle(
                        color=tuple(token_style_data["color"]))
                    player = data.Player(json['player_name'], token_style)
                    if not self.current_game and len(
                            self.players_by_session) < max_number_of_players:
                        self.players_by_session[
                            session["connection_id"]] = player

                    ########
                    def player_join(self, p):
                        if self._game_state == logic.Game.State.started:
                            if not self.rules.allow_reconnect:
                                raise logic.Game.InvalidPlayer()
                            else:
                                if p not in self.participants:
                                    if not any(p.name == x.name
                                               for x in self.initial_players):
                                        self.participants.append(p)
                        else:
                            if any([
                                    not data.TokenStyle.distinguishable(
                                        x.token_style, p.token_style)
                                    for x in self.participants
                            ]) or any(
                                [p.name == x.name for x in self.participants]):
                                raise logic.Game.InvalidPlayer()

                            if not len(self.participants
                                       ) < self.rules.number_of_players:
                                raise logic.Game.LobbyFull(
                                    len(self.participants))

                        self.participants.append(p)
                else:
                    return JSON.dumps({
                        "Error": {
                            "type":
                            "schema_error",
                            "message":
                            "The json data provided does not match the required schema."
                        }
                    })
            else:
                return JSON.dumps({
                    "Error": {
                        "type": "data_missing",
                        "message": "You need to provide json data."
                    }
                })
示例#5
0
 def retrieve_game(slug=None):
     slug = slugify(slug)
     requests_logger.debug(
         f"GET request to /games/{{{slug}}}. Sending game info…")
     if slug:
         try:
             game = RequestHandler.lobbies.get(slug)
             response = jsonify(game)
         except KeyError:
             response = exceptions.NotFound(
                 f"Game with slug {slug} not found.")
     else:
         response = exceptions.BadRequest("Need to specify game slug")
     return response
示例#6
0
 def handle_quit_game(json=None):
     requests_logger.debug(
         f"A player has tried to quit the game {self.lobby_name}")
     player = self.players_by_session.get(
         session.get("connection_id", None), None)
     if player:
         requests_logger.debug(
             f'Player {player} is trying to quit {self.name_space}')
     else:
         requests_logger.debug(
             f'A foreign connection has tried to quit {self.name_space}'
         )
示例#7
0
    def create_lobby():
        request_data = request.json
        try:
            jsonschema.validate(instance=request_data,
                                schema=schema.create_lobby_schema)
            lobby_name = request_data.get("lobby_name")
            lobby_slug = "lobby-" + slugify(request_data.get("lobby_name"))
            allow_rule_voting = request_data.get("allow_rule_voting")
            list_publicly = request_data.get("list_publicly")
            max_number_of_players = request_data.get("max_number_of_players")

            if all(x is not None for x in [
                    lobby_name, lobby_slug, allow_rule_voting, list_publicly,
                    max_number_of_players
            ]):
                with RequestHandler.lobbies_lock:
                    if lobby_slug in RequestHandler.lobbies:
                        raise ValueError("Game slug has been used already")
                    lobby = Lobby(lobby_name, lobby_slug, allow_rule_voting,
                                  list_publicly, max_number_of_players)
                    RequestHandler.lobbies.update({lobby_slug: lobby})
                requests_logger.debug(f"POST request to /games successful. "
                                      f"Created new Game \"{lobby_slug}\"")
                return jsonify(lobby.json())
            else:
                raise ValueError()
        except jsonschema.exceptions.SchemaError as e:
            requests_logger.debug(
                "POST request to /games failed. Data incomplete.")
            return exceptions.BadRequest(
                f"Data incomplete, Key Error: {e.args}")
        except ValueError as e:
            requests_logger.debug(
                "POST request to /games failed. Invalid Data.")
            return exceptions.BadRequest(f"Data invalid. {e.args}")
        except Exception as e:
            requests_logger.debug(
                "POST request to /games failed with unhandled Error.")
            raise e
示例#8
0
 def handle_game_action(json=None):
     requests_logger.debug(
         f"A player has tried to make a game action in game {self.lobby_name}"
     )
     player = self.players_by_session.get(
         session.get("connection_id", None), None)
     if player:
         requests_logger.debug(
             f'Player {player} is trying to commit a game action on {self.name_space}'
         )
         if json:
             if jsonschema.validate(json, schema.game_action_schema):
                 pass
             else:
                 return jsonify({
                     "Error": {
                         "type":
                         "schema_error",
                         "message":
                         "The json data provided does not match the required schema.",
                     }
                 })
         else:
             return jsonify({
                 "Error": {
                     "type": "data_missing",
                     "message": "You need to provide json data.",
                 }
             })
     else:
         requests_logger.debug(
             f'A foreign connection has tried to commit a game action on {self.name_space}'
         )
         return jsonify({
             "Error": {
                 "type":
                 "insufficient_authorization",
                 "message":
                 "you are not a player an hence not allowed to commit a game action.",
             }
         })
示例#9
0
 def list_games():
     requests_logger.debug("GET request to /games. Serving list of games…")
     response = jsonify(list(RequestHandler.lobbies.values()))
     return response
示例#10
0
 def handle_disconnect():
     requests_logger.debug(
         f"{session.get('connection_id', 0)} has been disconnected.")
示例#11
0
 def handle_connect():
     if session.get("connection_id", None) is None:
         session["connection_id"] = b64encode(os.urandom(2**5))
     requests_logger.debug(
         f"{session['connection_id']} connected. The sid is: {request.sid}, request: {request}"
     )
示例#12
0
        def handle_start_game(json=None):
            requests_logger.debug(
                f"A player has tried to start the game {self.lobby_name}")
            player = self.players_by_session.get(
                session.get("connection_id", None), None)
            if player:
                requests_logger.debug(
                    f'Player {player} is trying to start {self.name_space}')

                # no data is needed as the rules for a new game are stored in the lobby object
                def start_game(self, host_decision=False):
                    def game_can_be_started(_host_decision):
                        """Decide if the game can be started. Otherwise raise an exception stating the reason for the failure
                        to be handled by the backend."""
                        if self.rules.start_game_if_all_ready:
                            # Case 1: All Players are ready
                            if all(p.is_ready for p in self.participants):
                                # Case 1.1: Number of players variable
                                if self.rules.variable_player_count:
                                    # Case 1.1.1: Enough Players in Lobby → start game
                                    if len(self.participants) > 1:
                                        return True
                                    # Case 1.1.2: Not enough players for a game → Game cannot be started
                                    else:
                                        raise logic.Game.CannotBeStarted(
                                            logic.Game.CannotBeStarted.Reason.
                                            not_enough_players)

                                # Case 1.2: Number of Players fixed
                                else:
                                    # Case 1.2.1: Lobby is full → start game
                                    if len(self.participants
                                           ) == self.rules.number_of_players:
                                        return True
                                    # Case 1.2.2: Not enough players → Game cannot be started
                                    else:
                                        # Case 1.2.2.1: Host decided for the game to start → start game
                                        if _host_decision:
                                            return True
                                        # Case 1.2.2.2: No host decision → Game cannot be started
                                        else:
                                            raise logic.Game.CannotBeStarted(
                                                logic.Game.CannotBeStarted.
                                                Reason.not_enough_players)

                            # Case 2: Not all players are ready → Game cannot be started
                            else:
                                raise logic.Game.CannotBeStarted(
                                    logic.Game.CannotBeStarted.Reason.
                                    not_all_players_ready)

                        else:
                            # Case 1: Lobby full → start game
                            if len(self.participants
                                   ) == self.rules.number_of_players:
                                return True

                            # Case 2: Lobby not full (Host initiated start)
                            else:
                                # Case 2.1: Enough players → start game
                                if len(self.participants) > 1:
                                    return True
                                # Case 2.2: Not enough players → Game cannot be started
                                else:
                                    raise logic.Game.CannotBeStarted(
                                        logic.Game.CannotBeStarted.Reason.
                                        not_enough_players)

                    if game_can_be_started(host_decision):
                        self._game_state = logic.Game.State.started
                        self._current_turn = 0

                        # if self.rules.shuffle_turn_order_on_start:
                        #    random.shuffle(self.participants)
                        # replaced by:
                        # self.rules.apply(game=self)

                        self.initial_players = self.participants[:]
            else:
                requests_logger.debug(
                    f'A foreign connection has tried to start {self.name_space}'
                )
            quit()
            ############################################################################

            if json:
                try:
                    jsonschema.validate(instance=json,
                                        schema=schema.create_game_schema)
                    game_name = json.get("game_name")

                    rules = data.Rules(**json.get("rules"))
                    card_deck = data.CardDeck(**json.get("card_deck"))
                    host_player_data = json.get("player")

                    host_player = data.Player(
                        host_player_data["name"],
                        data.TokenStyle(**host_player_data["token_style"]))

                    if game_name and rules and card_deck and host_player:
                        new_game = logic.Game(game_name, host_player, rules,
                                              card_deck)
                        with RequestHandler.game_sockets_lock:
                            if new_game.slug in RequestHandler.game_sockets:
                                raise ValueError()
                            connection = GameSocket(game=new_game)
                            RequestHandler.game_sockets.update(
                                {new_game.slug: connection})
                        requests_logger.debug(
                            f"POST request to /games successful. "
                            f"Created new Game \"{new_game.slug}\"")
                        return JSON.dumps(new_game.json())
                    else:
                        raise ValueError()
                except jsonschema.exceptions.SchemaError as e:
                    requests_logger.debug(
                        "POST request to /games failed. Data incomplete.")
                    return exceptions.BadRequest(
                        f"Data incomplete, Key Error: {e.args}")
                except ValueError as e:
                    requests_logger.debug(
                        "POST request to /games failed. Invalid Data.")
                    return exceptions.BadRequest(f"Data invalid. {e.args}")
                except Exception as e:
                    requests_logger.debug(
                        f"Start game request by {session['connection_id']} to {self.name_space}"
                        f"failed with unhandled Error.")
                    raise e
            else:
                return exceptions.BadRequest("You need to provide json data.")