From 7209e8315937104201cc2c3340c448eb5a2f9ddc Mon Sep 17 00:00:00 2001 From: GuTaoZi Date: Tue, 21 Apr 2026 21:55:00 +0800 Subject: [PATCH] refactor(core): align runtime and utility helpers --- .clang-format | 2 +- src/bots/shinxbot.cpp | 28 ++--- src/bots/shinxbot.hpp | 34 ++---- src/bots/shinxbot_meta.cpp | 173 ++++++++++++++++----------- src/bots/shinxbot_module.cpp | 117 ++++++++++-------- src/bots/shinxbot_network.cpp | 6 +- src/bots/shinxbot_runtime.cpp | 48 +++----- src/dev_tools/inspector.cpp | 27 ++--- src/interfaces/bot.cpp | 26 ++-- src/main.cpp | 15 +-- src/meta_event/heartbeat.cpp | 21 ++-- src/utils/HTTP_connect.cpp | 159 +++++++++++++++++------- src/utils/command_utils.cpp | 33 ++--- src/utils/converter.cpp | 51 +++----- src/utils/file_utils.cpp | 40 +++---- src/utils/image_utils.cpp | 112 +++++++---------- src/utils/json_utils.cpp | 21 ++-- src/utils/log.cpp | 7 +- src/utils/meta_func/backup.cpp | 33 ++--- src/utils/meta_func/progress_bar.cpp | 22 ++-- src/utils/meta_func/timer.cpp | 42 ++++--- src/utils/meta_func/timer.h | 34 ++++++ src/utils/number.cpp | 39 ++---- src/utils/qq_utils.cpp | 42 +++---- src/utils/random.cpp | 12 +- src/utils/string_utils.cpp | 57 +++------ 26 files changed, 572 insertions(+), 629 deletions(-) create mode 100644 src/utils/meta_func/timer.h diff --git a/.clang-format b/.clang-format index 2ccc015..148e271 100644 --- a/.clang-format +++ b/.clang-format @@ -3,6 +3,6 @@ BasedOnStyle: llvm IndentWidth: 4 --- Language: Cpp -BreakBeforeBraces: Stroustrup +BreakBeforeBraces: Attach AccessModifierOffset: -4 diff --git a/src/bots/shinxbot.cpp b/src/bots/shinxbot.cpp index 2928c62..c778748 100644 --- a/src/bots/shinxbot.cpp +++ b/src/bots/shinxbot.cpp @@ -8,8 +8,7 @@ namespace fs = fs; // ===== Logging ===== -void shinxbot::refresh_log_stream() -{ +void shinxbot::refresh_log_stream() { std::time_t nt = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); tm tt = *std::localtime(&nt); @@ -35,22 +34,17 @@ void shinxbot::refresh_log_stream() } shinxbot::shinxbot(int recv_port, int send_port, const std::string &tk) - : bot(recv_port, send_port, tk) -{ -} + : bot(recv_port, send_port, tk) {} shinxbot::shinxbot(const Json::Value &J) - : bot(J["recv_port"].asInt(), J["send_port"].asInt(), J["token"].asString()) -{ -} + : bot(J["recv_port"].asInt(), J["send_port"].asInt(), + J["token"].asString()) {} -bool shinxbot::is_op(const userid_t a) const -{ +bool shinxbot::is_op(const userid_t a) const { return op_list.find(a) != op_list.end(); } // ===== Runtime logging and teardown ===== -void shinxbot::setlog(LOG type, std::string message) -{ +void shinxbot::setlog(LOG type, std::string message) { std::lock_guard lock(log_lock); std::time_t nt = @@ -69,15 +63,14 @@ void shinxbot::setlog(LOG type, std::string message) tt.tm_sec, LOG_name[type], message); if (type == LOG::ERROR) - fmt::print(stderr, formatted_message); + fmt::print(stderr, "{}", formatted_message); else - fmt::print(formatted_message); + fmt::print("{}", formatted_message); LOG_output[type] << formatted_message; LOG_output[type].flush(); } -void shinxbot::cq_send_all_op(const std::string &message) -{ +void shinxbot::cq_send_all_op(const std::string &message) { msg_meta conf = (msg_meta){"private", 0, 0, 0, this}; for (userid_t uid : op_list) { conf.user_id = uid; @@ -85,8 +78,7 @@ void shinxbot::cq_send_all_op(const std::string &message) } } -shinxbot::~shinxbot() -{ +shinxbot::~shinxbot() { if (this->mytimer != nullptr) { this->mytimer->timer_stop(); delete this->mytimer; diff --git a/src/bots/shinxbot.hpp b/src/bots/shinxbot.hpp index a311d9d..5b9544c 100644 --- a/src/bots/shinxbot.hpp +++ b/src/bots/shinxbot.hpp @@ -19,57 +19,45 @@ class blockItem { blockItem() : mode(true) {} blockItem(const std::set &blocklist, const std::set &whitelist, bool mode) - : blocklist(blocklist), whitelist(whitelist), mode(mode) - { - } - blockItem(const Json::Value &J) - { + : blocklist(blocklist), whitelist(whitelist), mode(mode) {} + blockItem(const Json::Value &J) { if (J.isMember("block") && J.isMember("white") && J.isMember("mode")) { parse_json_to_set(J["block"], blocklist); parse_json_to_set(J["white"], whitelist); mode = J["mode"].asBool(); - } - else { + } else { mode = true; } } - bool is_blocked(const std::string &message) - { + bool is_blocked(const std::string &message) { if (mode) { return blocklist.find(message) != blocklist.end(); - } - else { + } else { return whitelist.find(message) == whitelist.end(); } } - void add_block(const std::string &message) - { + void add_block(const std::string &message) { blocklist.insert(message); mode = true; } - void remove_block(const std::string &message) - { + void remove_block(const std::string &message) { blocklist.erase(message); mode = true; } - void add_white(const std::string &message) - { + void add_white(const std::string &message) { whitelist.insert(message); mode = false; } - void remove_white(const std::string &message) - { + void remove_white(const std::string &message) { whitelist.erase(message); mode = false; } - void clear() - { + void clear() { blocklist.clear(); whitelist.clear(); mode = true; } - Json::Value to_json() const - { + Json::Value to_json() const { Json::Value J; J["block"] = parse_set_to_json(blocklist); J["white"] = parse_set_to_json(whitelist); diff --git a/src/bots/shinxbot_meta.cpp b/src/bots/shinxbot_meta.cpp index f17cc78..0d698e7 100644 --- a/src/bots/shinxbot_meta.cpp +++ b/src/bots/shinxbot_meta.cpp @@ -1,5 +1,5 @@ -#include "shinxbot.hpp" #include "dynamic_lib.hpp" +#include "shinxbot.hpp" #include #include @@ -9,8 +9,7 @@ namespace fs = fs; -bool shinxbot::meta_func(std::string message, const msg_meta &conf) -{ +bool shinxbot::meta_func(std::string message, const msg_meta &conf) { std::string normalized = trim(message); const std::string at_me = "[CQ:at,qq=" + std::to_string(get_botqq()) + "]"; @@ -28,9 +27,8 @@ bool shinxbot::meta_func(std::string message, const msg_meta &conf) help_level_t help_level = help_level_t::public_only; if (conf.message_type == "private" && is_op(conf.user_id)) { help_level = help_level_t::bot_admin; - } - else if (conf.message_type == "group" && - is_group_op(conf.p, conf.group_id, conf.user_id)) { + } else if (conf.message_type == "group" && + is_group_op(conf.p, conf.group_id, conf.user_id)) { help_level = help_level_t::group_admin; } std::string help_message; @@ -127,8 +125,7 @@ bool shinxbot::meta_func(std::string message, const msg_meta &conf) std::string filepa = fs::absolute(oss.str()).string(); if (conf.message_type == "private") { send_file_private(conf.p, conf.user_id, filepa); - } - else { + } else { upload_file(conf.p, filepa, conf.group_id, "backup"); } return false; @@ -166,8 +163,7 @@ bool shinxbot::meta_func(std::string message, const msg_meta &conf) for (const auto &n : fn_names) { if (loaded_fn.find(n) != loaded_fn.end()) { loaded_fn_names.push_back(n); - } - else { + } else { unloaded_fn_names.push_back(n); } } @@ -177,8 +173,7 @@ bool shinxbot::meta_func(std::string message, const msg_meta &conf) for (const auto &n : ev_names) { if (loaded_ev.find(n) != loaded_ev.end()) { loaded_ev_names.push_back(n); - } - else { + } else { unloaded_ev_names.push_back(n); } } @@ -219,8 +214,7 @@ bool shinxbot::meta_func(std::string message, const msg_meta &conf) cq_send("已清除屏蔽功能", conf); save_blocklist(); return false; - } - else { + } else { return true; } }; @@ -235,8 +229,7 @@ bool shinxbot::meta_func(std::string message, const msg_meta &conf) cq_send("已添加屏蔽功能", conf); save_blocklist(); return false; - } - else { + } else { return true; } }; @@ -251,8 +244,7 @@ bool shinxbot::meta_func(std::string message, const msg_meta &conf) cq_send("已移除屏蔽功能", conf); save_blocklist(); return false; - } - else { + } else { return true; } }; @@ -267,8 +259,7 @@ bool shinxbot::meta_func(std::string message, const msg_meta &conf) cq_send("已添加白名单功能", conf); save_blocklist(); return false; - } - else { + } else { return true; } }; @@ -283,8 +274,7 @@ bool shinxbot::meta_func(std::string message, const msg_meta &conf) cq_send("已移除白名单功能", conf); save_blocklist(); return false; - } - else { + } else { return true; } }; @@ -296,13 +286,17 @@ bool shinxbot::meta_func(std::string message, const msg_meta &conf) normalized = normalized.substr(17); size_t pos = normalized.find(' '); if (pos == std::string::npos) { - cq_send("命令格式错误,正确格式:bot.module.clone [alias] [git address]", conf); + cq_send("命令格式错误,正确格式:bot.module.clone [alias] [git " + "address]", + conf); return true; } std::string alias = trim(normalized.substr(0, pos)); std::string git_addr = trim(normalized.substr(pos + 1)); if (alias.empty() || git_addr.empty()) { - cq_send("命令格式错误,正确格式:bot.module.clone [alias] [git address]", conf); + cq_send("命令格式错误,正确格式:bot.module.clone [alias] [git " + "address]", + conf); return true; } std::string plugin_path = "./plugins/" + alias; @@ -315,7 +309,8 @@ bool shinxbot::meta_func(std::string message, const msg_meta &conf) if (result != 0) { cq_send("更新失败,请检查网络连接和仓库状态", conf); } - cmd = "git -C " + plugin_path + " submodule update --init --recursive"; + cmd = "git -C " + plugin_path + + " submodule update --init --recursive"; setlog(LOG::INFO, "执行命令:" + cmd); result = system(cmd.c_str()); if (result != 0) { @@ -327,7 +322,8 @@ bool shinxbot::meta_func(std::string message, const msg_meta &conf) } else { fs::create_directories(plugin_path); // clone with submodules - std::string cmd = "git clone --recurse-submodules " + git_addr + " " + plugin_path; + std::string cmd = "git clone --recurse-submodules " + git_addr + + " " + plugin_path; setlog(LOG::INFO, "执行命令:" + cmd); int result = system(cmd.c_str()); if (result != 0) { @@ -345,14 +341,18 @@ bool shinxbot::meta_func(std::string message, const msg_meta &conf) std::istringstream iss(normalized); std::string alias, type, name; if (!(iss >> alias >> type >> name)) { - cq_send("命令格式错误,正确格式:bot.module.compile_and_load [alias] [functions/events/all] [name]", conf); + cq_send("命令格式错误,正确格式:bot.module.compile_and_load " + "[alias] [functions/events/all] [name]", + conf); return true; } alias = trim(alias); type = trim(type); name = trim(name); if (alias.empty() || type.empty() || (name.empty() && type != "all")) { - cq_send("命令格式错误,正确格式:bot.module.compile_and_load [alias] [functions/events/all] [name]", conf); + cq_send("命令格式错误,正确格式:bot.module.compile_and_load " + "[alias] [functions/events/all] [name]", + conf); return true; } std::string plugin_path = "./plugins/" + alias; @@ -360,24 +360,33 @@ bool shinxbot::meta_func(std::string message, const msg_meta &conf) cq_send("别名不存在", conf); return true; } - auto compile_and_load = [&](const std::string &type, const std::string &name) { + auto compile_and_load = [&](const std::string &type, + const std::string &name) { // use cmake to compile // function path: ./plugins/[alias]/[type]/[name]/ // output path: ./plugins/[alias]/lib/[type]/[name].so std::string source_path = plugin_path + "/" + type + "/" + name; - std::string output_path = plugin_path + "/lib/" + type + "/lib" + name + ".so"; + std::string output_path = + plugin_path + "/lib/" + type + "/lib" + name + ".so"; if (!fs::exists(source_path)) { - cq_send(fmt::format("{}/{}/{}: 源文件不存在", plugin_path, type, name), conf); + cq_send(fmt::format("{}/{}/{}: 源文件不存在", plugin_path, type, + name), + conf); return false; } std::string cmake_path = source_path + "/CMakeLists.txt"; if (!fs::exists(cmake_path)) { // 执行 cd source_path/.. && python3 generate_cmake.py - std::string cmd = "cd " + source_path + "/.. && python3 generate_cmake.py"; + std::string cmd = + "cd " + source_path + "/.. && python3 generate_cmake.py"; setlog(LOG::INFO, "执行命令:" + cmd); int result = system(cmd.c_str()); if (result != 0) { - cq_send(fmt::format("{}/{}/{}: 生成CMakeLists.txt失败,请检查源文件", plugin_path, type, name), conf); + cq_send( + fmt::format( + "{}/{}/{}: 生成CMakeLists.txt失败,请检查源文件", + plugin_path, type, name), + conf); return true; } } @@ -387,18 +396,24 @@ bool shinxbot::meta_func(std::string message, const msg_meta &conf) setlog(LOG::INFO, "执行命令:" + cmd); int result = system(cmd.c_str()); if (result != 0) { - cq_send(fmt::format("{}/{}/{}: cmake配置失败,请检查源文件", plugin_path, type, name), conf); + cq_send(fmt::format("{}/{}/{}: cmake配置失败,请检查源文件", + plugin_path, type, name), + conf); return false; } cmd = "cmake --build " + build_path + " --config Release"; setlog(LOG::INFO, "执行命令:" + cmd); result = system(cmd.c_str()); if (result != 0) { - cq_send(fmt::format("{}/{}/{}: 编译失败,请检查源文件", plugin_path, type, name), conf); + cq_send(fmt::format("{}/{}/{}: 编译失败,请检查源文件", + plugin_path, type, name), + conf); return false; } if (!fs::exists(output_path)) { - cq_send(fmt::format("{}/{}/{}: 编译成功,但未找到输出文件", plugin_path, type, name), conf); + cq_send(fmt::format("{}/{}/{}: 编译成功,但未找到输出文件", + plugin_path, type, name), + conf); return false; } // load module @@ -420,21 +435,25 @@ bool shinxbot::meta_func(std::string message, const msg_meta &conf) fs::copy_file(output_path, dest_path); auto u = load_function(dest_path); if (u.first != nullptr) { - functions.push_back(std::make_tuple(u.first, u.second, name)); + functions.push_back( + std::make_tuple(u.first, u.second, name)); init_func(name, u.first); if (already_loaded) { - cq_send(fmt::format("{}/{}/{}: 编译并重新加载成功", plugin_path, type, name), conf); + cq_send(fmt::format("{}/{}/{}: 编译并重新加载成功", + plugin_path, type, name), + conf); + } else { + cq_send(fmt::format("{}/{}/{}: 编译并加载成功", + plugin_path, type, name), + conf); } - else { - cq_send(fmt::format("{}/{}/{}: 编译并加载成功", plugin_path, type, name), conf); - } - } - else { - cq_send(fmt::format("{}/{}/{}: 编译成功,但加载失败", plugin_path, type, name), conf); + } else { + cq_send(fmt::format("{}/{}/{}: 编译成功,但加载失败", + plugin_path, type, name), + conf); return false; } - } - else if (type == "events") { + } else if (type == "events") { add_module_to_filter(name, true); std::string dest_path = "./lib/events/lib" + name + ".so"; bool already_loaded = false; @@ -455,18 +474,24 @@ bool shinxbot::meta_func(std::string message, const msg_meta &conf) events.push_back(std::make_tuple(u.first, u.second, name)); init_func(name, u.first); if (already_loaded) { - cq_send(fmt::format("{}/{}/{}: 编译并重新加载成功", plugin_path, type, name), conf); - } - else { - cq_send(fmt::format("{}/{}/{}: 编译并加载成功", plugin_path, type, name), conf); + cq_send(fmt::format("{}/{}/{}: 编译并重新加载成功", + plugin_path, type, name), + conf); + } else { + cq_send(fmt::format("{}/{}/{}: 编译并加载成功", + plugin_path, type, name), + conf); } - } - else { - cq_send(fmt::format("{}/{}/{}: 编译成功,但加载失败", plugin_path, type, name), conf); + } else { + cq_send(fmt::format("{}/{}/{}: 编译成功,但加载失败", + plugin_path, type, name), + conf); return false; } } else { - cq_send("命令格式错误,正确格式:bot.module.compile_and_load [alias] [functions/events/all] [name]", conf); + cq_send("命令格式错误,正确格式:bot.module.compile_and_load " + "[alias] [functions/events/all] [name]", + conf); return false; } return true; @@ -474,20 +499,21 @@ bool shinxbot::meta_func(std::string message, const msg_meta &conf) if (type == "functions") { compile_and_load("functions", name); - } - else if (type == "events") { + } else if (type == "events") { compile_and_load("events", name); - } - else if (type == "all") { + } else if (type == "all") { // all plugin in functions/events path std::string function_path = plugin_path + "/functions/"; std::string event_path = plugin_path + "/events/"; if (fs::exists(function_path)) { - for (const auto &entry : fs::directory_iterator(function_path)) { + for (const auto &entry : + fs::directory_iterator(function_path)) { if (entry.is_directory()) { std::string name = entry.path().filename().string(); if (!compile_and_load("functions", name)) { - cq_send(fmt::format("function {} 编译加载失败", name), conf); + cq_send( + fmt::format("function {} 编译加载失败", name), + conf); } } } @@ -497,14 +523,16 @@ bool shinxbot::meta_func(std::string message, const msg_meta &conf) if (entry.is_directory()) { std::string name = entry.path().filename().string(); if (!compile_and_load("events", name)) { - cq_send(fmt::format("event {} 编译加载失败", name), conf); + cq_send(fmt::format("event {} 编译加载失败", name), + conf); } } } } - } - else { - cq_send("命令格式错误,正确格式:bot.module.compile_and_load [alias] [functions/events/all] [name]", conf); + } else { + cq_send("命令格式错误,正确格式:bot.module.compile_and_load " + "[alias] [functions/events/all] [name]", + conf); } return true; }; @@ -546,8 +574,9 @@ bool shinxbot::meta_func(std::string message, const msg_meta &conf) {"bot.list_alias", handle_bot_list_alias, {require_op}}, {"bot.progress", handle_bot_progress, {}}, {"bot.blockclear", handle_group_blockclear, {require_group_at_bot}}, - {"bot.module.list", handle_module_list, {require_group_at_bot_or_private, require_op}} - }; + {"bot.module.list", + handle_module_list, + {require_group_at_bot_or_private, require_op}}}; const std::vector prefix_rules = { {"bot.load", @@ -563,9 +592,12 @@ bool shinxbot::meta_func(std::string message, const msg_meta &conf) {"bot.unblock ", handle_group_unblock, {require_group_at_bot}}, {"bot.white ", handle_group_white, {require_group_at_bot}}, {"bot.unwhite ", handle_group_unwhite, {require_group_at_bot}}, - {"bot.module.clone ", handle_module_clone, {require_group_at_bot_or_private, require_op}}, - {"bot.module.compile_and_load ", handle_module_compile_and_load, {require_group_at_bot_or_private, require_op}} - }; + {"bot.module.clone ", + handle_module_clone, + {require_group_at_bot_or_private, require_op}}, + {"bot.module.compile_and_load ", + handle_module_compile_and_load, + {require_group_at_bot_or_private, require_op}}}; bool handled = false; const bool route_result = @@ -577,8 +609,7 @@ bool shinxbot::meta_func(std::string message, const msg_meta &conf) return true; } -void shinxbot::save_blocklist() -{ +void shinxbot::save_blocklist() { Json::Value J_block; for (const auto &pair : group_blocklist) { groupid_t gid = pair.first; diff --git a/src/bots/shinxbot_module.cpp b/src/bots/shinxbot_module.cpp index 5f44a94..b18b33c 100644 --- a/src/bots/shinxbot_module.cpp +++ b/src/bots/shinxbot_module.cpp @@ -7,8 +7,7 @@ namespace fs = fs; -template void close_dl(void *handle, T *p) -{ +template void close_dl(void *handle, T *p) { typedef void (*close_t)(T *); close_t closex = reinterpret_cast(dlsym(handle, "destroy_t")); const char *dlsym_error = dlerror(); @@ -17,31 +16,27 @@ template void close_dl(void *handle, T *p) std::string("Cannot load symbol 'destroy_t': ") + dlsym_error); // delete p; // This is not always safe - } - else { + } else { closex(p); } dlclose(handle); } -void shinxbot::unload_func(std::tuple &f) -{ +void shinxbot::unload_func(std::tuple &f) { this->mytimer->remove_callback(std::get<2>(f)); this->archive->remove_path(std::get<2>(f)); close_dl(std::get<1>(f), std::get<0>(f)); } -void shinxbot::unload_func(std::tuple &f) -{ +void shinxbot::unload_func(std::tuple &f) { this->mytimer->remove_callback(std::get<2>(f)); this->archive->remove_path(std::get<2>(f)); close_dl(std::get<1>(f), std::get<0>(f)); } -void shinxbot::init_func(const std::string &name, processable *p) -{ - p->set_callback([&](std::function func) { +void shinxbot::init_func(const std::string &name, processable *p) { + p->set_callback([this, name](std::function func) { this->mytimer->add_callback(name, func); }); p->set_backup_files(this->archive, name); @@ -49,8 +44,7 @@ void shinxbot::init_func(const std::string &name, processable *p) void shinxbot::init_func(const std::string &name, eventprocess *p) {} -void shinxbot::load_module_filter_config() -{ +void shinxbot::load_module_filter_config() { const std::string cfg_path = bot_config_path(this, "core/module_load.json"); const bool cfg_exists = fs::exists(cfg_path); Json::Value J = string_to_json(readfile(cfg_path, "{}")); @@ -65,8 +59,7 @@ void shinxbot::load_module_filter_config() if (has_functions) { parse_json_to_set(J["functions"], enabled_functions); - } - else { + } else { auto fn_names = list_available_module_names(false); enabled_functions = std::set(fn_names.begin(), fn_names.end()); @@ -75,25 +68,23 @@ void shinxbot::load_module_filter_config() if (has_events) { parse_json_to_set(J["events"], enabled_events); - } - else { + } else { auto ev_names = list_available_module_names(true); - enabled_events = std::set(ev_names.begin(), ev_names.end()); + enabled_events = + std::set(ev_names.begin(), ev_names.end()); changed = true; } if (!cfg_exists || changed) { save_module_filter_config(); - set_global_log( - LOG::INFO, - "Initialized/updated module_load.json: functions=" + - std::to_string(enabled_functions.size()) + - ", events=" + std::to_string(enabled_events.size())); + set_global_log(LOG::INFO, + "Initialized/updated module_load.json: functions=" + + std::to_string(enabled_functions.size()) + + ", events=" + std::to_string(enabled_events.size())); } } -void shinxbot::save_module_filter_config() const -{ +void shinxbot::save_module_filter_config() const { Json::Value J(Json::objectValue); J["functions"] = parse_set_to_json(enabled_functions); J["events"] = parse_set_to_json(enabled_events); @@ -101,31 +92,27 @@ void shinxbot::save_module_filter_config() const J.toStyledString()); } -void shinxbot::add_module_to_filter(const std::string &name, bool is_event) -{ +void shinxbot::add_module_to_filter(const std::string &name, bool is_event) { if (is_event) { enabled_events.insert(name); - } - else { + } else { enabled_functions.insert(name); } save_module_filter_config(); } -void shinxbot::remove_module_from_filter(const std::string &name, bool is_event) -{ +void shinxbot::remove_module_from_filter(const std::string &name, + bool is_event) { if (is_event) { enabled_events.erase(name); - } - else { + } else { enabled_functions.erase(name); } save_module_filter_config(); } std::vector -shinxbot::list_available_module_names(bool is_event) const -{ +shinxbot::list_available_module_names(bool is_event) const { std::vector names; const fs::path dir = is_event ? fs::path("./lib/events/") : fs::path("./lib/functions/"); @@ -157,8 +144,8 @@ shinxbot::list_available_module_names(bool is_event) const return names; } -bool shinxbot::handle_bot_load(const std::string &message, const msg_meta &conf) -{ +bool shinxbot::handle_bot_load(const std::string &message, + const msg_meta &conf) { std::istringstream iss(message.substr(8)); std::ostringstream oss; std::string type, name; @@ -192,6 +179,11 @@ bool shinxbot::handle_bot_load(const std::string &message, const msg_meta &conf) bool found_loaded = false; for (size_t i = 0; i < functions.size(); ++i) { if (std::get<2>(functions[i]) == n) { + const bool restart_timer = (this->mytimer != nullptr && + this->mytimer->is_running()); + if (restart_timer) { + this->mytimer->timer_stop(); + } unload_func(functions[i]); auto u = load_function("./lib/functions/lib" + @@ -202,11 +194,13 @@ bool shinxbot::handle_bot_load(const std::string &message, const msg_meta &conf) init_func(n, u.first); add_module_to_filter(n, false); oss << "reload " << n << std::endl; - } - else { + } else { functions.erase(functions.begin() + i); oss << "load " << n << " failed" << std::endl; } + if (restart_timer) { + this->mytimer->timer_start(); + } found_loaded = true; break; } @@ -220,8 +214,7 @@ bool shinxbot::handle_bot_load(const std::string &message, const msg_meta &conf) init_func(n, u.first); add_module_to_filter(n, false); oss << "load " << n << std::endl; - } - else { + } else { oss << "load " << n << " failed" << std::endl; } } @@ -243,6 +236,11 @@ bool shinxbot::handle_bot_load(const std::string &message, const msg_meta &conf) bool found_loaded = false; for (size_t i = 0; i < events.size(); ++i) { if (std::get<2>(events[i]) == n) { + const bool restart_timer = (this->mytimer != nullptr && + this->mytimer->is_running()); + if (restart_timer) { + this->mytimer->timer_stop(); + } unload_func(events[i]); auto u = load_function("./lib/events/lib" + @@ -253,11 +251,13 @@ bool shinxbot::handle_bot_load(const std::string &message, const msg_meta &conf) init_func(n, u.first); add_module_to_filter(n, true); oss << "reload " << n << std::endl; - } - else { + } else { events.erase(events.begin() + i); oss << "load " << n << " failed" << std::endl; } + if (restart_timer) { + this->mytimer->timer_start(); + } found_loaded = true; break; } @@ -271,8 +271,7 @@ bool shinxbot::handle_bot_load(const std::string &message, const msg_meta &conf) init_func(n, u.first); add_module_to_filter(n, true); oss << "load " << n << std::endl; - } - else { + } else { oss << "load " << n << " failed" << std::endl; } } @@ -286,8 +285,7 @@ bool shinxbot::handle_bot_load(const std::string &message, const msg_meta &conf) } bool shinxbot::handle_bot_unload(const std::string &message, - const msg_meta &conf) -{ + const msg_meta &conf) { std::istringstream iss(message.substr(10)); std::ostringstream oss; std::string type, name; @@ -308,8 +306,16 @@ bool shinxbot::handle_bot_unload(const std::string &message, bool flg = true; for (size_t i = 0; i < functions.size(); ++i) { if (std::get<2>(functions[i]) == n) { + const bool restart_timer = (this->mytimer != nullptr && + this->mytimer->is_running()); + if (restart_timer) { + this->mytimer->timer_stop(); + } unload_func(functions[i]); functions.erase(functions.begin() + i); + if (restart_timer) { + this->mytimer->timer_start(); + } oss << "unload " << n << std::endl; flg = false; break; @@ -330,8 +336,16 @@ bool shinxbot::handle_bot_unload(const std::string &message, bool flg = true; for (size_t i = 0; i < events.size(); ++i) { if (std::get<2>(events[i]) == n) { + const bool restart_timer = (this->mytimer != nullptr && + this->mytimer->is_running()); + if (restart_timer) { + this->mytimer->timer_stop(); + } unload_func(events[i]); events.erase(events.begin() + i); + if (restart_timer) { + this->mytimer->timer_start(); + } oss << "unload " << n << std::endl; flg = false; break; @@ -352,8 +366,7 @@ bool shinxbot::handle_bot_unload(const std::string &message, } bool shinxbot::handle_bot_reload(const std::string &message, - const msg_meta &conf) -{ + const msg_meta &conf) { std::istringstream iss(message.substr(10)); std::ostringstream oss; std::string type; @@ -379,15 +392,13 @@ bool shinxbot::handle_bot_reload(const std::string &message, bool ok = false; try { ok = func->reload(conf); - } - catch (...) { + } catch (...) { ok = false; } if (ok) { oss << "reload " << alias << " ok" << std::endl; - } - else { + } else { oss << "reload " << alias << " skipped (stateless or unsupported)" << std::endl; } diff --git a/src/bots/shinxbot_network.cpp b/src/bots/shinxbot_network.cpp index 5b00f58..7a96d72 100644 --- a/src/bots/shinxbot_network.cpp +++ b/src/bots/shinxbot_network.cpp @@ -4,8 +4,7 @@ #include #include -int shinxbot::start_server() -{ +int shinxbot::start_server() { httplib::Server svr; svr.Post("/", [&](const httplib::Request &req, httplib::Response &res) { @@ -15,6 +14,7 @@ int shinxbot::start_server() res.set_content("{}", "application/json"); }); - set_global_log(LOG::INFO, fmt::format("Server is starting on port {}...", receive_port)); + set_global_log(LOG::INFO, fmt::format("Server is starting on port {}...", + receive_port)); return svr.listen("0.0.0.0", receive_port); } diff --git a/src/bots/shinxbot_runtime.cpp b/src/bots/shinxbot_runtime.cpp index 91d96d1..5b3cef9 100644 --- a/src/bots/shinxbot_runtime.cpp +++ b/src/bots/shinxbot_runtime.cpp @@ -7,15 +7,13 @@ namespace fs = fs; -void shinxbot::init() -{ +void shinxbot::init() { for (;;) { try { Json::Value J = string_to_json(cq_get("get_login_info")); botqq = J["data"]["user_id"].asUInt64(); break; - } - catch (...) { + } catch (...) { } sleep(10); // 10 sec } @@ -54,8 +52,7 @@ void shinxbot::init() this->archive->set_default_pwd(std::to_string(this->botqq)); } -void shinxbot::input_process(const std::string &input) -{ +void shinxbot::input_process(const std::string &input) { if (input.empty()) { return; } @@ -72,8 +69,7 @@ void shinxbot::input_process(const std::string &input) even->process(this, J); } } - } - else if (post_type == "message") { + } else if (post_type == "message") { if (J.isMember("message_type") && J.isMember("message")) { std::string messageStr = messageArr_to_string(J["message"]); Json::Value messageArr = expand_string_to_messageArr(messageStr); @@ -104,40 +100,34 @@ void shinxbot::input_process(const std::string &input) if (func->check(messageArr, conf)) { func->process(messageArr, conf); } - } - else { + } else { if (func->check(messageStr, conf)) { func->process(messageStr, conf); } } - } - catch (const char *e) { + } catch (const char *e) { cq_send((std::string) "Throw an char*: " + e, conf); - setlog(LOG::ERROR, - name + ": Throw an char*: " + e); - } - catch (const std::string &e) { + setlog(LOG::ERROR, name + ": Throw an char*: " + e); + } catch (const std::string &e) { cq_send("Throw an string: " + e, conf); - setlog(LOG::ERROR, name + ": Throw an string: " + e); - } - catch (std::exception &e) { + setlog(LOG::ERROR, + name + ": Throw an string: " + e); + } catch (std::exception &e) { cq_send((std::string) "Throw an exception: " + e.what(), conf); setlog(LOG::ERROR, - name + ": Throw an exception: " + - e.what()); - } - catch (...) { + name + ": Throw an exception: " + e.what()); + } catch (...) { cq_send("Throw an unknown error", conf); - setlog(LOG::ERROR, name + ": Throw an unknown error"); + setlog(LOG::ERROR, + name + ": Throw an unknown error"); } } } } } - } - else if (post_type == "meta_event") { + } else if (post_type == "meta_event") { if (J.isMember("meta_event_type") && J["meta_event_type"].asString() == "heartbeat") { recorder->inform(); @@ -145,8 +135,7 @@ void shinxbot::input_process(const std::string &input) } } -void shinxbot::run() -{ +void shinxbot::run() { this->mytimer = new Timer(std::chrono::milliseconds(500), this); // smallest time: 1s this->archive = new archivist(); @@ -192,8 +181,7 @@ void shinxbot::run() ":" + filename); } } - } - catch (const fs::filesystem_error &ex) { + } catch (const fs::filesystem_error &ex) { set_global_log(LOG::ERROR, std::string("Error accessing directory: ") + ex.what()); diff --git a/src/dev_tools/inspector.cpp b/src/dev_tools/inspector.cpp index 75c4e48..22f4b80 100644 --- a/src/dev_tools/inspector.cpp +++ b/src/dev_tools/inspector.cpp @@ -14,8 +14,7 @@ int receive_port_bot; // https://stackoverflow.com/a/26221725/17792535 template -std::string string_format(const std::string &format, Args... args) -{ +std::string string_format(const std::string &format, Args... args) { int size_s = std::snprintf(nullptr, 0, format.c_str(), args...) + 1; // Extra space for '\0' if (size_s <= 0) { @@ -28,31 +27,27 @@ std::string string_format(const std::string &format, Args... args) buf.get() + size - 1); // We don't want the '\0' inside } -void get_config() -{ +void get_config() { std::ifstream iport("../../config/port.txt"); if (iport.is_open()) { iport >> send_port_bot >> receive_port_bot; std::cout << send_port_bot << " " << receive_port_bot << std::endl; iport.close(); - } - else { + } else { std::cerr << "Please first generate port.txt by running `cq_bot`" << std::endl; std::exit(1); } } -std::string process(const std::string request) -{ +std::string process(const std::string request) { std::string response = "{}"; std::istringstream iss{request}; std::string newline; std::getline(iss, newline); if (newline.find("/get_login_info") != std::string::npos) { response = "{\"user_id\": 23333, \"nickname\":\"Test\"}"; - } - else if (newline.find("/get_friend_list") != std::string::npos) { + } else if (newline.find("/get_friend_list") != std::string::npos) { response = "[" "{\"user_id\": 9982,\"nickname\": \"hi\"}," "{\"user_id\": 9983,\"nickname\": \"hi\"}," @@ -72,8 +67,7 @@ std::string process(const std::string request) return cq_body; } -void read_server_message(int new_socket) -{ +void read_server_message(int new_socket) { char buffer[4096]; try { std::string s_buffer; @@ -101,15 +95,13 @@ void read_server_message(int new_socket) std::string response = head + body; send(new_socket, response.c_str(), response.length(), 0); - } - catch (const std::exception &exc) { + } catch (const std::exception &exc) { std::cerr << exc.what(); } close(new_socket); } -int start_server() -{ +int start_server() { get_config(); int server_fd, new_socket; struct sockaddr_in address; @@ -158,8 +150,7 @@ int start_server() return 0; } -int main(int argc, char *argv[]) -{ +int main(int argc, char *argv[]) { start_server(); return 0; } diff --git a/src/interfaces/bot.cpp b/src/interfaces/bot.cpp index 4b9de58..05e1589 100644 --- a/src/interfaces/bot.cpp +++ b/src/interfaces/bot.cpp @@ -7,29 +7,21 @@ // } msg_meta::msg_meta(const msg_meta &u) : message_type(u.message_type), user_id(u.user_id), group_id(u.group_id), - message_id(u.message_id), p(u.p) -{ -} + message_id(u.message_id), p(u.p) {} msg_meta::msg_meta(const msg_meta &&u) : message_type(u.message_type), user_id(u.user_id), group_id(u.group_id), - message_id(u.message_id), p(u.p) -{ -} + message_id(u.message_id), p(u.p) {} msg_meta::msg_meta(std::string mt, userid_t uid, groupid_t gid, int64_t mid, bot *pp) - : message_type(mt), user_id(uid), group_id(gid), message_id(mid), p(pp) -{ -} + : message_type(mt), user_id(uid), group_id(gid), message_id(mid), p(pp) {} bot::bot(int recv_port, int send_port, const std::string &tk) - : receive_port(recv_port), send_port(send_port), token(tk), botqq(0) -{ -} + : receive_port(recv_port), send_port(send_port), token(tk), botqq(0) {} bool bot::is_op(const userid_t a) const { return false; } -std::string bot::cq_send(const std::string &message, const msg_meta &conf) const -{ +std::string bot::cq_send(const std::string &message, + const msg_meta &conf) const { if (trim(message).empty()) { return std::string("{\"data\": {\"message_id\": 0}}"); } @@ -42,15 +34,13 @@ std::string bot::cq_send(const std::string &message, const msg_meta &conf) const } std::string bot::cq_send(const std::string &end_point, - const Json::Value &J) const -{ + const Json::Value &J) const { return do_post((std::string) "127.0.0.1", send_port, (std::string) "/" + end_point, false, J, {{"Authorization", "Bearer " + token}}); } -std::string bot::cq_get(const std::string &end_point) const -{ +std::string bot::cq_get(const std::string &end_point) const { return do_get((std::string) "127.0.0.1", send_port, (std::string) "/" + end_point, false, {{"Authorization", "Bearer " + token}}); diff --git a/src/main.cpp b/src/main.cpp index c563f1c..ee1e21a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -11,25 +11,21 @@ int send_port, receive_port; bot *bots; -void bot_run(bot *u) -{ +void bot_run(bot *u) { while (1) { int k = fork(); if (k == -1) { std::cerr << "Process Error!" << std::endl; - } - else if (k == 0) { + } else if (k == 0) { u->run(); exit(0); - } - else { + } else { waitpid(k, NULL, 0); } } } -int main() -{ +int main() { Magick::InitializeMagick("shinxBot"); signal(SIGPIPE, SIG_IGN); signal(SIGALRM, SIG_IGN); @@ -41,8 +37,7 @@ int main() iport >> x >> y >> token; } iport.close(); - } - else { + } else { std::cout << "Please input the send_port: (receive port in Onebot11):"; std::cin >> x; std::cout << "Please input the receive_port: (send port in Onebot11):"; diff --git a/src/meta_event/heartbeat.cpp b/src/meta_event/heartbeat.cpp index 1f86093..505ccab 100644 --- a/src/meta_event/heartbeat.cpp +++ b/src/meta_event/heartbeat.cpp @@ -1,20 +1,17 @@ #include "heartbeat.h" -static inline std::time_t get_current_time() -{ +static inline std::time_t get_current_time() { auto now = std::chrono::system_clock::now(); return std::chrono::system_clock::to_time_t(now); } static void wait_child(pid_t id) { waitpid(id, NULL, 0); } -void heartBeat::start_recover() -{ +void heartBeat::start_recover() { pid_t k = fork(); if (k == -1) { std::cerr << "Process Error!" << std::endl; - } - else if (k == 0) { + } else if (k == 0) { for (const std::string &u : recover_commands) { int rc = system(u.c_str()); if (rc == -1) { @@ -23,19 +20,16 @@ void heartBeat::start_recover() } } exit(0); - } - else { + } else { std::thread(wait_child, k).detach(); } } heartBeat::heartBeat(const std::vector &commands) - : recover_commands(commands), las_time(get_current_time()) -{ + : recover_commands(commands), las_time(get_current_time()) { is_recorded = false; recovering = true; } -void heartBeat::run() -{ +void heartBeat::run() { while (running_.load()) { if (is_recorded && get_current_time() - las_time >= 3600 * 8 && !recovering) { // 8h @@ -48,8 +42,7 @@ void heartBeat::run() void heartBeat::stop() { running_.store(false); } -void heartBeat::inform() -{ +void heartBeat::inform() { las_time = get_current_time(); is_recorded = true; recovering = false; diff --git a/src/utils/HTTP_connect.cpp b/src/utils/HTTP_connect.cpp index aefd305..23c8637 100644 --- a/src/utils/HTTP_connect.cpp +++ b/src/utils/HTTP_connect.cpp @@ -1,6 +1,7 @@ #include "utils.h" #include "httplib.h" +#include #include #include #include @@ -8,40 +9,119 @@ enum class http_req_method { GET, POST }; // for now, these are enough +static std::string summarize_body_for_log(const std::string &body) { + if (body.empty()) { + return "empty"; + } + + const bool looks_html = body.find("(body.size(), 192)); + bool last_space = false; + for (char ch : body) { + unsigned char uch = static_cast(ch); + if (std::isspace(uch)) { + if (!last_space) { + flat.push_back(' '); + last_space = true; + } + continue; + } + + flat.push_back(std::isprint(uch) ? ch : '?'); + last_space = false; + if (flat.size() >= 180) { + break; + } + } + + if (flat.empty()) { + flat = "[non-printable body]"; + } + if (body.size() > 180) { + flat += "..."; + } + return flat; +} + std::string do_http_request(httplib::Client &client, const std::string &httpaddr, const std::string &httppath, const std::map &headers, const bool proxy_flg, const http_req_method hrm, - const Json::Value &json_message = Json::Value()) -{ + const Json::Value &json_message = Json::Value()) { client.set_connection_timeout(600, 0); // 10 minutes client.set_read_timeout(600, 0); // 10 minutes client.set_write_timeout(600, 0); // 10 minutes if (proxy_flg) { - const char *http_proxy = std::getenv("http_proxy"); - if (!http_proxy) { - http_proxy = std::getenv("HTTP_PROXY"); + auto get_env = [](const char *k1, const char *k2) -> const char * { + const char *v = std::getenv(k1); + return v ? v : std::getenv(k2); + }; + + const bool is_https = httpaddr.rfind("https://", 0) == 0; + const char *proxy_env = is_https ? get_env("https_proxy", "HTTPS_PROXY") + : get_env("http_proxy", "HTTP_PROXY"); + if (!proxy_env) { + proxy_env = get_env("http_proxy", "HTTP_PROXY"); } - if (http_proxy) { + + if (proxy_env) { try { - std::string proxy_str(http_proxy); - size_t colon_pos = proxy_str.find(':'); - if (proxy_str[colon_pos + 1] == '/') { - colon_pos = proxy_str.find(':', colon_pos + 1); + std::string proxy_str(proxy_env); + + const size_t scheme_pos = proxy_str.find("://"); + if (scheme_pos != std::string::npos) { + proxy_str = proxy_str.substr(scheme_pos + 3); + } + + const size_t slash_pos = proxy_str.find('/'); + if (slash_pos != std::string::npos) { + proxy_str = proxy_str.substr(0, slash_pos); + } + + const size_t at_pos = proxy_str.rfind('@'); + if (at_pos != std::string::npos) { + proxy_str = proxy_str.substr(at_pos + 1); + } + + std::string proxy_host; + std::string proxy_port_str; + if (!proxy_str.empty() && proxy_str[0] == '[') { + const size_t close = proxy_str.find(']'); + if (close != std::string::npos) { + proxy_host = proxy_str.substr(1, close - 1); + if (close + 2 < proxy_str.size() && + proxy_str[close + 1] == ':') { + proxy_port_str = proxy_str.substr(close + 2); + } + } + } else { + const size_t colon_pos = proxy_str.rfind(':'); + if (colon_pos != std::string::npos) { + proxy_host = proxy_str.substr(0, colon_pos); + proxy_port_str = proxy_str.substr(colon_pos + 1); + } } - if (colon_pos != std::string::npos) { - std::string proxy_host = proxy_str.substr(0, colon_pos); - int proxy_port = std::stoi(proxy_str.substr(colon_pos + 1)); + + if (!proxy_host.empty() && !proxy_port_str.empty()) { + const int proxy_port = std::stoi(proxy_port_str); client.set_proxy(proxy_host, proxy_port); + } else { + set_global_log(LOG::WARNING, + "Unable to resolve proxy host/port"); } - } - catch (...) { + } catch (...) { set_global_log(LOG::WARNING, "Unable to resolve proxy"); } - } - else { + } else { set_global_log( LOG::WARNING, fmt::format( @@ -66,14 +146,19 @@ std::string do_http_request(httplib::Client &client, if (!res || res->status / 100 != 2) { auto err = res.error(); - std::cout << (res ? res->body : "No response") << std::endl; - set_global_log(LOG::ERROR, - fmt::format("Connect to {} failed with code {}, err: {}", - httpaddr + httppath, - std::to_string(res ? res->status : -1), - httplib::to_string(err))); - throw fmt::format("HTTP Connect failed, err {}", - httplib::to_string(err)); + const int status = res ? res->status : -1; + const std::string body = res ? res->body : "No response"; + const std::string body_head = summarize_body_for_log(body); + + set_global_log( + LOG::ERROR, + fmt::format( + "Connect to {} failed with code {}, err: {}, body_head: {}", + httpaddr + httppath, status, httplib::to_string(err), + body_head)); + throw fmt::format( + "HTTP request failed: status={} err={} body_head='{}'", status, + httplib::to_string(err), body_head); } return res->body; @@ -82,8 +167,7 @@ std::string do_http_request(httplib::Client &client, std::string do_post(const std::string &httpaddr, const Json::Value &json_message, const std::map &headers, - const bool proxy_flg) -{ + const bool proxy_flg) { auto cli = httplib::Client(httpaddr); return do_http_request(cli, httpaddr, "", headers, proxy_flg, http_req_method::POST, json_message); @@ -91,8 +175,7 @@ std::string do_post(const std::string &httpaddr, std::string do_get(const std::string &httpaddr, const std::map &headers, - const bool proxy_flg) -{ + const bool proxy_flg) { auto cli = httplib::Client(httpaddr); return do_http_request(cli, httpaddr, "", headers, proxy_flg, http_req_method::GET); @@ -101,8 +184,7 @@ std::string do_get(const std::string &httpaddr, std::string do_post(const std::string &httpaddr, const std::string &httppath, bool enc, const Json::Value &json_message, const std::map &headers, - const bool proxy_flg) -{ + const bool proxy_flg) { auto cli = httplib::Client(httpaddr); cli.set_path_encode(enc); return do_http_request(cli, httpaddr, httppath, headers, proxy_flg, @@ -111,8 +193,7 @@ std::string do_post(const std::string &httpaddr, const std::string &httppath, std::string do_get(const std::string &httpaddr, const std::string &httppath, bool enc, const std::map &headers, - const bool proxy_flg) -{ + const bool proxy_flg) { auto cli = httplib::Client(httpaddr); cli.set_path_encode(enc); return do_http_request(cli, httpaddr, httppath, headers, proxy_flg, @@ -122,8 +203,7 @@ std::string do_get(const std::string &httpaddr, const std::string &httppath, std::string do_post(const std::string &httpaddr, int port, const Json::Value &json_message, const std::map &headers, - const bool proxy_flg) -{ + const bool proxy_flg) { auto cli = httplib::Client(httpaddr, port); return do_http_request(cli, fmt::format("{}:{}", httpaddr, port), "", headers, proxy_flg, http_req_method::POST, @@ -132,8 +212,7 @@ std::string do_post(const std::string &httpaddr, int port, std::string do_get(const std::string &httpaddr, int port, const std::map &headers, - const bool proxy_flg) -{ + const bool proxy_flg) { auto cli = httplib::Client(httpaddr, port); return do_http_request(cli, fmt::format("{}:{}", httpaddr, port), "", headers, proxy_flg, http_req_method::GET); @@ -143,8 +222,7 @@ std::string do_post(const std::string &httpaddr, int port, const std::string &httppath, bool enc, const Json::Value &json_message, const std::map &headers, - const bool proxy_flg) -{ + const bool proxy_flg) { auto cli = httplib::Client(httpaddr, port); cli.set_path_encode(enc); return do_http_request(cli, fmt::format("{}:{}", httpaddr, port), httppath, @@ -155,8 +233,7 @@ std::string do_post(const std::string &httpaddr, int port, std::string do_get(const std::string &httpaddr, int port, const std::string &httppath, bool enc, const std::map &headers, - const bool proxy_flg) -{ + const bool proxy_flg) { auto cli = httplib::Client(httpaddr, port); cli.set_path_encode(enc); return do_http_request(cli, fmt::format("{}:{}", httpaddr, port), httppath, diff --git a/src/utils/command_utils.cpp b/src/utils/command_utils.cpp index 64cdd33..6fb21d1 100644 --- a/src/utils/command_utils.cpp +++ b/src/utils/command_utils.cpp @@ -1,8 +1,7 @@ #include "utils.h" bool cmd_match_exact(const std::string &message, - const std::vector &commands) -{ + const std::vector &commands) { for (const auto &cmd : commands) { if (message == cmd) { return true; @@ -12,8 +11,7 @@ bool cmd_match_exact(const std::string &message, } bool cmd_match_exact(const std::wstring &message, - const std::vector &commands) -{ + const std::vector &commands) { for (const auto &cmd : commands) { if (message == cmd) { return true; @@ -23,8 +21,7 @@ bool cmd_match_exact(const std::wstring &message, } bool cmd_match_prefix(const std::string &message, - const std::vector &prefixes) -{ + const std::vector &prefixes) { for (const auto &prefix : prefixes) { if (starts_with(message, prefix)) { return true; @@ -34,8 +31,7 @@ bool cmd_match_prefix(const std::string &message, } bool cmd_match_prefix(const std::wstring &message, - const std::vector &prefixes) -{ + const std::vector &prefixes) { for (const auto &prefix : prefixes) { if (starts_with(message, prefix)) { return true; @@ -45,8 +41,7 @@ bool cmd_match_prefix(const std::wstring &message, } bool cmd_strip_prefix(const std::string &message, const std::string &prefix, - std::string &body_out) -{ + std::string &body_out) { if (!starts_with(message, prefix)) { return false; } @@ -55,8 +50,7 @@ bool cmd_strip_prefix(const std::string &message, const std::string &prefix, } bool cmd_strip_prefix(const std::wstring &message, const std::wstring &prefix, - std::wstring &body_out) -{ + std::wstring &body_out) { if (!starts_with(message, prefix)) { return false; } @@ -66,8 +60,7 @@ bool cmd_strip_prefix(const std::wstring &message, const std::wstring &prefix, bool cmd_parse_prefixed(const std::string &raw, const std::vector &prefixes, - std::string &cmd_out) -{ + std::string &cmd_out) { const std::string m = trim(raw); for (const auto &prefix : prefixes) { if (cmd_strip_prefix(m, prefix, cmd_out)) { @@ -79,8 +72,7 @@ bool cmd_parse_prefixed(const std::string &raw, bool cmd_parse_prefixed(const std::wstring &raw, const std::vector &prefixes, - std::wstring &cmd_out) -{ + std::wstring &cmd_out) { const std::wstring m = trim(raw); for (const auto &prefix : prefixes) { if (cmd_strip_prefix(m, prefix, cmd_out)) { @@ -90,8 +82,7 @@ bool cmd_parse_prefixed(const std::wstring &raw, return false; } -bool cmd_run_middlewares(const std::vector &middlewares) -{ +bool cmd_run_middlewares(const std::vector &middlewares) { for (const auto &mw : middlewares) { if (!mw || !mw()) { return false; @@ -102,8 +93,7 @@ bool cmd_run_middlewares(const std::vector &middlewares) bool cmd_dispatch(const std::string &message, const std::vector &exact_rules, - const std::vector &prefix_rules) -{ + const std::vector &prefix_rules) { bool handled = false; (void)cmd_try_dispatch(message, exact_rules, prefix_rules, handled); return handled; @@ -112,8 +102,7 @@ bool cmd_dispatch(const std::string &message, bool cmd_try_dispatch(const std::string &message, const std::vector &exact_rules, const std::vector &prefix_rules, - bool &handled_out) -{ + bool &handled_out) { handled_out = false; for (const auto &r : exact_rules) { if (message == r.cmd) { diff --git a/src/utils/converter.cpp b/src/utils/converter.cpp index 7854e1f..e030cf0 100644 --- a/src/utils/converter.cpp +++ b/src/utils/converter.cpp @@ -3,19 +3,16 @@ bool is_op(const bot *p, const userid_t a) { return p->is_op(a); } std::string cq_send(const bot *p, const std::string &message, - const msg_meta &conf) -{ + const msg_meta &conf) { return p->cq_send(message, conf); } std::string cq_send(const bot *p, const std::string &end_point, - const Json::Value &J) -{ + const Json::Value &J) { return p->cq_send(end_point, J); } -std::string cq_get(const bot *p, const std::string &end_point) -{ +std::string cq_get(const bot *p, const std::string &end_point) { return p->cq_get(end_point); } @@ -25,50 +22,42 @@ userid_t get_botqq(const bot *p) { return p->get_botqq(); } std::string get_local_path() { return fs::current_path(); } -void input_process(bot *p, const std::string &input) -{ +void input_process(bot *p, const std::string &input) { p->input_process(input); } -std::string bot_config_path(const bot *p, const fs::path &relative) -{ +std::string bot_config_path(const bot *p, const fs::path &relative) { const fs::path base = p ? fs::path(p->getConfigDir()) : fs::path("./config"); return (base / relative).string(); } -std::string bot_resource_path(const bot *p, const fs::path &relative) -{ +std::string bot_resource_path(const bot *p, const fs::path &relative) { const fs::path base = p ? fs::path(p->getResourceDir()) : fs::path("./resource"); return (base / relative).string(); } -std::string bot_config_path(const fs::path &relative) -{ +std::string bot_config_path(const fs::path &relative) { return bot_config_path(nullptr, relative); } -std::string bot_resource_path(const fs::path &relative) -{ +std::string bot_resource_path(const fs::path &relative) { return bot_resource_path(nullptr, relative); } -std::string message_to_string(const Json::Value &J) -{ +std::string message_to_string(const Json::Value &J) { if (J.isString()) { return J.asString(); } if (J["type"].asString() == "text") { return cq_encode(J["data"]["text"].asString()); - } - else { + } else { std::string ret = "[CQ:" + J["type"].asString(); for (auto u : J["data"].getMemberNames()) { if (J["data"][u].isString()) { ret += "," + u + "=" + cq_encode(J["data"][u].asString()); - } - else { + } else { ret += "," + u + "=" + cq_encode(J["data"][u].toStyledString()); } } @@ -77,26 +66,22 @@ std::string message_to_string(const Json::Value &J) } } -std::string messageArr_to_string(const Json::Value &J) -{ +std::string messageArr_to_string(const Json::Value &J) { if (J.isString()) { return J.asString(); - } - else if (J.isArray()) { + } else if (J.isArray()) { std::string ret; Json::ArrayIndex sz = J.size(); for (Json::ArrayIndex i = 0; i < sz; i++) { ret += message_to_string(J[i]); } return ret; - } - else { + } else { return message_to_string(J); } } -Json::Value string_to_message(const std::string &s) -{ +Json::Value string_to_message(const std::string &s) { Json::Value J; if (s[0] == '[') { size_t pos = s.find(','), laspos; @@ -116,16 +101,14 @@ Json::Value string_to_message(const std::string &s) cq_decode(s.substr(mid + 1, pos - mid - 1)); laspos = pos; } - } - else { + } else { J["type"] = "text"; J["data"]["text"] = cq_decode(s); } return J; } -Json::Value string_to_messageArr(const std::string &s) -{ +Json::Value string_to_messageArr(const std::string &s) { size_t pos = 0, laspos = 0; Json::Value J; while ((pos = s.find('[', pos)) != s.npos) { diff --git a/src/utils/file_utils.cpp b/src/utils/file_utils.cpp index cd017e5..9e3a76e 100644 --- a/src/utils/file_utils.cpp +++ b/src/utils/file_utils.cpp @@ -6,8 +6,7 @@ #include std::fstream openfile(const fs::path file_path, - const std::ios_base::openmode mode) -{ + const std::ios_base::openmode mode) { if (!fs::exists(file_path)) { fs::path path(file_path); fs::create_directories(path.parent_path()); @@ -15,16 +14,14 @@ std::fstream openfile(const fs::path file_path, std::fstream file(file_path, mode); if (file.is_open()) { return file; - } - else { + } else { set_global_log(LOG::ERROR, "Cannot open file: " + file_path.string()); throw(file_path.string() + ": open file failed").c_str(); } } std::string readfile(const fs::path &file_path, - const std::string &default_content) -{ + const std::string &default_content) { std::ifstream afile; afile.open(file_path, std::ios::in); @@ -36,30 +33,28 @@ std::string readfile(const fs::path &file_path, } afile.close(); return ans; - } - else { - set_global_log(LOG::WARNING, "Reading file: " + file_path.string() + " not exist, using default content..."); + } else { + set_global_log(LOG::WARNING, + "Reading file: " + file_path.string() + + " not exist, using default content..."); try { std::fstream ofile = openfile(file_path, std::ios::out); ofile << default_content; ofile.flush(); ofile.close(); return default_content; - } - catch (...) { + } catch (...) { return ""; } } } void writefile(const fs::path file_path, const std::string &content, - bool is_append) -{ + bool is_append) { std::fstream ofile; try { ofile = openfile(file_path, is_append ? std::ios::app : std::ios::out); - } - catch (...) { + } catch (...) { } ofile << content; ofile.flush(); @@ -68,8 +63,7 @@ void writefile(const fs::path file_path, const std::string &content, void command_download(const std::string &httpAddress, const std::string &filePath, const std::string &fileName, - const bool proxy) -{ + const bool proxy) { fs::path p(filePath); if (!fs::exists(p)) { fs::create_directories(p); @@ -90,8 +84,7 @@ void command_download(const std::string &httpAddress, } void download(const std::string &httpAddress, const fs::path &filePath, - const std::string &fileName, const bool proxy) -{ + const std::string &fileName, const bool proxy) { try { auto ret = split_http_addr(httpAddress); std::string data = do_get(ret.first, ret.second, false, {}, proxy); @@ -99,8 +92,7 @@ void download(const std::string &httpAddress, const fs::path &filePath, try { ofile = openfile(filePath / fileName, std::ios::out | std::ios::binary); - } - catch (...) { + } catch (...) { set_global_log(LOG::ERROR, "Cannot open file " + (filePath / fileName).string() + " for download."); @@ -109,14 +101,12 @@ void download(const std::string &httpAddress, const fs::path &filePath, ofile << data; ofile.flush(); ofile.close(); - } - catch (const std::exception &e) { + } catch (const std::exception &e) { set_global_log(LOG::ERROR, "At download from" + httpAddress + " to " + (filePath / fileName).string() + ", Exception occurred: " + e.what()); throw; - } - catch (const std::string &e) { + } catch (const std::string &e) { set_global_log(LOG::ERROR, "At download from" + httpAddress + " to " + (filePath / fileName).string() + ", Exception occurred: " + e); diff --git a/src/utils/image_utils.cpp b/src/utils/image_utils.cpp index ae61669..d78f3a9 100644 --- a/src/utils/image_utils.cpp +++ b/src/utils/image_utils.cpp @@ -1,8 +1,7 @@ #include "image_utils.h" #include "utils.h" -void addRandomNoiseSingle(Magick::Image &img, int strength = 4) -{ +void addRandomNoiseSingle(Magick::Image &img, int strength = 4) { size_t width = img.columns(); size_t height = img.rows(); if (width * height > 4000000) { @@ -34,8 +33,7 @@ void addRandomNoiseSingle(Magick::Image &img, int strength = 4) } } -void addRandomNoise(const std::string &filePath) -{ +void addRandomNoise(const std::string &filePath) { try { if (filePath.find(".gif") != filePath.npos) { std::vector img; @@ -51,20 +49,17 @@ void addRandomNoise(const std::string &filePath) result.push_back(frame); } Magick::writeImages(result.begin(), result.end(), filePath); - } - else { + } else { Magick::Image img(filePath); addRandomNoiseSingle(img); img.write(filePath); } - } - catch (std::exception &e) { + } catch (std::exception &e) { set_global_log(LOG::ERROR, e.what()); } } -std::pair image2base64(std::string filepath) -{ +std::pair image2base64(std::string filepath) { Magick::Image img(filepath); img.thumbnail(Magick::Geometry(2048, 2048)); @@ -73,20 +68,15 @@ std::pair image2base64(std::string filepath) std::string type = img.magick(); if (type == "PNG") { type = "image/png"; - } - else if (type == "JPEG") { + } else if (type == "JPEG") { type = "image/jpeg"; - } - else if (type == "WEBP") { + } else if (type == "WEBP") { type = "image/webp"; - } - else if (type == "HEIC") { + } else if (type == "HEIC") { type = "image/heic"; - } - else if (type == "HEIF") { + } else if (type == "HEIF") { type = "image/heif"; - } - else { + } else { type = "image/error"; } return std::make_pair(type, blob.base64()); @@ -94,8 +84,7 @@ std::pair image2base64(std::string filepath) void copyImageTo(Magick::Image &dst, const Magick::Image src, size_t src_row_start, size_t src_row_end, size_t src_col_start, - size_t src_col_end, size_t dst_row, size_t dst_col) -{ + size_t src_col_end, size_t dst_row, size_t dst_col) { size_t crop_width = src_col_end - src_col_start; size_t crop_height = src_row_end - src_row_start; Magick::Geometry crop_region(crop_width, crop_height, src_col_start, @@ -107,8 +96,7 @@ void copyImageTo(Magick::Image &dst, const Magick::Image src, } void mirrorImage(Magick::Image &img, char axis, bool direction, - const Magick::Image las) -{ + const Magick::Image las) { Magick::Image new_img = img; // Mirror operation @@ -124,16 +112,13 @@ void mirrorImage(Magick::Image &img, char axis, bool direction, if (direction == 0) { copyImageTo(img, new_img, new_img.rows() >> 1, new_img.rows(), 0, new_img.columns(), img.rows() >> 1, 0); - } - else if (direction == 1) { + } else if (direction == 1) { copyImageTo(img, new_img, 0, new_img.rows() >> 1, 0, new_img.columns(), 0, 0); - } - else { + } else { goto mirrorImageError; } - } - else if (axis == 1) { // Horizontal axis (flop) + } else if (axis == 1) { // Horizontal axis (flop) // Delete original half side first for (size_t y = 0; y < img.rows(); ++y) { for (size_t x = (direction == 0 ? img.columns() >> 1 : 0); @@ -146,16 +131,13 @@ void mirrorImage(Magick::Image &img, char axis, bool direction, if (direction == 0) { copyImageTo(img, new_img, 0, new_img.rows(), new_img.columns() >> 1, new_img.columns(), 0, img.columns() >> 1); - } - else if (direction == 1) { + } else if (direction == 1) { copyImageTo(img, new_img, 0, new_img.rows(), 0, new_img.columns() >> 1, 0, 0); - } - else { + } else { goto mirrorImageError; } - } - else { + } else { goto mirrorImageError; } if (las.columns() > 1) { @@ -174,8 +156,7 @@ void mirrorImage(Magick::Image &img, char axis, bool direction, } void mirrorImage(std::vector &img, char axis, bool direction, - std::function callback) -{ + std::function callback) { std::vector coalesced; Magick::coalesceImages(&coalesced, img.begin(), img.end()); @@ -192,8 +173,7 @@ void mirrorImage(std::vector &img, char axis, bool direction, using namespace Magick; -void crop_to_square(Magick::Image &img) -{ +void crop_to_square(Magick::Image &img) { Magick::Geometry geo = Magick::Geometry(img.columns(), img.rows()); size_t len = std::min(geo.width(), geo.height()); geo.xOff((geo.width() - len) >> 1); @@ -204,8 +184,7 @@ void crop_to_square(Magick::Image &img) img.page(Magick::Geometry(0, 0, 0, 0)); } -void crop_to_circle(Magick::Image &img) -{ +void crop_to_circle(Magick::Image &img) { crop_to_square(img); size_t len = img.columns(); double radius = len / 2.0; @@ -223,8 +202,7 @@ void crop_to_circle(Magick::Image &img) } } -void constsize_rotate(Magick::Image &img, double deg) -{ +void constsize_rotate(Magick::Image &img, double deg) { size_t oriWidth = img.columns(), oriHeight = img.rows(); // img.backgroundColor(Magick::Color(5, 0, 0, 0)); img.rotate(deg); @@ -242,8 +220,7 @@ void constsize_rotate(Magick::Image &img, double deg) std::vector rotateImage(const Magick::Image img, int fps, bool clockwise, - std::function callback) -{ + std::function callback) { Magick::Image dimg = img; dimg.alphaChannel(MagickCore::AlphaChannelOption::SetAlphaChannel); @@ -276,8 +253,7 @@ std::vector rotateImage(const Magick::Image img, int fps, } void rotateImage(std::vector &img, int fps, bool clockwise, - std::function callback) -{ + std::function callback) { std::vector coalesced; Magick::coalesceImages(&coalesced, img.begin(), img.end()); int total_delay = 0; @@ -296,20 +272,17 @@ void rotateImage(std::vector &img, int fps, bool clockwise, double delay = 100.0 / fps; if (total_delay > 80 && total_delay < 130) { delay = total_delay * 1.0 / fps; - } - else if (total_delay >= 130) { + } else if (total_delay >= 130) { if (total_delay % 100 > 80 || total_delay % 100 < 30) { fps *= (total_delay + 50) / 100; delay = total_delay * 1.0 / fps; - } - else { + } else { total_delay <<= 1; fps *= (total_delay + 50) / 100; delay = total_delay * 1.0 / fps; total_delay >>= 1; } - } - else if (total_delay >= 20) { + } else if (total_delay >= 20) { double ratio = total_delay / 100.0; double availables[] = {2, 3, 4, 5}; // find the nearest available ratio @@ -324,9 +297,10 @@ void rotateImage(std::vector &img, int fps, bool clockwise, im.animationDelay(im.animationDelay() * ra); } } - set_global_log(LOG::INFO, "rotateImage: total_delay=" + std::to_string(total_delay) + - ", fps=" + std::to_string(fps) + - ", delay=" + std::to_string(delay)); + set_global_log(LOG::INFO, + "rotateImage: total_delay=" + std::to_string(total_delay) + + ", fps=" + std::to_string(fps) + + ", delay=" + std::to_string(delay)); int index = 0; double frac = 0.001; @@ -367,8 +341,7 @@ struct TileTransform { void buildRandomCanvas(const std::vector &input, std::vector &output, std::function callback = nullptr, - double cover_rate = 0.98, double scaleFactor = 4.0) -{ + double cover_rate = 0.98, double scaleFactor = 4.0) { if (input.empty()) return; @@ -424,8 +397,8 @@ void buildRandomCanvas(const std::vector &input, canvas.alpha(true); for (int x = 0; x < canvasW; x += baseW) { for (int y = 0; y < canvasH; y += baseH) { - canvas.composite(src, x, y, - MagickCore::CompositeOperator::OverCompositeOp); + canvas.composite( + src, x, y, MagickCore::CompositeOperator::OverCompositeOp); } } @@ -464,8 +437,7 @@ void buildRandomCanvas(const std::vector &input, Magick::Image buildRandomCanvas(const Image &input, std::function callback = nullptr, double cover_rate = 0.98, - double scaleFactor = 4.0) -{ + double scaleFactor = 4.0) { int w = input.columns(); int h = input.rows(); double scale = std::min(500.0 / w, 500.0 / h); @@ -486,7 +458,7 @@ Magick::Image buildRandomCanvas(const Image &input, for (int x = 0; x < canvasW; x += w) { for (int y = 0; y < canvasH; y += h) { canvas.composite(input, x, y, - MagickCore::CompositeOperator::OverCompositeOp); + MagickCore::CompositeOperator::OverCompositeOp); } } @@ -531,8 +503,7 @@ Magick::Image buildRandomCanvas(const Image &input, } Magick::Image kaleidoscopeSectorSymmetry(const Magick::Image &canvas, - int sectors = 12) -{ + int sectors = 12) { int w = canvas.columns(); int h = canvas.rows(); @@ -584,8 +555,7 @@ Magick::Image kaleidoscopeSectorSymmetry(const Magick::Image &canvas, piece.flip(); piece.page(Magick::Geometry(0, 0, 0, 0)); piece.rotate((i + 1) * sectorAngle); - } - else { + } else { piece.page(Magick::Geometry(0, 0, 0, 0)); piece.rotate(i * sectorAngle); } @@ -605,15 +575,13 @@ Magick::Image kaleidoscopeSectorSymmetry(const Magick::Image &canvas, } void kaleido(Magick::Image &img, int layers, int nums_per_layer, - std::function callback) -{ + std::function callback) { img = kaleidoscopeSectorSymmetry(buildRandomCanvas(img, callback), nums_per_layer); } void kaleido(std::vector &img, int layers, int nums_per_layer, - std::function callback) -{ + std::function callback) { std::vector coalesced; Magick::coalesceImages(&coalesced, img.begin(), img.end()); diff --git a/src/utils/json_utils.cpp b/src/utils/json_utils.cpp index d6c580f..e2077d4 100644 --- a/src/utils/json_utils.cpp +++ b/src/utils/json_utils.cpp @@ -3,8 +3,7 @@ #include #include -Json::Value string_to_json(const std::string &str) -{ +Json::Value string_to_json(const std::string &str) { Json::Value root; Json::Reader re; try { @@ -14,8 +13,7 @@ Json::Value string_to_json(const std::string &str) re.getFormattedErrorMessages() + "\nstring: " + str); } - } - catch (std::exception &e) { + } catch (std::exception &e) { set_global_log(LOG::ERROR, "string to json exception: " + std::string(e.what()) + "\nstring: " + str); @@ -24,31 +22,27 @@ Json::Value string_to_json(const std::string &str) return root; } -void parse_json_to_set(const Json::Value &J, std::set &mp) -{ +void parse_json_to_set(const Json::Value &J, std::set &mp) { Json::ArrayIndex sz = J.size(); for (Json::ArrayIndex i = 0; i < sz; i++) { mp.insert(J[i].asUInt64()); } } -void parse_json_to_set(const Json::Value &J, std::set &mp) -{ +void parse_json_to_set(const Json::Value &J, std::set &mp) { Json::ArrayIndex sz = J.size(); for (Json::ArrayIndex i = 0; i < sz; i++) { mp.insert(J[i].asString()); } } -Json::ArrayIndex json_array_find(const Json::Value &J, const uint64_t &data) -{ +Json::ArrayIndex json_array_find(const Json::Value &J, const uint64_t &data) { Json::ArrayIndex sz = J.size(); for (Json::ArrayIndex i = 0; i < sz; i++) { try { if (J[i].asUInt64() == data) { return i; } - } - catch (...) { // Json::LogicError + } catch (...) { // Json::LogicError continue; } } @@ -88,7 +82,8 @@ Json::Value expand_string_to_messageArr(std::string s) { if (next_comma == std::string::npos) { next_comma = cq_code.size(); } - std::string item = cq_code.substr(comma_pos + 1, next_comma - comma_pos - 1); + std::string item = + cq_code.substr(comma_pos + 1, next_comma - comma_pos - 1); size_t equal_pos = item.find("="); if (equal_pos != std::string::npos) { std::string key = item.substr(0, equal_pos); diff --git a/src/utils/log.cpp b/src/utils/log.cpp index fdbff23..8caff8e 100644 --- a/src/utils/log.cpp +++ b/src/utils/log.cpp @@ -7,8 +7,7 @@ std::string LOG_name[3] = {"INFO", "WARNING", "ERROR"}; -void set_global_log(LOG type, std::string message) -{ +void set_global_log(LOG type, std::string message) { std::time_t nt = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); tm tt = *std::localtime(&nt); @@ -18,7 +17,7 @@ void set_global_log(LOG type, std::string message) tt.tm_sec, LOG_name[type], message); if (type == LOG::ERROR) - fmt::print(stderr, formatted_message); + fmt::print(stderr, "{}", formatted_message); else - fmt::print(formatted_message); + fmt::print("{}", formatted_message); } \ No newline at end of file diff --git a/src/utils/meta_func/backup.cpp b/src/utils/meta_func/backup.cpp index bbc3ce4..cf10489 100644 --- a/src/utils/meta_func/backup.cpp +++ b/src/utils/meta_func/backup.cpp @@ -3,20 +3,17 @@ #include void archivist::add_path(const std::string &name, const fs::path &path, - const fs::path &rele_path, const std::string &passwd) -{ + const fs::path &rele_path, const std::string &passwd) { this->arc_list[name].emplace_back(path, rele_path, passwd); } -void archivist::remove_path(const std::string &name) -{ +void archivist::remove_path(const std::string &name) { this->arc_list.erase(name); } bool archivist::archive_add_file(zip_t *archive, const fs::path &path, const std::string &passwd, - const fs::path &rele_path) -{ + const fs::path &rele_path) { zip_source_t *source = zip_source_file(archive, path.c_str(), 0, ZIP_LENGTH_TO_END); if (source == NULL) { @@ -38,8 +35,7 @@ bool archivist::archive_add_file(zip_t *archive, const fs::path &path, set_global_log(LOG::ERROR, "backup file enc error"); return false; } - } - else { + } else { int ret = zip_file_set_encryption(archive, ind, ZIP_EM_AES_256, NULL); if (ret < 0) { set_global_log(LOG::ERROR, "backup file enc error"); @@ -50,8 +46,7 @@ bool archivist::archive_add_file(zip_t *archive, const fs::path &path, } bool archivist::archive_add_dir(zip_t *archive, const fs::path &path, const std::string &passwd, - const fs::path &rele_path) -{ + const fs::path &rele_path) { for (const auto &entry : fs::directory_iterator(path)) { if (!archive_add_path(archive, entry.path(), passwd, rele_path / path.filename())) { @@ -62,27 +57,22 @@ bool archivist::archive_add_dir(zip_t *archive, const fs::path &path, } bool archivist::archive_add_path(zip_t *archive, const fs::path &path, const std::string &passwd, - const fs::path &rele_path) -{ + const fs::path &rele_path) { if (fs::is_directory(path)) { return this->archive_add_dir(archive, path, passwd, rele_path); - } - else if (fs::is_regular_file(path)) { + } else if (fs::is_regular_file(path)) { return this->archive_add_file(archive, path, passwd, rele_path); - } - else { + } else { return true; // symbolic link? } } -bool archivist::make_archive(const fs::path &path) -{ +bool archivist::make_archive(const fs::path &path) { zip_t *archive = zip_open(path.c_str(), ZIP_CREATE | ZIP_TRUNCATE, nullptr); if (archive == NULL) { set_global_log(LOG::ERROR, "backup zip create error"); return false; - } - else { + } else { zip_set_default_password(archive, default_pwd.c_str()); for (const auto &f : this->arc_list) { for (const auto &[path, rele_path, passwd] : f.second) { @@ -97,7 +87,6 @@ bool archivist::make_archive(const fs::path &path) } } -void archivist::set_default_pwd(const std::string &pwd) -{ +void archivist::set_default_pwd(const std::string &pwd) { this->default_pwd = pwd; } \ No newline at end of file diff --git a/src/utils/meta_func/progress_bar.cpp b/src/utils/meta_func/progress_bar.cpp index 8b7f4ff..6be0075 100644 --- a/src/utils/meta_func/progress_bar.cpp +++ b/src/utils/meta_func/progress_bar.cpp @@ -10,18 +10,14 @@ static std::mutex m; BarInfo::BarInfo(float pg, const std::string &dc) - : progress(pg), desc(dc), f(nullptr), b(nullptr) -{ -} + : progress(pg), desc(dc), f(nullptr), b(nullptr) {} void BarInfo::setProgress(float pg) { progress = pg; } void BarInfo::setDesc(const std::string &d) { this->desc = d; } -void BarInfo::setBar(float pg, const std::string &d) -{ +void BarInfo::setBar(float pg, const std::string &d) { progress = pg; this->desc = d; } -BarInfo::~BarInfo() -{ +BarInfo::~BarInfo() { std::lock_guard lock(m); if (b != nullptr) b->f = f; @@ -29,15 +25,13 @@ BarInfo::~BarInfo() f->b = b; } -progressBar::progressBar() -{ +progressBar::progressBar() { root.b = &tail; tail.f = &root; root.f = tail.b = nullptr; } -void progressBar::addBar(BarInfo *u) -{ +void progressBar::addBar(BarInfo *u) { std::lock_guard lock(m); if (u->f != nullptr) { set_global_log( @@ -51,8 +45,7 @@ void progressBar::addBar(BarInfo *u) tail.f = u; } -std::string progressBar::desc() const -{ +std::string progressBar::desc() const { std::lock_guard lock(m); std::ostringstream oss; BarInfo *p = root.b; @@ -80,8 +73,7 @@ std::string progressBar::desc() const return fmt::format("Total {} Tasks running.\n{}", cnt, oss.str()); } -progressBar::~progressBar() -{ +progressBar::~progressBar() { if (root.b != &tail || tail.f != &root) { set_global_log(LOG::ERROR, "progressBar list not properly released. " "May result in Segmentation fault."); diff --git a/src/utils/meta_func/timer.cpp b/src/utils/meta_func/timer.cpp index 5300f6d..7de1b74 100644 --- a/src/utils/meta_func/timer.cpp +++ b/src/utils/meta_func/timer.cpp @@ -1,34 +1,36 @@ #include "timer.h" -void Timer::run() -{ +void Timer::run() { while (running.load()) { std::this_thread::sleep_for(interval); if (running.load()) { - for (auto u : this->callbacks) { + std::map>> + snapshot; + { + std::lock_guard lock(callbacks_mutex); + snapshot = callbacks; + } + + for (auto u : snapshot) { for (auto f : u.second) { try { f(this->p); - } - catch (char *e) { + } catch (char *e) { p->cq_send_all_op( (std::string) "Timer Throw an char*: " + e); p->setlog(LOG::ERROR, (std::string) "Timer Throw an char*: " + e); - } - catch (std::string e) { + } catch (std::string e) { p->cq_send_all_op("Timer Throw an string: " + e); p->setlog(LOG::ERROR, "Timer Throw an string: " + e); - } - catch (std::exception &e) { + } catch (std::exception &e) { p->cq_send_all_op( (std::string) "Timer Throw an exception: " + e.what()); p->setlog(LOG::ERROR, (std::string) "Timer Throw an exception: " + e.what()); - } - catch (...) { + } catch (...) { p->cq_send_all_op("Timer Throw an unknown error"); p->setlog(LOG::ERROR, "Timer Throw an unknown error"); } @@ -39,29 +41,25 @@ void Timer::run() } Timer::Timer(std::chrono::duration dur, bot *p) - : interval(dur), running(false), p(p) -{ -} + : interval(dur), running(false), p(p) {} void Timer::set_interval(std::chrono::duration dur) { interval = dur; } void Timer::add_callback(const std::string &name, - std::function cb) -{ + std::function cb) { + std::lock_guard lock(callbacks_mutex); this->callbacks[name].push_back(cb); } -void Timer::remove_callback(const std::string &name) -{ +void Timer::remove_callback(const std::string &name) { + std::lock_guard lock(callbacks_mutex); this->callbacks.erase(name); } -void Timer::timer_start() -{ +void Timer::timer_start() { running.store(true); timerThread = std::thread(&Timer::run, this); } -void Timer::timer_stop() -{ +void Timer::timer_stop() { running.store(false); if (timerThread.joinable()) { timerThread.join(); diff --git a/src/utils/meta_func/timer.h b/src/utils/meta_func/timer.h new file mode 100644 index 0000000..cff1cea --- /dev/null +++ b/src/utils/meta_func/timer.h @@ -0,0 +1,34 @@ +#pragma once + +#include "bot.h" +#include +#include +#include +#include +#include +#include + +class Timer { +private: + std::chrono::duration interval; + std::atomic running; + std::thread timerThread; + std::mutex callbacks_mutex; + std::map>> callbacks; + bot *p; + + void run(); + +public: + Timer(std::chrono::duration dur, bot *p); + + void set_interval(std::chrono::duration dur); + void add_callback(const std::string &name, std::function cb); + void remove_callback(const std::string &name); + bool is_running() const { return running.load(); } + + void timer_start(); + void timer_stop(); + + ~Timer(); +}; \ No newline at end of file diff --git a/src/utils/number.cpp b/src/utils/number.cpp index 4dc7309..6f79abb 100644 --- a/src/utils/number.cpp +++ b/src/utils/number.cpp @@ -3,8 +3,7 @@ #include #include -std::string to_human_string(const int64_t u) -{ +std::string to_human_string(const int64_t u) { std::stringstream ss; if (u > 1000000000) ss << std::fixed << std::setprecision(2) << u / 1000000000.0 << "B"; @@ -17,8 +16,7 @@ std::string to_human_string(const int64_t u) return ss.str(); } -int64_t my_string2int64(const std::wstring &s) -{ +int64_t my_string2int64(const std::wstring &s) { int64_t ans = 0; int64_t f = 1; bool is_digit = false; @@ -26,39 +24,33 @@ int64_t my_string2int64(const std::wstring &s) if (s[i] == L'-') { f = -1; is_digit = true; - } - else if (L'0' <= s[i] && s[i] <= L'9') { + } else if (L'0' <= s[i] && s[i] <= L'9') { ans = ans * 10 + s[i] - L'0'; is_digit = true; - } - else if (is_digit) { + } else if (is_digit) { break; } } return ans * f; } -uint64_t my_string2uint64(const std::wstring &s) -{ +uint64_t my_string2uint64(const std::wstring &s) { uint64_t ans = 0; bool is_digit = false; for (size_t i = 0; i < s.length(); i++) { if (s[i] == L'-') { is_digit = true; - } - else if (L'0' <= s[i] && s[i] <= L'9') { + } else if (L'0' <= s[i] && s[i] <= L'9') { ans = ans * 10 + s[i] - L'0'; is_digit = true; - } - else if (is_digit) { + } else if (is_digit) { break; } } return ans; } -int64_t my_string2int64(const std::string &s) -{ +int64_t my_string2int64(const std::string &s) { int64_t ans = 0; int64_t f = 1; bool is_digit = false; @@ -66,31 +58,26 @@ int64_t my_string2int64(const std::string &s) if (s[i] == '-') { f = -1; is_digit = true; - } - else if ('0' <= s[i] && s[i] <= '9') { + } else if ('0' <= s[i] && s[i] <= '9') { ans = ans * 10 + s[i] - '0'; is_digit = true; - } - else if (is_digit) { + } else if (is_digit) { break; } } return ans * f; } -uint64_t my_string2uint64(const std::string &s) -{ +uint64_t my_string2uint64(const std::string &s) { uint64_t ans = 0; bool is_digit = false; for (size_t i = 0; i < s.length(); i++) { if (s[i] == '-') { is_digit = true; - } - else if ('0' <= s[i] && s[i] <= '9') { + } else if ('0' <= s[i] && s[i] <= '9') { ans = ans * 10 + s[i] - '0'; is_digit = true; - } - else if (is_digit) { + } else if (is_digit) { break; } } diff --git a/src/utils/qq_utils.cpp b/src/utils/qq_utils.cpp index f87fe32..3d6e116 100644 --- a/src/utils/qq_utils.cpp +++ b/src/utils/qq_utils.cpp @@ -5,8 +5,7 @@ #include #include -std::string get_stranger_name(const bot *p, userid_t user_id) -{ +std::string get_stranger_name(const bot *p, userid_t user_id) { Json::Value input; input["user_id"] = user_id; std::string res = p->cq_send("get_stranger_info", input); @@ -19,8 +18,7 @@ std::string get_stranger_name(const bot *p, userid_t user_id) } std::string get_group_member_name(const bot *p, userid_t user_id, - groupid_t group_id) -{ + groupid_t group_id) { Json::Value input; input["user_id"] = user_id; input["group_id"] = group_id; @@ -38,18 +36,15 @@ std::string get_group_member_name(const bot *p, userid_t user_id, return name; } -std::string get_username(const bot *p, userid_t user_id, groupid_t group_id) -{ +std::string get_username(const bot *p, userid_t user_id, groupid_t group_id) { if (group_id == 0) { return get_stranger_name(p, user_id); - } - else { + } else { return get_group_member_name(p, user_id, group_id); } } -userid_t extract_qq_from_at_segment(const std::string &seg) -{ +userid_t extract_qq_from_at_segment(const std::string &seg) { size_t qq_pos = seg.find("qq="); if (qq_pos == std::string::npos) { return 0; @@ -62,8 +57,7 @@ userid_t extract_qq_from_at_segment(const std::string &seg) return my_string2uint64(seg.substr(qq_pos, qq_end - qq_pos)); } -std::string display_name_in_group(const msg_meta &conf, userid_t user_id) -{ +std::string display_name_in_group(const msg_meta &conf, userid_t user_id) { std::string name = get_username(conf.p, user_id, conf.group_id); if (!trim(name).empty()) { return name; @@ -72,8 +66,7 @@ std::string display_name_in_group(const msg_meta &conf, userid_t user_id) } bool is_folder_exist(const bot *p, const groupid_t &group_id, - const std::string &path) -{ + const std::string &path) { Json::Value J; J["group_id"] = group_id; J = string_to_json( @@ -88,8 +81,7 @@ bool is_folder_exist(const bot *p, const groupid_t &group_id, } std::string get_folder_id(const bot *p, const groupid_t &group_id, - const std::string &path) -{ + const std::string &path) { Json::Value J; J["group_id"] = group_id; J = string_to_json( @@ -107,8 +99,7 @@ std::string get_folder_id(const bot *p, const groupid_t &group_id, * file: reletive path */ void upload_file(bot *p, const fs::path &file, const groupid_t &group_id, - const std::string &path) -{ + const std::string &path) { try { if (!is_folder_exist(p, group_id, path) && is_group_op(p, group_id, p->get_botqq())) { @@ -128,16 +119,14 @@ void upload_file(bot *p, const fs::path &file, const groupid_t &group_id, if (J.isMember("msg")) { p->cq_send(J.toStyledString(), msg_meta("group", 0, group_id, 0)); } - } - catch (...) { + } catch (...) { p->setlog(LOG::WARNING, "File upload failed."); p->cq_send("File upload failed.", msg_meta("group", 0, group_id, 0)); } } bool is_group_op(const bot *p, const groupid_t &group_id, - const userid_t &user_id) -{ + const userid_t &user_id) { if (group_id == 0) return false; Json::Value J; @@ -150,8 +139,7 @@ bool is_group_op(const bot *p, const groupid_t &group_id, } bool is_group_member(const bot *p, const groupid_t &group_id, - const userid_t &user_id) -{ + const userid_t &user_id) { Json::Value J; J["group_id"] = group_id; J = string_to_json(p->cq_send("get_group_member_list", J)); @@ -164,8 +152,7 @@ bool is_group_member(const bot *p, const groupid_t &group_id, return false; } -bool is_friend(const bot *p, const userid_t &user_id) -{ +bool is_friend(const bot *p, const userid_t &user_id) { Json::Value J = string_to_json(p->cq_get("get_friend_list"))["data"]; Json::ArrayIndex sz = J.size(); for (Json::ArrayIndex i = 0; i < sz; i++) { @@ -177,8 +164,7 @@ bool is_friend(const bot *p, const userid_t &user_id) } void send_file_private(const bot *p, const userid_t user_id, - const fs::path &path) -{ + const fs::path &path) { Json::Value J; J["user_id"] = user_id; J["file"] = path.string(); diff --git a/src/utils/random.cpp b/src/utils/random.cpp index e842e24..bb354cb 100644 --- a/src/utils/random.cpp +++ b/src/utils/random.cpp @@ -5,27 +5,23 @@ using u32 = uint32_t; using engine = std::mt19937; -engine &rng() -{ +engine &rng() { thread_local static engine gen(std::random_device{}()); return gen; } -int get_random(int maxi) -{ +int get_random(int maxi) { if (maxi <= 0) return 0; return std::uniform_int_distribution(0, maxi - 1)(rng()); } -int get_random(int mini, int maxi) -{ +int get_random(int mini, int maxi) { if (maxi <= mini) return mini; return std::uniform_int_distribution(mini, maxi - 1)(rng()); } -float get_random_f(float mini, float maxi) -{ +float get_random_f(float mini, float maxi) { return std::uniform_real_distribution(mini, maxi)(rng()); } \ No newline at end of file diff --git a/src/utils/string_utils.cpp b/src/utils/string_utils.cpp index 9a1fbe3..be2f0f0 100644 --- a/src/utils/string_utils.cpp +++ b/src/utils/string_utils.cpp @@ -6,20 +6,17 @@ static std::wstring_convert> converter; -std::wstring string_to_wstring(const std::string &u) -{ +std::wstring string_to_wstring(const std::string &u) { return converter.from_bytes(u); } -std::string wstring_to_string(const std::wstring &u) -{ +std::string wstring_to_string(const std::wstring &u) { return converter.to_bytes(u); } static std::string whitespaces = "\t\r\n "; static std::wstring w_whitespaces = L"\t\r\n "; -std::string trim(const std::string &u) -{ +std::string trim(const std::string &u) { size_t fir = u.find_first_not_of(whitespaces); if (fir == std::string::npos) { return ""; @@ -28,20 +25,17 @@ std::string trim(const std::string &u) return u.substr(fir, las - fir + 1); } -bool starts_with(const std::string &s, const std::string &prefix) -{ +bool starts_with(const std::string &s, const std::string &prefix) { return s.size() >= prefix.size() && s.compare(0, prefix.size(), prefix) == 0; } -bool starts_with(const std::wstring &s, const std::wstring &prefix) -{ +bool starts_with(const std::wstring &s, const std::wstring &prefix) { return s.size() >= prefix.size() && s.compare(0, prefix.size(), prefix) == 0; } -std::wstring trim(const std::wstring &u) -{ +std::wstring trim(const std::wstring &u) { size_t fir = u.find_first_not_of(w_whitespaces); if (fir == std::wstring::npos) { return L""; @@ -50,8 +44,7 @@ std::wstring trim(const std::wstring &u) return u.substr(fir, las - fir + 1); } -std::string my_replace(const std::string &s, const char old, const char ne) -{ +std::string my_replace(const std::string &s, const char old, const char ne) { // std::string ans; // for (size_t i = 0; i < s.length(); i++) { // if (s[i] == old) { @@ -67,8 +60,7 @@ std::string my_replace(const std::string &s, const char old, const char ne) return u; } -std::string cq_encode(const std::string &input) -{ +std::string cq_encode(const std::string &input) { std::regex amp("&"); std::regex lBracket("\\["); std::regex rBracket("\\]"); @@ -82,8 +74,7 @@ std::string cq_encode(const std::string &input) return result; } -std::string cq_decode(const std::string &input) -{ +std::string cq_decode(const std::string &input) { std::regex amp("&"); std::regex lBracket("["); std::regex rBracket("]"); @@ -97,8 +88,7 @@ std::string cq_decode(const std::string &input) return result; } -std::wstring cq_encode(const std::wstring &input) -{ +std::wstring cq_encode(const std::wstring &input) { std::wregex amp(L"&"); std::wregex lBracket(L"\\["); std::wregex rBracket(L"\\]"); @@ -112,8 +102,7 @@ std::wstring cq_encode(const std::wstring &input) return result; } -std::wstring cq_decode(const std::wstring &input) -{ +std::wstring cq_decode(const std::wstring &input) { std::wregex amp(L"&"); std::wregex lBracket(L"["); std::wregex rBracket(L"]"); @@ -127,8 +116,7 @@ std::wstring cq_decode(const std::wstring &input) return result; } -std::pair split_http_addr(const std::string &addr) -{ +std::pair split_http_addr(const std::string &addr) { size_t p = addr.find("/"); while (p != addr.npos && ((p > 0 && addr[p - 1] == '/') || (p < addr.length() && addr[p + 1] == '/'))) { @@ -136,14 +124,12 @@ std::pair split_http_addr(const std::string &addr) } if (p == addr.npos) { return std::make_pair(addr, ""); - } - else { + } else { return std::make_pair(addr.substr(0, p), addr.substr(p)); } } -float similarity(const std::string &s1, const std::string &s2) -{ +float similarity(const std::string &s1, const std::string &s2) { size_t m = s1.length(); size_t n = s2.length(); std::vector> dp(m + 1, std::vector(n + 1)); @@ -151,11 +137,9 @@ float similarity(const std::string &s1, const std::string &s2) for (size_t j = 0; j <= n; j++) { if (i == 0 || j == 0) { dp[i][j] = 0; - } - else if (s1[i - 1] == s2[j - 1]) { + } else if (s1[i - 1] == s2[j - 1]) { dp[i][j] = dp[i - 1][j - 1] + 1; - } - else { + } else { dp[i][j] = std::max(dp[i - 1][j], dp[i][j - 1]); } } @@ -163,8 +147,7 @@ float similarity(const std::string &s1, const std::string &s2) return (float)dp[m][n] / n; } -float similarity(const std::wstring &s1, const std::wstring &s2) -{ +float similarity(const std::wstring &s1, const std::wstring &s2) { size_t m = s1.length(); size_t n = s2.length(); std::vector> dp(m + 1, std::vector(n + 1)); @@ -172,11 +155,9 @@ float similarity(const std::wstring &s1, const std::wstring &s2) for (size_t j = 0; j <= n; j++) { if (i == 0 || j == 0) { dp[i][j] = 0; - } - else if (s1[i - 1] == s2[j - 1]) { + } else if (s1[i - 1] == s2[j - 1]) { dp[i][j] = dp[i - 1][j - 1] + 1; - } - else { + } else { dp[i][j] = std::max(dp[i - 1][j], dp[i][j - 1]); } }