Esempio n. 1
0
 async def leave_game(self):
     request_payload = api.Request(leave_game=api.RequestLeaveGame())
     self.server.status = "idle"
     async with websockets.connect(
         "ws://{0}:{1}/sc2api".format(self.server.address, self.server.port)
     ) as websocket:
         await websocket.send(request_payload.SerializeToString())
         response = await websocket.recv()
         response = api.Response.FromString(response)
         return response
Esempio n. 2
0
    async def leave(self):
        is_resign = self._game_result is None

        if is_resign:
            # For all clients that can leave, result of leaving the game either
            # loss, or the client will ignore the result
            self._game_result = {self._player_id: Result.Defeat}

        try:
            await self._execute(leave_game=sc_pb.RequestLeaveGame())
        except ProtocolError:
            if is_resign:
                raise
Esempio n. 3
0
    async def proxy_handler(self, request):
        bot_ws = web.WebSocketResponse(receive_timeout=30)
        await bot_ws.prepare(request)
        try:
            async for msg in bot_ws:
                if msg.data is None:
                    raise TypeError(f"data is None, {msg}")
                if msg.data and msg.type == WSMsgType.BINARY:

                    await self.parse_request(msg)

                    response_bytes = await self.get_response()
                    if response_bytes is None:
                        raise ConnectionError("Could not get response_bytes")

                    new_response = await self.parse_response(response_bytes)
                    await bot_ws.send_bytes(new_response.SerializeToString())

                elif msg.type == WSMsgType.CLOSED:
                    logger.error("Client shutdown")
                else:
                    logger.error("Incorrect message type")
        # pylint: disable=W0703
        # TODO Catching too general exception Exception (broad-except)
        except Exception as e:
            ignored_errors = {ConnectionError, asyncio.CancelledError}
            if not any(isinstance(e, E) for E in ignored_errors):
                tb = traceback.format_exc()
                logger.info(
                    f"Proxy({self.player.name}): Caught {e} traceback: {tb}")
        finally:
            try:
                if self.controller._status in {
                        Status.in_game, Status.in_replay
                }:
                    await self.controller._execute(
                        leave_game=sc_pb.RequestLeaveGame())
                await bot_ws.close()
            # pylint: disable=W0703
            # TODO Catching too general exception Exception (broad-except)
            except Exception as e:
                tbb = traceback.format_exc()
                logger.info(
                    f"Proxy({self.player.name}): Caught during Surrender", e,
                    "traceback:", tbb)
            self.done = True
        return bot_ws
Esempio n. 4
0
 async def parse_request(self, msg):
     request = sc_pb.Request()
     request.ParseFromString(msg.data)
     if request.HasField("quit"):
         request = sc_pb.Request(leave_game=sc_pb.RequestLeaveGame())
     if request.HasField("leave_game"):
         if self.controller._status == Status.in_game:
             logger.info(
                 f"Proxy: player {self.player.name}({self.player_id}) surrenders"
             )
             self.result = {self.player_id: Result.Defeat}
         elif self.controller._status == Status.ended:
             await self.get_response()
     elif request.HasField(
             "join_game") and not request.join_game.HasField("player_name"):
         request.join_game.player_name = self.player.name
     await self.controller._ws.send_bytes(request.SerializeToString())
Esempio n. 5
0
    async def leave(self):
        """ You can use 'await self.client.leave()' to surrender midst game. """
        is_resign = self._game_result is None

        if is_resign:
            # For all clients that can leave, result of leaving the game either
            # loss, or the client will ignore the result
            self._game_result = {self._player_id: Result.Defeat}

        try:
            if self.save_replay_path is not None:
                await self.save_replay(self.save_replay_path)
                self.save_replay_path = None
            await self._execute(leave_game=sc_pb.RequestLeaveGame())
        except (ProtocolError, ConnectionAlreadyClosed):
            if is_resign:
                raise
Esempio n. 6
0
async def a_run_multiple_games_nokill(matches: List[GameMatch]):
    """Run multiple matches while reusing SCII processes.
    Prone to crashes and stalls
    """
    # FIXME: check whether crashes between bot-vs-bot are avoidable or not
    if not matches:
        return

    # Start the matches
    results = []
    controllers = []
    for m in matches:
        logger.info(f"Starting match {1 + len(results)}: {m}")
        result = None
        try:
            await maintain_SCII_count(m.needed_sc2_count, controllers,
                                      m.sc2_config)
            result = await run_match(controllers, m, close_ws=False)
        except SystemExit as e:
            logger.critical(f"Game sys.exit'ed as {e} during match {m}")
        except Exception as e:
            logger.trace(f"Exception {e} thrown in match {m}")
        finally:
            for c in controllers:
                try:
                    await c.ping()
                    if c._status != Status.launched:
                        await c._execute(leave_game=sc_pb.RequestLeaveGame())
                except Exception as e:
                    if not (isinstance(e, ProtocolError)
                            and e.is_game_over_error):
                        logger.info(f"controller {c.__dict__} threw {e}")

            results.append(result)

    # Fire the killswitch manually, instead of letting the winning player fire it.
    await asyncio.wait_for(asyncio.gather(*(c._process._close_connection()
                                            for c in controllers)),
                           timeout=50)
    kill_switch.kill_all()
    signal.signal(signal.SIGINT, signal.SIG_DFL)

    return results
Esempio n. 7
0
 def leave(self):
     """Disconnect from a multiplayer game."""
     return self._client.send(leave_game=sc_pb.RequestLeaveGame())
Esempio n. 8
0
 async def leave(self):
     try:
         await self._execute(leave_game=sc_pb.RequestLeaveGame())
     except websockets.exceptions.ConnectionClosed:
         pass
Esempio n. 9
0
 async def leave(self):
     await self._execute(leave_game=sc_pb.RequestLeaveGame())