mirror of
http://shenjack.top:5100/shenjack/icalingua-python-bot.git
synced 2024-11-22 20:21:06 +08:00
我知道没修好,但是先丢上来
This commit is contained in:
parent
4ae11b4d4f
commit
de09257249
|
@ -1,13 +1,18 @@
|
|||
|
||||
# python 插件路径
|
||||
py_plugin_path = "/path/to/your/plugin"
|
||||
py_config_path = "/path/to/your/config"
|
||||
|
||||
# 填写 [ica] 但不填写此项则不启用 ica
|
||||
enable_ica = true # 是否启用 ica
|
||||
# 填写 [matrix] 但不填写此项则不启用 matrix
|
||||
enable_matrix = true # 是否启用 matrix
|
||||
|
||||
enable_py = true # 是否启用 python 插件
|
||||
|
||||
[py]
|
||||
|
||||
# python 插件路径
|
||||
plugin_path = "/path/to/your/plugin"
|
||||
config_path = "/path/to/your/config"
|
||||
|
||||
[ica]
|
||||
|
||||
private_key = "" # 与 icalingua 客户端使用的 private_key 一致
|
||||
|
|
|
@ -39,6 +39,14 @@ pub struct MatrixConfig {
|
|||
pub notice_start: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
pub struct PyConfig {
|
||||
/// 插件路径
|
||||
pub plugin_path: String,
|
||||
/// 配置文件路径
|
||||
pub config_path: String,
|
||||
}
|
||||
|
||||
/// 主配置
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
pub struct BotConfig {
|
||||
|
@ -50,10 +58,10 @@ pub struct BotConfig {
|
|||
pub enable_matrix: Option<bool>,
|
||||
/// Matrix 配置
|
||||
pub matrix: Option<MatrixConfig>,
|
||||
/// Python 插件路径
|
||||
pub py_plugin_path: Option<String>,
|
||||
/// Python 配置文件路径
|
||||
pub py_config_path: Option<String>,
|
||||
/// 是否启用 Python 插件
|
||||
pub enable_py: Option<bool>,
|
||||
/// Python 插件配置
|
||||
pub py: Option<PyConfig>,
|
||||
}
|
||||
|
||||
impl BotConfig {
|
||||
|
@ -109,5 +117,27 @@ impl BotConfig {
|
|||
}
|
||||
}
|
||||
|
||||
/// 检查是否启用 Python 插件
|
||||
pub fn check_py(&self) -> bool {
|
||||
match self.enable_py {
|
||||
Some(enable) => {
|
||||
if enable && self.py.is_none() {
|
||||
warn!("enable_py 为 true 但未填写 [py] 配置\n将不启用 Python 插件");
|
||||
false
|
||||
} else {
|
||||
true
|
||||
}
|
||||
}
|
||||
None => {
|
||||
if self.py.is_some() {
|
||||
warn!("未填写 enable_py 但填写了 [py] 配置\n将不启用 Python 插件");
|
||||
}
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ica(&self) -> IcaConfig { self.ica.clone().expect("No ica config found") }
|
||||
pub fn matrix(&self) -> MatrixConfig { self.matrix.clone().expect("No matrix config found") }
|
||||
pub fn py(&self) -> PyConfig { self.py.clone().expect("No py config found") }
|
||||
}
|
||||
|
|
0
ica-rs/src/error.rs
Normal file
0
ica-rs/src/error.rs
Normal file
|
@ -4,12 +4,13 @@ pub mod events;
|
|||
use futures_util::FutureExt;
|
||||
use rust_socketio::asynchronous::{Client, ClientBuilder};
|
||||
use rust_socketio::{Event, Payload, TransportType};
|
||||
use tracing::info;
|
||||
use tracing::{event, info, Level};
|
||||
|
||||
use crate::config::IcaConfig;
|
||||
use crate::{wrap_any_callback, wrap_callback};
|
||||
|
||||
pub async fn start_ica(config: &IcaConfig, stop_reciver: tokio::sync::oneshot::Receiver<()>) {
|
||||
event!(Level::INFO, "ica-async-rs v{} start ica", crate::ICA_VERSION);
|
||||
let socket = ClientBuilder::new(config.host.clone())
|
||||
.transport_type(TransportType::Websocket)
|
||||
.on_any(wrap_any_callback!(events::any_event))
|
||||
|
@ -33,7 +34,7 @@ pub async fn start_ica(config: &IcaConfig, stop_reciver: tokio::sync::oneshot::R
|
|||
if config.notice_start {
|
||||
for room in config.notice_room.iter() {
|
||||
let startup_msg = crate::data_struct::ica::messages::SendMessage::new(
|
||||
format!("ica-async-rs bot v{}", crate::VERSION),
|
||||
format!("shenbot v {}\nica-async-rs bot v{}", crate::VERSION, crate::ICA_VERSION),
|
||||
*room,
|
||||
None,
|
||||
);
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
use crate::config::{BotConfig, IcaConfig};
|
||||
use crate::data_struct::ica::all_rooms::Room;
|
||||
use crate::data_struct::ica::messages::{DeleteMessage, SendMessage};
|
||||
use crate::data_struct::ica::online_data::OnlineData;
|
||||
use crate::ClientStatus_Global;
|
||||
use crate::MainStatus;
|
||||
|
||||
use colored::Colorize;
|
||||
use ed25519_dalek::{Signature, Signer, SigningKey};
|
||||
|
@ -46,93 +45,6 @@ pub async fn delete_message(client: &Client, message: &DeleteMessage) -> bool {
|
|||
// #[allow(dead_code)]
|
||||
// pub async fn fetch_history(client: &Client, roomd_id: RoomId) -> bool { false }
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct BotStatus {
|
||||
pub login: bool,
|
||||
/// currentLoadedMessagesCount
|
||||
pub current_loaded_messages_count: u64,
|
||||
pub online_data: Option<OnlineData>,
|
||||
pub rooms: Option<Vec<Room>>,
|
||||
pub config: Option<BotConfig>,
|
||||
}
|
||||
|
||||
impl Default for BotStatus {
|
||||
fn default() -> Self { Self::new() }
|
||||
}
|
||||
|
||||
impl BotStatus {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
login: false,
|
||||
current_loaded_messages_count: 0,
|
||||
online_data: None,
|
||||
rooms: None,
|
||||
config: Some(BotConfig::new_from_cli()),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn update_online_data(online_data: OnlineData) {
|
||||
unsafe {
|
||||
ClientStatus_Global.online_data = Some(online_data);
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
pub fn update_rooms(rooms: Vec<Room>) {
|
||||
unsafe {
|
||||
ClientStatus_Global.rooms = Some(rooms);
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
pub fn update_login_status(login: bool) {
|
||||
unsafe {
|
||||
ClientStatus_Global.login = login;
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
pub fn update_config(config: BotConfig) {
|
||||
unsafe {
|
||||
ClientStatus_Global.config = Some(config);
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
pub fn update_loaded_messages_count(count: u64) {
|
||||
unsafe {
|
||||
ClientStatus_Global.current_loaded_messages_count = count;
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
pub fn get_login_status() -> bool { unsafe { ClientStatus_Global.login } }
|
||||
#[inline]
|
||||
pub fn get_rooms() -> &'static Vec<Room> {
|
||||
unsafe { ClientStatus_Global.rooms.as_ref().expect("rooms should be set") }
|
||||
}
|
||||
#[inline]
|
||||
pub fn get_loaded_messages_count() -> u64 {
|
||||
unsafe { ClientStatus_Global.current_loaded_messages_count }
|
||||
}
|
||||
#[inline]
|
||||
pub fn get_online_data() -> &'static OnlineData {
|
||||
unsafe { ClientStatus_Global.online_data.as_ref().expect("online_data should be set") }
|
||||
}
|
||||
#[inline]
|
||||
pub fn get_config() -> &'static BotConfig {
|
||||
unsafe { ClientStatus_Global.config.as_ref().expect("config should be set") }
|
||||
}
|
||||
#[inline]
|
||||
pub fn get_ica_config() -> &'static IcaConfig {
|
||||
unsafe {
|
||||
ClientStatus_Global
|
||||
.config
|
||||
.as_ref()
|
||||
.expect("config should be set")
|
||||
.ica
|
||||
.as_ref()
|
||||
.expect("ica should be set")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn sign_callback(payload: Payload, client: Client) {
|
||||
// 获取数据
|
||||
let require_data = match payload {
|
||||
|
@ -142,15 +54,17 @@ pub async fn sign_callback(payload: Payload, client: Client) {
|
|||
.expect("Payload should be Json data");
|
||||
|
||||
let (auth_key, version) = (&require_data[0], &require_data[1]);
|
||||
debug!("auth_key: {:?}, version: {:?}", auth_key, version);
|
||||
debug!("auth_key: {:?}, server_version: {:?}", auth_key, version);
|
||||
let auth_key = match &require_data.first() {
|
||||
Some(Value::String(auth_key)) => Some(auth_key),
|
||||
_ => None,
|
||||
}
|
||||
.expect("auth_key should be string");
|
||||
|
||||
let salt = hex::decode(auth_key).expect("Got an invalid salt from the server");
|
||||
// 签名
|
||||
let private_key = BotStatus::get_config().ica().private_key.clone();
|
||||
let private_key = MainStatus::global_config().ica().private_key.clone();
|
||||
|
||||
let array_key: [u8; 32] = hex::decode(private_key)
|
||||
.expect("Not a vaild pub key")
|
||||
.try_into()
|
||||
|
@ -158,6 +72,7 @@ pub async fn sign_callback(payload: Payload, client: Client) {
|
|||
let signing_key: SigningKey = SigningKey::from_bytes(&array_key);
|
||||
let signature: Signature = signing_key.sign(salt.as_slice());
|
||||
|
||||
// 发送签名
|
||||
let sign = signature.to_bytes().to_vec();
|
||||
client.emit("auth", sign).await.expect("Faild to send signin data");
|
||||
}
|
||||
|
|
|
@ -10,8 +10,7 @@ mod py;
|
|||
mod status;
|
||||
|
||||
use config::BotConfig;
|
||||
use tracing::info;
|
||||
|
||||
use tracing::{event, info, Level};
|
||||
|
||||
pub static mut MAIN_STATUS: status::BotStatus = status::BotStatus {
|
||||
config: None,
|
||||
|
@ -22,6 +21,8 @@ pub static mut MAIN_STATUS: status::BotStatus = status::BotStatus {
|
|||
pub type MainStatus = status::BotStatus;
|
||||
|
||||
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||
pub const ICA_VERSION: &str = "0.5.0";
|
||||
pub const MATRIX_VERSION: &str = "0.1.0";
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! wrap_callback {
|
||||
|
@ -40,13 +41,13 @@ macro_rules! wrap_any_callback {
|
|||
#[tokio::main]
|
||||
async fn main() {
|
||||
tracing_subscriber::fmt().with_max_level(tracing::Level::DEBUG).init();
|
||||
info!("ica-async-rs v{}", VERSION);
|
||||
event!(Level::INFO, "shenbot-async-rs v{} main", VERSION);
|
||||
|
||||
// 从命令行获取 host 和 key
|
||||
// 从命令行获取配置文件路径
|
||||
let bot_config = BotConfig::new_from_cli();
|
||||
ica::client::BotStatus::update_config(bot_config.clone());
|
||||
py::init_py(&bot_config);
|
||||
MainStatus::static_init(bot_config);
|
||||
let bot_config = MainStatus::global_config();
|
||||
|
||||
py::init_py();
|
||||
|
||||
// 准备一个用于停止 socket 的变量
|
||||
let (send, recv) = tokio::sync::oneshot::channel::<()>();
|
||||
|
|
|
@ -6,8 +6,8 @@ use tracing::{debug, info, warn};
|
|||
|
||||
use crate::data_struct::ica::messages::NewMessage;
|
||||
use crate::data_struct::ica::MessageId;
|
||||
use crate::ica::client::BotStatus;
|
||||
use crate::py::{class, PyPlugin, PyStatus};
|
||||
use crate::MainStatus;
|
||||
|
||||
pub fn get_func<'py>(py_module: &'py PyAny, path: &PathBuf, name: &'py str) -> Option<&'py PyAny> {
|
||||
// 要处理的情况:
|
||||
|
|
|
@ -8,8 +8,8 @@ use crate::data_struct::ica::messages::{
|
|||
DeleteMessage, MessageTrait, NewMessage, ReplyMessage, SendMessage,
|
||||
};
|
||||
use crate::data_struct::ica::MessageId;
|
||||
use crate::ica::client::{delete_message, send_message, BotStatus};
|
||||
use crate::ClientStatus_Global;
|
||||
use crate::ica::client::{delete_message, send_message};
|
||||
use crate::MainStatus;
|
||||
|
||||
#[pyclass]
|
||||
#[pyo3(name = "IcaStatus")]
|
||||
|
@ -20,37 +20,47 @@ impl IcaStatusPy {
|
|||
#[new]
|
||||
pub fn py_new() -> Self { Self {} }
|
||||
#[getter]
|
||||
pub fn get_login(&self) -> bool { unsafe { ClientStatus_Global.login } }
|
||||
pub fn get_qq_login(&self) -> bool { MainStatus::global_ica_status().qq_login }
|
||||
#[getter]
|
||||
pub fn get_online(&self) -> bool { BotStatus::get_online_data().online }
|
||||
pub fn get_online(&self) -> bool { MainStatus::global_ica_status().online_status.online }
|
||||
#[getter]
|
||||
pub fn get_self_id(&self) -> i64 { BotStatus::get_online_data().qqid }
|
||||
pub fn get_self_id(&self) -> i64 { MainStatus::global_ica_status().online_status.qqid }
|
||||
#[getter]
|
||||
pub fn get_nick_name(&self) -> String { BotStatus::get_online_data().nick.clone() }
|
||||
pub fn get_nick_name(&self) -> String {
|
||||
MainStatus::global_ica_status().online_status.nick.clone()
|
||||
}
|
||||
#[getter]
|
||||
pub fn get_loaded_messages_count(&self) -> u64 { BotStatus::get_loaded_messages_count() }
|
||||
pub fn get_loaded_messages_count(&self) -> u64 {
|
||||
MainStatus::global_ica_status().current_loaded_messages_count
|
||||
}
|
||||
#[getter]
|
||||
pub fn get_ica_version(&self) -> String {
|
||||
BotStatus::get_online_data().icalingua_info.ica_version.clone()
|
||||
MainStatus::global_ica_status().online_status.icalingua_info.ica_version.clone()
|
||||
}
|
||||
|
||||
#[getter]
|
||||
pub fn get_os_info(&self) -> String {
|
||||
BotStatus::get_online_data().icalingua_info.os_info.clone()
|
||||
MainStatus::global_ica_status().online_status.icalingua_info.os_info.clone()
|
||||
}
|
||||
|
||||
#[getter]
|
||||
pub fn get_resident_set_size(&self) -> String {
|
||||
BotStatus::get_online_data().icalingua_info.resident_set_size.clone()
|
||||
MainStatus::global_ica_status()
|
||||
.online_status
|
||||
.icalingua_info
|
||||
.resident_set_size
|
||||
.clone()
|
||||
}
|
||||
|
||||
#[getter]
|
||||
pub fn get_heap_used(&self) -> String {
|
||||
BotStatus::get_online_data().icalingua_info.heap_used.clone()
|
||||
MainStatus::global_ica_status().online_status.icalingua_info.heap_used.clone()
|
||||
}
|
||||
|
||||
#[getter]
|
||||
pub fn get_load(&self) -> String { BotStatus::get_online_data().icalingua_info.load.clone() }
|
||||
pub fn get_load(&self) -> String {
|
||||
MainStatus::global_ica_status().online_status.icalingua_info.load.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for IcaStatusPy {
|
||||
|
@ -197,6 +207,10 @@ impl IcaClientPy {
|
|||
pub fn get_status(&self) -> IcaStatusPy { IcaStatusPy::new() }
|
||||
#[getter]
|
||||
pub fn get_version(&self) -> String { crate::VERSION.to_string() }
|
||||
#[getter]
|
||||
pub fn get_ica_version(&self) -> String { crate::ICA_VERSION.to_string() }
|
||||
#[getter]
|
||||
pub fn get_matrix_version(&self) -> String { crate::MATRIX_VERSION.to_string() }
|
||||
|
||||
pub fn debug(&self, content: String) {
|
||||
debug!("{}", content);
|
||||
|
|
|
@ -7,10 +7,9 @@ use std::{collections::HashMap, path::PathBuf};
|
|||
|
||||
use pyo3::prelude::*;
|
||||
use pyo3::types::PyTuple;
|
||||
use tracing::{debug, info, warn};
|
||||
use tracing::{debug, info, span, warn, Level};
|
||||
|
||||
use crate::config::BotConfig;
|
||||
use crate::ica::client::BotStatus;
|
||||
use crate::MainStatus;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct PyStatus {
|
||||
|
@ -243,14 +242,20 @@ pub fn load_py_file(path: &PathBuf) -> std::io::Result<RawPyPlugin> {
|
|||
Ok((path.clone(), changed_time, content))
|
||||
}
|
||||
|
||||
pub fn init_py(config: &BotConfig) {
|
||||
/// Python 侧初始化
|
||||
pub fn init_py() {
|
||||
// 从 全局配置中获取 python 插件路径
|
||||
let span = span!(Level::INFO, "Init Python Plugin");
|
||||
let enter = span.enter();
|
||||
|
||||
let global_config = MainStatus::global_config().py();
|
||||
|
||||
debug!("initing python threads");
|
||||
pyo3::prepare_freethreaded_python();
|
||||
if let Some(plugin_path) = &config.py_plugin_path {
|
||||
let path = PathBuf::from(plugin_path);
|
||||
load_py_plugins(&path);
|
||||
debug!("python 插件列表: {:#?}", PyStatus::get_files());
|
||||
}
|
||||
|
||||
let path = PathBuf::from(global_config.plugin_path);
|
||||
load_py_plugins(&path);
|
||||
debug!("python 插件列表: {:#?}", PyStatus::get_files());
|
||||
|
||||
info!("python inited")
|
||||
}
|
||||
|
|
|
@ -1,15 +1,69 @@
|
|||
use crate::config::BotConfig;
|
||||
use crate::MAIN_STATUS;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct BotStatus {
|
||||
pub config: Option<BotConfig>,
|
||||
pub ica_status: Option<ica::MainStatus>,
|
||||
pub matrix_status: Option<matrix::MainStatus>,
|
||||
}
|
||||
|
||||
impl BotStatus {
|
||||
pub fn update_static_config(config: BotConfig) {
|
||||
unsafe {
|
||||
MAIN_STATUS.config = Some(config);
|
||||
}
|
||||
}
|
||||
pub fn update_ica_status(status: ica::MainStatus) {
|
||||
unsafe {
|
||||
MAIN_STATUS.ica_status = Some(status);
|
||||
}
|
||||
}
|
||||
pub fn update_matrix_status(status: matrix::MainStatus) {
|
||||
unsafe {
|
||||
MAIN_STATUS.matrix_status = Some(status);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn static_init(config: BotConfig) {
|
||||
unsafe {
|
||||
MAIN_STATUS.config = Some(config);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn global_config() -> &'static BotConfig { unsafe { MAIN_STATUS.config.as_ref().unwrap() } }
|
||||
pub fn global_ica_status() -> &'static ica::MainStatus {
|
||||
unsafe { MAIN_STATUS.ica_status.as_ref().unwrap() }
|
||||
}
|
||||
pub fn global_matrix_status() -> &'static matrix::MainStatus {
|
||||
unsafe { MAIN_STATUS.matrix_status.as_ref().unwrap() }
|
||||
}
|
||||
}
|
||||
|
||||
pub mod ica {
|
||||
pub struct MainStatus {}
|
||||
use crate::data_struct::ica::all_rooms::Room;
|
||||
use crate::data_struct::ica::online_data::OnlineData;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct MainStatus {
|
||||
/// 是否启用 ica
|
||||
pub enable: bool,
|
||||
/// qq 是否登录
|
||||
pub qq_login: bool,
|
||||
/// 当前已加载的消息数量
|
||||
pub current_loaded_messages_count: u64,
|
||||
/// 房间数据
|
||||
pub rooms: Vec<Room>,
|
||||
/// 在线数据 (Icalingua 信息)
|
||||
pub online_status: OnlineData,
|
||||
}
|
||||
}
|
||||
|
||||
pub mod matrix {
|
||||
pub struct MainStatus {}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct MainStatus {
|
||||
/// 是否启用 matrix
|
||||
pub enable: bool,
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user