diff options
| author | ilotterytea <iltsu@alright.party> | 2025-04-17 02:40:32 +0500 |
|---|---|---|
| committer | ilotterytea <iltsu@alright.party> | 2025-04-17 02:40:32 +0500 |
| commit | 0d1935d624a0f7c10cadc752c37f354bc792af32 (patch) | |
| tree | 18a0fa759b8efc9bb09d10e9207b939f2adbed83 | |
| parent | 05a2b0472ed116fb5939a25e44aaecbcfa9d7537 (diff) | |
feat: !timer in lua
| -rw-r--r-- | bot/src/commands/command.cpp | 3 | ||||
| -rw-r--r-- | bot/src/modules/timer.hpp | 113 | ||||
| -rw-r--r-- | luamods/timer.lua | 210 |
3 files changed, 210 insertions, 116 deletions
diff --git a/bot/src/commands/command.cpp b/bot/src/commands/command.cpp index 410d5ba..417746c 100644 --- a/bot/src/commands/command.cpp +++ b/bot/src/commands/command.cpp @@ -13,7 +13,6 @@ #include <string> #include "../bundle.hpp" -#include "../modules/timer.hpp" #include "../utils/chrono.hpp" #include "commands/lua.hpp" #include "modules/lua.hpp" @@ -23,8 +22,6 @@ namespace bot { namespace command { CommandLoader::CommandLoader() { - this->add_command(std::make_unique<mod::Timer>()); - this->add_command(std::make_unique<mod::LuaExecution>()); this->add_command(std::make_unique<mod::LuaRemoteExecution>()); diff --git a/bot/src/modules/timer.hpp b/bot/src/modules/timer.hpp deleted file mode 100644 index 5fd3549..0000000 --- a/bot/src/modules/timer.hpp +++ /dev/null @@ -1,113 +0,0 @@ -#pragma once - -#include <string> -#include <vector> - -#include "../bundle.hpp" -#include "../commands/command.hpp" -#include "../commands/response_error.hpp" - -namespace bot { - namespace mod { - class Timer : public command::Command { - std::string get_name() const override { return "timer"; } - - schemas::PermissionLevel get_permission_level() const override { - return schemas::PermissionLevel::MODERATOR; - } - - std::vector<std::string> get_subcommand_ids() const override { - return {"new", "remove"}; - } - - command::Response run(const InstanceBundle &bundle, - const command::Request &request) const override { - if (!request.subcommand_id.has_value()) { - throw ResponseException<NOT_ENOUGH_ARGUMENTS>( - request, bundle.localization, command::SUBCOMMAND); - } - - const std::string &subcommand_id = request.subcommand_id.value(); - - if (!request.message.has_value()) { - throw ResponseException<ResponseError::NOT_ENOUGH_ARGUMENTS>( - request, bundle.localization, command::CommandArgument::NAME); - } - - const std::string &message = request.message.value(); - std::vector<std::string> s = utils::string::split_text(message, ' '); - - std::string name = s[0]; - s.erase(s.begin()); - - pqxx::work work(request.conn); - pqxx::result timers = work.exec( - "SELECT id FROM timers WHERE name = '" + name + - "' AND channel_id = " + std::to_string(request.channel.get_id())); - - if (subcommand_id == "new") { - if (!timers.empty()) { - throw ResponseException<ResponseError::NAMESAKE_CREATION>( - request, bundle.localization, name); - } - - if (s.empty()) { - throw ResponseException<ResponseError::NOT_ENOUGH_ARGUMENTS>( - request, bundle.localization, - command::CommandArgument::INTERVAL); - } - - int interval_s; - - try { - interval_s = std::stoi(s[0]); - } catch (std::exception e) { - throw ResponseException<ResponseError::INCORRECT_ARGUMENT>( - request, bundle.localization, s[0]); - } - - s.erase(s.begin()); - - if (s.empty()) { - throw ResponseException<ResponseError::NOT_ENOUGH_ARGUMENTS>( - request, bundle.localization, - command::CommandArgument::MESSAGE); - } - - std::string m = utils::string::str(s.begin(), s.end(), ' '); - - work.exec( - "INSERT INTO timers(channel_id, name, message, interval_sec) " - "VALUES " - "(" + - std::to_string(request.channel.get_id()) + ", '" + name + - "', '" + m + "', " + std::to_string(interval_s) + ")"); - work.commit(); - - return command::Response( - bundle.localization - .get_formatted_line(request, loc::LineId::TimerNew, {name}) - .value()); - } else if (subcommand_id == "remove") { - if (timers.empty()) { - throw ResponseException<ResponseError::NOT_FOUND>( - request, bundle.localization, name); - } - - work.exec("DELETE FROM timers WHERE id = " + - std::to_string(timers[0][0].as<int>())); - work.commit(); - - return command::Response( - bundle.localization - .get_formatted_line(request, loc::LineId::TimerDelete, - {name}) - .value()); - } - - throw ResponseException<ResponseError::SOMETHING_WENT_WRONG>( - request, bundle.localization); - } - }; - } -} diff --git a/luamods/timer.lua b/luamods/timer.lua new file mode 100644 index 0000000..c76dcc1 --- /dev/null +++ b/luamods/timer.lua @@ -0,0 +1,210 @@ +local lines = { + english = { + ["no_subcommand"] = + "{sender.alias_name}: No subcommand provided. Use '{channel.prefix}help timer' for more info.", + ["no_message"] = "{sender.alias_name}: No message provided.", + ["list"] = "{sender.alias_name}: %s", + ["no_list"] = "{sender.alias_name}: There are no timers in this channel.", + ["namesake"] = "{sender.alias_name}: A timer with the same name already exists.", + ["new"] = "{sender.alias_name}: Created a new timer %s! First execution will be in %s.", + ["not_found"] = "{sender.alias_name}: Timer %s does not exist.", + ["delete"] = "{sender.alias_name}: Successfully deleted timer %s", + ["edit"] = "{sender.alias_name}: Edited the message for timer %s", + ["no_new_name"] = "{sender.alias_name}: No new name provided.", + ["rename"] = "{sender.alias_name}: Renamed timer from %s to %s", + ["no_interval"] = "{sender.alias_name}: No interval (in seconds) provided.", + ["bad_interval"] = "{sender.alias_name}: Interval (in seconds) must be a number. (%s)", + ["interval"] = "{sender.alias_name}: Changed an interval for timer %s. Next execution will be in %s.", + ["view"] = "{sender.alias_name}: ID %s | %s | Runs every %s | %s", + }, + russian = { + ["no_subcommand"] = + "{sender.alias_name}: Нет подкоманды. Используйте '{channel.prefix}help cmd', чтобы получить больше информации.", + ["no_message"] = "{sender.alias_name}: Сообщение не предоставлено.", + ["list"] = "{sender.alias_name}: %s", + ["no_list"] = "{sender.alias_name}: На этом канале нет таймеров.", + ["namesake"] = "{sender.alias_name}: Таймер с таким же именем уже существует.", + ["new"] = "{sender.alias_name}: Успешно создан новый таймер %s! Первый запуск будет через %s.", + ["not_found"] = "{sender.alias_name}: Таймер %s не существует.", + ["delete"] = "{sender.alias_name}: Успешно удален таймер %s", + ["edit"] = "{sender.alias_name}: Сообщение для таймера %s было успешно отредактировано.", + ["no_new_name"] = "{sender.alias_name}: Новое имя не было предоставлено.", + ["rename"] = "{sender.alias_name}: Таймер %s был переименован в %s", + ["no_interval"] = "{sender.alias_name}: Интервал (в секундах) не предоставлен.", + ["bad_interval"] = "{sender.alias_name}: Интервал (в секундах) должен быть числом. (%s)", + ["interval"] = "{sender.alias_name}: Изменил интервал для таймера %s. Следующий запуск будет через %s.", + ["view"] = "{sender.alias_name}: ID %s | %s | Каждые %s | %s", + }, +} + +return { + name = "timer", + description = [[ +> This command is for broadcaster and moderators only + + +The `!timer` command gives the ability to create timers that sends messages to the chat room every specified interval. + + +## Syntax + +### Create a new timer +`!timer new [name] [interval] [message...]` + ++ `[name]` - The name for new timer. It should be unique for your chat. ++ `[interval]` - Message sending interval *(in seconds)*. ++ `[message]` - Text that will be sent after the interval has passed. + +### Delete the timer +`!timer delete [name]` OR `!timer remove [name]` + ++ `[name]` - The name of the timer. + +### Edit the message for the timer +`!timer edit [name] [message...]` + ++ `[name]` - The name of the timer. ++ `[message]` - Text with which to replace. + +### Edit the interval for the timer +`!timer interval [name] [interval]` + ++ `[name]` - The name of the timer. ++ `[interval]` - An interval *(in seconds)* with which to replace. + +### Check the information about the timer +`!timer view [name]` + ++ `[name]` - The name of the timer. + +### Call the timer +`!timer call [name]` + ++ `[name]` - The name of the timer. + +### Get the list of created timers +`!timer list` +]], + delay_sec = 1, + options = {}, + subcommands = { "new", "delete", "remove", "interval", "edit", "rename", "list", "view", "call" }, + aliases = {}, + minimal_rights = "moderator", + handle = function(request) + if request.subcommand_id == nil then + return l10n_custom_formatted_line_request(request, lines, "no_subcommand", {}) + end + + local scid = request.subcommand_id + + if scid == "list" then + local cmds = db_query('SELECT name FROM timers WHERE channel_id = $1', { request.channel.id }) + local names = {} + for i = 1, #cmds, 1 do + table.insert(names, cmds[i].name) + end + + if #names == 0 then + return l10n_custom_formatted_line_request(request, lines, "no_list", {}) + end + + return l10n_custom_formatted_line_request(request, lines, "list", { table.concat(names, ', ') }) + end + + if request.message == nil then + return l10n_custom_formatted_line_request(request, lines, "no_message", {}) + end + + local parts = str_split(request.message, ' ') + + local name = parts[1] + table.remove(parts, 1) + + local timers = db_query( + 'SELECT id, name, interval_sec, message FROM timers WHERE name = $1 AND channel_id = $2', + { name, request.channel.id }) + + if scid == "new" then + if #timers > 0 then + return l10n_custom_formatted_line_request(request, lines, "namesake", {}) + end + + if #parts == 0 then + return l10n_custom_formatted_line_request(request, lines, "no_interval", {}) + end + + local interval_sec = tonumber(parts[1]) + if interval_sec == nil then + return l10n_custom_formatted_line_request(request, lines, "bad_interval", { parts[1] }) + end + table.remove(parts, 1) + + if #parts == 0 then + return l10n_custom_formatted_line_request(request, lines, "no_message", {}) + end + + local message = table.concat(parts, ' ') + + db_execute('INSERT INTO timers(channel_id, name, interval_sec, message) VALUES ($1, $2, $3, $4)', + { request.channel.id, name, interval_sec, message }) + + return l10n_custom_formatted_line_request(request, lines, "new", { name, time_humanize(interval_sec) }) + end + + if #timers == 0 then + return l10n_custom_formatted_line_request(request, lines, "not_found", { name }) + end + + local timer = timers[1] + + if scid == "delete" or scid == "remove" then + db_execute('DELETE FROM timers WHERE id = $1', { timer.id }) + return l10n_custom_formatted_line_request(request, lines, "delete", { name }) + elseif scid == "edit" then + if #parts == 0 then + return l10n_custom_formatted_line_request(request, lines, "no_message", {}) + end + + local message = table.concat(parts, ' ') + + db_execute('UPDATE timers SET message = $1 WHERE id = $2', { message, timer.id }) + + return l10n_custom_formatted_line_request(request, lines, "edit", { name }) + elseif scid == "rename" then + if #parts == 0 then + return l10n_custom_formatted_line_request(request, lines, "no_new_name", {}) + end + + local new_name = parts[1] + + local new_timers = db_query('SELECT id FROM timers WHERE name = $1', { new_name }) + if #new_timers > 0 then + return l10n_custom_formatted_line_request(request, lines, "namesake", {}) + end + + db_execute('UPDATE timers SET name = $1 WHERE id = $2', { new_name, timer.id }) + + return l10n_custom_formatted_line_request(request, lines, "rename", { name, new_name }) + elseif scid == "interval" then + if #parts == 0 then + return l10n_custom_formatted_line_request(request, lines, "no_interval", {}) + end + + local interval_sec = tonumber(parts[1]) + if interval_sec == nil then + return l10n_custom_formatted_line_request(request, lines, "bad_interval", { parts[1] }) + end + + db_execute('UPDATE timers SET interval_sec = $1 WHERE id = $2', + { interval_sec, timer.id }) + + return l10n_custom_formatted_line_request(request, lines, "interval", + { name, time_humanize(interval_sec) }) + elseif scid == "view" then + return l10n_custom_formatted_line_request(request, lines, "view", + { timer.id, timer.name, time_humanize(tonumber(timer.interval_sec)), timer.message }) + elseif scid == "call" then + return timer.message + end + end, +} |
