diff --git a/.gitmodules b/.gitmodules index 3f60a66c..239f0730 100644 --- a/.gitmodules +++ b/.gitmodules @@ -22,9 +22,6 @@ [submodule "external/TF2_NavFile_Reader"] path = external/TF2_NavFile_Reader url = https://github.com/nullworks/TF2_NavFile_Reader -[submodule "external/IRCClient"] - path = external/IRCClient - url = https://github.com/nullworks/IRCClient [submodule "external/chirc"] path = external/chirc - url = https://gitlab.com/TotallyNotElite/chirc.git + url = https://gitlab.com/TotallyNotElite/chirc.git \ No newline at end of file diff --git a/external/IRCClient b/external/IRCClient deleted file mode 160000 index 8c07a4a1..00000000 --- a/external/IRCClient +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 8c07a4a1d9d1ed104ec24b921f0734a59d5a1d0e diff --git a/external/chirc b/external/chirc index 7799d931..a25ff4c3 160000 --- a/external/chirc +++ b/external/chirc @@ -1 +1 @@ -Subproject commit 7799d931b9c555a54b61025df6cb25f602bd3f39 +Subproject commit a25ff4c3d00135b6bca709acc8421f39b1116df0 diff --git a/include/irc.hpp b/include/irc.hpp index 568960c4..59dbc458 100644 --- a/include/irc.hpp +++ b/include/irc.hpp @@ -3,5 +3,5 @@ namespace IRC { bool sendmsg(std::string &msg, bool loopback = false); -//void auth(bool reply = false); +void auth(bool reply = false); } // namespace IRC diff --git a/src/hooks/CreateMove.cpp b/src/hooks/CreateMove.cpp index 3d14bc77..6a3e2082 100644 --- a/src/hooks/CreateMove.cpp +++ b/src/hooks/CreateMove.cpp @@ -259,7 +259,7 @@ DEFINE_HOOKED_METHOD(CreateMove, bool, void *this_, float input_sample_time, DelayTimer.update(); hacks::tf2::NavBot::Init(); hacks::tf2::NavBot::initonce(); - //IRC::auth(); + IRC::auth(); firstcm = false; } g_Settings.bInvalid = false; diff --git a/src/irc.cpp b/src/irc.cpp index 22759abd..38607c56 100644 --- a/src/irc.cpp +++ b/src/irc.cpp @@ -18,43 +18,217 @@ static settings::String address("irc.address", "cathook.irc.inkcat.net"); static settings::Int port("irc.port", "8080"); static ChIRC::ChIRC irc; + +void printmsg(std::string &usr, std::string &msg) +{ + if (msg.size() > 256 || usr.size() > 256) + { + logging::Info("IRC: Message too large."); + return; + } + if (g_Settings.bInvalid) + logging::Info("[IRC] %s: %s", usr.c_str(), msg.c_str()); + else + PrintChat("\x07%06X[IRC] %s\x01: %s", 0xe05938, usr.c_str(), + msg.c_str()); +} +void printmsgcopy(std::string usr, std::string msg) +{ + if (msg.size() > 256 || usr.size() > 256) + { + logging::Info("IRC: Message too large."); + return; + } + if (g_Settings.bInvalid) + logging::Info("[IRC] %s: %s", usr.c_str(), msg.c_str()); + else + PrintChat("\x07%06X[IRC] %s\x01: %s", 0xe05938, usr.c_str(), + msg.c_str()); +} + +void handleMessage(IRCMessage message, IRCClient *client) +{ + std::string &cmd = message.command; + std::string &channel = message.parameters.at(0); + std::string &rawmsg = message.parameters.at(1); + std::string &usr = message.prefix.nick; + if (!ucccccp::validate(rawmsg)) + return; + std::string msg(ucccccp::decrypt(rawmsg)); + if (msg == "Attempt at ucccccping and failing" || + msg == "Unsupported version") + return; + + // Handle privmsg (Message to #channel) + if (cmd == "PRIVMSG") + { + if (msg.empty() || usr.empty()) + return; + // Handle messages + if (msg.find("msg") == 0) + { + 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++) + { + 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 updateData(std::string commandandcontrol) { - std::string nick = g_ISteamFriends->GetPersonaName(); + std::string nick("Anon"); + if (!*anon) + nick = g_ISteamFriends->GetPersonaName(); irc.UpdateData(nick, nick, *channel, commandandcontrol, *address, *port); } -static HookedFunction paint(HookedFunctions_types::HF_Paint, "IRC", 16, - []() { irc.Update(); }); -template -void rvarCallback(settings::VariableBase &var, T after) +bool sendmsg(std::string &msg, bool loopback) { - irc.Disconnect(); - updateData(""); - if (enabled) - irc.Connect(); + std::string raw = "msg" + msg; + if (irc.privmsg(raw)) + { + if (loopback) + { + printmsgcopy(irc.getData().nick, msg); + } + return true; + } + if (loopback) + printmsgcopy("Cathook", "Error! Couldn't send message."); + return false; } -void rvarCallback_enabled(settings::VariableBase &var, bool after) +void auth(bool reply) { - irc.Disconnect(); - if (after) - irc.Connect(); + if (g_Settings.bInvalid && !g_Settings.is_create_move) + return; + if (!*authenticate) + return; + MD5Value_t result; + MD5_ProcessSingleBuffer(&LOCAL_E->player_info.friendsID, sizeof(uint32), + result); + std::string msg = "auth"; + if (reply) + msg.append("rep"); + for (auto i : result.bits) + { + for (int j = 0; j < 8; j++) + msg.append(std::to_string((i >> j) & 1)); + } + irc.privmsg(msg); +} + +static bool restarting{ false }; + +static HookedFunction paint(HookedFunctions_types::HF_Paint, "IRC", 16, []() { + if (!restarting) + irc.Update(); +}); + +template void rvarCallback(settings::VariableBase &var, T after) +{ + if (!restarting) + { + restarting = true; + std::thread reload([]() { + std::this_thread::sleep_for( + std::chrono_literals::operator""ms(500)); + irc.Disconnect(); + updateData(""); + if (enabled) + irc.Connect(); + restarting = false; + }); + reload.detach(); + } } static InitRoutine init([]() { updateData(""); - enabled.installChangeCallback(rvarCallback_enabled); + enabled.installChangeCallback(rvarCallback); anon.installChangeCallback(rvarCallback); authenticate.installChangeCallback(rvarCallback); channel.installChangeCallback(rvarCallback); address.installChangeCallback(rvarCallback); port.installChangeCallback(rvarCallback); + irc.installCallback("PRIVMSG", handleMessage); irc.Connect(); }); -static CatCommand send("irc_send", "Send message to IRC", - [](const CCommand &args) { irc.privmsg(args.ArgS()); }); +static CatCommand irc_send_cmd("irc_send_cmd", "Send cmd to IRC", + [](const CCommand &args) { + irc.sendraw(args.ArgS()); + }); + +static CatCommand irc_send("irc_send", "Send message to IRC", + [](const CCommand &args) { + std::string msg(args.ArgS()); + sendmsg(msg, true); + }); + +static CatCommand irc_auth("irc_auth", + "Auth via IRC (Find users on same server)", + []() { auth(); }); } // namespace IRC diff --git a/src/visual/menu/menu/special/VariableListEntry.cpp b/src/visual/menu/menu/special/VariableListEntry.cpp index e258fde8..c378bd2d 100755 --- a/src/visual/menu/menu/special/VariableListEntry.cpp +++ b/src/visual/menu/menu/special/VariableListEntry.cpp @@ -182,7 +182,7 @@ void zerokernel::VariableListEntry::onMove() void zerokernel::VariableListEntry::recalculateSize() { - printf("VLE::recalculateSize()\n"); + //printf("VLE::recalculateSize()\n"); bb.updateFillSize(); bb.shrinkContent(); bb.extend(label.getBoundingBox());