1use kovi::event::MessageEventTrait;
2use kovi::event::id::ID;
3use kovi::log::info;
4pub use kovi::tokio;
5use kovi::utils::{load_json_data, save_json_data};
6use kovi::{PluginBuilder as P, RuntimeBot};
7use serde::{Deserialize, Serialize};
8use serde_json::json;
9use std::path::PathBuf;
10use std::sync::{Arc, Mutex};
11use std::time::{SystemTime, UNIX_EPOCH};
12
13#[cfg(not(any(feature = "onebot", feature = "milky")))]
14compile_error!("请至少启用一个协议 feature: \"onebot\" 或 \"milky\"");
15
16#[cfg(all(feature = "onebot", feature = "milky"))]
17compile_error!("不能同时启用 onebot 和 milky feature");
18
19#[cfg(feature = "onebot")]
20use kovi_onebot::*;
21
22#[cfg(feature = "milky")]
23use kovi_milky::*;
24
25#[derive(Debug, Clone, Serialize, Deserialize)]
26struct Config {
27 today: Vec<ID>,
28 data_time: u64,
30 like_times: usize,
31 msg: Msg,
32}
33
34#[derive(Debug, Clone, Serialize, Deserialize)]
35struct Msg {
36 cmd: String,
37 like: String,
38 today: String,
39 do_not_like_you: String,
40}
41
42#[kovi::plugin]
43async fn main() {
44 let bot = P::get_runtime_bot();
45 let mut path = bot.get_data_path();
46 path.push("config.json");
47
48 let config: Config = {
49 let config: Config = serde_json::from_value(json!({
50 "today": [],
51 "data_time": 1,
52 "like_times": 10,
53 "msg": {
54 "cmd": "赞我",
55 "like": "已为你点赞10次",
56 "today": "今天赞过了,一边呆着去!",
57 "do_not_like_you": "就不给你点,略略略"
58 }
59 }))
60 .unwrap();
61
62 let mut config: Config = match load_json_data(config.clone(), &path) {
63 Ok(v) => v,
64 Err(e) => {
65 if let Some(_parse_error) = e.downcast_ref::<serde_json::Error>() {
67 save_json_data(&config, &path).unwrap();
68 config
69 } else {
70 panic!("{e}")
71 }
72 }
73 };
74 let now = SystemTime::now()
75 .duration_since(UNIX_EPOCH)
76 .unwrap()
77 .as_secs();
78 if config.data_time / 86400 != now / 86400 {
79 config.today = Vec::new();
80 config.data_time = now;
81 save_json_data(&config, &path).unwrap();
82 }
83 config
84 };
85
86 let msg = Arc::new(config.msg.clone());
87 let path = Arc::new(path);
88 let config_arc = Arc::new(Mutex::new(config));
89
90 use kovi::async_move;
91
92 P::on(async_move!(e; msg, bot, config_arc, path; {
93 on_msg_send_like(e, msg, bot, config_arc, path).await
94 }));
95
96 P::cron("0 0 * * *", move || {
113 let config_clone_for_reset = config_arc.clone();
114 let path = path.clone();
115 async move {
116 let mut config = config_clone_for_reset.lock().unwrap();
118 config.today.clear();
119 config.data_time = SystemTime::now()
120 .duration_since(UNIX_EPOCH)
121 .unwrap()
122 .as_secs();
123 info!("like插件正在清理");
124 save_json_data(&*config, &*path).unwrap();
125 }
126 })
127 .unwrap();
128}
129
130async fn on_msg_send_like(
131 e: Arc<MsgEvent>,
132 msg: Arc<Msg>,
133 bot: Arc<RuntimeBot>,
134 config_arc: Arc<Mutex<Config>>,
135 path: Arc<PathBuf>,
136) {
137 if e.borrow_text() != Some(&msg.cmd) {
138 return;
139 }
140
141 {
142 let config_lock = config_arc.lock().unwrap();
143
144 if config_lock.today.contains(&e.get_sender_id().to_id()) {
145 e.reply_and_quote(&msg.today);
146 return;
147 }
148 }
149
150 #[cfg(feature = "onebot")]
151 let res = bot
152 .send_like_return(*(e.get_sender_id().try_as_i64_or_panic()), 10)
153 .await;
154
155 #[cfg(feature = "milky")]
156 let res = {
157 bot.send_api_return(
158 "send_profile_like",
159 json!({
160 "user_id": e.get_sender_id().try_as_i64_or_panic(),
161 "count": 10
162 }),
163 )
164 .await
165 };
166
167 {
168 let mut config_lock = config_arc.lock().unwrap();
169
170 match res {
171 Ok(_) => {
172 e.reply_and_quote(&msg.like);
173 config_lock.today.push(e.get_sender_id().to_id());
174 save_json_data(&*config_lock, &*path).unwrap();
175 }
176 Err(_) => e.reply_and_quote(&msg.do_not_like_you),
177 };
178 }
179}