diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..613973c --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +*.c linguist-detectable=false \ No newline at end of file diff --git a/README.md b/README.md index 362d2a4..c1421c2 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,12 @@ # MTA Discord Module -Discord bot module for MTA. Does not require NodeJS setup or sockets module. You just need to setup a bot on discord developer site and get the token. +Discord bot module for MTA. This module lets you setup a mta discord bot that does not require NodeJS setup or sockets module. You just need to setup a bot on discord developer site and get the token. **Note:** - This module is still in development and may be incomplete, unstable, and/or broken. It can crash your MTA server, use at your own risk. - Only x64 (64-bit) is supported. I'll add support for 32-bit if I get the time. # Installation -- Simply grab the DLL or SO file from Release and follow installation steps at the bottom of this doc +- Simply grab the DLL or SO file from Release and follow installation steps from the "Installing the module" section at the bottom of this doc # Build Guidelines ## Requirements diff --git a/bot/module/Bot.cpp b/bot/module/Bot.cpp index 74d62da..672ba96 100644 --- a/bot/module/Bot.cpp +++ b/bot/module/Bot.cpp @@ -6,8 +6,8 @@ Bot::Bot(const std::string& token, lua_State* vm, void* userdata) : SleepyDiscord::DiscordClient(token) { m_VM = vm; - m_State = new sol::state_view(m_VM); m_Userdata = userdata; + m_State = new sol::state_view(m_VM); } Bot::~Bot() @@ -17,17 +17,19 @@ Bot::~Bot() void Bot::onReady(SleepyDiscord::Ready readyResult) { - nlohmann::json o; - o["id"] = this->getID().string(); - o["user"] = + nlohmann::json responseObject; + responseObject["id"] = this->getID().string(); + responseObject["user"] = { {"id", readyResult.user.ID.string()}, {"username", readyResult.user.username} }; try { - g_Pulses.push_back(new BotPulse(m_State, "onDiscordReady", o.dump())); - //TRIGGER_MTA_EVENT(m_State, "onDiscordReady", o.dump()); + g_Pulses.push_back(new BotPulse(m_State, "onDiscordReady", responseObject.dump())); + } + catch (const std::bad_alloc& e) { + std::cout << "Failed to allocate heap (" << e.what() << ")\n"; } catch (const nlohmann::json::exception& e) { std::cerr << e.what() << '\n'; @@ -41,15 +43,15 @@ void Bot::onResumed() void Bot::onServer(SleepyDiscord::Server server) { - nlohmann::json o; + nlohmann::json responseObject; std::stringstream ss; - o["server"] = + responseObject["server"] = { {"id", server.ID.string()}, {"name", server.name} }; - o["roles"] = {}; + responseObject["roles"] = {}; auto& rolesList = server.roles; for (auto& role : rolesList) @@ -57,7 +59,7 @@ void Bot::onServer(SleepyDiscord::Server server) ss.str(std::string()); ss << "0x" << std::hex << std::setfill('0') << std::setw(2) << role.color; - o["roles"].push_back + responseObject["roles"].push_back ({ {"id", role.ID.string()}, {"name", role.name}, @@ -66,8 +68,10 @@ void Bot::onServer(SleepyDiscord::Server server) } try { - g_Pulses.push_back(new BotPulse(m_State, "onDiscordServer", o.dump())); - //TRIGGER_MTA_EVENT(m_State, "onDiscordServer", o.dump()); + g_Pulses.push_back(new BotPulse(m_State, "onDiscordServer", responseObject.dump())); + } + catch (const std::bad_alloc& e) { + std::cout << "Failed to allocate heap (" << e.what() << ")\n"; } catch (const nlohmann::json::exception& e) { std::cerr << e.what() << '\n'; @@ -80,26 +84,26 @@ void Bot::onMessage(SleepyDiscord::Message message) if (message.startsWith(m_Prefix)) { - nlohmann::json o; + nlohmann::json responseObject; const SleepyDiscord::ServerMember serverMember = getMember(message.serverID, message.author.ID); const SleepyDiscord::Channel channel = getChannel(message.channelID); auto& roles = serverMember.roles; - o["user"] = {}; + responseObject["user"] = {}; nlohmann::json rolesObj = {}; for (auto& role : roles) rolesObj[role.string()] = true; - o["message"] = + responseObject["message"] = { {"prefix", m_Prefix}, {"raw_content", message.content}, {"content", message.content.substr(m_Prefix.length())} }; - o["message"]["author"] = + responseObject["message"]["author"] = { {"id", message.author.ID.string()}, {"username", message.author.username}, @@ -107,7 +111,7 @@ void Bot::onMessage(SleepyDiscord::Message message) {"roles", rolesObj} }; - o["message"]["channel"] = + responseObject["message"]["channel"] = { {"id", channel.ID.string()}, {"name", channel.name}, @@ -116,8 +120,10 @@ void Bot::onMessage(SleepyDiscord::Message message) }; try { - g_Pulses.push_back(new BotPulse(m_State, "onDiscordMessage", o.dump())); - //TRIGGER_MTA_EVENT(m_State, "onDiscordMessage", o.dump()); + g_Pulses.push_back(new BotPulse(m_State, "onDiscordMessage", responseObject.dump())); + } + catch (const std::bad_alloc& e) { + std::cout << "Failed to allocate heap (" << e.what() << ")\n"; } catch (const nlohmann::json::exception& e) { std::cerr << e.what() << '\n'; @@ -125,8 +131,6 @@ void Bot::onMessage(SleepyDiscord::Message message) } } - - void Bot::setPrefix(const std::string& newPrefix) { m_Prefix = newPrefix; diff --git a/bot/module/BotSession.cpp b/bot/module/BotSession.cpp index 5db44cb..a3e4926 100644 --- a/bot/module/BotSession.cpp +++ b/bot/module/BotSession.cpp @@ -22,7 +22,8 @@ std::mutex g_PulseMutex; usertype["setPrefix"] = &BotSession::setPrefix; usertype["sendMessage"] = &BotSession::sendMessage; - usertype["editMessage"] = &BotSession::editMessage; + usertype["sendEmbed"] = &BotSession::sendEmbed; + usertype["editMessage"] = &BotSession::editMessage; usertype["setActivity"] = &BotSession::setActivity; } @@ -68,9 +69,13 @@ void BotSession::login(const std::string& token, sol::this_state s) m_VM = s.lua_state(); m_Userdata = lua_newuserdata(m_VM, 128); - m_Bot = new Bot(token, m_VM, m_Userdata); - - m_Thread = new std::thread(&BotSession::threadHandle, this); + try { + m_Bot = new Bot(token, m_VM, m_Userdata); + m_Thread = new std::thread(&BotSession::threadHandle, this); + } + catch (const std::bad_alloc& e) { + std::cout << "Failed to allocate heap (" << e.what() << ")\n"; + } } void BotSession::disconnect() @@ -92,7 +97,7 @@ void BotSession::disconnect() void BotSession::setPrefix(const std::string& newPrefix) { - if (!isReady()) + if (!isConnected()) return; m_Prefix = newPrefix; // This is for the operator() overload @@ -114,10 +119,29 @@ void BotSession::sendMessage(const std::string& channelID, const std::string& me } } +void BotSession::sendEmbed(const std::string& channelID, const std::string& message) +{ + if (!isConnected()) + return; + + try + { + //nlohmann::json embedMessage(message); + SleepyDiscord::Embed embed(message); + if (!embed.empty()) + m_Bot->sendMessage(channelID, "", embed); + } + catch (...) + { + pModuleManager->ErrorPrintf("BotSession::sendMessage Failed!"); + } +} + void BotSession::editMessage(const std::string& channelID, const std::string& messageID, const std::string& newMessage) { if (!isConnected()) return; + try { m_Bot->editMessage(channelID, messageID, newMessage); @@ -132,6 +156,7 @@ void BotSession::setActivity(const std::string& activity) { if (!isConnected()) return; + try { m_Bot->updateStatus(activity); diff --git a/bot/module/BotSession.h b/bot/module/BotSession.h index 3d82c1a..6c16d39 100644 --- a/bot/module/BotSession.h +++ b/bot/module/BotSession.h @@ -25,6 +25,7 @@ class BotSession void setPrefix(const std::string& newPrefix); void sendMessage(const std::string& channelID, const std::string& message); + void sendEmbed(const std::string& channelID, const std::string& message); void editMessage(const std::string& channelID, const std::string& messageID, const std::string& newMessage); void setActivity(const std::string& activity); diff --git a/bot/module/Main.cpp b/bot/module/Main.cpp index 88b161f..f6d9d28 100644 --- a/bot/module/Main.cpp +++ b/bot/module/Main.cpp @@ -28,7 +28,7 @@ MTAEXPORT bool InitModule(ILuaModuleManager10* pManager, char* szModuleName, cha const auto author = "DizzasTeR"; std::memcpy(szModuleName, module_name, MAX_INFO_LENGTH); std::memcpy(szAuthor, author, MAX_INFO_LENGTH); - *fVersion = 1.0f; + *fVersion = 1.1f; return true; }