From 291b5cd947595e797f5949020d5ae9a5d14a4cd8 Mon Sep 17 00:00:00 2001 From: JustinAJ Date: Fri, 17 Oct 2014 00:48:01 -0400 Subject: [PATCH] Added isFirstGame(), isFirstKill(), and isFirstDeath(). Join spam after map change is now filtered. --- Release/Plugins/RenX.Core.lib | Bin 55790 -> 56672 bytes RenX.Core/RenX_Server.cpp | 146 ++++++++++++++++++++++------------ RenX.Core/RenX_Server.h | 40 ++++++++++ 3 files changed, 135 insertions(+), 51 deletions(-) diff --git a/Release/Plugins/RenX.Core.lib b/Release/Plugins/RenX.Core.lib index 7815143cf9242c9d0c2cc5d6f92f989ee78429f3..bded1e12598563fc6854aefba49b044f75ab04cb 100644 GIT binary patch delta 5880 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 diff --git a/RenX.Core/RenX_Server.cpp b/RenX.Core/RenX_Server.cpp index fd91508..3b3684d 100644 --- a/RenX.Core/RenX_Server.cpp +++ b/RenX.Core/RenX_Server.cpp @@ -72,6 +72,21 @@ bool RenX::Server::isConnected() const return RenX::Server::connected; } +bool RenX::Server::isFirstGame() const +{ + return RenX::Server::firstGame; +} + +bool RenX::Server::isFirstKill() const +{ + return RenX::Server::firstKill; +} + +bool RenX::Server::isFirstDeath() const +{ + return RenX::Server::firstDeath; +} + bool RenX::Server::isPublicLogChanType(int type) const { return RenX::Server::logChanType == type; @@ -491,72 +506,83 @@ inline RenX::PlayerInfo *getPlayerOrAdd(RenX::Server *server, const Jupiter::Rea return r; } -inline void onPreGameOver(RenX::Server *server, RenX::WinType winType, RenX::TeamType team, int gScore, int nScore) +void RenX::Server::processLine(const Jupiter::ReadableString &line) { - RenX::PlayerInfo *player; - - if (server->players.size() != 0) + /** Local functions */ + auto onPreGameOver = [&](RenX::Server *server, RenX::WinType winType, RenX::TeamType team, int gScore, int nScore) { - for (Jupiter::DLList::Node *n = server->players.getNode(0); n != nullptr; n = n->next) + RenX::PlayerInfo *player; + + if (server->players.size() != 0) { - player = n->data; - if (player != nullptr) + for (Jupiter::DLList::Node *n = server->players.getNode(0); n != nullptr; n = n->next) { - if (player->team == team) - player->wins++; - else player->loses++; + player = n->data; + if (player != nullptr) + { + if (player->team == team) + player->wins++; + else player->loses++; + } } } - } -} - -inline void onPostGameOver(RenX::Server *server, RenX::WinType winType, RenX::TeamType team, int gScore, int nScore) -{ - RenX::PlayerInfo *player; - - if (server->players.size() != 0) + }; + auto onPostGameOver = [&](RenX::Server *server, RenX::WinType winType, RenX::TeamType team, int gScore, int nScore) { - for (Jupiter::DLList::Node *n = server->players.getNode(0); n != nullptr; n = n->next) + this->firstGame = false; + this->firstAction = false; + this->firstKill = false; + this->firstDeath = false; + RenX::PlayerInfo *player; + + if (server->players.size() != 0) { - player = n->data; - if (player != nullptr) + for (Jupiter::DLList::Node *n = server->players.getNode(0); n != nullptr; n = n->next) { - player->kills = 0; - player->deaths = 0; - player->suicides = 0; - player->headshots = 0; - player->vehicleKills = 0; - player->buildingKills = 0; - player->defenceKills = 0; + player = n->data; + if (player != nullptr) + { + player->kills = 0; + player->deaths = 0; + player->suicides = 0; + player->headshots = 0; + player->vehicleKills = 0; + player->buildingKills = 0; + player->defenceKills = 0; + } } } - } -} - -inline void onChat(RenX::Server *server, RenX::PlayerInfo *player, const Jupiter::ReadableString &message, bool isPublic) -{ - const Jupiter::ReadableString &prefix = server->getCommandPrefix(); - if (message.find(prefix) == 0 && message.size() != prefix.size()) + }; + auto onChat = [&](RenX::Server *server, RenX::PlayerInfo *player, const Jupiter::ReadableString &message, bool isPublic) { - Jupiter::ReferenceString command; - Jupiter::ReferenceString parameters; - if (containsSymbol(WHITESPACE, message.get(prefix.size()))) + const Jupiter::ReadableString &prefix = server->getCommandPrefix(); + if (message.find(prefix) == 0 && message.size() != prefix.size()) { - command = Jupiter::ReferenceString::getWord(message, 1, WHITESPACE); - parameters = Jupiter::ReferenceString::gotoWord(message, 2, WHITESPACE); + Jupiter::ReferenceString command; + Jupiter::ReferenceString parameters; + if (containsSymbol(WHITESPACE, message.get(prefix.size()))) + { + command = Jupiter::ReferenceString::getWord(message, 1, WHITESPACE); + parameters = Jupiter::ReferenceString::gotoWord(message, 2, WHITESPACE); + } + else + { + command = Jupiter::ReferenceString::getWord(message, 0, WHITESPACE); + command.shiftRight(prefix.size()); + parameters = Jupiter::ReferenceString::gotoWord(message, 1, WHITESPACE); + } + server->triggerCommand(command, player, parameters); } - else + }; + auto onAction = [&]() + { + if (this->firstAction == false) { - command = Jupiter::ReferenceString::getWord(message, 0, WHITESPACE); - command.shiftRight(prefix.size()); - parameters = Jupiter::ReferenceString::gotoWord(message, 1, WHITESPACE); + this->firstAction = true; + this->silenceJoins = false; } - server->triggerCommand(command, player, parameters); - } -} + }; -void RenX::Server::processLine(const Jupiter::ReadableString &line) -{ Jupiter::ReferenceString buff = line; Jupiter::ArrayList &xPlugins = *RenX::getCore()->getPlugins(); Jupiter::ReferenceString header = buff.getWord(0, RenX::DelimS); @@ -576,6 +602,7 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) if (objectType.match("*Beacon")) player->beaconPlacements++; for (size_t i = 0; i < xPlugins.size(); i++) xPlugins.get(i)->RenX_OnDeploy(this, player, objectType); + onAction(); } else if (action.equals("suicided by")) { @@ -585,6 +612,8 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) Jupiter::ReferenceString damageType = buff.getWord(3, RenX::DelimS); for (size_t i = 0; i < xPlugins.size(); i++) xPlugins.get(i)->RenX_OnSuicide(this, player, damageType); + this->firstDeath = true; + onAction(); } else if (action.equals("killed")) { @@ -615,6 +644,10 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) for (size_t i = 0; i < xPlugins.size(); i++) xPlugins.get(i)->RenX_OnKill(this, player, victim, damageType); + + this->firstKill = true; + this->firstDeath = true; + onAction(); } else if (action.match("died by")) { @@ -623,6 +656,8 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) Jupiter::ReferenceString damageType = buff.getWord(3, RenX::DelimS); for (size_t i = 0; i < xPlugins.size(); i++) xPlugins.get(i)->RenX_OnDie(this, player, damageType); + this->firstDeath = true; + onAction(); } else if (action.match("destroyed*")) { @@ -647,6 +682,7 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) } for (size_t i = 0; i < xPlugins.size(); i++) xPlugins.get(i)->RenX_OnDestroy(this, player, victim, damageType, type); + onAction(); } else if (playerData.match("??? wins (*)")) { @@ -718,6 +754,7 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) for (size_t i = 0; i < xPlugins.size(); i++) xPlugins.get(i)->RenX_OnChat(this, player, message); } + onAction(); } else if (header.equals("lPLAYER:")) { @@ -748,8 +785,9 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) break; } - for (size_t i = 0; i < xPlugins.size(); i++) - xPlugins.get(i)->RenX_OnJoin(this, player); + if (this->silenceJoins == false) + for (size_t i = 0; i < xPlugins.size(); i++) + xPlugins.get(i)->RenX_OnJoin(this, player); } else if (action.equals("changed name to:")) { @@ -759,6 +797,7 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) player->name = newName; if (RenX::Server::uuidMode == 1) player->uuid = player->name; + onAction(); } } else if (header.equals("lRCON:")) @@ -887,6 +926,11 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) else if (gameVersion.equals("Open Beta 3")) this->profile = RenX::openBeta3Profile; + if (this->profile->disconnectOnGameOver == false) + this->firstGame = true; + else if (this->firstGame == false) + this->silenceJoins = true; + for (size_t i = 0; i < xPlugins.size(); i++) xPlugins.get(i)->RenX_OnVersion(this, buff); buff.shiftLeft(1); diff --git a/RenX.Core/RenX_Server.h b/RenX.Core/RenX_Server.h index e3ab079..76feb9b 100644 --- a/RenX.Core/RenX_Server.h +++ b/RenX.Core/RenX_Server.h @@ -73,6 +73,41 @@ namespace RenX */ bool isConnected() const; + /** + * @brief Checks if the game in progress is the first game. + * + * @return True if this is the first game, false otherwise. + */ + bool isFirstGame() const; + + /** + * @brief Checks if the first kill has already been processed. + * Note: This does not set to "true" until AFTER the first kill has been fully processed. + * This includes processing by plugins. + * + * @return True if the first kill has been fully processed, false otherwise. + */ + bool isFirstKill() const; + + /** + * @brief Checks if the first death has already been processed. + * Note: This does not set to "true" until AFTER the first death has been fully processed. + * This includes processing by plugins. + * + * @return True if the first death has been fully processed, false otherwise. + */ + bool isFirstDeath() const; + + /** + * @brief Checks if the first action has already been processed. + * Note: This does not set to "true" until AFTER the first action has been fully processed. + * This includes processing by plugins. + * An action is a kill, death, message, destroy, or any other player-induced interaction other than a join or part. + * + * @return True if the first action has been fully processed, false otherwise. + */ + bool isFirstAction() const; + /** * @brief Checks if a channel type is a public channel type. * @@ -438,6 +473,8 @@ namespace RenX bool connected = false; bool needsCList = false; bool silenceParts = false; + bool silenceJoins = false; + bool firstGame = true; unsigned int rconVersion = 0; unsigned short port; int logChanType; @@ -446,6 +483,9 @@ namespace RenX time_t delay; int steamFormat; /** 16 = hex, 10 = base 10, 8 = octal, -2 = SteamID 2, -3 = SteamID 3 */ unsigned int uuidMode; /** 0 = steam, 1 = nickname */ + bool firstKill = false; + bool firstDeath = false; + bool firstAction = false; Jupiter::TCPSocket sock; Jupiter::CStringS clientHostname; Jupiter::CStringS hostname;