예제 #1
0
    async def handle_move(self, client: Client, msg: ProtocolMessage):
        our_ctrl: GameController = self.user_game_ctrl[client.username]
        other_ctrl: GameController = self.user_game_ctrl[
            our_ctrl.opponent_name]

        try:
            positions: Positions = our_ctrl.run(msg)
        except BattleshipError as e:
            answer: ProtocolMessage = ProtocolMessage.create_error(
                e.error_code)
            await self.send(client, answer)
            return
        except Exception as e:
            raise e

        our_ctrl.timeout_counter = 0
        our_ctrl.cancel_timeout()

        # notify
        params = {}
        if not len(positions.positions) == 0:
            params["positions"] = positions
        msg_moved: ProtocolMessage = ProtocolMessage.create_single(
            ProtocolMessageType.MOVED, params)

        await self.send(other_ctrl.client, msg_moved)
        await self.send(our_ctrl.client, msg_moved)
        our_ctrl.run(msg_moved)
        other_ctrl.run(msg_moved)

        other_ctrl.start_timeout(self.handle_timeout_wrapper)
예제 #2
0
    async def handle_login(self, client: Client, msg: ProtocolMessage):
        params: Dict[str, Any] = msg.parameters
        answer: Optional[ProtocolMessage] = None

        if client.state is not ClientConnectionState.NOT_CONNECTED:
            answer = ProtocolMessage.create_error(
                ErrorCode.ILLEGAL_STATE_ALREADY_LOGGED_IN)
        elif len(params["username"]) > ProtocolConfig.USERNAME_MAX_LENGTH:
            answer = ProtocolMessage.create_error(
                ErrorCode.SYNTAX_USERNAME_TOO_LONG)
        else:
            login_successful: bool = self.login_user(params["username"],
                                                     client)
            if not login_successful:
                answer = ProtocolMessage.create_error(
                    ErrorCode.PARAMETER_USERNAME_ALREADY_EXISTS)
            else:
                client.state = ClientConnectionState.GAME_SELECTION
                #self.users[username].state = ClientConnectionState.GAME_SELECTION
                client.username = params["username"]
                self.users[client.username] = client
                self.print_client(
                    client, "Client successfully logged in with '{}'".format(
                        client.username))
                await self.send_games_to_user(client)

        if answer is not None:
            await self.send(client, answer)

        self.print_stats()
예제 #3
0
    async def end_game_with_reason(self, our_ctrl: GameController,
                                   other_ctrl: GameController,
                                   our_reason: EndGameReason,
                                   other_reason: EndGameReason):
        our_ctrl.cancel_timeout()
        other_ctrl.cancel_timeout()

        del self.games[our_ctrl.game_id]
        del self.user_game_ctrl[our_ctrl.username]
        del self.user_game_ctrl[other_ctrl.username]
        del self.user_gid[our_ctrl.username]
        del self.user_gid[other_ctrl.username]

        # if this was called from logout, the user no longer exists
        if our_ctrl.username in self.users:
            self.users[
                our_ctrl.username].state = ClientConnectionState.GAME_SELECTION

        # if this was called from logout, the user no longer exists
        if other_ctrl.username in self.users:
            self.users[other_ctrl.
                       username].state = ClientConnectionState.GAME_SELECTION

        await self.send(
            other_ctrl.client,
            ProtocolMessage.create_single(ProtocolMessageType.ENDGAME,
                                          {"reason": other_reason}))
        await self.send(
            our_ctrl.client,
            ProtocolMessage.create_single(ProtocolMessageType.ENDGAME,
                                          {"reason": our_reason}))

        self.print_stats()
예제 #4
0
    async def handle_msg(self, client: Client, msg: ProtocolMessage):

        if msg.missing_or_unkown_param:
            answer: ProtocolMessage = ProtocolMessage.create_error(
                ErrorCode.SYNTAX_MISSING_OR_UNKNOWN_PARAMETER)
            await self.send(client, answer)

        # No other command is permitted if the client is not logged in
        elif client.state is ClientConnectionState.NOT_CONNECTED and msg.type is not ProtocolMessageType.LOGIN:
            answer = ProtocolMessage.create_error(
                ErrorCode.ILLEGAL_STATE_NOT_LOGGED_IN)
            await self.send(client, answer)

        elif msg.type == ProtocolMessageType.LOGIN:
            await self.handle_login(client, msg)

        elif msg.type == ProtocolMessageType.LOGOUT:
            await self.handle_logout(client, msg)

        elif msg.type == ProtocolMessageType.CHAT_SEND:
            await self.handle_chat_send(client, msg)

        elif msg.type == ProtocolMessageType.GET_GAMES:
            await self.handle_get_games(client, msg)

        elif msg.type == ProtocolMessageType.CREATE_GAME:
            await self.handle_create_game(client, msg)

        # handle_cancel handles the case when the user has not created a game
        elif msg.type == ProtocolMessageType.CANCEL:
            await self.handle_cancel(client, msg)

        # handle_join handles the case that they created a game themselves
        elif msg.type == ProtocolMessageType.JOIN:
            await self.handle_join(client, msg)

        # all the following messages are only valid when playing
        elif not client.state == ClientConnectionState.PLAYING:
            answer = ProtocolMessage.create_error(
                ErrorCode.ILLEGAL_STATE_NOT_IN_GAME)
            await self.send(client, answer)

        elif msg.type == ProtocolMessageType.PLACE:
            await self.handle_place(client, msg)

        elif msg.type == ProtocolMessageType.ABORT:
            await self.handle_abort(client, msg)

        elif msg.type == ProtocolMessageType.MOVE:
            await self.handle_move(client, msg)

        elif msg.type == ProtocolMessageType.SHOOT:
            await self.handle_shoot(client, msg)
예제 #5
0
    async def handle_shoot(self, client: Client, msg: ProtocolMessage):
        our_ctrl: GameController = self.user_game_ctrl[client.username]
        other_ctrl: GameController = self.user_game_ctrl[
            our_ctrl.opponent_name]

        try:
            hit: bool = other_ctrl.run(msg)
        except BattleshipError as e:
            answer = ProtocolMessage.create_error(e.error_code)
            await self.send(client, answer)
            return
        except Exception as e:
            raise e

        our_ctrl.timeout_counter = 0
        our_ctrl.cancel_timeout()

        if hit:
            sunk: bool = other_ctrl.ship_sunk_at_pos(
                msg.parameters["position"].horizontal,
                msg.parameters["position"].vertical)
            msg_hit: ProtocolMessage = ProtocolMessage.create_single(
                ProtocolMessageType.HIT, {
                    "sunk": sunk,
                    "position": msg.parameters["position"]
                })

            await self.send(other_ctrl.client, msg_hit)
            await self.send(our_ctrl.client, msg_hit)
            our_ctrl.run(msg_hit)
            other_ctrl.run(msg_hit)

            our_ctrl.start_timeout(self.handle_timeout_wrapper)

            if other_ctrl.all_ships_sunk():
                await self.end_game_with_reason(our_ctrl, other_ctrl,
                                                EndGameReason.YOU_WON,
                                                EndGameReason.OPPONENT_WON)

        else:
            msg_fail: ProtocolMessage = ProtocolMessage.create_single(
                ProtocolMessageType.FAIL,
                {"position": msg.parameters["position"]})

            await self.send(other_ctrl.client, msg_fail)
            await self.send(our_ctrl.client, msg_fail)
            our_ctrl.run(msg_fail)
            other_ctrl.run(msg_fail)

            other_ctrl.start_timeout(self.handle_timeout_wrapper)
예제 #6
0
    async def handle_create_game(self, client: Client, msg: ProtocolMessage):

        if client.state in [
                ClientConnectionState.GAME_CREATED,
                ClientConnectionState.PLAYING
        ]:
            # TODO: in the case of GAME_CREATED, this is more or less in line with the RFC
            # TODO: in the case of PLAYING, a better error code would be nice
            msg_error = ProtocolMessage.create_error(
                ErrorCode.ILLEGAL_STATE_NUMBER_OF_GAMES_LIMIT_EXCEEDED)
            await self.send(client, msg_error)
            return

        game_id: int = ServerLobbyController.next_game_id
        ServerLobbyController.next_game_id += 1

        game_controller: GameController = await GameController.create_from_msg(
            game_id, client, self.loop, msg, client.username)

        if game_controller is not None:
            client.state = ClientConnectionState.GAME_CREATED
            self.user_gid[client.username] = game_id
            self.games[game_id] = (game_controller, None)
            self.user_game_ctrl[client.username] = game_controller
            # and send the game to all users
            game_msg: ProtocolMessage = game_controller.to_game_msg()
            await self.msg_to_all(game_msg)

            self.print_stats()
        # the game controller already sends the error messages, so this is fine.
        # TODO: move this here to be consistent.
        else:
            pass
예제 #7
0
    async def handle_timeout(self, client: Client):
        if not client.username in self.user_game_ctrl:
            # This happened once when a timeout came almost exactly when the game ended
            return

        our_ctrl: GameController = self.user_game_ctrl[client.username]

        if not our_ctrl.opponent_name in self.user_game_ctrl:
            # This happened once when a timeout came almost exactly when the game ended
            return

        other_ctrl: GameController = self.user_game_ctrl[
            our_ctrl.opponent_name]

        our_ctrl.timeout_counter += 1

        if our_ctrl.timeout_counter >= 3:
            # TODO: really send OPPONENT_WON?
            await self.end_game_with_reason(our_ctrl, other_ctrl,
                                            EndGameReason.OPPONENT_WON,
                                            EndGameReason.OPPONENT_TIMEOUT)
            return

        msg_timeout: ProtocolMessage = ProtocolMessage.create_single(
            ProtocolMessageType.TIMEOUT)

        await self.send(our_ctrl.client, msg_timeout)
        await self.send(other_ctrl.client, msg_timeout)
        our_ctrl.run(msg_timeout)
        other_ctrl.run(msg_timeout)

        other_ctrl.start_timeout(self.handle_timeout_wrapper)
예제 #8
0
    async def client():
        nonlocal test_msg, test_msg_received

        async def client_msg_callback(msg: ProtocolMessage):
            print("< {}".format(msg))

        def client_closed_callback():
            print("< server closed connection".format())

        battleship_client = BattleshipClient(loop, client_msg_callback,
                                             client_closed_callback)
        await battleship_client.connect(Constants.SERVER_IP,
                                        Constants.SERVER_PORT)

        for i in range(2000):
            for msg_type in list(ProtocolMessageType):
                test_msg = ProtocolMessage.random_from_type(msg_type)
                try:
                    await battleship_client.send(test_msg)
                except Exception as e:
                    print("Was trying to send the following message:")
                    print("{}".format(test_msg))
                    raise e
                await test_msg_received.wait()
                test_msg_received.clear()
예제 #9
0
    async def send_cancel(self):
        msg = ProtocolMessage.create_single(ProtocolMessageType.CANCEL)
        await self.client.send_and_wait_for_answer(msg)

        # TODO: timeouts
        if self.client.last_msg_was_error:
            raise BattleshipError(self.client.last_error)
예제 #10
0
    async def handle_place(self, client: Client, msg: ProtocolMessage):
        our_ctrl: GameController = self.user_game_ctrl[client.username]
        other_ctrl: GameController = self.user_game_ctrl[
            our_ctrl.opponent_name]

        try:
            our_ctrl.run(msg)
        except BattleshipError as e:
            # TODO: maybe check if it's not an internal error
            answer: ProtocolMessage = ProtocolMessage.create_error(
                e.error_code)
            await self.send(client, answer)
            return
        except Exception as e:
            raise e

        # notify the other
        msg_placed: ProtocolMessage = ProtocolMessage.create_single(
            ProtocolMessageType.PLACED)
        await self.send(other_ctrl.client, msg_placed)

        # if both are on waiting, the game can start
        if our_ctrl.state == GameState.WAITING and other_ctrl.state == GameState.WAITING:
            # who starts?
            starting_ctrl: GameController
            waiting_ctrl: GameController
            (starting_ctrl, waiting_ctrl) = (
                our_ctrl, other_ctrl) if randrange(2) == 1 else (other_ctrl,
                                                                 our_ctrl)

            youstart: ProtocolMessage = ProtocolMessage.create_single(
                ProtocolMessageType.YOUSTART)
            await self.send(starting_ctrl.client, youstart)
            starting_ctrl.run(youstart)
            starting_ctrl.timeout_counter = 0
            starting_ctrl.start_timeout(self.handle_timeout_wrapper)

            youwait: ProtocolMessage = ProtocolMessage.create_single(
                ProtocolMessageType.WAIT)
            await self.send(waiting_ctrl.client, youwait)
            waiting_ctrl.run(youwait)

            # TODO: fix this, should be merged with state, is this even used anymore?
            starting_ctrl._game_started = True
            waiting_ctrl._game_started = True
예제 #11
0
    async def handle_chat_send(self, client: Client, msg: ProtocolMessage):
        params: Dict[str, Any] = msg.parameters
        answer: Optional[ProtocolMessage] = None
        forward: ProtocolMessage

        text: str = params["text"]
        recipient: str = params["username"]

        if len(text) > ProtocolConfig.CHAT_MAX_TEXT_LENGTH:
            answer = ProtocolMessage.create_error(
                ErrorCode.SYNTAX_MESSAGE_TEXT_TOO_LONG)

        # check if the message is for all users
        elif recipient == "":
            forward = ProtocolMessage.create_single(
                ProtocolMessageType.CHAT_RECV, {
                    "sender": client.username,
                    "recipient": "",
                    "text": text
                })
            await self.msg_to_all_but_one(forward, client.username)
            self.print_client(
                client,
                "Forwarding chat message to all logged in users but {}".format(
                    client.username))

        elif recipient not in self.users:
            answer = ProtocolMessage.create_error(
                ErrorCode.PARAMETER_USERNAME_DOES_NOT_EXIST)

        else:
            forward = ProtocolMessage.create_single(
                ProtocolMessageType.CHAT_RECV, {
                    "sender": client.username,
                    "recipient": recipient,
                    "text": text
                })
            await self.msg_to_user(forward, recipient)
            self.print_client(
                client, "Forwarding chat message to '{}'".format(recipient))

        if answer is not None:
            await self.send(client, answer)
예제 #12
0
    async def client(client_id: int):

        async def msg_callback(msg: ProtocolMessage):
            print("< [{}] {}".format(client_id, msg))

        def closed_callback():
            print("< [{}] server closed connection".format(client_id))

        async def _send_and_wait(msg: ProtocolMessage, seconds_to_wait: float = 0.0):
            print("> [{}] {}".format(client_id, msg))
            await battleship_client.send(msg)
            if seconds_to_wait > 0:
                await asyncio.sleep(seconds_to_wait)

        battleship_client = BattleshipClient(loop, msg_callback, closed_callback)
        await battleship_client.connect(Constants.SERVER_IP, Constants.SERVER_PORT)

        # the following messages are just to test
        # normally you can just call `await battleship_client.send(msg)`
        # await is necessary because it's asynchronous

        await _send_and_wait(ProtocolMessage.create_single(ProtocolMessageType.LOGIN,
                                                    {"username": "******".format(client_id)}))

        if client_id % 2 == 0:
            await _send_and_wait(ProtocolMessage.create_single(ProtocolMessageType.CREATE_GAME,
                                         {"board_size": 10,
                                          "num_ships": NumShips([1, 1, 1, 1, 1]),
                                          "round_time": 25,
                                          "options": GameOptions.PASSWORD,
                                          "password": "******"
                                              }))

        #await do_join.wait()
        await asyncio.sleep(10)

        if client_id % 2 == 1:
            await _send_and_wait(ProtocolMessage.create_single(ProtocolMessageType.JOIN,
                                                    {"game_id": int((client_id+1)/2), "password": "******"}))

        #await finished.wait()
        await asyncio.sleep(10)
        battleship_client.close()
예제 #13
0
    async def send_join(self, game_id: int, password: str = ""):
        params: Dict[str, Any] = {"game_id": game_id}
        if not password == "":
            params["password"] = password
        msg: ProtocolMessage = ProtocolMessage.create_single(
            ProtocolMessageType.JOIN, params)
        await self.client.send_and_wait_for_answer(msg)

        # TODO: timeouts
        if self.client.last_msg_was_error:
            raise BattleshipError(self.client.last_error)
예제 #14
0
 async def send_chat(self, username, text):
     if len(text) > ProtocolConfig.CHAT_MAX_TEXT_LENGTH:
         offset = 0
         while offset < len(text):
             next_text = text[offset:offset +
                              ProtocolConfig.CHAT_MAX_TEXT_LENGTH]
             offset += ProtocolConfig.CHAT_MAX_TEXT_LENGTH
             msg = ProtocolMessage.create_single(
                 ProtocolMessageType.CHAT_SEND, {
                     "username": username,
                     "text": next_text
                 })
             await self.client.send(msg)
     else:
         msg = ProtocolMessage.create_single(ProtocolMessageType.CHAT_SEND,
                                             {
                                                 "username": username,
                                                 "text": text
                                             })
         await self.client.send(msg)
예제 #15
0
    async def send_get_games(self):
        try:
            msg = ProtocolMessage.create_single(ProtocolMessageType.GET_GAMES)
            self.games = {}
            await self.client.send_and_wait_for_answer(msg)
        except Exception as e:
            logging.debug("send_get_games-->".format(str(e)))

        # TODO: timeouts
        if self.client.last_msg_was_error:
            raise BattleshipError(self.client.last_error)
예제 #16
0
 async def handle_cancel(self, client: Client, msg: ProtocolMessage):
     if client.state == ClientConnectionState.GAME_CREATED:
         game_id: int = self.user_gid[client.username]
         del self.user_gid[client.username]
         del self.user_game_ctrl[client.username]
         del self.games[game_id]
         client.state = ClientConnectionState.GAME_SELECTION
         await self.send_delete_game(game_id)
     else:
         msg_error: ProtocolMessage = ProtocolMessage.create_error(
             ErrorCode.PARAMETER_UNKNOWN_GAME_ID)
         await self.send(client, msg_error)
예제 #17
0
    async def try_login(self, server, port, username):
        if not self.client.connected:
            await self.client.connect(server, port)

        if username.strip() == "":
            raise BattleshipError(ErrorCode.PARAMETER_INVALID_USERNAME)
        elif len(username) > ProtocolConfig.USERNAME_MAX_LENGTH:
            raise BattleshipError(ErrorCode.SYNTAX_USERNAME_TOO_LONG)

        msg = ProtocolMessage.create_single(ProtocolMessageType.LOGIN,
                                            {"username": username})
        await self.client.send_and_wait_for_answer(msg)

        # TODO: timeouts
        if self.client.last_msg_was_error:
            raise BattleshipError(self.client.last_error)
예제 #18
0
    async def msg_callback(msg: ProtocolMessage):
        logging.debug("< {}".format(msg))

        # if we receive a non error message, we take this as a hint that we are successfully logged in
        if lobby_controller.state is ClientConnectionState.NOT_CONNECTED and not msg.type == ProtocolMessageType.ERROR:
            lobby_controller.state = ClientConnectionState.CONNECTED

        if msg.type == ProtocolMessageType.ERROR:
            pass
        elif msg.type == ProtocolMessageType.GAMES:
            await lobby_controller.handle_games(msg)
        elif msg.type == ProtocolMessageType.GAME:
            await lobby_controller.handle_game(msg)
        elif msg.type == ProtocolMessageType.DELETE_GAME:
            await lobby_controller.handle_delete_game(msg)
        elif msg.type == ProtocolMessageType.CHAT_RECV:
            if in_lobby_or_battle is True:
                await lobby_controller.handle_chat_recv(msg)
        elif msg.type == ProtocolMessageType.HIT:
            await lobby_controller.handle_hit(msg)
        elif msg.type == ProtocolMessageType.WAIT:
            await lobby_controller.handle_wait(msg)
        elif msg.type == ProtocolMessageType.YOUSTART:
            await lobby_controller.handle_youstart(msg)
        elif msg.type == ProtocolMessageType.TIMEOUT:
            await lobby_controller.handle_timeout(msg)
        elif msg.type == ProtocolMessageType.FAIL:
            await lobby_controller.handle_fail(msg)
        elif msg.type == ProtocolMessageType.ENDGAME:
            await lobby_controller.handle_endgame(msg)
        elif msg.type == ProtocolMessageType.MOVED:
            await lobby_controller.handle_moved(msg)
        elif msg.type == ProtocolMessageType.STARTGAME:
            await lobby_controller.handle_start_game(msg)
        elif msg.type == ProtocolMessageType.PLACED:
            await lobby_controller.handle_placed(msg)
        elif msg.type == ProtocolMessageType.NONE:
            err: ProtocolMessage = ProtocolMessage.create_error(
                ErrorCode.UNKNOWN)
            await lobby_controller.client.send(err)
        # add the other types if needed
        else:
            pass
예제 #19
0
    async def send_games_to_user(self, client: Client):
        # TODO: the type annotation Any can be more exact
        repeating_parameters: List[Any] = []
        for game_id, (game_controller1,
                      game_controller2) in self.games.items():
            if game_controller1.state == GameState.IN_LOBBY:
                parameters = {
                    "game_id": game_id,
                    "username": game_controller1.username,
                    "board_size": game_controller1.length,
                    "num_ships": NumShips(game_controller1.ships),
                    "round_time": game_controller1.round_time,
                    "options": game_controller1.options
                }
                repeating_parameters.append(parameters)

        msg: ProtocolMessage = ProtocolMessage.create_repeating(
            ProtocolMessageType.GAMES, repeating_parameters)
        await self.send_repeating(client, msg)
예제 #20
0
    async def client(client_id: int):
        async def msg_callback(msg: ProtocolMessage):
            print("< [{}] {}".format(client_id, msg))

        def closed_callback():
            print("< [{}] server closed connection".format(client_id))

        async def _send_and_wait(msg: ProtocolMessage,
                                 seconds_to_wait: float = 0.5):
            print("> [{}] {}".format(client_id, msg))
            await battleship_client.send(msg)
            if seconds_to_wait > 0:
                await asyncio.sleep(seconds_to_wait)

        # Ding was die Verbindung managed zum Server
        battleship_client = BattleshipClient(loop, msg_callback,
                                             closed_callback)
        await battleship_client.connect(Constants.SERVER_IP,
                                        Constants.SERVER_PORT)
        #await battleship_client.connect("192.168.0.1", "4242")
        # the following messages are just to test
        # normally you can just call `await battleship_client.send(msg)`
        # await is necessary because it's asynchronous

        await _send_and_wait(
            ProtocolMessage.create_single(
                ProtocolMessageType.LOGIN,
                {"username": "******".format(client_id)}))

        # await _send_and_wait(ProtocolMessage.create_single(ProtocolMessageType.CREATE_GAME,
        #                                 {"board_size": 5,
        #                                  "num_ships": NumShips([1, 2, 3, 4, 5]),
        #                                  "round_time": 25,
        #                                  "options": GameOptions.PASSWORD,
        #                                  "password": "******"
        #                                      }))
        #
        # await _send_and_wait(ProtocolMessage.create_single(ProtocolMessageType.CREATE_GAME,
        #                                 {"board_size": 5,
        #                                  "num_ships": NumShips([1, 2, 3, 4, 5]),
        #                                  "round_time": 25,
        #                                  "options": 0
        #                                      }))
        input("PUSH THE BUTTON for chatting")
        await _send_and_wait(
            ProtocolMessage.create_single(
                ProtocolMessageType.CHAT_SEND, {
                    "username": "******".format((client_id + 1) % 2),
                    "text":
                    "client {} schießt den server ab :P".format(client_id)
                }))
        input("PUSH THE BUTTON to create a game")
        #await _send_and_wait(ProtocolMessage.create_single(ProtocolMessageType.CHAT_SEND, {"username": "", "text": "z"}))

        await _send_and_wait(
            ProtocolMessage.create_single(
                ProtocolMessageType.CREATE_GAME, {
                    "board_size": 10,
                    "num_ships": NumShips([1, 0, 0, 0, 2]),
                    "round_time": 25,
                    "options": 0
                }))

        input("PUSH THE BUTTON to place a game")
        msg = ProtocolMessage.create_single(
            ProtocolMessageType.PLACE, {
                "ship_positions":
                ShipPositions([
                    ShipPosition(Position(0, 0), Orientation.EAST),
                    ShipPosition(Position(3, 0), Orientation.EAST)
                ])
            })

        await _send_and_wait(msg)
        ####################################################################################################################
        # Start Playing #
        ####################################################################################################################
        end = input("x=exit, m=move, s=shoot:_")
        while end is not "x":
            if end == "s":
                turn_counter = int(input("insert turn_counter to shoot: "))
                x_pos = int(input("shot x_pos: "))
                y_pos = int(input("shoot y_pos: "))
                msg = ProtocolMessage.create_single(
                    ProtocolMessageType.SHOOT, {
                        "position": Position(y_pos, x_pos),
                        "turn_counter": turn_counter
                    })

            if end == "m":
                turn_counter = int(input("insert turn_counter to move: "))
                move_direction = int(input("insert move direction: "))
                msg = ProtocolMessage.create_single(
                    ProtocolMessageType.MOVE, {
                        "ship_id": 0,
                        "direction": move_direction,
                        "turn_counter": turn_counter
                    })

            await _send_and_wait(msg)
            end = input("x=exit, m=move, s=shoot:_")

#ABORT
        input("PUSH THE BOTTEN for abort")
        msg = ProtocolMessage.create_single(ProtocolMessageType.ABORT)
        await _send_and_wait(msg)

        # await _send_and_wait(ProtocolMessage.create_single(ProtocolMessageType.MOVE, {"turn_counter": 2, "ship_id": 146579, "direction": Orientation.EAST}))
        #
        # await _send_and_wait(ProtocolMessage.create_single(ProtocolMessageType.GAME, {
        #     "game_id": 60000, "username": "******", "board_size": 7, "num_ships": NumShips([1, 2, 3, 4, 5]), "round_time": 25, "options": GameOptions.PASSWORD}))
        #
        # await _send_and_wait(ProtocolMessage.create_repeating(ProtocolMessageType.GAMES, [
        #     {"game_id": 60000, "username": "******", "board_size": 7, "num_ships": NumShips([1, 2, 3, 4, 5]),
        #         "round_time": 25, "options": GameOptions.PASSWORD},
        #     {"game_id": 60001, "username": "******", "board_size": 8, "num_ships": NumShips([1, 2, 3, 4, 6]),
        #         "round_time": 30, "options": 0},
        #     {"game_id": 60002, "username": "******", "board_size": 9, "num_ships": NumShips([1, 2, 3, 4, 7]),
        #      "round_time": 35, "options": GameOptions.PASSWORD}]))
        #
        # await _send_and_wait(ProtocolMessage.create_single(ProtocolMessageType.JOIN, {"game_id": 60000, "password": "******"}))
        # await _send_and_wait(ProtocolMessage.create_single(ProtocolMessageType.JOIN, {"game_id": 60001}))

        ####################################################################################################################
        # Logout #
        ####################################################################################################################
        input("PUSH THE BUTTON to logout")
        await _send_and_wait(
            ProtocolMessage.create_single(ProtocolMessageType.LOGOUT))

        battleship_client.close()
예제 #21
0
    async def client(client_id: int):

        async def msg_callback(msg: ProtocolMessage):
            print("< [{}] {}".format(client_id, msg))

        def closed_callback():
            print("< [{}] server closed connection".format(client_id))

        async def _send_and_wait(msg: ProtocolMessage, seconds_to_wait: float = 1.0):
            print("> [{}] {}".format(client_id, msg))
            await battleship_client.send(msg)
            if seconds_to_wait > 0:
                await asyncio.sleep(seconds_to_wait)

        battleship_client = BattleshipClient(loop, msg_callback, closed_callback)
        await battleship_client.connect(Constants.SERVER_IP, Constants.SERVER_PORT)

        # the following messages are just to test
        # normally you can just call `await battleship_client.send(msg)`
        # await is necessary because it's asynchronous

        await _send_and_wait(ProtocolMessage.create_single(ProtocolMessageType.LOGIN,
                                                    {"username": "******".format(client_id)}))

        # await _send_and_wait(ProtocolMessage.create_single(ProtocolMessageType.CREATE_GAME,
        #                                 {"board_size": 5,
        #                                  "num_ships": NumShips([1, 2, 3, 4, 5]),
        #                                  "round_time": 25,
        #                                  "options": GameOptions.PASSWORD,
        #                                  "password": "******"
        #                                      }))
        #
        # await _send_and_wait(ProtocolMessage.create_single(ProtocolMessageType.CREATE_GAME,
        #                                 {"board_size": 5,
        #                                  "num_ships": NumShips([1, 2, 3, 4, 5]),
        #                                  "round_time": 25,
        #                                  "options": 0
        #                                      }))

        await _send_and_wait(ProtocolMessage.create_single(ProtocolMessageType.CHAT_SEND, {"username": "******".format((client_id + 1) % 2), "text": "hurz from client {}".format(client_id)}))
        await _send_and_wait(ProtocolMessage.create_single(ProtocolMessageType.CHAT_SEND, {"username": "", "text": "z"}))
        #
        # await _send_and_wait(ProtocolMessage.create_single(ProtocolMessageType.MOVE, {"turn_counter": 2, "ship_id": 146579, "direction": Orientation.EAST}))
        #
        # await _send_and_wait(ProtocolMessage.create_single(ProtocolMessageType.GAME, {
        #     "game_id": 60000, "username": "******", "board_size": 7, "num_ships": NumShips([1, 2, 3, 4, 5]), "round_time": 25, "options": GameOptions.PASSWORD}))
        #
        # await _send_and_wait(ProtocolMessage.create_repeating(ProtocolMessageType.GAMES, [
        #     {"game_id": 60000, "username": "******", "board_size": 7, "num_ships": NumShips([1, 2, 3, 4, 5]),
        #         "round_time": 25, "options": GameOptions.PASSWORD},
        #     {"game_id": 60001, "username": "******", "board_size": 8, "num_ships": NumShips([1, 2, 3, 4, 6]),
        #         "round_time": 30, "options": 0},
        #     {"game_id": 60002, "username": "******", "board_size": 9, "num_ships": NumShips([1, 2, 3, 4, 7]),
        #      "round_time": 35, "options": GameOptions.PASSWORD}]))
        #
        # await _send_and_wait(ProtocolMessage.create_single(ProtocolMessageType.JOIN, {"game_id": 60000, "password": "******"}))
        # await _send_and_wait(ProtocolMessage.create_single(ProtocolMessageType.JOIN, {"game_id": 60001}))

        await _send_and_wait(ProtocolMessage.create_single(ProtocolMessageType.LOGOUT))

        battleship_client.close()
예제 #22
0
 async def send_delete_game(self, game_id: int):
     del_msg: ProtocolMessage = ProtocolMessage.create_single(
         ProtocolMessageType.DELETE_GAME, {"game_id": game_id})
     await self.msg_to_all(del_msg)
예제 #23
0
 async def send_abort(self):
     msg = ProtocolMessage.create_single(ProtocolMessageType.ABORT)
     await self.client.send_and_wait_for_answer(msg)
예제 #24
0
    async def handle_join(self, client: Client, msg: ProtocolMessage):
        answer: Optional[ProtocolMessage] = None

        game_id: int = msg.parameters["game_id"]

        if not client.state == ClientConnectionState.GAME_SELECTION:
            # TODO: this is not really the right error message, but… there is no other
            answer = ProtocolMessage.create_error(
                ErrorCode.ILLEGAL_STATE_GAME_ALREADY_STARTED)

        # there is no available game with the specified game_ID (error code 104)
        elif not game_id in self.games.keys():
            answer = ProtocolMessage.create_error(
                ErrorCode.PARAMETER_UNKNOWN_GAME_ID)

        # the message lacks the password parameter although a password is required (error code 105)
        elif self.games[game_id][
                0].options == GameOptions.PASSWORD and not "password" in msg.parameters:
            answer = ProtocolMessage.create_error(
                ErrorCode.PARAMETER_PASSWORD_REQUIRED)

        # a password is required for the game, but the given password is incorrect (error code 106)
        elif self.games[game_id][
                0].options == GameOptions.PASSWORD and not msg.parameters[
                    "password"] == self.games[game_id][0].password:
            answer = ProtocolMessage.create_error(
                ErrorCode.PARAMETER_INVALID_PASSWORD)

        # the user wants to join his own game (error code 107)
        elif self.games[game_id][0].username == client.username:
            answer = ProtocolMessage.create_error(
                ErrorCode.PARAMETER_ILLEGAL_JOIN)

        # the game has already started (error code 8)
        elif not self.games[game_id][0].state == GameState.IN_LOBBY:
            answer = ProtocolMessage.create_error(
                ErrorCode.ILLEGAL_STATE_GAME_ALREADY_STARTED)

        # Everything ok, let them play
        else:
            # setup a game_controller for the other one
            game_controller1: GameController = self.games[game_id][0]
            game_controller1.opponent_name = client.username
            game_controller1.state = GameState.PLACE_SHIPS

            client1: Client = self.games[game_id][0].client

            game_controller2: GameController = GameController.create_from_existing_for_opponent(
                game_controller1, client)
            game_controller2.state = GameState.PLACE_SHIPS

            self.games[game_id] = (self.games[game_id][0], game_controller2)

            self.user_gid[client.username] = game_id
            # this is already done for the other user

            self.user_game_ctrl[client.username] = game_controller2

            # set client states
            client.state = ClientConnectionState.PLAYING
            client1.state = ClientConnectionState.PLAYING

            # send startgame messages
            await self.send(client, game_controller2.to_start_game_msg())
            await self.send(client1, game_controller1.to_start_game_msg())

            # inform the other users the game is no longer available
            await self.send_delete_game(game_id)

            self.print_stats()

        if answer is not None:
            await self.send(client, answer)