-
Notifications
You must be signed in to change notification settings - Fork 140
/
Copy pathbg_loops.py
89 lines (68 loc) · 2.79 KB
/
bg_loops.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
from __future__ import annotations
import asyncio
import time
import app.packets
import app.settings
import app.state
from app.constants.privileges import Privileges
from app.logging import Ansi
from app.logging import log
OSU_CLIENT_MIN_PING_INTERVAL = 300000 // 1000 # defined by osu!
async def initialize_housekeeping_tasks() -> None:
"""Create tasks for each housekeeping tasks."""
log("Initializing housekeeping tasks.", Ansi.LCYAN)
loop = asyncio.get_running_loop()
app.state.sessions.housekeeping_tasks.update(
{
loop.create_task(task)
for task in (
_remove_expired_donation_privileges(interval=30 * 60),
_update_bot_status(interval=5 * 60),
_disconnect_ghosts(interval=OSU_CLIENT_MIN_PING_INTERVAL // 3),
)
},
)
async def _remove_expired_donation_privileges(interval: int) -> None:
"""Remove donation privileges from users with expired sessions."""
while True:
if app.settings.DEBUG:
log("Removing expired donation privileges.", Ansi.LMAGENTA)
expired_donors = await app.state.services.database.fetch_all(
"SELECT id FROM users "
"WHERE donor_end <= UNIX_TIMESTAMP() "
"AND priv & :donor_priv",
{"donor_priv": Privileges.DONATOR.value},
)
for expired_donor in expired_donors:
player = await app.state.sessions.players.from_cache_or_sql(
id=expired_donor["id"],
)
assert player is not None
# TODO: perhaps make a `revoke_donor` method?
await player.remove_privs(Privileges.DONATOR)
player.donor_end = 0
await app.state.services.database.execute(
"UPDATE users SET donor_end = 0 WHERE id = :id",
{"id": player.id},
)
if player.is_online:
player.enqueue(
app.packets.notification("Your supporter status has expired."),
)
log(f"{player}'s supporter status has expired.", Ansi.LMAGENTA)
await asyncio.sleep(interval)
async def _disconnect_ghosts(interval: int) -> None:
"""Actively disconnect users above the
disconnection time threshold on the osu! server."""
while True:
await asyncio.sleep(interval)
current_time = time.time()
for player in app.state.sessions.players:
if current_time - player.last_recv_time > OSU_CLIENT_MIN_PING_INTERVAL:
log(f"Auto-dced {player}.", Ansi.LMAGENTA)
player.logout()
async def _update_bot_status(interval: int) -> None:
"""Re roll the bot status, every `interval`."""
while True:
await asyncio.sleep(interval)
app.packets.bot_stats.cache_clear()