use kovi::event::MessageEventTrait;
use kovi::event::id::ID;
use kovi::log::info;
pub use kovi::tokio;
use kovi::utils::{load_json_data, save_json_data};
use kovi::{PluginBuilder as P, RuntimeBot};
use serde::{Deserialize, Serialize};
use serde_json::json;
use std::path::PathBuf;
use std::sync::{Arc, Mutex};
use std::time::{SystemTime, UNIX_EPOCH};
#[cfg(not(any(feature = "onebot", feature = "milky")))]
compile_error!("请至少启用一个协议 feature: \"onebot\" 或 \"milky\"");
#[cfg(all(feature = "onebot", feature = "milky"))]
compile_error!("不能同时启用 onebot 和 milky feature");
#[cfg(feature = "onebot")]
use kovi_onebot::*;
#[cfg(feature = "milky")]
use kovi_milky::*;
#[derive(Debug, Clone, Serialize, Deserialize)]
struct Config {
today: Vec<ID>,
data_time: u64,
like_times: usize,
msg: Msg,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
struct Msg {
cmd: String,
like: String,
today: String,
do_not_like_you: String,
}
#[kovi::plugin]
async fn main() {
let bot = P::get_runtime_bot();
let mut path = bot.get_data_path();
path.push("config.json");
let config: Config = {
let config: Config = serde_json::from_value(json!({
"today": [],
"data_time": 1,
"like_times": 10,
"msg": {
"cmd": "赞我",
"like": "已为你点赞10次",
"today": "今天赞过了,一边呆着去!",
"do_not_like_you": "就不给你点,略略略"
}
}))
.unwrap();
let mut config: Config = match load_json_data(config.clone(), &path) {
Ok(v) => v,
Err(e) => {
if let Some(_parse_error) = e.downcast_ref::<serde_json::Error>() {
save_json_data(&config, &path).unwrap();
config
} else {
panic!("{e}")
}
}
};
let now = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs();
if config.data_time / 86400 != now / 86400 {
config.today = Vec::new();
config.data_time = now;
save_json_data(&config, &path).unwrap();
}
config
};
let msg = Arc::new(config.msg.clone());
let path = Arc::new(path);
let config_arc = Arc::new(Mutex::new(config));
use kovi::async_move;
P::on(async_move!(e; msg, bot, config_arc, path; {
on_msg_send_like(e, msg, bot, config_arc, path).await
}));
P::cron("0 0 * * *", move || {
let config_clone_for_reset = config_arc.clone();
let path = path.clone();
async move {
let mut config = config_clone_for_reset.lock().unwrap();
config.today.clear();
config.data_time = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs();
info!("like插件正在清理");
save_json_data(&*config, &*path).unwrap();
}
})
.unwrap();
}
async fn on_msg_send_like(
e: Arc<MsgEvent>,
msg: Arc<Msg>,
bot: Arc<RuntimeBot>,
config_arc: Arc<Mutex<Config>>,
path: Arc<PathBuf>,
) {
if e.borrow_text() != Some(&msg.cmd) {
return;
}
{
let config_lock = config_arc.lock().unwrap();
if config_lock.today.contains(&e.get_sender_id().to_id()) {
e.reply_and_quote(&msg.today);
return;
}
}
#[cfg(feature = "onebot")]
let res = bot
.send_like_return(*(e.get_sender_id().try_as_i64_or_panic()), 10)
.await;
#[cfg(feature = "milky")]
let res = {
use kovi::bot::runtimebot::CanSendApi as _;
bot.send_api_return(
"send_profile_like",
json!({
"user_id": e.get_sender_id().try_as_i64_or_panic(),
"count": 10
}),
)
.await
};
{
let mut config_lock = config_arc.lock().unwrap();
match res {
Ok(_) => {
e.reply_and_quote(&msg.like);
config_lock.today.push(e.get_sender_id().to_id());
save_json_data(&*config_lock, &*path).unwrap();
}
Err(_) => e.reply_and_quote(&msg.do_not_like_you),
};
}
}