From a592dc8d775cee7a2015bcb48febe78b14c3130c Mon Sep 17 00:00:00 2001 From: LaoLittle Date: Tue, 3 Jan 2023 21:41:06 +0800 Subject: [PATCH] update --- src/client/mod.rs | 4 ++++ src/config/login.rs | 8 ++++++++ src/config/mod.rs | 1 + src/config/plugin.rs | 13 +++++++++++++ src/plugin/ffi/mod.rs | 1 + src/plugin/ffi/rt.rs | 6 ------ src/plugin/ffi/string.rs | 20 ++++++++++++++++++++ src/plugin/mod.rs | 7 +++++-- src/service/login.rs | 15 +++++++++++++++ 9 files changed, 67 insertions(+), 8 deletions(-) create mode 100644 src/config/plugin.rs create mode 100644 src/plugin/ffi/string.rs diff --git a/src/client/mod.rs b/src/client/mod.rs index 56898b5..a583d84 100644 --- a/src/client/mod.rs +++ b/src/client/mod.rs @@ -110,6 +110,10 @@ impl Client { let id = client.id(); let mut reconnected = false; loop { + if !crate::service::login::auto_reconnect() { + return; + } + if client.network_status() == OFFLINE_STATUS as u8 { if reconnected { error!( diff --git a/src/config/login.rs b/src/config/login.rs index 9ea9e62..5fb9175 100644 --- a/src/config/login.rs +++ b/src/config/login.rs @@ -2,20 +2,28 @@ use serde::{Deserialize, Serialize}; pub const DEFAULT_CONFIG: &[u8] = include_bytes!("../../default_config/default_login_conf.toml"); +/// 登录配置 #[derive(Deserialize, Serialize, Debug, Default)] pub struct LoginConfig { + /// 默认登录协议 pub default_protocol: Protocol, + /// 是否自动重连 #[serde(default = "true_bool")] pub auto_reconnect: bool, + /// 所有配置进行登录的客户端 #[serde(rename = "client")] pub clients: Vec, } #[derive(Deserialize, Serialize, Debug)] pub struct ClientConfig { + /// 账号 pub account: i64, + /// 密码 pub password: Option, + /// 登录协议 pub protocol: Option, + /// 是否进行登录 #[serde(default = "true_bool")] pub auto_login: bool, } diff --git a/src/config/mod.rs b/src/config/mod.rs index 45a73f6..6f66de4 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -1,6 +1,7 @@ use std::path::{Path, PathBuf}; pub mod login; +pub mod plugin; const SERVICE_CONFIG_PATH: &str = "service"; diff --git a/src/config/plugin.rs b/src/config/plugin.rs new file mode 100644 index 0000000..808d142 --- /dev/null +++ b/src/config/plugin.rs @@ -0,0 +1,13 @@ +use serde::{Deserialize, Serialize}; + +/// 对插件产生错误的态度 +#[derive(Serialize, Deserialize, Default)] +pub enum FaultAttitude { + #[default] + /// 立即结束程序, 记录堆栈 + FastFault, + /// 忽略错误, 关闭产生错误的监听器, 记录堆栈 + /// + /// 可能导致内存泄露或其他问题 + Ignore, +} diff --git a/src/plugin/ffi/mod.rs b/src/plugin/ffi/mod.rs index 9b75265..583afd8 100644 --- a/src/plugin/ffi/mod.rs +++ b/src/plugin/ffi/mod.rs @@ -8,6 +8,7 @@ pub mod log; pub mod member; pub mod message; pub mod rt; +pub mod string; fn cast_ref<'a, T>(ptr: *const ()) -> &'a T { unsafe { &*(ptr as *const T) } diff --git a/src/plugin/ffi/rt.rs b/src/plugin/ffi/rt.rs index 378844f..dcf97f8 100644 --- a/src/plugin/ffi/rt.rs +++ b/src/plugin/ffi/rt.rs @@ -24,12 +24,6 @@ pub extern "C" fn plugin_manager_block_on( manager.async_runtime().block_on(future) } -pub extern "C" fn c_str_cvt(ptr: *const c_char) -> RustString { - let cstr = unsafe { CStr::from_ptr(ptr) }; - - cstr.to_string_lossy().to_string().into() -} - pub fn future_block_on(manager: *const (), future: F) -> F::Output where F: Future, diff --git a/src/plugin/ffi/string.rs b/src/plugin/ffi/string.rs new file mode 100644 index 0000000..88bd692 --- /dev/null +++ b/src/plugin/ffi/string.rs @@ -0,0 +1,20 @@ +use atri_ffi::{RustStr, RustString}; +use std::ffi::{c_char, CStr, CString}; +use std::ptr::null_mut; + +pub extern "C" fn rust_str_cvt(str: RustStr) -> *mut c_char { + let str = str.as_str(); + CString::new(str) + .map(CString::into_raw) + .unwrap_or(null_mut()) +} + +pub extern "C" fn c_str_cvt(ptr: *const c_char) -> RustString { + let cstr = unsafe { CStr::from_ptr(ptr) }; + + cstr.to_string_lossy().to_string().into() +} + +pub extern "C" fn rust_string_drop(str: RustString) { + drop(String::from(str)); +} diff --git a/src/plugin/mod.rs b/src/plugin/mod.rs index 9722000..2209726 100644 --- a/src/plugin/mod.rs +++ b/src/plugin/mod.rs @@ -1,6 +1,7 @@ mod ffi; -use crate::plugin::ffi::rt::{c_str_cvt, plugin_manager_block_on, plugin_manager_spawn}; +use crate::plugin::ffi::rt::{plugin_manager_block_on, plugin_manager_spawn}; +use crate::plugin::ffi::string::{c_str_cvt, rust_str_cvt, rust_string_drop}; use ffi::client::{ client_find_friend, client_find_group, client_get_friends, client_get_groups, client_get_id, client_get_list, client_get_nickname, find_client, @@ -148,6 +149,8 @@ pub extern "C" fn plugin_get_function(sig: u16) -> *const () { 30101 => message_chain_from_json, // ffi - 30500 => c_str_cvt, + 30500 => rust_str_cvt, + 30501 => c_str_cvt, + 30502 => rust_string_drop, } } diff --git a/src/service/login.rs b/src/service/login.rs index 5737a6f..1301fe6 100644 --- a/src/service/login.rs +++ b/src/service/login.rs @@ -1,5 +1,6 @@ use std::io; use std::path::Path; +use std::sync::atomic::{AtomicBool, Ordering}; use std::time::Duration; use rand::{thread_rng, Rng}; @@ -50,6 +51,10 @@ pub async fn login_clients() -> Result<(), RQError> { } }; + if login_conf.auto_reconnect { + set_auto_reconnect(true); + } + let clients_path = config::clients_dir_path(); if !clients_path.is_dir() { fs::create_dir(&clients_path).await?; @@ -169,3 +174,13 @@ async fn login_client( } } } + +static AUTO_RECONNECT: AtomicBool = AtomicBool::new(false); + +pub fn auto_reconnect() -> bool { + AUTO_RECONNECT.load(Ordering::Relaxed) +} + +pub fn set_auto_reconnect(s: bool) { + AUTO_RECONNECT.store(s, Ordering::Relaxed); +}