diff --git a/discord_bot.py b/discord_bot.py index f968c39..b58a478 100644 --- a/discord_bot.py +++ b/discord_bot.py @@ -101,6 +101,8 @@ def format_game(game): async def update_status_message(): + if not client.is_ready(): # Check if the client is connected + return global current_online global global_channel global global_online_list_message @@ -200,73 +202,94 @@ def any_player_name_contains_a_banned_word(players): game_list = {} -background_task_running = 0 +background_task_running = False async def background_task(): global gameTTL global current_online + global background_task_running last_refresh = 0 refresh_seconds = 60 # refresh gamelist every x seconds - while True: - await asyncio.sleep(1) - if time.time() - last_refresh >= refresh_seconds: - last_refresh = time.time() - # Call the external program and get the output - proc = await asyncio.create_subprocess_shell( - './devilutionx-gamelist', - stdout=asyncio.subprocess.PIPE, - stderr=asyncio.subprocess.PIPE) - - stdout, stderr = await proc.communicate() - output = stdout.decode() - if not output: + background_task_running = True + try: + while True: + # Before each loop iteration, check if the client is still connected. + if not client.is_ready(): + await asyncio.sleep(10) # Wait a bit before rechecking. continue - # Load the output as a JSON list - games = json.loads(output) + await asyncio.sleep(1) + if time.time() - last_refresh >= refresh_seconds: + last_refresh = time.time() + # Call the external program and get the output + proc = await asyncio.create_subprocess_shell( + './devilutionx-gamelist', + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE) + + stdout, stderr = await proc.communicate() + output = stdout.decode() + if not output: + continue + + # Load the output as a JSON list + games = json.loads(output) - ct = datetime.datetime.now() - print('[' + str(ct) + '] Refreshing game list - ' + str(len(games)) + ' games') + ct = datetime.datetime.now() + print('[' + str(ct) + '] Refreshing game list - ' + str(len(games)) + ' games') - for game in games: - if any_player_name_is_invalid(game['players']) or any_player_name_contains_a_banned_word(game['players']): - continue + for game in games: + if any_player_name_is_invalid(game['players']) or any_player_name_contains_a_banned_word( + game['players']): + continue - key = game['id'].upper() - if key in game_list: - game_list[key]['players'] = game['players'] + key = game['id'].upper() + if key in game_list: + game_list[key]['players'] = game['players'] + game_list[key]['last_seen'] = time.time() + continue + + game_list[key] = game + game_list[key]['first_seen'] = time.time() game_list[key]['last_seen'] = time.time() - continue - game_list[key] = game - game_list[key]['first_seen'] = time.time() - game_list[key]['last_seen'] = time.time() + ended_games = [] + for key, game in game_list.items(): + if time.time() - game['last_seen'] < gameTTL: + continue + ended_games.append(key) + await end_game_message(key) - ended_games = [] - for key, game in game_list.items(): - if time.time() - game['last_seen'] < gameTTL: - continue - ended_games.append(key) - await end_game_message(key) + for key in ended_games: + del game_list[key] - for key in ended_games: - del game_list[key] + if len(ended_games) != 0: + await remove_game_messages(game_list.keys()) - if len(ended_games) != 0: - await remove_game_messages(game_list.keys()) + for gameId in game_list.keys(): + await update_game_message(gameId) - for gameId in game_list.keys(): - await update_game_message(gameId) + if (current_online == len(game_list)) or len(ended_games) != 0: + continue - if (current_online == len(game_list)) or len(ended_games) != 0: - continue + current_online = len(game_list) + await update_status_message() + + activity = discord.Activity(name='Games online: ' + str(current_online), + type=discord.ActivityType.watching) + await client.change_presence(activity=activity) + finally: + # Bot has disconnected during the loop, exit and set flag to false. + background_task_running = False - current_online = len(game_list) - await update_status_message() - activity = discord.Activity(name='Games online: '+str(current_online), type=discord.ActivityType.watching) - await client.change_presence(activity=activity) +@client.event +async def on_resumed(): + print("Resumed after a reconnect!") + global background_task_running + if not background_task_running: + await background_task() @client.event @@ -274,7 +297,10 @@ async def on_ready(): print(f'We have logged in as {client.user}') global global_channel global_channel = client.get_channel(DISCORD_CHANNEL_ID) - await background_task() + + loop = asyncio.get_event_loop() + loop.create_task(background_task()) # Run background_task() as a separate task when the client is ready. + with open('./discord_bot_token', 'r') as file: token = file.readline()