mirror of https://github.com/CympleTech/ESSE.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
484 lines
16 KiB
484 lines
16 KiB
use chat_types::{MessageType, CHAT_ID}; |
|
use esse_primitives::id_from_str; |
|
use std::sync::Arc; |
|
use tdn::types::{ |
|
message::SendType, |
|
primitives::{HandleResult, PeerId}, |
|
rpc::{json, rpc_response, RpcError, RpcHandler, RpcParam}, |
|
}; |
|
|
|
//use crate::event::InnerEvent; |
|
use crate::global::Global; |
|
use crate::rpc::session_create; |
|
use crate::storage::{chat_db, delete_avatar, session_db}; |
|
|
|
use super::layer::{update_session, LayerEvent}; |
|
use super::{raw_to_network_message, Friend, Message, Request}; |
|
|
|
#[inline] |
|
pub(crate) fn friend_info(friend: &Friend) -> RpcParam { |
|
rpc_response(0, "chat-friend-info", json!(friend.to_rpc())) |
|
} |
|
|
|
#[inline] |
|
pub(crate) fn friend_update(fid: i64, remark: &str) -> RpcParam { |
|
rpc_response(0, "chat-friend-update", json!([fid, remark])) |
|
} |
|
|
|
#[inline] |
|
pub(crate) fn friend_close(fid: i64) -> RpcParam { |
|
rpc_response(0, "chat-friend-close", json!([fid])) |
|
} |
|
|
|
#[inline] |
|
pub(crate) fn friend_delete(fid: i64) -> RpcParam { |
|
rpc_response(0, "chat-friend-delete", json!([fid])) |
|
} |
|
|
|
#[inline] |
|
pub(crate) fn request_create(req: &Request) -> RpcParam { |
|
rpc_response(0, "chat-request-create", json!(req.to_rpc())) |
|
} |
|
|
|
#[inline] |
|
pub(crate) fn request_delivery(id: i64, is_d: bool) -> RpcParam { |
|
rpc_response(0, "chat-request-delivery", json!([id, is_d])) |
|
} |
|
|
|
#[inline] |
|
pub(crate) fn request_agree(id: i64, friend: &Friend) -> RpcParam { |
|
rpc_response(0, "chat-request-agree", json!([id, friend.to_rpc()])) |
|
} |
|
|
|
#[inline] |
|
pub(crate) fn request_reject(id: i64) -> RpcParam { |
|
rpc_response(0, "chat-request-reject", json!([id])) |
|
} |
|
|
|
#[inline] |
|
pub(crate) fn request_delete(id: i64) -> RpcParam { |
|
rpc_response(0, "chat-request-delete", json!([id])) |
|
} |
|
|
|
#[inline] |
|
pub(crate) fn message_create(msg: &Message) -> RpcParam { |
|
rpc_response(0, "chat-message-create", json!(msg.to_rpc())) |
|
} |
|
|
|
#[inline] |
|
pub(crate) fn message_delivery(id: i64, is_d: bool) -> RpcParam { |
|
rpc_response(0, "chat-message-delivery", json!([id, is_d])) |
|
} |
|
|
|
#[inline] |
|
pub(crate) fn message_delete(id: i64) -> RpcParam { |
|
rpc_response(0, "chat-message-delete", json!([id])) |
|
} |
|
|
|
#[inline] |
|
fn request_list(requests: Vec<Request>) -> RpcParam { |
|
let mut results = vec![]; |
|
for request in requests { |
|
results.push(request.to_rpc()); |
|
} |
|
json!(results) |
|
} |
|
|
|
#[inline] |
|
fn message_list(messages: Vec<Message>) -> RpcParam { |
|
let mut results = vec![]; |
|
for msg in messages { |
|
results.push(msg.to_rpc()); |
|
} |
|
json!(results) |
|
} |
|
|
|
#[inline] |
|
fn detail_list(friend: Friend, messages: Vec<Message>) -> RpcParam { |
|
let mut message_results = vec![]; |
|
for msg in messages { |
|
message_results.push(msg.to_rpc()); |
|
} |
|
json!([friend.to_rpc(), message_results]) |
|
} |
|
|
|
pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<Global>) { |
|
handler.add_method("chat-echo", |params, _| async move { |
|
Ok(HandleResult::rpc(json!(params))) |
|
}); |
|
|
|
handler.add_method( |
|
"chat-friend-list", |
|
|params: Vec<RpcParam>, state: Arc<Global>| async move { |
|
let need_online = params[0].as_bool().ok_or(RpcError::ParseError)?; |
|
|
|
let pid = state.pid().await; |
|
let db_key = state.group.read().await.db_key(&pid)?; |
|
let db = chat_db(&state.base, &pid, &db_key)?; |
|
|
|
let friends = Friend::list(&db)?; |
|
|
|
let mut results = vec![]; |
|
let layer_lock = state.layer.read().await; |
|
if need_online { |
|
for friend in friends { |
|
let online = layer_lock.chat_is_online(&friend.pid); |
|
results.push(friend.to_rpc_online(online)); |
|
} |
|
} else { |
|
for friend in friends { |
|
results.push(friend.to_rpc()); |
|
} |
|
} |
|
drop(layer_lock); |
|
|
|
Ok(HandleResult::rpc(json!(results))) |
|
}, |
|
); |
|
|
|
handler.add_method( |
|
"chat-friend-update", |
|
|params: Vec<RpcParam>, state: Arc<Global>| async move { |
|
let id = params[0].as_i64().ok_or(RpcError::ParseError)?; |
|
let remark = params[1].as_str().ok_or(RpcError::ParseError)?; |
|
|
|
let mut results = HandleResult::new(); |
|
let pid = state.pid().await; |
|
let db_key = state.group.read().await.db_key(&pid)?; |
|
let db = chat_db(&state.base, &pid, &db_key)?; |
|
|
|
let mut f = Friend::get(&db, &id)?; |
|
f.remark = remark.to_owned(); |
|
f.me_update(&db)?; |
|
drop(db); |
|
|
|
// state.group.write().await.broadcast( |
|
// &gid, |
|
// InnerEvent::SessionFriendUpdate(f.gid, f.remark), |
|
// FRIEND_TABLE_PATH, |
|
// f.id, |
|
// &mut results, |
|
// )?; |
|
|
|
Ok(results) |
|
}, |
|
); |
|
|
|
handler.add_method( |
|
"chat-friend-close", |
|
|params: Vec<RpcParam>, state: Arc<Global>| async move { |
|
let id = params[0].as_i64().ok_or(RpcError::ParseError)?; |
|
|
|
let mut results = HandleResult::new(); |
|
let pid = state.pid().await; |
|
let db_key = state.group.read().await.db_key(&pid)?; |
|
let db = chat_db(&state.base, &pid, &db_key)?; |
|
|
|
let friend = Friend::get(&db, &id)?; |
|
friend.close(&db)?; |
|
drop(db); |
|
|
|
let online = state.layer.write().await.chat_rm_online(&friend.pid); |
|
if let Some(faddr) = online { |
|
let data = bincode::serialize(&LayerEvent::Close)?; |
|
results |
|
.layers |
|
.push((CHAT_ID, SendType::Event(0, friend.pid, data))); |
|
|
|
results |
|
.layers |
|
.push((CHAT_ID, SendType::Disconnect(friend.pid))); |
|
} |
|
|
|
// state.group.write().await.broadcast( |
|
// &gid, |
|
// InnerEvent::SessionFriendClose(friend.gid), |
|
// FRIEND_TABLE_PATH, |
|
// friend.id, |
|
// &mut results, |
|
// )?; |
|
|
|
Ok(results) |
|
}, |
|
); |
|
|
|
handler.add_method( |
|
"chat-friend-delete", |
|
|params: Vec<RpcParam>, state: Arc<Global>| async move { |
|
let id = params[0].as_i64().ok_or(RpcError::ParseError)?; |
|
|
|
let mut results = HandleResult::new(); |
|
let pid = state.pid().await; |
|
let db_key = state.group.read().await.db_key(&pid)?; |
|
let db = chat_db(&state.base, &pid, &db_key)?; |
|
|
|
let friend = Friend::get(&db, &id)?; |
|
Friend::delete(&db, &id)?; |
|
drop(db); |
|
|
|
let online = state.layer.write().await.chat_rm_online(&friend.pid); |
|
delete_avatar(&state.base, &pid, &friend.pid).await?; |
|
|
|
if let Some(faddr) = online { |
|
let data = bincode::serialize(&LayerEvent::Close)?; |
|
results |
|
.layers |
|
.push((CHAT_ID, SendType::Event(0, friend.pid, data))); |
|
|
|
results |
|
.layers |
|
.push((CHAT_ID, SendType::Disconnect(friend.pid))); |
|
} |
|
|
|
// state.group.write().await.broadcast( |
|
// &gid, |
|
// InnerEvent::SessionFriendDelete(friend.gid), |
|
// FRIEND_TABLE_PATH, |
|
// friend.id, |
|
// &mut results, |
|
// )?; |
|
|
|
Ok(results) |
|
}, |
|
); |
|
|
|
handler.add_method( |
|
"chat-request-list", |
|
|_params: Vec<RpcParam>, state: Arc<Global>| async move { |
|
let pid = state.pid().await; |
|
let db_key = state.group.read().await.db_key(&pid)?; |
|
let db = chat_db(&state.base, &pid, &db_key)?; |
|
let requests = Request::list(&db)?; |
|
drop(db); |
|
Ok(HandleResult::rpc(request_list(requests))) |
|
}, |
|
); |
|
|
|
handler.add_method( |
|
"chat-request-create", |
|
|params: Vec<RpcParam>, state: Arc<Global>| async move { |
|
let remote_pid = id_from_str(params[0].as_str().ok_or(RpcError::ParseError)?)?; |
|
let remote_name = params[1].as_str().ok_or(RpcError::ParseError)?.to_string(); |
|
let remark = params[2].as_str().ok_or(RpcError::ParseError)?.to_string(); |
|
|
|
let pid = state.pid().await; |
|
let db_key = state.group.read().await.db_key(&pid)?; |
|
let db = chat_db(&state.base, &pid, &db_key)?; |
|
|
|
if Friend::is_friend(&db, &remote_pid)? { |
|
debug!("Had friend."); |
|
return Ok(HandleResult::new()); |
|
} |
|
|
|
if let Ok(req) = Request::get_id(&db, &remote_pid) { |
|
debug!("Had request."); |
|
Request::delete(&db, &req.id)?; |
|
} |
|
|
|
let mut request = |
|
Request::new(remote_pid, remote_name.clone(), remark.clone(), true, false); |
|
request.insert(&db)?; |
|
drop(db); |
|
|
|
let mut results = HandleResult::rpc(json!(request.to_rpc())); |
|
|
|
let name = state.group.read().await.account(&pid)?.name.clone(); |
|
let req = LayerEvent::Request(name, request.remark); |
|
let data = bincode::serialize(&req).unwrap_or(vec![]); |
|
let msg = SendType::Event(0, request.pid, data); |
|
results.layers.push((CHAT_ID, msg)); |
|
|
|
Ok(results) |
|
}, |
|
); |
|
|
|
handler.add_method( |
|
"chat-request-agree", |
|
|params: Vec<RpcParam>, state: Arc<Global>| async move { |
|
let id = params[0].as_i64().ok_or(RpcError::ParseError)?; |
|
|
|
let mut results = HandleResult::new(); |
|
let pid = state.pid().await; |
|
let db_key = state.group.read().await.db_key(&pid)?; |
|
let db = chat_db(&state.base, &pid, &db_key)?; |
|
|
|
let mut request = Request::get(&db, &id)?; |
|
|
|
// group_lock.broadcast( |
|
// &gid, |
|
// InnerEvent::SessionRequestHandle(request.gid, true, vec![]), |
|
// REQUEST_TABLE_PATH, |
|
// request.id, |
|
// &mut results, |
|
// )?; |
|
request.is_ok = true; |
|
request.is_over = true; |
|
request.update(&db)?; |
|
|
|
let friend = Friend::from_remote( |
|
&db, |
|
request.pid, |
|
request.name, |
|
"".to_owned(), |
|
PeerId::default(), |
|
[0u8; 32], |
|
)?; |
|
results.rpcs.push(json!([id, friend.to_rpc()])); |
|
|
|
// ADD NEW SESSION. |
|
let s_db = session_db(&state.base, &pid, &db_key)?; |
|
let mut session = friend.to_session(); |
|
session.insert(&s_db)?; |
|
results.rpcs.push(session_create(&session)); |
|
|
|
let data = bincode::serialize(&LayerEvent::Agree).unwrap_or(vec![]); |
|
let msg = SendType::Event(0, friend.pid, data); |
|
results.layers.push((CHAT_ID, msg)); |
|
|
|
Ok(results) |
|
}, |
|
); |
|
|
|
handler.add_method( |
|
"chat-request-reject", |
|
|params: Vec<RpcParam>, state: Arc<Global>| async move { |
|
let id = params[0].as_i64().ok_or(RpcError::ParseError)?; |
|
|
|
let pid = state.pid().await; |
|
let db_key = state.group.read().await.db_key(&pid)?; |
|
let db = chat_db(&state.base, &pid, &db_key)?; |
|
|
|
let mut req = Request::get(&db, &id)?; |
|
req.is_ok = false; |
|
req.is_over = true; |
|
req.update(&db)?; |
|
drop(db); |
|
|
|
let data = bincode::serialize(&LayerEvent::Reject).unwrap_or(vec![]); |
|
let msg = SendType::Event(0, req.pid, data); |
|
let mut results = HandleResult::layer(CHAT_ID, msg); |
|
|
|
// state.group.write().await.broadcast( |
|
// &gid, |
|
// InnerEvent::SessionRequestHandle(req.gid, false, vec![]), |
|
// REQUEST_TABLE_PATH, |
|
// req.id, |
|
// &mut results, |
|
// )?; |
|
Ok(results) |
|
}, |
|
); |
|
|
|
handler.add_method( |
|
"chat-request-delete", |
|
|params: Vec<RpcParam>, state: Arc<Global>| async move { |
|
let id = params[0].as_i64().ok_or(RpcError::ParseError)?; |
|
|
|
let pid = state.pid().await; |
|
let db_key = state.group.read().await.db_key(&pid)?; |
|
let db = chat_db(&state.base, &pid, &db_key)?; |
|
|
|
let req = Request::get(&db, &id)?; |
|
Request::delete(&db, &id)?; |
|
|
|
// delete avatar. check had friend. |
|
if Friend::get_id(&db, &req.pid).is_err() { |
|
delete_avatar(&state.base, &pid, &req.pid).await?; |
|
} |
|
drop(db); |
|
|
|
let results = HandleResult::new(); |
|
// state.group.write().await.broadcast( |
|
// &gid, |
|
// InnerEvent::SessionRequestDelete(req.gid), |
|
// REQUEST_TABLE_PATH, |
|
// req.id, |
|
// &mut results, |
|
// )?; |
|
Ok(results) |
|
}, |
|
); |
|
|
|
handler.add_method( |
|
"chat-detail", |
|
|params: Vec<RpcParam>, state: Arc<Global>| async move { |
|
let id = params[0].as_i64().ok_or(RpcError::ParseError)?; |
|
|
|
let pid = state.pid().await; |
|
let db_key = state.group.read().await.db_key(&pid)?; |
|
let db = chat_db(&state.base, &pid, &db_key)?; |
|
|
|
let friend = Friend::get(&db, &id)?; |
|
let messages = Message::get_by_fid(&db, &id)?; |
|
drop(db); |
|
|
|
Ok(HandleResult::rpc(detail_list(friend, messages))) |
|
}, |
|
); |
|
|
|
handler.add_method( |
|
"chat-message-list", |
|
|params: Vec<RpcParam>, state: Arc<Global>| async move { |
|
let fid = params[0].as_i64().ok_or(RpcError::ParseError)?; |
|
|
|
let pid = state.pid().await; |
|
let db_key = state.group.read().await.db_key(&pid)?; |
|
let db = chat_db(&state.base, &pid, &db_key)?; |
|
|
|
let messages = Message::get_by_fid(&db, &fid)?; |
|
drop(db); |
|
Ok(HandleResult::rpc(message_list(messages))) |
|
}, |
|
); |
|
|
|
handler.add_method( |
|
"chat-message-create", |
|
|params: Vec<RpcParam>, state: Arc<Global>| async move { |
|
let fid = params[0].as_i64().ok_or(RpcError::ParseError)?; |
|
let fpid = id_from_str(params[1].as_str().ok_or(RpcError::ParseError)?)?; |
|
let m_type = MessageType::from_int(params[2].as_i64().ok_or(RpcError::ParseError)?); |
|
let content = params[3].as_str().ok_or(RpcError::ParseError)?; |
|
|
|
let pid = state.pid().await; |
|
let db_key = state.group.read().await.db_key(&pid)?; |
|
let db = chat_db(&state.base, &pid, &db_key)?; |
|
|
|
let (nm, raw) = |
|
raw_to_network_message(&pid, &state.base, &db_key, &m_type, content).await?; |
|
let mut msg = Message::new(&pid, fid, true, m_type, raw, false); |
|
msg.insert(&db)?; |
|
|
|
let mut results = HandleResult::rpc(json!(msg.to_rpc())); |
|
|
|
let tid = state.layer.write().await.delivery(msg.id); |
|
let event = LayerEvent::Message(msg.hash, nm); |
|
let data = bincode::serialize(&event).unwrap_or(vec![]); |
|
results |
|
.layers |
|
.push((CHAT_ID, SendType::Event(tid, fpid, data))); |
|
|
|
// UPDATE SESSION. |
|
let s_db = session_db(&state.base, &pid, &db_key)?; |
|
update_session(&s_db, &fid, &msg, &mut results); |
|
|
|
Ok(results) |
|
}, |
|
); |
|
|
|
handler.add_method( |
|
"chat-message-delete", |
|
|params: Vec<RpcParam>, state: Arc<Global>| async move { |
|
let id = params[0].as_i64().ok_or(RpcError::ParseError)?; |
|
|
|
let pid = state.pid().await; |
|
let db_key = state.group.read().await.db_key(&pid)?; |
|
let db = chat_db(&state.base, &pid, &db_key)?; |
|
|
|
let msg = Message::get(&db, &id)?; |
|
Message::delete(&db, &id)?; |
|
drop(db); |
|
|
|
Ok(HandleResult::new()) |
|
}, |
|
); |
|
}
|
|
|