Basic command creation/overwriting system
This commit is contained in:
parent
005dad899b
commit
3656080a43
@ -11,6 +11,7 @@ GatewayHandler::GatewayHandler() {
|
|||||||
last_seq = 0;
|
last_seq = 0;
|
||||||
|
|
||||||
ah = std::make_shared<APIHelper>();
|
ah = std::make_shared<APIHelper>();
|
||||||
|
command_helper = std::make_unique<CommandHelper>();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GatewayHandler::handle_data(std::string data, client &c, websocketpp::connection_hdl &hdl) {
|
void GatewayHandler::handle_data(std::string data, client &c, websocketpp::connection_hdl &hdl) {
|
||||||
@ -95,6 +96,7 @@ void GatewayHandler::on_dispatch(json decoded, client &c, websocketpp::connectio
|
|||||||
|
|
||||||
std::vector<std::string> words;
|
std::vector<std::string> words;
|
||||||
boost::split(words, message, boost::is_any_of(" "));
|
boost::split(words, message, boost::is_any_of(" "));
|
||||||
|
Command custom_command;
|
||||||
if (words[0] == "`trivia" || words[0] == "`t") {
|
if (words[0] == "`trivia" || words[0] == "`t") {
|
||||||
int questions = 10;
|
int questions = 10;
|
||||||
int delay = 8;
|
int delay = 8;
|
||||||
@ -136,14 +138,6 @@ void GatewayHandler::on_dispatch(json decoded, client &c, websocketpp::connectio
|
|||||||
games[channel->id] = std::make_unique<TriviaGame>(this, ah, channel->id, questions, delay);
|
games[channel->id] = std::make_unique<TriviaGame>(this, ah, channel->id, questions, delay);
|
||||||
games[channel->id]->start();
|
games[channel->id]->start();
|
||||||
}
|
}
|
||||||
else if (words[0] == "`channels") {
|
|
||||||
std::string m = "Channel List:\n";
|
|
||||||
for (auto ch : channels) {
|
|
||||||
m += "> " + ch.second->name + " (" + ch.second->id + ") [" + ch.second->type + "] Guild: "
|
|
||||||
+ guilds[ch.second->guild_id]->name + " (" + ch.second->guild_id + ")\n";
|
|
||||||
}
|
|
||||||
ah->send_message(channel->id, m);
|
|
||||||
}
|
|
||||||
else if (words[0] == "`guilds") {
|
else if (words[0] == "`guilds") {
|
||||||
std::string m = "Guild List:\n";
|
std::string m = "Guild List:\n";
|
||||||
for (auto &gu : guilds) {
|
for (auto &gu : guilds) {
|
||||||
@ -154,13 +148,40 @@ void GatewayHandler::on_dispatch(json decoded, client &c, websocketpp::connectio
|
|||||||
else if (words[0] == "`info") {
|
else if (words[0] == "`info") {
|
||||||
ah->send_message(channel->id, ":information_source: trivia-bot by Jack. <http://github.com/jackb-p/TriviaDiscord>");
|
ah->send_message(channel->id, ":information_source: trivia-bot by Jack. <http://github.com/jackb-p/TriviaDiscord>");
|
||||||
}
|
}
|
||||||
else if (words[0] == "`js") {
|
else if (words[0] == "`js" && message.length() > 4) {
|
||||||
std::string js = message.erase(0, 3);
|
std::string js = message.substr(4);
|
||||||
auto it = v8_instances.find(channel->guild_id);
|
auto it = v8_instances.find(channel->guild_id);
|
||||||
if (it != v8_instances.end()) {
|
if (it != v8_instances.end() && js.length() > 0) {
|
||||||
it->second->exec_js(js, channel->id);
|
it->second->exec_js(js, channel->id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (words[0] == "`createjs" && message.length() > 8) {
|
||||||
|
std::string args = message.substr(10);
|
||||||
|
size_t seperator_loc = args.find("|");
|
||||||
|
if (seperator_loc != std::string::npos) {
|
||||||
|
std::string command_name = args.substr(0, seperator_loc);
|
||||||
|
std::string script = args.substr(seperator_loc + 1);
|
||||||
|
int result = command_helper->insert_command(channel->guild_id, command_name, script);
|
||||||
|
switch (result) {
|
||||||
|
case 0:
|
||||||
|
ah->send_message(channel->id, ":warning: Error!"); break;
|
||||||
|
case 1:
|
||||||
|
ah->send_message(channel->id, ":new: Command `" + command_name + "` successfully created."); break;
|
||||||
|
case 2:
|
||||||
|
ah->send_message(channel->id, ":arrow_heading_up: Command `" + command_name + "` successfully updated."); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (words[0] == "`shutdown" && sender.id == "82232146579689472") { // it me
|
||||||
|
ah->send_message(channel->id, ":zzz: Goodbye!");
|
||||||
|
c.close(hdl, websocketpp::close::status::going_away, "`shutdown command used.");
|
||||||
|
}
|
||||||
|
else if (command_helper->get_command(channel->guild_id, words[0], custom_command)) {
|
||||||
|
auto it = v8_instances.find(channel->guild_id);
|
||||||
|
if (it != v8_instances.end() && custom_command.script.length() > 0) {
|
||||||
|
it->second->exec_js(custom_command.script, channel->id);
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (games.find(channel->id) != games.end()) { // message received in channel with ongoing game
|
else if (games.find(channel->id) != games.end()) { // message received in channel with ongoing game
|
||||||
games[channel->id]->handle_answer(message, sender);
|
games[channel->id]->handle_answer(message, sender);
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include "json/json.hpp"
|
#include "json/json.hpp"
|
||||||
|
|
||||||
#include "TriviaGame.hpp"
|
#include "TriviaGame.hpp"
|
||||||
|
#include "js/CommandHelper.hpp"
|
||||||
#include "js/V8Instance.hpp"
|
#include "js/V8Instance.hpp"
|
||||||
#include "data_structures/User.hpp"
|
#include "data_structures/User.hpp"
|
||||||
#include "data_structures/Guild.hpp"
|
#include "data_structures/Guild.hpp"
|
||||||
@ -62,6 +63,8 @@ private:
|
|||||||
// bot's user obj
|
// bot's user obj
|
||||||
DiscordObjects::User user_object;
|
DiscordObjects::User user_object;
|
||||||
|
|
||||||
|
std::unique_ptr<CommandHelper> command_helper;
|
||||||
|
|
||||||
// <id, ptr to data>
|
// <id, ptr to data>
|
||||||
std::map<std::string, std::unique_ptr<DiscordObjects::Guild>> guilds;
|
std::map<std::string, std::unique_ptr<DiscordObjects::Guild>> guilds;
|
||||||
// channels pointers are shared pointers, held here but also in guild objects
|
// channels pointers are shared pointers, held here but also in guild objects
|
||||||
|
@ -40,8 +40,6 @@ int main(int argc, char *argv[]) {
|
|||||||
std::cerr << "other exception" << std::endl;
|
std::cerr << "other exception" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::getchar();
|
|
||||||
|
|
||||||
v8::V8::Dispose();
|
v8::V8::Dispose();
|
||||||
v8::V8::ShutdownPlatform();
|
v8::V8::ShutdownPlatform();
|
||||||
delete platform;
|
delete platform;
|
||||||
|
@ -1,14 +1,20 @@
|
|||||||
BEGIN TRANSACTION;
|
BEGIN TRANSACTION;
|
||||||
CREATE TABLE "TotalScores" (
|
CREATE TABLE "TotalScores" (
|
||||||
`User` TEXT UNIQUE,
|
`User` TEXT NOT NULL,
|
||||||
`TotalScore` INTEGER,
|
`TotalScore` INTEGER NOT NULL,
|
||||||
`AverageTime` INTEGER,
|
`AverageTime` INTEGER NOT NULL,
|
||||||
PRIMARY KEY(User)
|
PRIMARY KEY(User)
|
||||||
);
|
);
|
||||||
CREATE TABLE "Questions" (
|
CREATE TABLE "Questions" (
|
||||||
`ID` INTEGER PRIMARY KEY AUTOINCREMENT,
|
`ID` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
`Category` TEXT,
|
`Category` TEXT NOT NULL,
|
||||||
`Question` TEXT,
|
`Question` TEXT NOT NULL,
|
||||||
`Answer` TEXT
|
`Answer` TEXT NOT NULL
|
||||||
|
);
|
||||||
|
CREATE TABLE `CustomJS` (
|
||||||
|
`ID` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
`GuildID` TEXT NOT NULL,
|
||||||
|
`CommandName` TEXT NOT NULL,
|
||||||
|
`Script` TEXT NOT NULL
|
||||||
);
|
);
|
||||||
COMMIT;
|
COMMIT;
|
153
TriviaBot/bot/js/CommandHelper.cpp
Normal file
153
TriviaBot/bot/js/CommandHelper.cpp
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
#include "CommandHelper.hpp"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include <sqlite3.h>
|
||||||
|
|
||||||
|
CommandHelper::CommandHelper() {
|
||||||
|
sqlite3 *db; int return_code;
|
||||||
|
return_code = sqlite3_open("bot/db/trivia.db", &db);
|
||||||
|
|
||||||
|
std::string sql = "SELECT * FROM CustomJS";
|
||||||
|
|
||||||
|
sqlite3_stmt *stmt;
|
||||||
|
return_code = sqlite3_prepare_v2(db, sql.c_str(), -1, &stmt, 0);
|
||||||
|
|
||||||
|
|
||||||
|
while (return_code != SQLITE_DONE) {
|
||||||
|
return_code = sqlite3_step(stmt);
|
||||||
|
|
||||||
|
if (return_code == SQLITE_ROW) {
|
||||||
|
std::string guild_id = reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0));
|
||||||
|
std::string command_name = reinterpret_cast<const char *>(sqlite3_column_text(stmt, 1));
|
||||||
|
std::string script = reinterpret_cast<const char *>(sqlite3_column_text(stmt, 2));
|
||||||
|
|
||||||
|
commands.push_back({ guild_id, command_name, script });
|
||||||
|
}
|
||||||
|
else if (return_code != SQLITE_DONE) {
|
||||||
|
sqlite3_finalize(stmt);
|
||||||
|
std::cerr << "SQLite error." << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << commands.size() << " commands loaded." << std::endl;
|
||||||
|
|
||||||
|
sqlite3_finalize(stmt);
|
||||||
|
sqlite3_close(db);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CommandHelper::get_command(std::string guild_id, std::string command_name, Command &command) {
|
||||||
|
auto check_lambda = [guild_id, command_name](const Command &c) {
|
||||||
|
return guild_id == c.guild_id && command_name == c.command_name;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto it = std::find_if(commands.begin(), commands.end(), check_lambda);
|
||||||
|
if (it == commands.end()) {
|
||||||
|
command = {};
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
command = { it->guild_id, it->command_name, it->script };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns: 0 error, 1 inserted, 2 updated
|
||||||
|
int CommandHelper::insert_command(std::string guild_id, std::string command_name, std::string script) {
|
||||||
|
// TODO: if script empty, delete command
|
||||||
|
|
||||||
|
Command command { guild_id, command_name, script };
|
||||||
|
|
||||||
|
int ret_value;
|
||||||
|
std::string sql;
|
||||||
|
if (command_in_db(guild_id, command_name)) {
|
||||||
|
sql = "UPDATE CustomJS SET Script=?1 WHERE GuildID=?2 AND CommandName=?3;";
|
||||||
|
std::cout << "Command already exists, updating." << std::endl;
|
||||||
|
ret_value = 2;
|
||||||
|
} else {
|
||||||
|
sql = "INSERT INTO CustomJS(Script, GuildID, CommandName) VALUES (?1, ?2, ?3);";
|
||||||
|
std::cout << "Inserting new command." << std::endl;
|
||||||
|
ret_value = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlite3 *db; int return_code;
|
||||||
|
return_code = sqlite3_open("bot/db/trivia.db", &db);
|
||||||
|
if (!return_code_ok(return_code)) return 0;
|
||||||
|
|
||||||
|
sqlite3_stmt *stmt;
|
||||||
|
return_code = sqlite3_prepare_v2(db, sql.c_str(), -1, &stmt, 0);
|
||||||
|
if (!return_code_ok(return_code)) return 0;
|
||||||
|
|
||||||
|
return_code = sqlite3_bind_text(stmt, 1, script.c_str(), -1, (sqlite3_destructor_type)-1);
|
||||||
|
if (!return_code_ok(return_code)) return 0;
|
||||||
|
|
||||||
|
return_code = sqlite3_bind_text(stmt, 2, guild_id.c_str(), -1, (sqlite3_destructor_type)-1);
|
||||||
|
if (!return_code_ok(return_code)) return 0;
|
||||||
|
|
||||||
|
return_code = sqlite3_bind_text(stmt, 3, command_name.c_str(), -1, (sqlite3_destructor_type)-1);
|
||||||
|
if (!return_code_ok(return_code)) return 0;
|
||||||
|
|
||||||
|
return_code = sqlite3_step(stmt);
|
||||||
|
bool success = return_code == SQLITE_DONE;
|
||||||
|
|
||||||
|
sqlite3_finalize(stmt);
|
||||||
|
sqlite3_close(db);
|
||||||
|
|
||||||
|
if (success) {
|
||||||
|
if (ret_value == 1) {
|
||||||
|
commands.push_back({ guild_id, command_name, script });
|
||||||
|
}
|
||||||
|
if (ret_value == 2) {
|
||||||
|
// update command, don't add
|
||||||
|
auto check_lambda = [guild_id, command_name](const Command &c) {
|
||||||
|
return guild_id == c.guild_id && command_name == c.command_name;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto it = std::find_if(commands.begin(), commands.end(), check_lambda);
|
||||||
|
if (it == commands.end()) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
it->script = script;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CommandHelper::command_in_db(std::string guild_id, std::string command_name) {
|
||||||
|
sqlite3 *db; int return_code;
|
||||||
|
return_code = sqlite3_open("bot/db/trivia.db", &db);
|
||||||
|
if (!return_code_ok(return_code)) return false;
|
||||||
|
|
||||||
|
std::string sql = "SELECT EXISTS(SELECT 1 FROM CustomJS WHERE GuildID=?1 AND CommandName=?2);";
|
||||||
|
|
||||||
|
sqlite3_stmt *stmt;
|
||||||
|
return_code = sqlite3_prepare_v2(db, sql.c_str(), -1, &stmt, 0);
|
||||||
|
if (!return_code_ok(return_code)) return false;
|
||||||
|
|
||||||
|
return_code = sqlite3_bind_text(stmt, 1, guild_id.c_str(), -1, (sqlite3_destructor_type) -1);
|
||||||
|
if (!return_code_ok(return_code)) return false;
|
||||||
|
|
||||||
|
return_code = sqlite3_bind_text(stmt, 2, command_name.c_str(), -1, (sqlite3_destructor_type) -1);
|
||||||
|
if (!return_code_ok(return_code)) return false;
|
||||||
|
|
||||||
|
sqlite3_step(stmt);
|
||||||
|
|
||||||
|
bool exists = sqlite3_column_int(stmt, 0) == 1; // returns 1 (true) if exists
|
||||||
|
|
||||||
|
sqlite3_finalize(stmt);
|
||||||
|
sqlite3_close(db);
|
||||||
|
|
||||||
|
return exists;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CommandHelper::return_code_ok(int return_code) {
|
||||||
|
if (return_code != SQLITE_OK) {
|
||||||
|
std::cerr << "SQLite error. " << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
25
TriviaBot/bot/js/CommandHelper.hpp
Normal file
25
TriviaBot/bot/js/CommandHelper.hpp
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#ifndef BOT_JS_COMMANDHELPER
|
||||||
|
#define BOT_JS_COMMANDHELPER
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
struct Command {
|
||||||
|
std::string guild_id;
|
||||||
|
std::string command_name;
|
||||||
|
std::string script;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CommandHelper {
|
||||||
|
public:
|
||||||
|
CommandHelper();
|
||||||
|
int insert_command(std::string guild_id, std::string command_name, std::string script);
|
||||||
|
bool get_command(std::string guild_id, std::string name, Command &command);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool command_in_db(std::string guild_id, std::string command_name);
|
||||||
|
bool return_code_ok(int return_code);
|
||||||
|
|
||||||
|
std::vector<Command> commands;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user