fix: guests

* make guest status a flag on users
* add logout handlers
* add logout notification for other users
This commit is contained in:
Evan Carroll 2026-01-23 08:18:09 -06:00
parent 23630b19b2
commit 60a6680eaf
21 changed files with 523 additions and 601 deletions

View file

@ -472,8 +472,7 @@ async fn handle_socket(
continue;
}
let _ = tx.send(ServerMessage::PositionUpdated {
user_id: Some(user_id),
guest_session_id: None,
user_id,
x,
y,
});
@ -508,8 +507,7 @@ async fn handle_socket(
}
};
let _ = tx.send(ServerMessage::EmotionUpdated {
user_id: Some(user_id),
guest_session_id: None,
user_id,
emotion,
emotion_layer,
});
@ -573,8 +571,7 @@ async fn handle_socket(
let msg = ServerMessage::ChatMessageReceived {
message_id: Uuid::new_v4(),
user_id: Some(user_id),
guest_session_id: None,
user_id,
display_name: member.display_name.clone(),
content: content.clone(),
emotion: emotion_name.clone(),
@ -595,8 +592,7 @@ async fn handle_socket(
let sender_msg =
ServerMessage::ChatMessageReceived {
message_id: Uuid::new_v4(),
user_id: Some(user_id),
guest_session_id: None,
user_id,
display_name: member.display_name.clone(),
content,
emotion: emotion_name,
@ -627,8 +623,7 @@ async fn handle_socket(
// Broadcast: send to all users in the channel
let msg = ServerMessage::ChatMessageReceived {
message_id: Uuid::new_v4(),
user_id: Some(user_id),
guest_session_id: None,
user_id,
display_name: member.display_name.clone(),
content,
emotion: emotion_name,
@ -733,8 +728,7 @@ async fn handle_socket(
);
let _ = tx.send(ServerMessage::PropPickedUp {
prop_id: loose_prop_id,
picked_up_by_user_id: Some(user_id),
picked_up_by_guest_id: None,
picked_up_by_user_id: user_id,
});
}
Err(e) => {
@ -763,8 +757,7 @@ async fn handle_socket(
user_id
);
let _ = tx.send(ServerMessage::AvatarUpdated {
user_id: Some(user_id),
guest_session_id: None,
user_id,
avatar: render_data,
});
}
@ -1268,8 +1261,7 @@ async fn handle_socket(
// Broadcast avatar update to channel
let _ = tx.send(ServerMessage::AvatarUpdated {
user_id: Some(target_user_id),
guest_session_id: None,
user_id: target_user_id,
avatar: avatar_render_data,
});
@ -1360,8 +1352,7 @@ async fn handle_socket(
// Broadcast avatar update to channel
let _ = tx.send(ServerMessage::AvatarUpdated {
user_id: Some(target_user_id),
guest_session_id: None,
user_id: target_user_id,
avatar: original_avatar,
});
@ -1416,10 +1407,15 @@ async fn handle_socket(
}
}
Message::Close(close_frame) => {
// Check close code for scene change
// Check close code for scene change or logout
if let Some(CloseFrame { code, .. }) = close_frame {
if code == close_codes::SCENE_CHANGE {
disconnect_reason = DisconnectReason::SceneChange;
} else if code == close_codes::LOGOUT {
// Explicit logout - treat as graceful disconnect
#[cfg(debug_assertions)]
tracing::debug!("[WS] User {} logged out", user_id);
disconnect_reason = DisconnectReason::Graceful;
} else {
disconnect_reason = DisconnectReason::Graceful;
}
@ -1534,8 +1530,7 @@ async fn handle_socket(
// Broadcast departure with reason
let _ = channel_state.tx.send(ServerMessage::MemberLeft {
user_id: Some(user_id),
guest_session_id: None,
user_id,
reason: disconnect_reason,
});
}
@ -1554,18 +1549,14 @@ async fn get_members_with_avatars(
// This handles the priority chain: forced > custom > selected realm > selected server > realm default > server default
let mut result = Vec::with_capacity(members.len());
for member in members {
let avatar = if let Some(user_id) = member.user_id {
// Use the new effective avatar resolution which handles all priority levels
avatars::get_effective_avatar_render_data(pool, user_id, realm_id)
.await
.ok()
.flatten()
.map(|(render_data, _source)| render_data)
.unwrap_or_default()
} else {
// Guest users don't have avatars
AvatarRenderData::default()
};
// All members now have a user_id (guests are regular users with the 'guest' tag)
// Use the effective avatar resolution which handles all priority levels
let avatar = avatars::get_effective_avatar_render_data(pool, member.user_id, realm_id)
.await
.ok()
.flatten()
.map(|(render_data, _source)| render_data)
.unwrap_or_default();
result.push(ChannelMemberWithAvatar { member, avatar });
}