Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Separate Main Loop #19

Closed
wants to merge 8 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 73 additions & 47 deletions discord_bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -200,81 +202,105 @@ 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
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.
Comment on lines +301 to +302
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it necessary to call create_task() on the current event loop, or can we just call the higher-level asyncio.create_task() function? The asyncio documentation suggests that the event loop API calls are low-level functions that typically shouldn't need to be used by applications.

https://docs.python.org/3/library/asyncio-eventloop.html

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have no clue



with open('./discord_bot_token', 'r') as file:
token = file.readline()
Expand Down
Loading