添加在线统计

This commit is contained in:
咕谷酱
2025-08-22 03:16:21 +08:00
parent c32df9af0c
commit 719c9e601a
9 changed files with 514 additions and 3 deletions

View File

@@ -91,8 +91,14 @@ class MetadataHub(Hub[MetadataClientState]):
@override
async def _clean_state(self, state: MetadataClientState) -> None:
user_id = int(state.connection_id)
# Remove from online user tracking
from app.router.v2.stats import remove_online_user
asyncio.create_task(remove_online_user(user_id))
if state.pushable:
await asyncio.gather(*self.broadcast_tasks(int(state.connection_id), None))
await asyncio.gather(*self.broadcast_tasks(user_id, None))
redis = get_redis()
if await redis.exists(f"metadata:online:{state.connection_id}"):
await redis.delete(f"metadata:online:{state.connection_id}")
@@ -117,6 +123,10 @@ class MetadataHub(Hub[MetadataClientState]):
user_id = int(client.connection_id)
self.get_or_create_state(client)
# Track online user
from app.router.v2.stats import add_online_user
asyncio.create_task(add_online_user(user_id))
async with with_db() as session:
async with session.begin():
friends = (

View File

@@ -163,6 +163,11 @@ class MultiplayerHub(Hub[MultiplayerClientState]):
@override
async def _clean_state(self, state: MultiplayerClientState):
user_id = int(state.connection_id)
# Remove from online user tracking
from app.router.v2.stats import remove_online_user
asyncio.create_task(remove_online_user(user_id))
if state.room_id != 0 and state.room_id in self.rooms:
server_room = self.rooms[state.room_id]
room = server_room.room
@@ -172,6 +177,14 @@ class MultiplayerHub(Hub[MultiplayerClientState]):
self.get_client_by_id(str(user_id)), server_room, user
)
async def on_client_connect(self, client: Client) -> None:
"""Track online users when connecting to multiplayer hub"""
logger.info(f"[MultiplayerHub] Client {client.user_id} connected")
# Track online user
from app.router.v2.stats import add_online_user
asyncio.create_task(add_online_user(client.user_id))
def _ensure_in_room(self, client: Client) -> ServerMultiplayerRoom:
store = self.get_or_create_state(client)
if store.room_id == 0:

View File

@@ -169,12 +169,17 @@ class SpectatorHub(Hub[StoreClientState]):
Enhanced cleanup based on official osu-server-spectator implementation.
Properly notifies watched users when spectator disconnects.
"""
user_id = int(state.connection_id)
# Remove from online and playing tracking
from app.router.v2.stats import remove_online_user
asyncio.create_task(remove_online_user(user_id))
if state.state:
await self._end_session(int(state.connection_id), state.state, state)
await self._end_session(user_id, state.state, state)
# Critical fix: Notify all watched users that this spectator has disconnected
# This matches the official CleanUpState implementation
user_id = int(state.connection_id)
for watched_user_id in state.watched_user:
if (target_client := self.get_client_by_id(str(watched_user_id))) is not None:
await self.call_noblock(
@@ -191,6 +196,10 @@ class SpectatorHub(Hub[StoreClientState]):
"""
logger.info(f"[SpectatorHub] Client {client.user_id} connected")
# Track online user
from app.router.v2.stats import add_online_user
asyncio.create_task(add_online_user(client.user_id))
# Send all current player states to the new client
# This matches the official OnConnectedAsync behavior
active_states = []
@@ -295,6 +304,10 @@ class SpectatorHub(Hub[StoreClientState]):
)
logger.info(f"[SpectatorHub] {client.user_id} began playing {state.beatmap_id}")
# Track playing user
from app.router.v2.stats import add_playing_user
asyncio.create_task(add_playing_user(user_id))
# # 预缓存beatmap文件以加速后续PP计算
# await self._preload_beatmap_for_pp_calculation(state.beatmap_id)
@@ -343,6 +356,11 @@ class SpectatorHub(Hub[StoreClientState]):
) and any(k.is_hit() and v > 0 for k, v in score.score_info.statistics.items()):
await self._process_score(store, client)
await self._end_session(user_id, state, store)
# Remove from playing user tracking
from app.router.v2.stats import remove_playing_user
asyncio.create_task(remove_playing_user(user_id))
store.state = None
store.beatmap_status = None
store.checksum = None