feat: add teleport
This commit is contained in:
parent
226c2e02b5
commit
32e5e42462
11 changed files with 603 additions and 16 deletions
|
|
@ -391,11 +391,15 @@ async fn handle_socket(
|
|||
// Clone ws_state for use in recv_task
|
||||
let ws_state_for_recv = ws_state.clone();
|
||||
|
||||
// Clone pool for use in recv_task (for teleport queries)
|
||||
let pool_for_recv = pool.clone();
|
||||
|
||||
// Create recv timeout from config
|
||||
let recv_timeout = Duration::from_secs(ws_config.recv_timeout_secs);
|
||||
|
||||
// Spawn task to handle incoming messages from client
|
||||
let recv_task = tokio::spawn(async move {
|
||||
let pool = pool_for_recv;
|
||||
let ws_state = ws_state_for_recv;
|
||||
let mut disconnect_reason = DisconnectReason::Graceful;
|
||||
|
||||
|
|
@ -724,6 +728,90 @@ async fn handle_socket(
|
|||
}
|
||||
}
|
||||
}
|
||||
ClientMessage::Teleport { scene_id } => {
|
||||
// Validate teleport permission and scene
|
||||
// 1. Check realm allows user teleport
|
||||
let realm = match realms::get_realm_by_id(
|
||||
&pool,
|
||||
realm_id,
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(Some(r)) => r,
|
||||
Ok(None) => {
|
||||
let _ = direct_tx.send(ServerMessage::Error {
|
||||
code: "REALM_NOT_FOUND".to_string(),
|
||||
message: "Realm not found".to_string(),
|
||||
}).await;
|
||||
continue;
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::error!("[WS] Teleport realm lookup failed: {:?}", e);
|
||||
let _ = direct_tx.send(ServerMessage::Error {
|
||||
code: "TELEPORT_FAILED".to_string(),
|
||||
message: "Failed to verify teleport permission".to_string(),
|
||||
}).await;
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
if !realm.allow_user_teleport {
|
||||
let _ = direct_tx.send(ServerMessage::Error {
|
||||
code: "TELEPORT_DISABLED".to_string(),
|
||||
message: "Teleporting is not enabled for this realm".to_string(),
|
||||
}).await;
|
||||
continue;
|
||||
}
|
||||
|
||||
// 2. Validate scene exists, belongs to realm, and is not hidden
|
||||
let scene = match scenes::get_scene_by_id(&pool, scene_id).await {
|
||||
Ok(Some(s)) => s,
|
||||
Ok(None) => {
|
||||
let _ = direct_tx.send(ServerMessage::Error {
|
||||
code: "SCENE_NOT_FOUND".to_string(),
|
||||
message: "Scene not found".to_string(),
|
||||
}).await;
|
||||
continue;
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::error!("[WS] Teleport scene lookup failed: {:?}", e);
|
||||
let _ = direct_tx.send(ServerMessage::Error {
|
||||
code: "TELEPORT_FAILED".to_string(),
|
||||
message: "Failed to verify scene".to_string(),
|
||||
}).await;
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
if scene.realm_id != realm_id {
|
||||
let _ = direct_tx.send(ServerMessage::Error {
|
||||
code: "SCENE_NOT_IN_REALM".to_string(),
|
||||
message: "Scene does not belong to this realm".to_string(),
|
||||
}).await;
|
||||
continue;
|
||||
}
|
||||
|
||||
if scene.is_hidden {
|
||||
let _ = direct_tx.send(ServerMessage::Error {
|
||||
code: "SCENE_HIDDEN".to_string(),
|
||||
message: "Cannot teleport to a hidden scene".to_string(),
|
||||
}).await;
|
||||
continue;
|
||||
}
|
||||
|
||||
// 3. Send approval - client will disconnect and reconnect
|
||||
#[cfg(debug_assertions)]
|
||||
tracing::debug!(
|
||||
"[WS] User {} teleporting to scene {} ({})",
|
||||
user_id,
|
||||
scene.name,
|
||||
scene.slug
|
||||
);
|
||||
let _ = direct_tx.send(ServerMessage::TeleportApproved {
|
||||
scene_id: scene.id,
|
||||
scene_slug: scene.slug,
|
||||
}).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
Message::Close(close_frame) => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue