1
0
Fork 0
mirror of https://gitlab.com/niansa/SomeBot.git synced 2025-03-06 20:48:26 +01:00
SomeBot/modules/info.cpp
2023-12-07 01:31:19 +01:00

213 lines
8.9 KiB
C++

#include "info.hpp"
#include "../bot.hpp"
#include "globalchat.hpp"
#include <mutex>
#ifdef __linux__
# include <sys/sysinfo.h>
# include <sys/utsname.h>
#endif
namespace SysInfo { // TODO: This currently works on linux only
# ifdef __linux__
# define SYSINFO_WORKS
size_t memUsed() {
const std::string identifier = "VmRSS:\t";
std::ifstream pstatus("/proc/self/status");
// Check for success
if (not pstatus) {
return 0;
}
// Find line
std::string currline;
while (currline.find(identifier) != 0) {
std::getline(pstatus, currline);
}
// Close pstatus
pstatus.close();
// Get number
size_t res = 0;
for (const auto& character : currline) {
// Check if character is digit
if (character> '9' or character < '0') {
continue;
}
// Append digit to res
res += static_cast<size_t>(character - '0');
res *= 10;
}
res /= 10;
// Return result in MB
return res / 1000;
}
size_t memTotal() {
// Get sysinfo
struct sysinfo i;
sysinfo(&i);
// Get total ram in MB
return i.totalram / 1000000;
}
std::string kernelNameAndVersion() {
static auto fres = []() {
struct utsname name;
uname(&name);
return std::string(name.sysname)+" "+std::string(name.release);
}();
return fres;
}
# endif
}
namespace InfoExternal {
dpp::embed generate_user_info_embed(const dpp::user& user) {
dpp::embed embed;
embed.set_title(user.format_username())
.add_field("Username", user.username, true)
.add_field("Discriminator", user.discriminator?dpp::leading_zeroes(user.discriminator, 4):"None", true)
.add_field("ID", '`'+std::to_string(user.id)+'`', true)
.add_field("Is Bot", user.is_bot()?("Yes, "+std::string(user.is_verified_bot()?"but not ":"it's ")+"a verified bot."):"Nein", true)
.add_field("Account age", "<t:"+std::to_string(static_cast<time_t>(user.get_creation_time()))+":R>", true)
.set_image(user.get_avatar_url());
return embed;
}
dpp::embed generate_guild_info_embed(const dpp::guild& guild) {
dpp::embed embed;
static const char *nfsw_level_texts[] = {"Not specified", "Yes, may contain NSFW", "No", "Yes, is NSFW"};
embed.set_title(guild.name)
.add_field("Description", guild.description.empty()?"None":guild.description, true)
.add_field("ID", '`'+std::to_string(guild.id)+'`', true)
.add_field("Owner", "<@"+std::to_string(guild.owner_id)+'>', true)
.add_field("Age", "<t:"+std::to_string(static_cast<time_t>(guild.get_creation_time()))+":R>", true)
.add_field("Is NSFW", nfsw_level_texts[static_cast<unsigned>(guild.nsfw_level)], true)
.add_field("Members", std::to_string(guild.member_count), true)
.add_field("Roles", std::to_string(guild.roles.size()), true)
.add_field("Emojis", std::to_string(guild.emojis.size()), true)
.set_image(guild.get_icon_url());
return embed;
}
}
class Info {
Bot *bot;
unsigned server_count = 0;
public:
Info(Bot *_bot) : bot(_bot) {
bot->cluster.intents |= dpp::intents::i_guilds;
bot->add_chatcommand(Bot::ChatCommand({"help"}, "Get help"), [&](const dpp::slashcommand_t& event) {
dpp::embed embed;
embed.set_title("Commands");
for (const auto& command : bot->get_commands().chat_commands) {
std::string nameCollection;
switch (bot->config.command_alias_mode) {
case Bot::Config::CommandAliasMode::all: {
for (const auto& name : command.names) {
nameCollection.append(name);
nameCollection.push_back('/');
}
nameCollection.pop_back();
} break;
case Bot::Config::CommandAliasMode::first: {
nameCollection = command.names.front();
} break;
case Bot::Config::CommandAliasMode::last: {
nameCollection = command.names.back();
} break;
}
embed.add_field(nameCollection, command.description, true);
}
event.reply(dpp::message().add_embed(embed).set_flags(dpp::message_flags::m_ephemeral));
});
bot->add_chatcommand(Bot::ChatCommand({"admin_help"}, "Get help for admins"), [&](const dpp::slashcommand_t& event) {
dpp::embed embed;
embed.set_title("Commands");
for (const auto& [command, guild_id] : bot->get_commands().guild_chat_commands) {
if (guild_id != dpp::snowflake(bot->config.management_guild_id)) {
continue;
}
std::string nameCollection;
for (const auto& name : command.names) {
nameCollection.append(name);
nameCollection.push_back('/');
}
nameCollection.pop_back();
embed.add_field(nameCollection, command.description, true);
}
event.reply(dpp::message().add_embed(embed).set_flags(dpp::message_flags::m_ephemeral));
}, bot->config.management_guild_id);
bot->add_chatcommand(Bot::ChatCommand({"about", "info"}, "About me"), [&](const dpp::slashcommand_t& event) {
auto [bots, bots_lock] = bot->get_locked_property<std::vector<Bot*>>("main_all_instances");
std::ostringstream info;
if (!bot->config._private) {
info << "**Guild count**: " << server_count << "\n";
}
info << "**Instance count**: " << bots->size() << "\n"
"**Instance ID**: " << bot->config.id << "\n"
# ifdef SYSINFO_WORKS
"**Virtual memory usage**: " << SysInfo::memUsed() << " MB / " << SysInfo::memTotal() << " MB\n"
"**Kernel**: " << SysInfo::kernelNameAndVersion() << "\n"
# endif
"**Compiler**: " COMPILER_ID " " COMPILER_VERSION " (" COMPILER_PLATFORM ")\n"
"**C++ standard**: " << __cplusplus << "\n"
;
event.reply(dpp::message()
.add_embed(dpp::embed()
.set_title("About me")
.set_description(std::move(info).str())
)
.add_embed(InfoExternal::generate_user_info_embed(bot->cluster.me)));
});
if (!bot->config._private) {
bot->add_chatcommand(Bot::ChatCommand({"invite"}, "Invite me to your server"), [&](const dpp::slashcommand_t& event) {
event.reply(dpp::utility::bot_invite_url(bot->cluster.me.id, dpp::permissions::p_administrator));
});
}
bot->add_chatcommand(Bot::ChatCommand({"serverinfo"}, "Learn about a server"), [&](const dpp::slashcommand_t& event) {
event.reply(dpp::message().add_embed(InfoExternal::generate_guild_info_embed(event.command.get_guild())).set_flags(dpp::message_flags::m_ephemeral));
});
bot->add_usercommand(Bot::UserCommand({"userinfo"}, "Learn about a user"), [&](const dpp::user_context_menu_t& event) {
event.reply(dpp::message().add_embed(InfoExternal::generate_user_info_embed(event.get_user())).set_flags(dpp::message_flags::m_ephemeral));
});
bot->add_messagecommand(Bot::MessageCommand({"Sender info"}, "Learn about the sender of the message"), [&](const dpp::message_context_menu_t& event) {
std::thread([=]() {
const auto& target_message = event.get_message();
std::optional<dpp::user> target;
// Try to get target from globalchat embed
if (target_message.author.id == bot->cluster.me.id) {
try {
// Try to decode message that is part of globalchat
auto messageinfo = GlobalchatExternal::MessageInfo::decode_message(target_message);
// Get target from author ID
target = bot->cluster.user_get_sync(messageinfo.author);
} catch (...) {}
}
// Fall back to using message author if needed
if (!target.has_value()) {
target = target_message.author;
}
// Send reply
event.reply(dpp::message().add_embed(InfoExternal::generate_user_info_embed(target.value())).set_flags(dpp::message_flags::m_ephemeral));
}).detach();
});
bot->cluster.on_guild_create([&](const dpp::guild_create_t&) {
server_count++;
});
bot->cluster.on_guild_delete([&](const dpp::guild_delete_t&) {
server_count--;
});
}
};
BOT_ADD_MODULE(Info);