Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/super1207/redreply
Browse files Browse the repository at this point in the history
  • Loading branch information
super1207 committed Aug 12, 2024
2 parents 8a7d5af + e78d632 commit 1131427
Show file tree
Hide file tree
Showing 8 changed files with 172 additions and 18 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ sevenz-rust = "0.6.1"
jsonpath-rust = "0.7.0"
rusttype = "0.9.3"
# markdown = "1.0.0-alpha.7"
reqwest = {version = "0.12.5",default-features = false,features = ["native-tls-vendored","multipart"]}
reqwest = {version = "0.12.5",default-features = false,features = ["rustls-tls","multipart"]}
time = { version = "0.3.36", features = ["formatting", "macros"] }
# headless_chrome = {version="1.0.5",default-features = false}
webp = "0.3.0"
Expand Down
9 changes: 7 additions & 2 deletions docs/detailref/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -569,8 +569,6 @@ hellohellohellohellohello

X,Y都必须为非负整数,且Y**不能小于**X。

对于32位版本,X、Y最大支持32位二进制位,对于64位版本,X、Y最大支持64位二进制位。


### 闭包

Expand Down Expand Up @@ -1920,6 +1918,13 @@ return ""
返回语音字节集(mp3或wav),音色可以省略,也可以为`Xiaoyi`(女声)。


### 设置延迟触发

【设置延迟触发@<font color="red">关键词</font>@<font color="red">延迟时间(ms)</font>@<font color="red">传递数据</font>】

在<font color="red">延迟时间(ms)</font>后触发关键词为<font color="red">关键词</font>且触发方式为`延迟触发`的当前包脚本。平台相关的数据会被复制到被触发的脚本中,并且可使用【传递】命令取出<font color="red">传递数据</font>。


## 平台相关命令说明


Expand Down
5 changes: 3 additions & 2 deletions res/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,11 @@ <h1>红色问答 {{version}}</h1>
<option value="脚本错误">脚本错误</option>
<option value="群成员增加">群成员增加</option>
<option value="网络触发">网络触发</option>
<option value="内容过滤">内容过滤(测试中)</option>
<option value="内容过滤">内容过滤</option>
<option value="延迟触发">延迟触发</option>
</select>
<div v-if="(script_cffs != '框架初始化') && (script_cffs != '脚本错误') && (script_cffs != '群成员增加') && (script_cffs != '内容过滤')" class="input_div"><span>关键词:</span><input id="script_keyword" v-model="script_keyword"></input></div>
<select id="script_ppfs" v-model="script_ppfs" v-if="(script_cffs == '群聊触发') || (script_cffs == '私聊触发') || (script_cffs == '群、私聊触发') || (script_cffs == '网络触发')">
<select id="script_ppfs" v-model="script_ppfs" v-if="(script_cffs == '群聊触发') || (script_cffs == '私聊触发') || (script_cffs == '群、私聊触发') || (script_cffs == '网络触发') || (script_cffs == '延迟触发')">
<option disabled value="匹配方式">匹配方式</option>
<option value ="完全匹配">完全匹配</option>
<option value ="正则匹配">正则匹配</option>
Expand Down
2 changes: 1 addition & 1 deletion res/version.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.0.74
0.0.75
90 changes: 88 additions & 2 deletions src/cronevent/mod.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,25 @@
use std::thread;
use std::{cell::RefCell, collections::{HashMap, HashSet}, rc::Rc, sync::Arc, thread, time::SystemTime};

use chrono::TimeZone;

use crate::{read_code_cache, cqapi::cq_add_log_w};
use crate::{cqapi::cq_add_log_w, cqevent::is_key_match, read_code_cache, redlang::RedLang, RT_PTR};

// 【设置延迟触发@关键词@时间@传递数据】
#[derive(Clone,Debug)]
pub struct OneTimeRunStruct {
pub run_time:i64,
pub pkg_name:String,
pub flag:String,
pub sub_data:String,
pub data:HashMap<String, Arc<String>>,
}

lazy_static! {
static ref G_LAST_RUN_TIME:std::sync::Mutex<Option<i64>> = std::sync::Mutex::new(None);
pub static ref G_ONE_TIME_RUN:std::sync::Mutex<Vec<OneTimeRunStruct>> = std::sync::Mutex::new(vec![]);
}


fn get_script_info<'a>(script_json:&'a serde_json::Value) -> Result<(&'a str,&'a str,&'a str,&'a str,&'a str), Box<dyn std::error::Error>>{
let pkg_name_opt = script_json.get("pkg_name");
let mut pkg_name = "";
Expand All @@ -23,6 +34,22 @@ fn get_script_info<'a>(script_json:&'a serde_json::Value) -> Result<(&'a str,&'a
return Ok((keyword,cffs,code,name,pkg_name));
}

fn get_script_info2<'a>(script_json:&'a serde_json::Value) -> Result<(&'a str,&'a str,&'a str,&'a str,&'a str,&'a str), Box<dyn std::error::Error>>{
let pkg_name_opt = script_json.get("pkg_name");
let mut pkg_name = "";
if let Some(val) = pkg_name_opt {
pkg_name = val.as_str().ok_or("pkg_name不是字符串")?;
}
let name = script_json.get("name").ok_or("脚本中无name")?.as_str().ok_or("脚本中name不是str")?;
let node = script_json.get("content").ok_or("script.json文件缺少content字段")?;
let keyword = node.get("关键词").ok_or("脚本中无关键词")?.as_str().ok_or("脚本中关键词不是str")?;
let cffs = node.get("触发方式").ok_or("脚本中无触发方式")?.as_str().ok_or("脚本中触发方式不是str")?;
let code = node.get("code").ok_or("脚本中无code")?.as_str().ok_or("脚本中code不是str")?;
let ppfs = node.get("匹配方式").ok_or("脚本中无匹配方式")?.as_str().ok_or("脚本中匹配方式不是str")?;

return Ok((keyword,cffs,code,ppfs,name,pkg_name));
}

fn do_cron_event_t2() -> Result<i32, Box<dyn std::error::Error>> {


Expand Down Expand Up @@ -80,12 +107,71 @@ fn do_cron_event_t2() -> Result<i32, Box<dyn std::error::Error>> {
Ok(0)
}

fn do_timer_event_t2() -> Result<i32, Box<dyn std::error::Error>> {
let now_time = SystemTime::now().duration_since(std::time::UNIX_EPOCH)?.as_millis() as i64;
let mut run_vec = vec![];
{
let mut lk = G_ONE_TIME_RUN.lock().unwrap();
let mut can_run_index_vec = HashSet::<usize>::new();
for it in 0..lk.len() {
if lk[it].run_time <= now_time {
can_run_index_vec.insert(it);
}
}
for it in can_run_index_vec.iter() {
run_vec.push(lk[*it].clone());
}
let mut new_one_run_time = vec![];
for it in 0..lk.len() {
let index = it;
if !can_run_index_vec.contains(&index) {
new_one_run_time.push(lk[it].clone());
}
}
*lk = new_one_run_time;
}
// cq_add_log_w(&format!("{:?}",run_vec)).unwrap();
for it in &run_vec {
let script_json = read_code_cache()?;
for i in 0..script_json.as_array().ok_or("script.json文件不是数组格式")?.len(){
let (keyword,cffs,code,ppfs,name,pkg_name) = get_script_info2(&script_json[i])?;
if cffs == "延迟触发" && it.pkg_name == pkg_name{
let mut rl = RedLang::new();
if is_key_match(&mut rl,&ppfs,keyword,&it.flag)? {
let data = it.data.to_owned();
let sub_data = it.sub_data.to_owned();
let code = code.to_owned();
let name = name.to_owned();
let pkg_name_t = pkg_name.to_owned();
RT_PTR.spawn_blocking(move ||{
let mut rl = RedLang::new();
let exmap = data;
let code_t = code.to_owned();
let script_name_t = name.to_owned();
rl.exmap = Rc::new(RefCell::new(exmap.clone()));
rl.pkg_name = pkg_name_t.to_owned();
rl.script_name = script_name_t.to_owned();
rl.set_coremap("隐藏", &sub_data).unwrap();
if let Err(err) = crate::cqevent::do_script(&mut rl,&code_t) {
cq_add_log_w(&format!("{}",err)).unwrap();
}
});
}
}
}
}
Ok(0)
}

pub fn do_cron_event() -> Result<i32, Box<dyn std::error::Error>> {
thread::spawn(||{
loop {
if let Err(err) = do_cron_event_t2(){
cq_add_log_w(&err.to_string()).unwrap();
}
if let Err(err) = do_timer_event_t2(){
cq_add_log_w(&err.to_string()).unwrap();
}
let time_struct = core::time::Duration::from_millis(500);
std::thread::sleep(time_struct);
}
Expand Down
49 changes: 42 additions & 7 deletions src/redlang/cqexfun.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::{fs, collections::BTreeMap, path::{Path, PathBuf}, vec, str::FromStr, sync::Arc, thread, time::SystemTime};

use crate::{add_file_lock, cqapi::{cq_call_api, cq_get_app_directory1, cq_get_app_directory2}, del_file_lock, mytool::{cq_params_encode, cq_text_encode, read_json_str}, redlang::{get_const_val, get_temp_const_val, set_const_val, set_temp_const_val}, ScriptRelatMsg, CLEAR_UUID, G_INPUTSTREAM_VEC, G_SCRIPT_RELATE_MSG, PAGING_UUID};
use crate::{add_file_lock, cqapi::{cq_call_api, cq_get_app_directory1, cq_get_app_directory2}, del_file_lock, mytool::{cq_params_encode, cq_text_encode, read_json_str}, redlang::{get_const_val, get_temp_const_val, set_const_val, set_temp_const_val}, ScriptRelatMsg, CLEAR_UUID, G_INPUTSTREAM_VEC, G_QUIT_FLAG, G_SCRIPT_RELATE_MSG, PAGING_UUID};
use serde_json;
use super::{RedLang, exfun::do_json_parse};
use base64::{Engine as _, engine::{self, general_purpose}, alphabet};
Expand Down Expand Up @@ -707,7 +707,7 @@ pub fn init_cq_ex_fun_map() {
});
add_fun(vec!["输入流"],|self_t,params|{
let tm = self_t.get_param(params, 0)?;
let d = std::time::Duration::from_millis(tm.parse::<u64>().unwrap_or(15000));
let tm = tm.parse::<u64>().unwrap_or(15000);
let self_id = self_t.get_exmap("机器人ID");
let group_id = self_t.get_exmap("群ID");
let user_id = self_t.get_exmap("发送者ID");
Expand Down Expand Up @@ -740,8 +740,24 @@ pub fn init_cq_ex_fun_map() {
lk_vec.remove(pos);
}
});

let rv = rx.recv_timeout(d);
let mut tm = tm;
while tm > 1000 {
if *G_QUIT_FLAG.read().unwrap() == true {
return Err("输入流终止,因用户要求退出".into());
}
let rv = rx.recv_timeout(std::time::Duration::from_secs(1));
if let Ok(msg) = rv {
return Ok(Some(msg));
}
tm -= 1000;
}
if *G_QUIT_FLAG.read().unwrap() == true {
return Err("输入流终止,因用户要求退出".into());
}
let rv = rx.recv_timeout(std::time::Duration::from_millis(tm));
if let Ok(msg) = rv {
return Ok(Some(msg));
}
let mut ret_str = String::new();
if let Ok(msg) = rv {
ret_str = msg;
Expand All @@ -750,7 +766,7 @@ pub fn init_cq_ex_fun_map() {
});
add_fun(vec!["群输入流"],|self_t,params|{
let tm = self_t.get_param(params, 0)?;
let d = std::time::Duration::from_millis(tm.parse::<u64>().unwrap_or(15000));
let tm = tm.parse::<u64>().unwrap_or(15000);
let self_id = self_t.get_exmap("机器人ID");
let group_id = self_t.get_exmap("群ID");
let user_id = self_t.get_exmap("发送者ID");
Expand Down Expand Up @@ -783,9 +799,28 @@ pub fn init_cq_ex_fun_map() {
lk_vec.remove(pos);
}
});

let rv = rx.recv_timeout(d);
let mut ret_str = self_t.build_obj(BTreeMap::new());
let mut tm = tm;
while tm > 1000 {
if *G_QUIT_FLAG.read().unwrap() == true {
return Err("输入流终止,因用户要求退出".into());
}
let rv = rx.recv_timeout(std::time::Duration::from_secs(1));
if let Ok(msg) = rv {
let js:serde_json::Value = serde_json::from_str(&msg).unwrap();
let js_obj = js.as_object().unwrap();
let mut mp:BTreeMap::<String,String> = BTreeMap::new();
mp.insert("发送者ID".to_string(), js_obj["发送者ID"].as_str().unwrap().to_owned());
mp.insert("消息".to_string(), js_obj["消息"].as_str().unwrap().to_owned());
ret_str = self_t.build_obj(mp);
return Ok(Some(ret_str));
}
tm -= 1000;
}
if *G_QUIT_FLAG.read().unwrap() == true {
return Err("输入流终止,因用户要求退出".into());
}
let rv = rx.recv_timeout(std::time::Duration::from_millis(tm));
if let Ok(msg) = rv {
let js:serde_json::Value = serde_json::from_str(&msg).unwrap();
let js_obj = js.as_object().unwrap();
Expand Down
31 changes: 29 additions & 2 deletions src/redlang/exfun.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use super::RedLang;
use reqwest::header::HeaderName;
use reqwest::header::HeaderValue;
use std::io::Write;
use crate::{add_file_lock, cq_add_log_w, cqapi::{cq_add_log, get_tmp_dir}, del_file_lock, pyserver::call_py_block, redlang::get_random, G_DEFAULF_FONT, RT_PTR};
use crate::{add_file_lock, cq_add_log_w, cqapi::{cq_add_log, get_tmp_dir}, cronevent::{OneTimeRunStruct, G_ONE_TIME_RUN}, del_file_lock, pyserver::call_py_block, redlang::get_random, G_DEFAULF_FONT, G_QUIT_FLAG, RT_PTR};

use image::{AnimationDecoder, EncodableLayout, GenericImageView, ImageBuffer, ImageFormat, Rgba};
use imageproc::geometric_transformations::{Projection, warp_with, rotate_about_center};
Expand Down Expand Up @@ -627,7 +627,18 @@ pub fn init_ex_fun_map() {
return Ok(Some(self_t.build_bin(buf)));
});
add_fun(vec!["延时"],|self_t,params|{
let mill = self_t.get_param(params, 0)?.parse::<u64>()?;
let mut mill = self_t.get_param(params, 0)?.parse::<u64>()?;
while mill > 1000 {
let time_struct = core::time::Duration::from_secs(1);
std::thread::sleep(time_struct);
mill -= 1000;
if *G_QUIT_FLAG.read().unwrap() == true {
return Err("延时终止,因用户要求退出".into());
}
}
if *G_QUIT_FLAG.read().unwrap() == true {
return Err("延时终止,因用户要求退出".into());
}
let time_struct = core::time::Duration::from_millis(mill);
std::thread::sleep(time_struct);
return Ok(Some("".to_string()));
Expand Down Expand Up @@ -3564,6 +3575,22 @@ def red_out(sw):
}
return Ok(Some("".to_string()));
});
add_fun(vec!["设置延迟触发"],|self_t,params|{
// 【设置延迟触发@关键词@时间@传递数据】
let keyword = self_t.get_param(params, 0)?;
let mut tm = self_t.get_param(params, 1)?.parse::<i64>()?;
let subdata = self_t.get_param(params, 2)?;
let now_time = SystemTime::now().duration_since(std::time::UNIX_EPOCH)?.as_millis() as i64;
tm += now_time;
let mut lk = G_ONE_TIME_RUN.lock().unwrap();
lk.push(OneTimeRunStruct {
run_time: tm,
pkg_name: self_t.pkg_name.to_owned(),
flag: keyword,
sub_data: subdata,
data: (*self_t.exmap).borrow().clone() });
Ok(Some("".to_string()))
});
}


Expand Down
2 changes: 1 addition & 1 deletion src/redlang/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ pub struct RedLang {
xh_vec: Vec<[bool; 2]>, // 循环控制栈
params_vec: Vec<Vec<String>>, // 函数参数栈
fun_ret_vec: Vec<(bool,usize)>, // 记录函数是否返回,循环深度
pub exmap:Rc<RefCell<HashMap<String, Arc<String>>>>,
pub exmap:Rc<RefCell<HashMap<String, Arc<String>>>>, // 用于记录平台相关数据
xuhao: HashMap<String, usize>,
pub type_uuid:String,
pub pkg_name:String,
Expand Down

0 comments on commit 1131427

Please sign in to comment.