Initial commit: split VNOX monorepo into VNOX-Server
Unified server binary (vnox-serverd) combining: - Gateway (TCP, auth, channels, sessions, SQLite) - Voice-node (UDP relay, Opus, jitter buffer) Standalone gateway (vnox-gateway) and voice-node (vnox-voice-node) preserved as sub-crates.
This commit is contained in:
commit
e751e0bf5b
94 changed files with 9771 additions and 0 deletions
113
gateway/src/handler/direct_message/start.rs
Normal file
113
gateway/src/handler/direct_message/start.rs
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
use anyhow::Result;
|
||||
use tokio::net::TcpStream;
|
||||
|
||||
use crate::{
|
||||
domain::session,
|
||||
net::{io, state::State},
|
||||
proto::{self, DmStartPayload, DmStartResponsePayload, PacketId, SessionCrypto, to_payload},
|
||||
};
|
||||
|
||||
pub async fn handle_dm_start(
|
||||
stream: &mut TcpStream,
|
||||
seq: &mut u32,
|
||||
session_id: &str,
|
||||
payload: &[u8],
|
||||
crypto: &SessionCrypto,
|
||||
state: &State,
|
||||
) -> Result<()> {
|
||||
let req: DmStartPayload = serde_json::from_slice(payload)?;
|
||||
|
||||
let sess = session::get(&state.sessions, session_id)
|
||||
.await
|
||||
.ok_or_else(|| anyhow::anyhow!("session not found"))?;
|
||||
let my_id = sess.user_id.clone();
|
||||
drop(sess);
|
||||
|
||||
if state
|
||||
.storage
|
||||
.is_blocked(&req.target_user_id, &my_id)
|
||||
.await?
|
||||
{
|
||||
io::send_encrypted(
|
||||
stream,
|
||||
PacketId::Error,
|
||||
seq,
|
||||
&to_payload(&proto::ErrorPayload {
|
||||
code: proto::ErrorCode::Blocked as u32,
|
||||
message: "blocked".into(),
|
||||
}),
|
||||
crypto,
|
||||
)
|
||||
.await?;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
if req.target_user_id == my_id {
|
||||
io::send_encrypted(
|
||||
stream,
|
||||
PacketId::Error,
|
||||
seq,
|
||||
&to_payload(&proto::ErrorPayload {
|
||||
code: proto::ErrorCode::InvalidPacket as u32,
|
||||
message: "cannot DM yourself".into(),
|
||||
}),
|
||||
crypto,
|
||||
)
|
||||
.await?;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let (dm_id, unread_count) = state
|
||||
.storage
|
||||
.find_or_create_dm(&my_id, &req.target_user_id)
|
||||
.await?;
|
||||
let other_id = state
|
||||
.storage
|
||||
.get_dm_user_id(&dm_id, &my_id)
|
||||
.await?
|
||||
.ok_or_else(|| anyhow::anyhow!("user not in DM"))?;
|
||||
let nickname = state
|
||||
.storage
|
||||
.get_dm_nickname(&other_id)
|
||||
.await?
|
||||
.unwrap_or_else(|| other_id[..8].to_string());
|
||||
let messages = state
|
||||
.storage
|
||||
.get_dm_messages(&dm_id, 50, None, None)
|
||||
.await?;
|
||||
|
||||
let resp = DmStartResponsePayload {
|
||||
dm_id,
|
||||
other_user_id: other_id,
|
||||
other_nickname: nickname,
|
||||
messages,
|
||||
unread_count: unread_count as u32,
|
||||
};
|
||||
io::send_encrypted(stream, PacketId::DmStart, seq, &to_payload(&resp), crypto).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn handle_dm_read_ack(
|
||||
stream: &mut TcpStream,
|
||||
seq: &mut u32,
|
||||
session_id: &str,
|
||||
payload: &[u8],
|
||||
crypto: &SessionCrypto,
|
||||
state: &State,
|
||||
) -> Result<()> {
|
||||
let req: serde_json::Value = serde_json::from_slice(payload)?;
|
||||
let dm_id = req["dm_id"]
|
||||
.as_str()
|
||||
.ok_or_else(|| anyhow::anyhow!("missing dm_id"))?;
|
||||
|
||||
let sess = session::get(&state.sessions, session_id)
|
||||
.await
|
||||
.ok_or_else(|| anyhow::anyhow!("session not found"))?;
|
||||
let my_id = sess.user_id.clone();
|
||||
drop(sess);
|
||||
|
||||
state.storage.reset_dm_unread(dm_id, &my_id).await?;
|
||||
|
||||
io::send_encrypted(stream, PacketId::DmReadAck, seq, b"{}", crypto).await?;
|
||||
Ok(())
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue