I've been trying to figure out how to use this library called steam so I can set up a dota 2 bot with the dota2 library in python so it can create and be in multiple games. That, aside from requiring me to create different instances which is its own problem, would require me to set up the sentry files so it doesnt need login for each object that tries to run but I couldn't figure out how. I'm running this bot along with a Flask http server so it can receive requests from my backend and create the lobbys from there. I tried the documentation's way which is not much but I've tried and nothing. Does anybody know how I could achieve this? It is supposed to? generate a login_key for each succesfull login but it doesn't generate it (I've been using client.login(username=os.getenv("STEAM_USERNAME"), password=os.getenv("STEAM_PASSWORD")) for the logins) I also found a method that stores sentrys binaries but I don't know what should be in there in the first place, the documentation doesn't seem to have anything on this. from steam.client import SteamClient from dota2.client import Dota2Client from dota2.enums import DOTA_GC_TEAM, DOTA_GameState import time import os from dotenv import load_dotenv import logging logger = logging.getLogger(__name__) class BotInstance: def __init__(self): load_dotenv() self.client = SteamClient() sentry_path = os.path.abspath('./sentry') os.makedirs(sentry_path, exist_ok=True) self.client.set_credential_location(sentry_path) self.dota = Dota2Client(self.client) self.in_lobby = False self.setup_handlers() def setup_handlers(self): @self.client.on(self.client.EVENT_AUTH_CODE_REQUIRED) def _on_auth_code(is_2fa, code_mismatch): if is_2fa: code = input("Ingrese codigo 2FA: ") self.client.login(os.getenv("STEAM_USERNAME"), os.getenv("STEAM_PASSWORD"), two_factor_code=code) else: code = input("Ingrese codigo de email: ") self.client.login(os.getenv("STEAM_USERNAME"), os.getenv("STEAM_PASSWORD"), auth_code=code) self.client.on('logged_on', self._on_logged_on) self.client.on("error", lambda e: logger.error(f"Error: {e}")) # Eventos dota2 self.dota.on('ready', self._on_dota_ready) self.dota.on("lobby_new", self._on_lobby_created) self.dota.on("lobby_changed", self._on_lobby_changed) self.dota.on("lobby_removed", self._on_lobby_removed) def _on_logged_on(self): if self.client.login_key: with open(os.path.join(self.client.credential_location, f'sentry_{self.client.username.lower()}.key'), 'w') as f: f.write(self.client.login_key) self.dota.launch() def _on_dota_ready(self): if self.dota.lobby: logger.warning("Saliendo del lobby actual") self.dota.leave_practice_lobby() time.sleep(2) logger.info("Dota 2 bot listo para recibir comandos") def _on_lobby_created(self, lobby): logger.info(f"Lobby creado: {lobby}") self.in_lobby = True def _on_lobby_changed(self, lobby): """Callback para monitoreo del lobby""" logger.info("Lobby actualizado") if self.dota.lobby: logger.info("Miembros actuales en el lobby: %s" % len(self.dota.lobby.all_members)) logger.info("Estado %s" % str(self.dota.lobby.state)) # if self.dota.lobby.state == DOTA_GameState.DOTA_GAMERULES_STATE_GAME_IN_PROGRESS: # self.dota.leave_practice_lobby() def _on_lobby_removed(self, lobby): logger.info("Saliendo del lobby") self.in_lobby = False def check_players_in_lobby(self, steam_ids): if not self.dota.lobby: return False lobby_members = [member.id for member in self.dota.lobby.all_members] return all(int(steam_id) in lobby_members for steam_id in steam_ids) def join_as_spectator(self): try: if not self.dota.lobby: logger.warning("No hay lobby para unirse") return time.sleep(3) self.dota.join_practice_lobby_team(team=DOTA_GC_TEAM.PLAYER_POOL) # Permite que el bot siga en el lobby self.in_lobby = True logger.info("Unido como espectador") except Exception as e: logger.error("Error al unirse al canal de espectadores: %s" % e) def create_and_go(self, name, password, game_mode, steam_ids): try: if self.in_lobby: logger.warning("Estoy ocupado en otro lobby") return {'launch': 400, 'message': 'El bot está ocupado en otro lobby'} logger.info(f"Creando lobby con contraseña: {password} con modo de juego: {game_mode}") self.dota.create_practice_lobby(password=password, options={ "game_name": name, "game_mode": game_mode, "allow_cheats": False, "fill_with_bots": False, "allow_spectating": True, "server_region": 15, # Siempre será la región de perú }) # Esperar a que el lobby se cree wait_time = 10 start_time = time.time() while not self.dota.lobby and time.time() - start_time < wait_time: time.sleep(1) if self.dota.lobby: logger.info("Lobby creado exitosamente") self.join_as_spectator() if len(steam_ids) > 0: for steam_id in steam_ids: self.dota.invite_to_lobby(int(steam_id)) logger.info(f"Invitación enviada a {steam_id}") # Verificar que todos los jugadores hayan ingresado al lobby wait_time = 30 # tiempo máximo de espera para que los jugadores ingresen start_time = time.time() while not self.check_players_in_lobby(steam_ids) and time.time() - start_time < wait_time: time.sleep(1) if self.check_players_in_lobby(steam_ids): logger.info("Todos los jugadores están en el lobby") logger.info("Lobby creado") time.sleep(3) # self.dota.leave_practice_lobby() self.dota.launch_practice_lobby() # self.in_lobby = False return {'launch': 200} else: logger.warning("No todos los jugadores están en el lobby") self.dota.destroy_lobby() self.in_lobby = False return {'launch': 400, 'message': 'No todos los jugadores están en el lobby'} else: logger.warning("No hay steam ids para invitar") self.dota.destroy_lobby() self.in_lobby = False else: logger.warning("No se creó el lobby") return {'launch': 400, 'message': 'No se creó el lobby'} except Exception as e: logger.error(f"Error creando lobby: {e}") self.dota.leave_practice_lobby() self.in_lobby = False return {'launch': 400, 'message': str(e)} def run(self): try : self.client.login(username=os.getenv("STEAM_USERNAME"), password=os.getenv("STEAM_PASSWORD")) self.client.run_forever() except Exception as e: logger.error(f"Error al iniciar bot: {e}") self.client.logout() def shutdown(self): if self.dota.lobby: self.dota.leave_practice_lobby() self.in_lobby = False self.client.logout() self.client.disconnect() Continue reading...