ica-rs 重构一波
This commit is contained in:
parent
9c22f6c7b3
commit
5c3c6f6c2f
1
ica-rs/src/data_struct/mod.rs
Normal file
1
ica-rs/src/data_struct/mod.rs
Normal file
@ -0,0 +1 @@
|
||||
pub mod online_data;
|
226
ica-rs/src/data_struct/online_data.rs
Normal file
226
ica-rs/src/data_struct/online_data.rs
Normal file
@ -0,0 +1,226 @@
|
||||
use serde_json::Value as JsonValue;
|
||||
use tracing::warn;
|
||||
|
||||
#[derive(Debug, Clone, Hash)]
|
||||
pub struct IcalinguaInfo {
|
||||
pub ica_version: String,
|
||||
pub os_info: String,
|
||||
pub resident_set_size: String,
|
||||
pub heap_used: String,
|
||||
pub load: String,
|
||||
/// 服务器 nodejs 版本
|
||||
pub server_node: String,
|
||||
/// 客户端计数
|
||||
/// 我还不新 u16 (u16::MAX) 会溢出
|
||||
pub client_count: u16,
|
||||
}
|
||||
|
||||
impl IcalinguaInfo {
|
||||
pub fn new_from_str(s: &str) -> IcalinguaInfo {
|
||||
let mut ica_version = None;
|
||||
let mut os_info = None;
|
||||
let mut resident_set_size = None;
|
||||
let mut heap_used = None;
|
||||
let mut load = None;
|
||||
let mut server_node = None;
|
||||
let mut client_count = None;
|
||||
let info_list = s.split("\n").collect::<Vec<&str>>();
|
||||
for info in info_list {
|
||||
if info.starts_with("icalingua-bridge-oicq") {
|
||||
ica_version = Some(info.split_at(22).1.to_string());
|
||||
} else if info.starts_with("Running on") {
|
||||
os_info = Some(info.split_at(11).1.to_string());
|
||||
} else if info.starts_with("Resident Set Size") {
|
||||
resident_set_size = Some(info.split_at(18).1.to_string());
|
||||
} else if info.starts_with("Heap used") {
|
||||
heap_used = Some(info.split_at(10).1.to_string());
|
||||
} else if info.starts_with("Load") {
|
||||
load = Some(info.split_at(5).1.to_string());
|
||||
} else if info.starts_with("Server Node") {
|
||||
server_node = Some(info.split_at(12).1.to_string());
|
||||
} else if info.ends_with("clients connected") {
|
||||
client_count = Some(
|
||||
info.split(" ")
|
||||
.collect::<Vec<&str>>()
|
||||
.get(0)
|
||||
.unwrap_or(&"1")
|
||||
.parse::<u16>()
|
||||
.unwrap_or_else(|e| {
|
||||
warn!("client_count parse error: {}|raw: {}", e, info);
|
||||
1_u16
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
IcalinguaInfo {
|
||||
ica_version: ica_version.unwrap_or_else(|| {
|
||||
warn!("ica_version faild to parse");
|
||||
"UNKNOWN".to_string()
|
||||
}),
|
||||
os_info: os_info.unwrap_or_else(|| {
|
||||
warn!("os_info faild to parse");
|
||||
"UNKNOWN".to_string()
|
||||
}),
|
||||
resident_set_size: resident_set_size.unwrap_or_else(|| {
|
||||
warn!("resident_set_size faild to parse");
|
||||
"UNKNOWN".to_string()
|
||||
}),
|
||||
heap_used: heap_used.unwrap_or_else(|| {
|
||||
warn!("heap_used faild to parse");
|
||||
"UNKNOWN".to_string()
|
||||
}),
|
||||
load: load.unwrap_or_else(|| {
|
||||
warn!("load faild to parse");
|
||||
"UNKNOWN".to_string()
|
||||
}),
|
||||
server_node: server_node.unwrap_or_else(|| {
|
||||
warn!("server_node faild to parse");
|
||||
"UNKNOWN".to_string()
|
||||
}),
|
||||
client_count: client_count.unwrap_or_else(|| {
|
||||
warn!("client_count faild to parse");
|
||||
1_u16
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// {"bkn":<bkn>,
|
||||
/// "nick":<nick>,
|
||||
/// "online":true,
|
||||
/// "sysInfo":"icalingua-bridge-oicq 2.11.1\n
|
||||
/// Running on Linux c038fad79f13 4.4.302+\n
|
||||
/// Resident Set Size 95.43MB\n
|
||||
/// Heap used 37.31MB\n
|
||||
/// Load 4.23 2.15 1.59\n
|
||||
/// Server Node 18.19.0\n
|
||||
/// 2 clients connected",
|
||||
/// "uin": <qqid> }
|
||||
#[derive(Debug, Clone, Hash)]
|
||||
pub struct OnlineData {
|
||||
pub bkn: i64,
|
||||
pub nick: String,
|
||||
pub online: bool,
|
||||
pub qqid: i64,
|
||||
pub icalingua_info: IcalinguaInfo,
|
||||
}
|
||||
|
||||
impl OnlineData {
|
||||
pub fn new_from_json(value: &JsonValue) -> OnlineData {
|
||||
let bkn = value["bkn"].as_i64().unwrap_or_else(|| {
|
||||
warn!("bkn not found in online data");
|
||||
-1
|
||||
});
|
||||
let nick = value["nick"]
|
||||
.as_str()
|
||||
.unwrap_or_else(|| {
|
||||
warn!("nick not found in online data");
|
||||
"UNKNOWN"
|
||||
})
|
||||
.to_string();
|
||||
let online = value["online"].as_bool().unwrap_or_else(|| {
|
||||
warn!("online not found in online data");
|
||||
false
|
||||
});
|
||||
let qqid = value["uin"].as_i64().unwrap_or_else(|| {
|
||||
warn!("uin not found in online data");
|
||||
-1
|
||||
});
|
||||
let sys_info = value["sysInfo"].as_str().unwrap_or_else(|| {
|
||||
warn!("sysInfo not found in online data");
|
||||
""
|
||||
});
|
||||
let icalingua_info = IcalinguaInfo::new_from_str(sys_info);
|
||||
OnlineData {
|
||||
bkn,
|
||||
nick,
|
||||
online,
|
||||
qqid,
|
||||
icalingua_info,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn parse_empty_str() {
|
||||
let icalingua_info = IcalinguaInfo::new_from_str("");
|
||||
assert_eq!(icalingua_info.ica_version, "UNKNOWN");
|
||||
assert_eq!(icalingua_info.os_info, "UNKNOWN");
|
||||
assert_eq!(icalingua_info.resident_set_size, "UNKNOWN");
|
||||
assert_eq!(icalingua_info.heap_used, "UNKNOWN");
|
||||
assert_eq!(icalingua_info.load, "UNKNOWN");
|
||||
assert_eq!(icalingua_info.server_node, "UNKNOWN");
|
||||
assert_eq!(icalingua_info.client_count, 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_str() {
|
||||
let icalingua_info = IcalinguaInfo::new_from_str(
|
||||
"icalingua-bridge-oicq 2.11.1\n\
|
||||
Running on Linux c038fad79f13 4.4.302+\n\
|
||||
Resident Set Size 95.43MB\n\
|
||||
Heap used 37.31MB\n\
|
||||
Load 4.23 2.15 1.59\n\
|
||||
Server Node 18.19.0\n\
|
||||
2 clients connected",
|
||||
);
|
||||
assert_eq!(icalingua_info.ica_version, "2.11.1");
|
||||
assert_eq!(icalingua_info.os_info, "Linux c038fad79f13 4.4.302+");
|
||||
assert_eq!(icalingua_info.resident_set_size, "95.43MB");
|
||||
assert_eq!(icalingua_info.heap_used, "37.31MB");
|
||||
assert_eq!(icalingua_info.load, "4.23 2.15 1.59");
|
||||
assert_eq!(icalingua_info.server_node, "18.19.0");
|
||||
assert_eq!(icalingua_info.client_count, 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_online_data() {
|
||||
let online_data = OnlineData::new_from_json(&serde_json::json!({
|
||||
"bkn": 123,
|
||||
"nick": "test",
|
||||
"online": true,
|
||||
"sysInfo": "icalingua-bridge-oicq 2.11.1\n\
|
||||
Running on Linux c038fad79f13 4.4.302+\n\
|
||||
Resident Set Size 95.43MB\n\
|
||||
Heap used 37.31MB\n\
|
||||
Load 4.23 2.15 1.59\n\
|
||||
Server Node 18.19.0\n\
|
||||
2 clients connected",
|
||||
"uin": 123456
|
||||
}));
|
||||
assert_eq!(online_data.bkn, 123);
|
||||
assert_eq!(online_data.nick, "test");
|
||||
assert_eq!(online_data.online, true);
|
||||
assert_eq!(online_data.qqid, 123456);
|
||||
assert_eq!(online_data.icalingua_info.ica_version, "2.11.1");
|
||||
assert_eq!(
|
||||
online_data.icalingua_info.os_info,
|
||||
"Linux c038fad79f13 4.4.302+"
|
||||
);
|
||||
assert_eq!(online_data.icalingua_info.resident_set_size, "95.43MB");
|
||||
assert_eq!(online_data.icalingua_info.heap_used, "37.31MB");
|
||||
assert_eq!(online_data.icalingua_info.load, "4.23 2.15 1.59");
|
||||
assert_eq!(online_data.icalingua_info.server_node, "18.19.0");
|
||||
assert_eq!(online_data.icalingua_info.client_count, 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_online_data_empty() {
|
||||
let online_data = OnlineData::new_from_json(&serde_json::json!({}));
|
||||
assert_eq!(online_data.bkn, -1);
|
||||
assert_eq!(online_data.nick, "UNKNOWN");
|
||||
assert_eq!(online_data.online, false);
|
||||
assert_eq!(online_data.qqid, -1);
|
||||
assert_eq!(online_data.icalingua_info.ica_version, "UNKNOWN");
|
||||
assert_eq!(online_data.icalingua_info.os_info, "UNKNOWN");
|
||||
assert_eq!(online_data.icalingua_info.resident_set_size, "UNKNOWN");
|
||||
assert_eq!(online_data.icalingua_info.heap_used, "UNKNOWN");
|
||||
assert_eq!(online_data.icalingua_info.load, "UNKNOWN");
|
||||
assert_eq!(online_data.icalingua_info.server_node, "UNKNOWN");
|
||||
assert_eq!(online_data.icalingua_info.client_count, 1);
|
||||
}
|
||||
}
|
72
ica-rs/src/events.rs
Normal file
72
ica-rs/src/events.rs
Normal file
@ -0,0 +1,72 @@
|
||||
use colored::Colorize;
|
||||
use rust_socketio::{Event, Payload, RawClient};
|
||||
use tracing::{info, warn};
|
||||
|
||||
use crate::data_struct::online_data::OnlineData;
|
||||
use crate::py;
|
||||
|
||||
pub fn get_online_data(payload: Payload, _client: RawClient) {
|
||||
if let Payload::Text(values) = payload {
|
||||
if let Some(value) = values.first() {
|
||||
let online_data = OnlineData::new_from_json(value);
|
||||
info!("update_online_data {}", format!("{:#?}", online_data).cyan());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn any_event(event: Event, payload: Payload, _client: RawClient) {
|
||||
let handled = vec![
|
||||
"authSucceed",
|
||||
"authFailed",
|
||||
"authRequired",
|
||||
"requireAuth",
|
||||
"onlineData",
|
||||
];
|
||||
match &event {
|
||||
Event::Custom(event_name) => {
|
||||
if handled.contains(&event_name.as_str()) {
|
||||
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.to_string());
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn connect_callback(payload: Payload, _client: RawClient) {
|
||||
match payload {
|
||||
Payload::Text(values) => {
|
||||
if let Some(value) = values.first() {
|
||||
// if let Some("authSucceed") = value.as_str() {
|
||||
// println!("{}", "已经登录到 icalingua!".green());
|
||||
// }
|
||||
match value.as_str() {
|
||||
Some("authSucceed") => {
|
||||
py::run();
|
||||
info!("{}", "已经登录到 icalingua!".green())
|
||||
}
|
||||
Some("authFailed") => {
|
||||
info!("{}", "登录到 icalingua 失败!".red());
|
||||
panic!("登录失败")
|
||||
}
|
||||
Some("authRequired") => {
|
||||
warn!("{}", "需要登录到 icalingua!".yellow())
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
@ -1,67 +1,30 @@
|
||||
mod client;
|
||||
mod config;
|
||||
mod py;
|
||||
|
||||
use colored::Colorize;
|
||||
use rust_socketio::{ClientBuilder, Event, Payload, RawClient};
|
||||
use std::time::Duration;
|
||||
|
||||
#[allow(unused)]
|
||||
fn any_event(event: Event, payload: Payload, _client: RawClient) {
|
||||
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.to_string());
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
// println!("event: {} |{:?}|id{:?}", event, payload, id)
|
||||
}
|
||||
use rust_socketio::ClientBuilder;
|
||||
|
||||
mod client;
|
||||
mod config;
|
||||
mod data_struct;
|
||||
mod events;
|
||||
mod py;
|
||||
|
||||
fn ws_main() {
|
||||
py::init_py();
|
||||
// define a callback which is called when a payload is received
|
||||
// this callback gets the payload as well as an instance of the
|
||||
// socket to communicate with the server
|
||||
let connect_call_back = |payload: Payload, _client: RawClient| match payload {
|
||||
Payload::Text(values) => {
|
||||
if let Some(value) = values.first() {
|
||||
// if let Some("authSucceed") = value.as_str() {
|
||||
// println!("{}", "已经登录到 icalingua!".green());
|
||||
// }
|
||||
match value.as_str() {
|
||||
Some("authSucceed") => {
|
||||
py::run();
|
||||
println!("{}", "已经登录到 icalingua!".green())
|
||||
}
|
||||
Some("authFailed") => {
|
||||
println!("{}", "登录到 icalingua 失败!".red());
|
||||
panic!("登录失败")
|
||||
}
|
||||
Some("authRequired") => println!("{}", "需要登录到 icalingua!".yellow()),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
};
|
||||
|
||||
// 从命令行获取 host 和 key
|
||||
// 从命令行获取配置文件路径
|
||||
let ica_config = config::IcaConfig::new_from_cli();
|
||||
let ica_singer = client::IcalinguaSinger::new_from_config(ica_config);
|
||||
|
||||
// get a socket that is connected to the admin namespace
|
||||
|
||||
let socket = ClientBuilder::new(ica_singer.host.clone())
|
||||
.transport_type(rust_socketio::TransportType::Websocket)
|
||||
.on_any(any_event)
|
||||
.on("message", connect_call_back)
|
||||
.on_any(events::any_event)
|
||||
.on("onlineData", events::get_online_data)
|
||||
.on("message", events::connect_callback)
|
||||
.on("requireAuth", move |a, b| ica_singer.sign_callback(a, b))
|
||||
.on("authRequired", events::connect_callback)
|
||||
.on("authSucceed", events::connect_callback)
|
||||
.on("authFailed", events::connect_callback)
|
||||
.connect()
|
||||
.expect("Connection failed");
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user