Skip to content

Commit ec51343

Browse files
committed
plugin genshin_saying: create
1 parent a804934 commit ec51343

File tree

13 files changed

+439
-223
lines changed

13 files changed

+439
-223
lines changed

Cargo.lock

+213-175
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,4 @@ music_gen = { path = "../plugins/music_gen" }
3333
read = { path = "../plugins/read" }
3434
zxhdmx = { path = "../plugins/zxhdmx" }
3535
message_sender = { path = "../plugins/message_sender" }
36+
genshin_saying = { path = "../plugins/genshin_saying" }

app/src/main.rs

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ async fn main() {
3131
bot.add_plugin_static_register_hook(read::plugin_register);
3232
bot.add_plugin_static_register_hook(zxhdmx::plugin_register);
3333
bot.add_plugin_static_register_hook(message_sender::plugin_register);
34+
bot.add_plugin_static_register_hook(genshin_saying::plugin_register);
3435

3536
bot.init().await.expect("Failed to initialize bot.");
3637
bot.run().await.unwrap();

plugins/cats/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ clap = "2.34.0"
2323
regex = "1.5.4"
2424
lazy_static = "1.4.0"
2525
sha2 = "0.10.1"
26-
hmac = "0.12.0"
26+
hmac = "0.12.1"
2727
hex = "0.4.3"
2828
reqwest = "0.11.9"
2929
md5 = "0.7.0"

plugins/genshin_saying/Cargo.toml

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
[package]
2+
name = "genshin_saying"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7+
8+
[dependencies]
9+
countdown-bot3 = { path = "../../core" }
10+
async-trait = "0.1.52"
11+
# serde = "1.0.132"
12+
# reqwest = { version = "0.11.8"}
13+
# serde_json = "1.0.73"
14+
tokio = "1.15.0"
15+
# chrono = "0.4.19"
16+
log = "0.4.14"
17+
flexi_logger = "0.22.0"
18+
anyhow = "1.0.52"
19+
serde = "1.0.132"
20+
strfmt = "0.1.6"
21+
jieba-rs = "0.6.6"

plugins/genshin_saying/src/lib.rs

+140
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
use anyhow::anyhow;
2+
use async_trait::async_trait;
3+
use countdown_bot3::{
4+
countdown_bot::{
5+
bot,
6+
client::{CountdownBotClient, ResultType},
7+
command::{Command, SenderType},
8+
plugin::{BotPlugin, HookResult, PluginMeta},
9+
utils::load_config_or_save_default,
10+
},
11+
export_static_plugin,
12+
};
13+
use jieba_rs::Jieba;
14+
use log::{debug, error};
15+
use serde::{Deserialize, Serialize};
16+
use std::{collections::HashMap, sync::Arc};
17+
static PLUGIN_NAME: &str = "genshin_saying";
18+
19+
#[derive(Deserialize, Serialize)]
20+
pub struct GenshinSayingConfig {
21+
pub xamaran_template: String,
22+
}
23+
24+
impl Default for GenshinSayingConfig {
25+
fn default() -> Self {
26+
Self {
27+
xamaran_template: "今日{xx},明日{xx},百日之后{yy}中已不剩{yy},只剩{xx}。".into(),
28+
}
29+
}
30+
}
31+
32+
#[derive(Default)]
33+
struct GenshinSayingPlugin {
34+
client: Option<CountdownBotClient>,
35+
config: Option<GenshinSayingConfig>,
36+
jieba: Arc<Jieba>,
37+
}
38+
39+
#[async_trait]
40+
impl BotPlugin for GenshinSayingPlugin {
41+
fn on_enable(
42+
&mut self,
43+
bot: &mut bot::CountdownBot,
44+
_handle: tokio::runtime::Handle,
45+
) -> HookResult<()> {
46+
self.config = Some(load_config_or_save_default::<GenshinSayingConfig>(
47+
&bot.ensure_plugin_data_dir(PLUGIN_NAME)?,
48+
)?);
49+
bot.register_command(
50+
Command::new("xamaran")
51+
.description("生成赞玛兰风格语录: xamaran <xx> <yy>")
52+
.enable_all(),
53+
)?;
54+
bot.register_command(
55+
Command::new("neko")
56+
.description("生成寝子风格语录(对我、你等文字进行替换): neko <文本内容>")
57+
.enable_all(),
58+
)?;
59+
Ok(())
60+
}
61+
fn on_before_start(
62+
&mut self,
63+
_bot: &mut bot::CountdownBot,
64+
client: CountdownBotClient,
65+
) -> HookResult<()> {
66+
self.client = Some(client);
67+
Ok(())
68+
}
69+
fn get_meta(&self) -> PluginMeta {
70+
PluginMeta {
71+
author: String::from("officeyutong"),
72+
description: String::from("赞玛兰风格语录与寝子风格语录"),
73+
version: env!("CARGO_PKG_VERSION").to_string(),
74+
}
75+
}
76+
async fn on_command(
77+
&mut self,
78+
command: String,
79+
args: Vec<String>,
80+
sender: &SenderType,
81+
) -> Result<(), Box<dyn std::error::Error>> {
82+
match command.as_str() {
83+
"xamaran" => self.xamaran(&args, sender).await?,
84+
"neko" => self.neko(&args, sender).await?,
85+
_ => {}
86+
};
87+
Ok(())
88+
}
89+
}
90+
91+
impl GenshinSayingPlugin {
92+
async fn xamaran(&self, args: &Vec<String>, sender: &SenderType) -> ResultType<()> {
93+
let client = self.client.as_ref().unwrap();
94+
if let [x, y] = &args[..] {
95+
let cfg_str = self.config.as_ref().unwrap().xamaran_template.clone();
96+
let mut hmap = HashMap::<String, String>::new();
97+
hmap.insert("xx".into(), x.into());
98+
hmap.insert("yy".into(), y.into());
99+
100+
let result = strfmt::strfmt(&cfg_str, &hmap).map_err(|e| {
101+
error!("非法格式控制字符串 {}: {}", e, cfg_str);
102+
anyhow!("非法格式控制字符串!")
103+
})?;
104+
client.quick_send_by_sender(sender, &result).await?;
105+
return Ok(());
106+
} else {
107+
return Err(anyhow!("需要两个参数!").into());
108+
}
109+
}
110+
async fn neko(&self, args: &Vec<String>, sender: &SenderType) -> ResultType<()> {
111+
let text = args.join(" ");
112+
// let splitted =
113+
// let jieba = Jieba::new();
114+
debug!("Nekonize input: {:?}", text);
115+
let jieba = self.jieba.clone();
116+
let result: anyhow::Result<String> = tokio::task::spawn_blocking(move || {
117+
let words = jieba.cut(&text, false);
118+
debug!("Splitted words: {:?}", words);
119+
let result = words
120+
.iter()
121+
.map(|s| match *s {
122+
"我" => "奴家".into(),
123+
"你" => "汝等".into(),
124+
"。" => ",喵喵。".into(),
125+
t => t.to_string(),
126+
})
127+
.collect::<Vec<String>>()
128+
.join("");
129+
// words
130+
Ok(result)
131+
})
132+
.await?;
133+
let client = self.client.as_ref().unwrap();
134+
135+
client.quick_send_by_sender(sender, &result?).await?;
136+
return Ok(());
137+
}
138+
}
139+
140+
export_static_plugin!(PLUGIN_NAME, GenshinSayingPlugin::default());

plugins/zxhdmx/Cargo.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ flexi_logger = "0.22.0"
1414
anyhow = "1.0.52"
1515
serde = "1.0.132"
1616
serde_json = "1.0.73"
17-
rustpython-vm = { git = "https://github.com/RustPython/RustPython", features = ["freeze-stdlib"], rev = "bd295e0f" }
18-
rustpython-stdlib = { git = "https://github.com/RustPython/RustPython", rev = "bd295e0f" }
17+
rustpython-vm = { git = "https://github.com/RustPython/RustPython", features = ["freeze-stdlib"], rev = "49016b6a94e3c57bc6e26458f72fcb67191f7da4" }
18+
rustpython-stdlib = { git = "https://github.com/RustPython/RustPython", rev = "49016b6a94e3c57bc6e26458f72fcb67191f7da4" }
1919
futures = "0.3.19"
2020
num-bigint = "0.4.3"
2121
salvo = "0.16.8"

plugins/zxhdmx/src/handle_impl/command.rs

+21-15
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,3 @@
1-
use countdown_bot3::countdown_bot::client::{CountdownBotClient, ResultType};
2-
use log::debug;
3-
use pyvm::{
4-
builtins::{PyInt, PyModule, PyStr},
5-
function::{FuncArgs, IntoPyObject, KwArgs, PosArgs},
6-
PyMethod, PyRef, PyValue,
7-
};
8-
use rustpython_vm as pyvm;
9-
101
use crate::{
112
config::ZxhdmxConfig,
123
pytypes::{
@@ -16,6 +7,14 @@ use crate::{
167
utils::{check_player_in_game, transform_pyerr},
178
DataType, GameObjectType, InprType,
189
};
10+
use countdown_bot3::countdown_bot::client::{CountdownBotClient, ResultType};
11+
use log::debug;
12+
use pyvm::{
13+
builtins::{PyInt, PyModule},
14+
function::{FuncArgs, KwArgs, PosArgs, IntoPyObject},
15+
PyValue, PyRef,
16+
};
17+
use rustpython_vm as pyvm;
1918
pub fn handle_command(
2019
user_id: i64,
2120
group_id: i64,
@@ -36,9 +35,12 @@ pub fn handle_command(
3635
.unwrap()
3736
.enter(|vm| {
3837
let game_class = game_module.get_attr("Game", vm)?;
39-
let call_method =
40-
PyMethod::get(game_class, PyStr::from("__call__").into_ref(vm), vm)?;
41-
let obj = call_method.invoke(
38+
// vm.call_method(obj, method_name, args)
39+
// let call_method =
40+
// PyMethod::get(game_class, PyStr::from("__call__").into_ref(vm), vm)?;
41+
let obj = vm.call_method(
42+
&game_class,
43+
"__call__",
4244
FuncArgs::new(
4345
PosArgs::new(vec![
4446
WrappedCountdownBot::new((MyPyLogger {}).into_ref(vm), client.clone())
@@ -52,7 +54,6 @@ pub fn handle_command(
5254
]),
5355
KwArgs::default(),
5456
),
55-
vm,
5657
)?;
5758
return Ok(obj);
5859
})
@@ -68,13 +69,18 @@ pub fn handle_command(
6869
};
6970
py_inpr
7071
.enter(|vm| {
71-
PyMethod::get(game_inst, PyStr::from(method_name).into_ref(vm), vm)?.invoke(
72+
vm.call_method(
73+
&game_inst,
74+
method_name,
7275
FuncArgs::new(
7376
PosArgs::new(vec![PyInt::from(user_id).into_pyobject(vm)]),
7477
KwArgs::default(),
7578
),
76-
vm,
7779
)
80+
// PyMethod::get(game_inst, PyStr::from(method_name).into_ref(vm), vm)?.invoke(
81+
// ,
82+
// vm,
83+
// )
7884
})
7985
.map_err(transform_pyerr)?;
8086
return Ok(());

plugins/zxhdmx/src/handle_impl/event.rs

+6-8
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ use anyhow::anyhow;
77
use countdown_bot3::countdown_bot::client::{CountdownBotClient, ResultType};
88
use pyvm::{
99
builtins::{PyInt, PyStr},
10-
function::{FuncArgs, IntoPyObject, KwArgs},
11-
PyMethod, PyObjectRef, PyRef, PyValue, VirtualMachine,
10+
function::{FuncArgs, KwArgs, IntoPyObject},
11+
PyObjectRef, PyValue, PyRef, VirtualMachine,
1212
};
1313
use rustpython_vm as pyvm;
1414
pub fn handle_event(
@@ -154,9 +154,8 @@ fn quick_call<T>(
154154
where
155155
T: PyValue,
156156
{
157-
return PyMethod::get(obj, PyStr::from(func_name).into_ref(vm), vm)
158-
.map_err(transform_pyerr)?
159-
.invoke(FuncArgs::new(args, KwArgs::default()), vm)
157+
return vm
158+
.call_method(&obj, func_name, FuncArgs::new(args, KwArgs::default()))
160159
.map_err(transform_pyerr)?
161160
.downcast::<T>()
162161
.map_err(|_| anyhow!("Failed to perform type cast!"));
@@ -167,9 +166,8 @@ fn quick_call_no_ret(
167166
vm: &VirtualMachine,
168167
args: Vec<PyObjectRef>,
169168
) -> anyhow::Result<()> {
170-
return PyMethod::get(obj, PyStr::from(func_name).into_ref(vm), vm)
171-
.map_err(transform_pyerr)?
172-
.invoke(FuncArgs::new(args, KwArgs::default()), vm)
169+
return vm
170+
.call_method(&obj, func_name, FuncArgs::new(args, KwArgs::default()))
173171
.map_err(transform_pyerr)
174172
.map(|_| ());
175173
}

plugins/zxhdmx/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ use pytypes::{
3030
};
3131
use pyvm::{
3232
builtins::{PyBaseExceptionRef, PyModule},
33-
PyClassImpl, PyObjectRef, PyRef, PySettings,
33+
PyObjectRef, PyRef, PySettings, PyClassImpl,
3434
};
3535
use rustpython_vm as pyvm;
3636
use serde_json::Value;

plugins/zxhdmx/src/pytypes/wrapped_bot.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ use countdown_bot3::countdown_bot::client::CountdownBotClient;
22
use log::{debug, info};
33
use pyvm::{
44
builtins::{PyDict, PyDictRef, PyInt, PyIntRef, PyStr, PyStrRef},
5-
function::{IntoPyObject, KwArgs},
6-
pyclass, pyimpl, IntoPyRef, PyRef, PyResult, PyValue, VirtualMachine,
5+
function::{KwArgs, IntoPyObject},
6+
pyclass, pyimpl, PyValue, PyRef, PyResult, VirtualMachine, IntoPyRef,
77
};
88
use rustpython_vm as pyvm;
99
use std::fmt::Debug;

plugins/zxhdmx/src/pytypes/wrapped_plugin.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ use std::collections::HashMap;
22

33
use pyvm::{
44
builtins::{PyDict, PyDictRef, PyFunction, PyInt, PyIntRef, PyStr},
5-
function::{FuncArgs, IntoPyObject, KwArgs, PosArgs},
6-
pyclass, pyimpl, PyObjectRef, PyRef, PyResult, PyValue, VirtualMachine,
5+
function::{FuncArgs, KwArgs, PosArgs, IntoPyObject},
6+
pyclass, pyimpl, PyObjectRef, PyValue, PyRef, PyResult, VirtualMachine,
77
};
88
use rustpython_vm as pyvm;
99
use serde::{de::DeserializeOwned, Deserialize};

plugins/zxhdmx/src/utils.rs

+28-17
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
use anyhow::anyhow;
22
use countdown_bot3::countdown_bot::client::ResultType;
33
use num_bigint::BigInt;
4-
use pyvm::builtins::{PyInt, PyStr};
5-
use pyvm::function::{FuncArgs, IntoPyObject, KwArgs, PosArgs};
6-
use pyvm::{PyMethod, PyObjectRef, PyValue};
4+
use pyvm::builtins::PyInt;
5+
use pyvm::function::{FuncArgs, KwArgs, PosArgs, IntoPyObject};
6+
use pyvm::PyObjectRef;
77
use rustpython_vm as pyvm;
88
use rustpython_vm::builtins::PyBaseExceptionRef;
99
pub fn bigint_to_i64(bigint: &BigInt) -> i64 {
@@ -31,20 +31,31 @@ pub fn check_player_in_game(
3131
let pyintval = inpr
3232
.enter(|vm| {
3333
// pyvm::eval::eval(vm, source, scope, source_path)
34-
return Ok(PyMethod::get(
35-
game_inst.clone().get_attr("players", vm)?,
36-
PyStr::from("__contains__").into_ref(vm),
37-
vm,
38-
)?
39-
.invoke(
40-
FuncArgs::new(
41-
PosArgs::new(vec![PyInt::from(user_id).into_pyobject(vm)]),
42-
KwArgs::default(),
43-
),
44-
vm,
45-
)?
46-
.downcast::<PyInt>()
47-
.unwrap());
34+
return Ok(vm
35+
.call_method(
36+
&*game_inst.clone().get_attr("players", vm)?,
37+
"__contains__",
38+
FuncArgs::new(
39+
PosArgs::new(vec![PyInt::from(user_id).into_pyobject(vm)]),
40+
KwArgs::default(),
41+
),
42+
)?
43+
.downcast::<PyInt>()
44+
.unwrap());
45+
// return Ok(PyMethod::get(
46+
// game_inst.clone().get_attr("players", vm)?,
47+
// PyStr::from("__contains__").into_ref(vm),
48+
// vm,
49+
// )?
50+
// .invoke(
51+
// FuncArgs::new(
52+
// PosArgs::new(vec![PyInt::from(user_id).into_pyobject(vm)]),
53+
// KwArgs::default(),
54+
// ),
55+
// vm,
56+
// )?
57+
// .downcast::<PyInt>()
58+
// .unwrap());
4859
})
4960
.map_err(transform_pyerr)?;
5061
return Ok(bigint_to_i64(pyintval.as_bigint()) == 1);

0 commit comments

Comments
 (0)