From d18e8337e3dea51369c022afa2f384706dd026bc Mon Sep 17 00:00:00 2001 From: TotallyNotElite <1yourexperiment@protonmail.com> Date: Sun, 7 Oct 2018 14:21:40 +0200 Subject: [PATCH] IRC C&C --- external/chirc | 2 +- src/irc.cpp | 177 ++++++++++++++++++++++++++++++------------------- 2 files changed, 108 insertions(+), 71 deletions(-) diff --git a/external/chirc b/external/chirc index e2379b05..ecf241a3 160000 --- a/external/chirc +++ b/external/chirc @@ -1 +1 @@ -Subproject commit e2379b05d7915fab6506dcc3f61a44b156027465 +Subproject commit ecf241a326bc0e3dad2d3fb240a7b52d1d533fe0 diff --git a/src/irc.cpp b/src/irc.cpp index 10ea26b2..99677514 100644 --- a/src/irc.cpp +++ b/src/irc.cpp @@ -5,6 +5,7 @@ #include "Settings.hpp" #include "ChIRC.hpp" #include +#include "hack.hpp" namespace IRC { @@ -14,6 +15,8 @@ static settings::Bool authenticate("irc.auth", "true"); static settings::String channel("irc.channel", "#cat_comms"); static settings::String address("irc.address", "cathook.irc.inkcat.net"); static settings::Int port("irc.port", "8080"); +static settings::String commandandcontrol_channel("irc.cc.channel", ""); +static settings::String commandandcontrol_password("irc.cc.password", ""); static ChIRC::ChIRC irc; @@ -44,7 +47,77 @@ void printmsgcopy(std::string usr, std::string msg) msg.c_str()); } -void handleMessage(IRCMessage message, IRCClient *client) +namespace handlers +{ +void message(std::string &usr, std::string &msg) +{ + std::string toprint = msg.substr(3); + if (toprint.empty()) + return; + printmsg(usr, toprint); +} +void authreq(std::string &msg) +{ + // Check if we are in a game + if (g_Settings.bInvalid) + return; + bool isreply = false; + std::string steamidhash; + if (msg.find("authrep") == 0) + isreply = true; + // Get steamid hash from string + if (isreply) + steamidhash = msg.substr(7); + else + steamidhash = msg.substr(4); + + for (int i = 0; i < g_IEngine->GetMaxClients(); i++) + { + if (i == g_pLocalPlayer->entity_idx) + continue; + player_info_s pinfo; + // Get playerinfo and check if player on server + if (!g_IEngine->GetPlayerInfo(i, &pinfo)) + continue; + auto tarsteamid = pinfo.friendsID; + MD5Value_t result; + // Hash steamid + MD5_ProcessSingleBuffer(&tarsteamid, sizeof(tarsteamid), result); + // Get bits of hash and store in string + std::string tarhash; + for (auto i : result.bits) + { + for (int j = 0; j < 8; j++) + tarhash.append(std::to_string((i >> j) & 1)); + } + // Check if steamid of sender == steamid we currently check + // (using hashes) + if (tarhash == steamidhash) + { + // Use actual steamid to set cat status + auto &playerlistdata = playerlist::AccessData(tarsteamid); + if (playerlistdata.state == playerlist::k_EState::DEFAULT) + { + playerlistdata.state = playerlist::k_EState::CAT; + } + // Avoid replying to a reply + if (isreply) + // We are done here. Steamid duplicates don't exist. + return; + // If message is not a reply, reply. + auth(true); + // We are done here. Steamid duplicates don't exist. + return; + } + } +} +void cc_cmd(std::string &msg) +{ + hack::ExecuteCommand(msg.substr(6)); +} +} // namespace handlers + +void handleIRC(IRCMessage message, IRCClient *client) { std::string &cmd = message.command; std::string &channel = message.parameters.at(0); @@ -62,82 +135,38 @@ void handleMessage(IRCMessage message, IRCClient *client) { if (msg.empty() || usr.empty()) return; - // Handle messages - if (msg.find("msg") == 0) + // Handle public messages + if (channel == irc.getData().comms_channel) { - std::string toprint = msg.substr(3); - if (toprint.empty()) - return; - printmsg(usr, toprint); - return; - } - - // Handle auth requests - if (msg.find("auth") == 0) - { - // Check if we are in a game - if (g_Settings.bInvalid) - return; - bool isreply = false; - std::string steamidhash; - if (msg.find("authrep") == 0) - isreply = true; - // Get steamid hash from string - if (isreply) - steamidhash = msg.substr(7); - else - steamidhash = msg.substr(4); - - for (int i = 0; i < g_IEngine->GetMaxClients(); i++) + // Handle messages + if (msg.find("msg") == 0) { - if (i == g_pLocalPlayer->entity_idx) - continue; - player_info_s pinfo; - // Get playerinfo and check if player on server - if (!g_IEngine->GetPlayerInfo(i, &pinfo)) - continue; - auto tarsteamid = pinfo.friendsID; - MD5Value_t result; - // Hash steamid - MD5_ProcessSingleBuffer(&tarsteamid, sizeof(tarsteamid), - result); - // Get bits of hash and store in string - std::string tarhash; - for (auto i : result.bits) - { - for (int j = 0; j < 8; j++) - tarhash.append(std::to_string((i >> j) & 1)); - } - // Check if steamid of sender == steamid we currently check - // (using hashes) - if (tarhash == steamidhash) - { - // Use actual steamid to set cat status - auto &playerlistdata = playerlist::AccessData(tarsteamid); - if (playerlistdata.state == playerlist::k_EState::DEFAULT) - { - playerlistdata.state = playerlist::k_EState::CAT; - } - // Avoid replying to a reply - if (isreply) - // We are done here. Steamid duplicates don't exist. - return; - // If message is not a reply, reply. - auth(true); - // We are done here. Steamid duplicates don't exist. - return; - } + handlers::message(usr, msg); + return; + } + // Handle auth requests + else if (msg.find("auth") == 0) + { + handlers::authreq(msg); + } + } + else if (channel == irc.getData().commandandcontrol_channel) + { + if (msg.find("cc_cmd") == 0) + { + handlers::cc_cmd(msg); } } } } -void updateData(std::string commandandcontrol) +void updateData() { std::string nick("Anon"); if (!*anon) nick = g_ISteamFriends->GetPersonaName(); - irc.UpdateData(nick, nick, *channel, commandandcontrol, *address, *port); + irc.UpdateData(nick, nick, *channel, *commandandcontrol_channel, + *commandandcontrol_password, *address, *port); } bool sendmsg(std::string &msg, bool loopback) @@ -165,7 +194,7 @@ void auth(bool reply) MD5Value_t result; MD5_ProcessSingleBuffer(&LOCAL_E->player_info.friendsID, sizeof(uint32), result); - std::string msg = "auth"; + std::string msg("auth"); if (reply) msg.append("rep"); for (auto i : result.bits) @@ -192,7 +221,7 @@ template void rvarCallback(settings::VariableBase &var, T after) std::this_thread::sleep_for( std::chrono_literals::operator""ms(500)); irc.Disconnect(); - updateData(""); + updateData(); if (enabled) irc.Connect(); restarting = false; @@ -202,15 +231,17 @@ template void rvarCallback(settings::VariableBase &var, T after) } static InitRoutine init([]() { - updateData(""); + updateData(); enabled.installChangeCallback(rvarCallback); anon.installChangeCallback(rvarCallback); authenticate.installChangeCallback(rvarCallback); channel.installChangeCallback(rvarCallback); address.installChangeCallback(rvarCallback); port.installChangeCallback(rvarCallback); + commandandcontrol_channel.installChangeCallback(rvarCallback); + commandandcontrol_password.installChangeCallback(rvarCallback); - irc.installCallback("PRIVMSG", handleMessage); + irc.installCallback("PRIVMSG", handleIRC); irc.Connect(); }); @@ -218,6 +249,12 @@ static CatCommand irc_send_cmd("irc_send_cmd", "Send cmd to IRC", [](const CCommand &args) { irc.sendraw(args.ArgS()); }); +static CatCommand irc_exec_all("irc_exec_all", "Send command to C&C channel", + [](const CCommand &args) { + std::string msg("cc_cmd"); + msg.append(args.ArgS()); + irc.privmsg(msg, true); + }); static CatCommand irc_send("irc_send", "Send message to IRC", [](const CCommand &args) {