use std::path::PathBuf; use colored::Colorize; use rust_socketio::asynchronous::Client; use rust_socketio::{Event, Payload}; use tracing::{event, info, span, warn, Level}; use crate::data_struct::ica::all_rooms::Room; use crate::data_struct::ica::messages::{Message, MessageTrait, NewMessage}; use crate::data_struct::ica::online_data::OnlineData; use crate::ica::client::send_message; use crate::{help_msg, py, version_str, MainStatus, VERSION}; /// 获取在线数据 pub async fn get_online_data(payload: Payload, _client: Client) { if let Payload::Text(values) = payload { if let Some(value) = values.first() { let online_data = OnlineData::new_from_json(value); event!(Level::DEBUG, "update_online_data {}", format!("{:?}", online_data).cyan()); MainStatus::global_ica_status_mut().update_online_status(online_data); } } } /// 接收消息 pub async fn add_message(payload: Payload, client: Client) { if let Payload::Text(values) = payload { if let Some(value) = values.first() { let message: NewMessage = serde_json::from_value(value.clone()).unwrap(); // 检测是否在过滤列表内 if MainStatus::global_config().ica().filter_list.contains(&message.msg.sender_id) { return; } event!(Level::INFO, "new_msg {}", message.to_string().cyan()); // 就在这里处理掉最基本的消息 // 之后的处理交给插件 if !message.is_from_self() && !message.is_reply() { if message.content() == "/bot-rs" { let reply = message.reply_with(&version_str()); send_message(&client, &reply).await; } else if message.content() == "/bot-ls" { let reply = message.reply_with(&format!( "shenbot-py v{}\n{}", VERSION, if MainStatus::global_config().check_py() { py::PyStatus::display() } else { "未启用 Python 插件".to_string() } )); send_message(&client, &reply).await; } else if message.content() == "/bot-help" { let reply = message.reply_with(&help_msg()); send_message(&client, &reply).await; } if MainStatus::global_config().ica().admin_list.contains(&message.sender_id()) { // admin 区 if message.content().starts_with("/bot-enable") { // 先判定是否为 admin // 尝试获取后面的信息 let mut content = message.content().split_whitespace(); content.next(); if let Some(name) = content.next() { let path_name = PathBuf::from(name); match py::PyStatus::get_status(&path_name) { None => { let reply = message.reply_with("未找到插件"); send_message(&client, &reply).await; } Some(true) => { let reply = message.reply_with("无变化, 插件已经启用"); send_message(&client, &reply).await; } Some(false) => { py::PyStatus::set_status(&path_name, true); let reply = message.reply_with("启用插件完成"); send_message(&client, &reply).await; } } } } else if message.content().starts_with("/bot-disable") { let mut content = message.content().split_whitespace(); content.next(); if let Some(name) = content.next() { let path_name = PathBuf::from(name); match py::PyStatus::get_status(&path_name) { None => { let reply = message.reply_with("未找到插件"); send_message(&client, &reply).await; } Some(false) => { let reply = message.reply_with("无变化, 插件已经禁用"); send_message(&client, &reply).await; } Some(true) => { py::PyStatus::set_status(&path_name, false); let reply = message.reply_with("禁用插件完成"); send_message(&client, &reply).await; } } } } } } // python 插件 py::call::ica_new_message_py(&message, &client).await; } } } /// 理论上不会用到 (因为依赖一个客户端去请求) /// 但反正实际上还是我去请求, 所以只是暂时 /// 加载一个房间的所有消息 pub async fn set_messages(payload: Payload, _client: Client) { if let Payload::Text(values) = payload { if let Some(value) = values.first() { let messages: Vec = serde_json::from_value(value["messages"].clone()).unwrap(); let room_id = value["roomId"].as_i64().unwrap(); info!("set_messages {} len: {}", room_id.to_string().cyan(), messages.len()); } } } /// 撤回消息 pub async fn delete_message(payload: Payload, client: Client) { if let Payload::Text(values) = payload { // 消息 id if let Some(value) = values.first() { if let Some(msg_id) = value.as_str() { event!(Level::INFO, "delete_message {}", msg_id.to_string().yellow()); py::call::ica_delete_message_py(msg_id.to_string(), &client).await; } } } } pub async fn update_all_room(payload: Payload, _client: Client) { if let Payload::Text(values) = payload { if let Some(value) = values.first() { if let Some(raw_rooms) = value.as_array() { let rooms: Vec = raw_rooms.iter().map(Room::new_from_json).collect(); event!(Level::DEBUG, "update_all_room {}", rooms.len()); MainStatus::global_ica_status_mut().update_rooms(rooms); } } } } pub async fn success_message(payload: Payload, _client: Client) { if let Payload::Text(values) = payload { if let Some(value) = values.first() { info!("messageSuccess {}", value.to_string().green()); } } } pub async fn failed_message(payload: Payload, _client: Client) { if let Payload::Text(values) = payload { if let Some(value) = values.first() { warn!("messageFailed {}", value.to_string().red()); } } } /// 所有 pub async fn any_event(event: Event, payload: Payload, _client: Client) { let handled = vec![ // 真正处理过的 "authSucceed", "authFailed", "authRequired", "requireAuth", "onlineData", "addMessage", "deleteMessage", "setAllRooms", "setMessages", // 也许以后会用到 "messageSuccess", "messageFailed", "setAllChatGroups", "handleRequest", // 处理验证消息 (加入请求之类的) // 忽略的 "notify", "syncRead", // 同步已读 "closeLoading", // 发送消息/加载新聊天 有一个 loading "renewMessage", // 我也不确定到底是啥事件 "requestSetup", // 需要登录 "updateRoom", ]; match &event { Event::Custom(event_name) => { if handled.contains(&event_name.as_str()) { return; } } Event::Message => { if let Payload::Text(values) = payload { if let Some(value) = values.first() { if handled.contains(&value.as_str().unwrap()) { return; } info!("收到消息 {}", value.to_string().yellow()); } } return; } _ => (), } match payload { Payload::Binary(ref data) => { println!("event: {} |{:?}", event, data) } Payload::Text(ref data) => { print!("event: {}", event.as_str().purple()); for value in data { println!("|{}", value); } } _ => (), } } pub async fn connect_callback(payload: Payload, _client: Client) { let span = span!(Level::INFO, "ica connect_callback"); let _enter = span.enter(); if let Payload::Text(values) = payload { if let Some(value) = values.first() { match value.as_str() { Some("authSucceed") => { event!(Level::INFO, "{}", "已经登录到 icalingua!".green()) } Some("authFailed") => { event!(Level::ERROR, "{}", "登录到 icalingua 失败!".red()); panic!("登录失败") } Some("authRequired") => { event!(Level::INFO, "{}", "需要登录到 icalingua!".yellow()) } Some(msg) => { event!(Level::INFO, "{}{}", "未知消息".yellow(), msg); } _ => (), } } } }