async def _join_game( players, realtime, portconfig, save_replay_as=None, game_time_limit=None, ): async with SC2Process(fullscreen=players[1].fullscreen) as server: await server.ping() client = Client(server._ws) # Bot can decide if it wants to launch with 'raw_affects_selection=True' if not isinstance(players[1], Human) and getattr(players[1].ai, "raw_affects_selection", None) is not None: client.raw_affects_selection = players[1].ai.raw_affects_selection result = await _play_game(players[1], client, realtime, portconfig, game_time_limit) if save_replay_as is not None: await client.save_replay(save_replay_as) try: await client.leave() except ConnectionAlreadyClosed: logger.error("Connection was closed before the game ended") await client.quit() return result
def draw_unit_target(self, client: Client, unit: Unit, potential_targets: Units, color=DebugColor()): """Must be sent by send_debug""" unit_target = unit.order_target if unit_target: if isinstance(unit_target, int): unit_target = potential_targets.find_by_tag(unit_target) if unit_target: client.debug_line_out(unit, unit_target, color=color) else: point2 = Point3((*unit_target, unit.position3d.z)) client.debug_line_out(unit, point2, color=color)
async def join_ladder_game(host, port, players, realtime, portconfig, save_replay_as=None, step_time_limit=None, game_time_limit=None): ws_url = "ws://{}:{}/sc2api".format(host, port) ws_connection = await aiohttp.ClientSession().ws_connect(ws_url, timeout=120) client = Client(ws_connection) try: result = await sc2.main._play_game(players[0], client, realtime, portconfig, step_time_limit, game_time_limit) if save_replay_as is not None: await client.save_replay(save_replay_as) # await client.leave() # await client.quit() except ConnectionAlreadyClosed: logging.error(f"Connection was closed before the game ended") return None finally: await ws_connection.close() return result
async def _join_game(players, realtime, portconfig, save_replay_as=None, step_time_limit=None, game_time_limit=None, rgb_render_config=None): async with SC2Process() as server: await server.ping() client = Client(server._ws) try: result = await _play_game(players[1], client, realtime, portconfig, step_time_limit, game_time_limit, rgb_render_config=rgb_render_config) if save_replay_as is not None: await client.save_replay(save_replay_as) await client.leave() await client.quit() except ConnectionAlreadyClosed: logging.error(f"Connection was closed before the game ended") return None return result
async def join_ladder_game(host, port, players, realtime, portconfig, save_replay_as=None, step_time_limit=None, game_time_limit=None): ws_url = f"ws://{host}:{port}/sc2api" ws_connection = await aiohttp.ClientSession().ws_connect(ws_url, timeout=120) client = Client(ws_connection) try: result = await sc2.main._play_game(players[0], client, realtime, portconfig, step_time_limit, game_time_limit) if save_replay_as is not None: await client.save_replay(save_replay_as) except ConnectionAlreadyClosed: logging.error(f"Connection was closed before the game ended") return None finally: # await ws_connection.close() ? # __init__.py:81: RuntimeWarning: coroutine 'ClientWebSocketResponse.close' was never awaited # ws_connection.close() ws_connection.close() return result
async def _setup_host_game( server: Controller, map_settings, players, realtime, random_seed=None, disable_fog=None, save_replay_as=None ): r = await server.create_game(map_settings, players, realtime, random_seed, disable_fog) if r.create_game.HasField("error"): err = f"Could not create game: {CreateGameError(r.create_game.error)}" if r.create_game.HasField("error_details"): err += f": {r.create_game.error_details}" logger.critical(err) raise RuntimeError(err) return Client(server._ws, save_replay_as)
async def _join_game( task_dict, players, aio_event, alive_evnet, req_kill_event, exc_queue, n_games, realtime=False, portconfig=None, save_replay_as=None, step_time_limit=None, game_time_limit=None, ): async with SC2Process() as server: try: for _ in range(n_games): # host에서 게임을 세팅할 때까지 기다림 await aio_event.wait() aio_event.clear() # 게임을 재시작했음을 부모 프로세스에 알림 alive_evnet.set() # 게임 시작 await server.ping() client = Client(server._ws) result = await _play_game( players[1], client, realtime, portconfig, step_time_limit, game_time_limit ) if save_replay_as is not None: await client.save_replay(save_replay_as) await client.leave() # await client.quit() # 게임 인스턴스 재시작을 위해 프로세스 종료하지 않음 except: # 예외가 발생하면 부모 프로세스에 전달 import traceback exc_queue.put(traceback.format_exc()) # n_games 만큼 게임을 반복했음을 부모 프로세스에 알림 # join에서 host를 죽이거나, host에서 join을 죽일 경우를 대비해서, # host와 join 양쪽에 req_kill_evnet를 set 해야함 # -> 어떤 경우에도 부모는 이 프로세스를 종료해야함을 알 수 있음 req_kill_event.set()
async def _join_game_aiter(players, realtime, portconfig): assert players, "Can't create a game without players" assert any(isinstance(p, (Human, Bot)) for p in players) async with SC2Process() as server: while True: await server.ping() client = Client(server._ws) try: result = await _play_game(players[1], client, realtime, portconfig) await client.leave() except ConnectionAlreadyClosed: print(f"Connection was closed before the game ended") return new_players = yield result if new_players is not None: players = new_players
async def play_from_websocket( ws_connection: Union[str, ClientWebSocketResponse], player: AbstractPlayer, realtime: bool = False, portconfig: Portconfig = None, save_replay_as=None, game_time_limit: int = None, should_close=True, ): """Use this to play when the match is handled externally e.g. for bot ladder games. Portconfig MUST be specified if not playing vs Computer. :param ws_connection: either a string("ws://{address}:{port}/sc2api") or a ClientWebSocketResponse object :param should_close: closes the connection if True. Use False if something else will reuse the connection e.g. ladder usage: play_from_websocket("ws://127.0.0.1:5162/sc2api", MyBot, False, portconfig=my_PC) """ session = None try: if isinstance(ws_connection, str): session = ClientSession() ws_connection = await session.ws_connect(ws_connection, timeout=120) should_close = True client = Client(ws_connection) result = await _play_game(player, client, realtime, portconfig, game_time_limit=game_time_limit) if save_replay_as is not None: await client.save_replay(save_replay_as) except ConnectionAlreadyClosed: logger.error("Connection was closed before the game ended") return None finally: if should_close: await ws_connection.close() if session: await session.close() return result
def draw_unit_range(self, client: Client, unit: Unit, color=DebugColor()): """Must be sent by send_debug""" unit_range = max(unit.ground_range, unit.air_range) + unit.radius client.debug_sphere_out(unit, unit_range, color=color)
async def _setup_replay(server, replay_path, realtime, observed_id): await server.start_replay(replay_path, realtime, observed_id) return Client(server._ws)