fix(multiplayer): handle user leave logic and improve room state updates
This commit is contained in:
@@ -892,34 +892,21 @@ class MultiplayerHub(Hub[MultiplayerClientState]):
|
|||||||
|
|
||||||
async def make_user_leave(
|
async def make_user_leave(
|
||||||
self,
|
self,
|
||||||
client: Client,
|
client: Client | None,
|
||||||
room: ServerMultiplayerRoom,
|
room: ServerMultiplayerRoom,
|
||||||
user: MultiplayerRoomUser,
|
user: MultiplayerRoomUser,
|
||||||
kicked: bool = False,
|
kicked: bool = False,
|
||||||
):
|
):
|
||||||
self.remove_from_group(client, self.group_id(room.room.room_id))
|
if client:
|
||||||
|
self.remove_from_group(client, self.group_id(room.room.room_id))
|
||||||
room.room.users.remove(user)
|
room.room.users.remove(user)
|
||||||
|
|
||||||
if len(room.room.users) == 0:
|
target_store = self.state.get(user.user_id)
|
||||||
await self.end_room(room)
|
if target_store:
|
||||||
await self.update_room_state(room)
|
target_store.room_id = 0
|
||||||
if (
|
|
||||||
len(room.room.users) != 0
|
|
||||||
and room.room.host
|
|
||||||
and room.room.host.user_id == user.user_id
|
|
||||||
):
|
|
||||||
next_host = room.room.users[0]
|
|
||||||
await self.set_host(room, next_host)
|
|
||||||
|
|
||||||
if kicked:
|
redis = get_redis()
|
||||||
await self.call_noblock(client, "UserKicked", user)
|
await redis.publish("chat:room:left", f"{room.room.channel_id}:{user.user_id}")
|
||||||
await self.broadcast_group_call(
|
|
||||||
self.group_id(room.room.room_id), "UserKicked", user
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
await self.broadcast_group_call(
|
|
||||||
self.group_id(room.room.room_id), "UserLeft", user
|
|
||||||
)
|
|
||||||
|
|
||||||
async with AsyncSession(engine) as session:
|
async with AsyncSession(engine) as session:
|
||||||
async with session.begin():
|
async with session.begin():
|
||||||
@@ -939,12 +926,28 @@ class MultiplayerHub(Hub[MultiplayerClientState]):
|
|||||||
raise InvokeException("Room does not exist in database")
|
raise InvokeException("Room does not exist in database")
|
||||||
db_room.participant_count -= 1
|
db_room.participant_count -= 1
|
||||||
|
|
||||||
target_store = self.state.get(user.user_id)
|
if len(room.room.users) == 0:
|
||||||
if target_store:
|
await self.end_room(room)
|
||||||
target_store.room_id = 0
|
return
|
||||||
|
await self.update_room_state(room)
|
||||||
|
if (
|
||||||
|
len(room.room.users) != 0
|
||||||
|
and room.room.host
|
||||||
|
and room.room.host.user_id == user.user_id
|
||||||
|
):
|
||||||
|
next_host = room.room.users[0]
|
||||||
|
await self.set_host(room, next_host)
|
||||||
|
|
||||||
redis = get_redis()
|
if kicked:
|
||||||
await redis.publish("chat:room:left", f"{room.room.channel_id}:{user.user_id}")
|
if client:
|
||||||
|
await self.call_noblock(client, "UserKicked", user)
|
||||||
|
await self.broadcast_group_call(
|
||||||
|
self.group_id(room.room.room_id), "UserKicked", user
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
await self.broadcast_group_call(
|
||||||
|
self.group_id(room.room.room_id), "UserLeft", user
|
||||||
|
)
|
||||||
|
|
||||||
async def end_room(self, room: ServerMultiplayerRoom):
|
async def end_room(self, room: ServerMultiplayerRoom):
|
||||||
assert room.room.host
|
assert room.room.host
|
||||||
@@ -1005,8 +1008,6 @@ class MultiplayerHub(Hub[MultiplayerClientState]):
|
|||||||
user.user_id,
|
user.user_id,
|
||||||
)
|
)
|
||||||
target_client = self.get_client_by_id(str(user.user_id))
|
target_client = self.get_client_by_id(str(user.user_id))
|
||||||
if target_client is None:
|
|
||||||
return
|
|
||||||
await self.make_user_leave(target_client, server_room, user, kicked=True)
|
await self.make_user_leave(target_client, server_room, user, kicked=True)
|
||||||
logger.info(
|
logger.info(
|
||||||
f"[MultiplayerHub] {user.user_id} was kicked from room {room.room_id}"
|
f"[MultiplayerHub] {user.user_id} was kicked from room {room.room_id}"
|
||||||
|
|||||||
Reference in New Issue
Block a user