mirror of
http://shenjack.top:5100/shenjack/icalingua-python-bot.git
synced 2024-11-23 12:41:05 +08:00
hmmm
This commit is contained in:
parent
4da93570c9
commit
d12773981d
9
Cargo.lock
generated
9
Cargo.lock
generated
|
@ -675,6 +675,7 @@ dependencies = [
|
||||||
"rust_socketio",
|
"rust_socketio",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
"thiserror",
|
||||||
"tokio",
|
"tokio",
|
||||||
"toml",
|
"toml",
|
||||||
"tracing",
|
"tracing",
|
||||||
|
@ -1557,18 +1558,18 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "thiserror"
|
||||||
version = "1.0.61"
|
version = "1.0.63"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709"
|
checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"thiserror-impl",
|
"thiserror-impl",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror-impl"
|
name = "thiserror-impl"
|
||||||
version = "1.0.61"
|
version = "1.0.63"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533"
|
checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
|
|
@ -50,3 +50,4 @@ anyhow = { version = "1.0", features = ["backtrace"] }
|
||||||
# log
|
# log
|
||||||
tracing = "0.1.40"
|
tracing = "0.1.40"
|
||||||
tracing-subscriber = { version = "0.3.18", features = ["time"] }
|
tracing-subscriber = { version = "0.3.18", features = ["time"] }
|
||||||
|
thiserror = "1.0.63"
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
// use thiserror::Error;
|
||||||
|
|
||||||
pub type ClientResult<T, E> = Result<T, E>;
|
pub type ClientResult<T, E> = Result<T, E>;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
|
@ -10,7 +10,8 @@ use crate::config::IcaConfig;
|
||||||
use crate::error::{ClientResult, IcaError};
|
use crate::error::{ClientResult, IcaError};
|
||||||
use crate::StopGetter;
|
use crate::StopGetter;
|
||||||
|
|
||||||
const ICA_PROTOCOL_VERSION: &str = "2.12.12";
|
/// icalingua 客户端的兼容版本号
|
||||||
|
pub const ICA_PROTOCOL_VERSION: &str = "2.12.12";
|
||||||
|
|
||||||
pub async fn start_ica(config: &IcaConfig, stop_reciver: StopGetter) -> ClientResult<(), IcaError> {
|
pub async fn start_ica(config: &IcaConfig, stop_reciver: StopGetter) -> ClientResult<(), IcaError> {
|
||||||
let span = span!(Level::INFO, "Icalingua Client");
|
let span = span!(Level::INFO, "Icalingua Client");
|
||||||
|
@ -80,7 +81,7 @@ pub async fn start_ica(config: &IcaConfig, stop_reciver: StopGetter) -> ClientRe
|
||||||
event!(Level::INFO, "socketio client stopped");
|
event!(Level::INFO, "socketio client stopped");
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
event!(Level::ERROR, "socketio client stopped with error: {:?}", inner_e);
|
event!(Level::ERROR, "socketio 客户端出现了 Error: {:?}", inner_e);
|
||||||
Err(IcaError::SocketIoError(
|
Err(IcaError::SocketIoError(
|
||||||
rust_socketio::Error::IncompleteResponseFromEngineIo(inner_e),
|
rust_socketio::Error::IncompleteResponseFromEngineIo(inner_e),
|
||||||
))
|
))
|
||||||
|
|
|
@ -7,7 +7,7 @@ use ed25519_dalek::{Signature, Signer, SigningKey};
|
||||||
use rust_socketio::asynchronous::Client;
|
use rust_socketio::asynchronous::Client;
|
||||||
use rust_socketio::Payload;
|
use rust_socketio::Payload;
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
use tracing::{debug, info, span, warn, event, Level};
|
use tracing::{debug, event, span, warn, Level};
|
||||||
|
|
||||||
/// "安全" 的 发送一条消息
|
/// "安全" 的 发送一条消息
|
||||||
pub async fn send_message(client: &Client, message: &SendMessage) -> bool {
|
pub async fn send_message(client: &Client, message: &SendMessage) -> bool {
|
||||||
|
@ -56,7 +56,12 @@ async fn inner_sign(payload: Payload, client: Client) -> ClientResult<(), IcaErr
|
||||||
|
|
||||||
let (auth_key, version) = (&require_data[0], &require_data[1]);
|
let (auth_key, version) = (&require_data[0], &require_data[1]);
|
||||||
|
|
||||||
event!(Level::INFO, "服务器发过来的待签名key: {:?}, 服务端版本号: {:?}", auth_key, version);
|
event!(
|
||||||
|
Level::INFO,
|
||||||
|
"服务器发过来的待签名key: {:?}, 服务端版本号: {:?}",
|
||||||
|
auth_key,
|
||||||
|
version
|
||||||
|
);
|
||||||
// 判定和自己的兼容版本号是否 一致
|
// 判定和自己的兼容版本号是否 一致
|
||||||
let server_protocol_version = version
|
let server_protocol_version = version
|
||||||
.get("protocolVersion")
|
.get("protocolVersion")
|
||||||
|
|
|
@ -25,8 +25,6 @@ pub async fn get_online_data(payload: Payload, _client: Client) {
|
||||||
pub async fn add_message(payload: Payload, client: Client) {
|
pub async fn add_message(payload: Payload, client: Client) {
|
||||||
if let Payload::Text(values) = payload {
|
if let Payload::Text(values) = payload {
|
||||||
if let Some(value) = values.first() {
|
if let Some(value) = values.first() {
|
||||||
let span = span!(Level::INFO, "ica new_msg");
|
|
||||||
let _enter = span.enter();
|
|
||||||
let message: NewMessage = serde_json::from_value(value.clone()).unwrap();
|
let message: NewMessage = serde_json::from_value(value.clone()).unwrap();
|
||||||
// 检测是否在过滤列表内
|
// 检测是否在过滤列表内
|
||||||
if MainStatus::global_config().ica().filter_list.contains(&message.msg.sender_id) {
|
if MainStatus::global_config().ica().filter_list.contains(&message.msg.sender_id) {
|
||||||
|
@ -184,7 +182,7 @@ pub async fn connect_callback(payload: Payload, _client: Client) {
|
||||||
Some(msg) => {
|
Some(msg) => {
|
||||||
event!(Level::INFO, "{}{}", "未知消息".yellow(), msg);
|
event!(Level::INFO, "{}{}", "未知消息".yellow(), msg);
|
||||||
}
|
}
|
||||||
None => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -135,7 +135,7 @@ pub async fn ica_new_message_py(message: &ica::messages::NewMessage, client: &Cl
|
||||||
// 验证插件是否改变
|
// 验证插件是否改变
|
||||||
verify_plugins();
|
verify_plugins();
|
||||||
|
|
||||||
let plugins = PyStatus::get_files();
|
let plugins = PyStatus::get_map();
|
||||||
for (path, plugin) in plugins.iter().filter(|(_, plugin)| plugin.enabled) {
|
for (path, plugin) in plugins.iter().filter(|(_, plugin)| plugin.enabled) {
|
||||||
let msg = class::ica::NewMessagePy::new(message);
|
let msg = class::ica::NewMessagePy::new(message);
|
||||||
let client = class::ica::IcaClientPy::new(client);
|
let client = class::ica::IcaClientPy::new(client);
|
||||||
|
@ -148,7 +148,7 @@ pub async fn ica_new_message_py(message: &ica::messages::NewMessage, client: &Cl
|
||||||
pub async fn ica_delete_message_py(msg_id: ica::MessageId, client: &Client) {
|
pub async fn ica_delete_message_py(msg_id: ica::MessageId, client: &Client) {
|
||||||
verify_plugins();
|
verify_plugins();
|
||||||
|
|
||||||
let plugins = PyStatus::get_files();
|
let plugins = PyStatus::get_map();
|
||||||
for (path, plugin) in plugins.iter().filter(|(_, plugin)| plugin.enabled) {
|
for (path, plugin) in plugins.iter().filter(|(_, plugin)| plugin.enabled) {
|
||||||
let msg_id = msg_id.clone();
|
let msg_id = msg_id.clone();
|
||||||
let client = class::ica::IcaClientPy::new(client);
|
let client = class::ica::IcaClientPy::new(client);
|
||||||
|
@ -163,7 +163,7 @@ pub async fn tailchat_new_message_py(
|
||||||
) {
|
) {
|
||||||
verify_plugins();
|
verify_plugins();
|
||||||
|
|
||||||
let plugins = PyStatus::get_files();
|
let plugins = PyStatus::get_map();
|
||||||
for (path, plugin) in plugins.iter().filter(|(_, plugin)| plugin.enabled) {
|
for (path, plugin) in plugins.iter().filter(|(_, plugin)| plugin.enabled) {
|
||||||
let msg = class::tailchat::TailchatReceiveMessagePy::from_recive_message(message);
|
let msg = class::tailchat::TailchatReceiveMessagePy::from_recive_message(message);
|
||||||
let client = class::tailchat::TailchatClientPy::new(client);
|
let client = class::tailchat::TailchatClientPy::new(client);
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
|
|
@ -2,6 +2,7 @@ pub mod call;
|
||||||
pub mod class;
|
pub mod class;
|
||||||
pub mod config;
|
pub mod config;
|
||||||
|
|
||||||
|
use std::fmt::Display;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::time::SystemTime;
|
use std::time::SystemTime;
|
||||||
use std::{collections::HashMap, path::PathBuf};
|
use std::{collections::HashMap, path::PathBuf};
|
||||||
|
@ -9,18 +10,65 @@ use std::{collections::HashMap, path::PathBuf};
|
||||||
use colored::Colorize;
|
use colored::Colorize;
|
||||||
use pyo3::prelude::*;
|
use pyo3::prelude::*;
|
||||||
use pyo3::types::PyTuple;
|
use pyo3::types::PyTuple;
|
||||||
use tracing::{debug, info, span, warn, Level};
|
use tracing::{debug, event, info, span, warn, Level};
|
||||||
|
|
||||||
use crate::MainStatus;
|
use crate::MainStatus;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct PyStatus {
|
pub struct PyStatus {
|
||||||
pub files: Option<HashMap<PathBuf, PyPlugin>>,
|
pub files: Option<PyPlugins>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type PyPluginData = HashMap<PathBuf, PyPlugin>;
|
pub type PyPlugins = HashMap<PathBuf, PyPlugin>;
|
||||||
pub type RawPyPlugin = (PathBuf, Option<SystemTime>, String);
|
pub type RawPyPlugin = (PathBuf, Option<SystemTime>, String);
|
||||||
|
|
||||||
|
impl PyStatus {
|
||||||
|
pub fn init() {
|
||||||
|
unsafe {
|
||||||
|
if PYSTATUS.files.is_none() {
|
||||||
|
PYSTATUS.files = Some(HashMap::new());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_file(path: PathBuf, plugin: PyPlugin) { Self::get_mut_map().insert(path, plugin); }
|
||||||
|
|
||||||
|
pub fn verify_file(path: &PathBuf) -> bool {
|
||||||
|
Self::get_map().get(path).map_or(false, |plugin| plugin.verifiy())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_map() -> &'static PyPlugins {
|
||||||
|
unsafe {
|
||||||
|
match PYSTATUS.files.as_ref() {
|
||||||
|
Some(files) => files,
|
||||||
|
None => {
|
||||||
|
Self::init();
|
||||||
|
PYSTATUS.files.as_ref().unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_mut_map() -> &'static mut PyPlugins {
|
||||||
|
unsafe {
|
||||||
|
match PYSTATUS.files.as_mut() {
|
||||||
|
Some(files) => files,
|
||||||
|
None => {
|
||||||
|
Self::init();
|
||||||
|
PYSTATUS.files.as_mut().unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn list_plugins() -> Vec<PathBuf> { Self::get_map().keys().cloned().collect() }
|
||||||
|
|
||||||
|
pub fn display() -> String {
|
||||||
|
let map = Self::get_map();
|
||||||
|
format!("Python 插件 {{ {} }}", (",".join(map.keys().map(|x| x.to_string()))))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_py_err_traceback(py_err: &PyErr) -> String {
|
pub fn get_py_err_traceback(py_err: &PyErr) -> String {
|
||||||
Python::with_gil(|py| match py_err.traceback_bound(py) {
|
Python::with_gil(|py| match py_err.traceback_bound(py) {
|
||||||
Some(traceback) => match traceback.format() {
|
Some(traceback) => match traceback.format() {
|
||||||
|
@ -218,56 +266,15 @@ impl TryFrom<RawPyPlugin> for PyPlugin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PyStatus {
|
|
||||||
pub fn get_files() -> &'static PyPluginData {
|
|
||||||
unsafe {
|
|
||||||
match PYSTATUS.files.as_ref() {
|
|
||||||
Some(files) => files,
|
|
||||||
None => {
|
|
||||||
PYSTATUS.files = Some(HashMap::new());
|
|
||||||
PYSTATUS.files.as_ref().unwrap()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn add_file(path: PathBuf, plugin: PyPlugin) {
|
|
||||||
unsafe {
|
|
||||||
match PYSTATUS.files.as_mut() {
|
|
||||||
Some(files) => {
|
|
||||||
files.insert(path, plugin);
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
let mut files: PyPluginData = HashMap::new();
|
|
||||||
files.insert(path, plugin);
|
|
||||||
PYSTATUS.files = Some(files);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn verify_file(path: &PathBuf) -> bool {
|
|
||||||
unsafe {
|
|
||||||
match PYSTATUS.files.as_ref() {
|
|
||||||
Some(files) => match files.get(path) {
|
|
||||||
Some(plugin) => plugin.verifiy(),
|
|
||||||
None => false,
|
|
||||||
},
|
|
||||||
None => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub static mut PYSTATUS: PyStatus = PyStatus { files: None };
|
pub static mut PYSTATUS: PyStatus = PyStatus { files: None };
|
||||||
|
|
||||||
pub fn load_py_plugins(path: &PathBuf) {
|
pub fn load_py_plugins(path: &PathBuf) {
|
||||||
if path.exists() {
|
if path.exists() {
|
||||||
info!("finding plugins in: {:?}", path);
|
event!(Level::INFO, "finding plugins in: {:?}", path);
|
||||||
// 搜索所有的 py 文件 和 文件夹单层下面的 py 文件
|
// 搜索所有的 py 文件 和 文件夹单层下面的 py 文件
|
||||||
match path.read_dir() {
|
match path.read_dir() {
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
warn!("failed to read plugin path: {:?}", e);
|
event!(Level::WARN, "failed to read plugin path: {:?}", e);
|
||||||
}
|
}
|
||||||
Ok(dir) => {
|
Ok(dir) => {
|
||||||
for entry in dir {
|
for entry in dir {
|
||||||
|
@ -284,12 +291,13 @@ pub fn load_py_plugins(path: &PathBuf) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
warn!("plugin path not exists: {:?}", path);
|
event!(Level::WARN, "插件加载目录不存在: {:?}", path);
|
||||||
}
|
}
|
||||||
info!(
|
event!(
|
||||||
|
Level::INFO,
|
||||||
"python 插件目录: {:?} 加载完成, 加载到 {} 个插件",
|
"python 插件目录: {:?} 加载完成, 加载到 {} 个插件",
|
||||||
path,
|
path,
|
||||||
PyStatus::get_files().len()
|
PyStatus::get_map().len()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -325,12 +333,12 @@ pub fn init_py() {
|
||||||
|
|
||||||
let global_config = MainStatus::global_config().py();
|
let global_config = MainStatus::global_config().py();
|
||||||
|
|
||||||
debug!("initing python threads");
|
event!(Level::INFO, "正在初始化 python");
|
||||||
pyo3::prepare_freethreaded_python();
|
pyo3::prepare_freethreaded_python();
|
||||||
|
|
||||||
let plugin_path = PathBuf::from(global_config.plugin_path);
|
let plugin_path = PathBuf::from(global_config.plugin_path);
|
||||||
load_py_plugins(&plugin_path);
|
load_py_plugins(&plugin_path);
|
||||||
debug!("python 插件列表: {:#?}", PyStatus::get_files());
|
event!(Level::DEBUG, "python 插件列表: {}", PyStatus::display());
|
||||||
|
|
||||||
info!("python inited")
|
info!("python inited")
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user