From e30caeb947c5c68fbf80171b98d939535571ffc8 Mon Sep 17 00:00:00 2001 From: JustinAJ Date: Thu, 6 Aug 2015 20:38:10 -0400 Subject: [PATCH] RenX.Core: * Map rotation is now tracked. * Changed more types from time_t * Player data is now reset on "MAP Changing;" instead of "GAME MatchEnd;" RenX.Commands: * Added "Rotation", "Mutators", and "Map" IRC commands. * "setmap" now takes partial map names. RenX.HybridUUID: Corrected plugin name RenX.NicknameUUID: Corrected plugin name --- Release/Plugins/RenX.Core.lib | Bin 132726 -> 134426 bytes RenX.Commands/RenX_Commands.cpp | 145 ++++++++++++++++++++++++-- RenX.Commands/RenX_Commands.h | 3 + RenX.Core/RenX_Server.cpp | 73 +++++++++++-- RenX.Core/RenX_Server.h | 39 +++++-- RenX.HybridUUID/RenX_HybridUUID.h | 2 +- RenX.NicknameUUID/RenX_NicknameUUID.h | 2 +- 7 files changed, 239 insertions(+), 25 deletions(-) diff --git a/Release/Plugins/RenX.Core.lib b/Release/Plugins/RenX.Core.lib index ccebe6c1174376daa5a785b6b73a2bffdb16b407..7ad58b09e46702e44539071b155475db303253de 100644 GIT binary patch delta 14181 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"); + static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Provides a list of buildings, and the status of each one. Syntax: BuildingInfo"); return defaultHelp; } IRC_COMMAND_INIT(BuildingInfoIRCCommand) +// Mutators IRC Command + +void MutatorsIRCCommand::create() +{ + this->addTrigger("mutators"_jrs); + this->addTrigger("mutator"_jrs); +} + +void MutatorsIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters) +{ + Jupiter::IRC::Client::Channel *chan = source->getChannel(channel); + if (chan != nullptr) + { + int type = chan->getType(); + Jupiter::String list; + size_t index = 0; + for (unsigned int i = 0; i != RenX::getCore()->getServerCount(); i++) + { + RenX::Server *server = RenX::getCore()->getServer(i); + if (server->isLogChanType(type)) + { + list = STRING_LITERAL_AS_REFERENCE(IRCCOLOR "03[Mutators]" IRCNORMAL); + for (index = 0; index != server->mutators.size(); ++index) + list += " "_jrs + *server->mutators.get(index); + if (index == 0) + source->sendMessage(channel, "No mutators loaded"_jrs); + else + source->sendMessage(channel, list); + } + } + if (list.isEmpty()) + source->sendMessage(channel, "Error: Channel not attached to any connected Renegade X servers."_jrs); + } +} + +const Jupiter::ReadableString &MutatorsIRCCommand::getHelp(const Jupiter::ReadableString &) +{ + static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Provides a list of mutators being used. Syntax: Mutators"); + return defaultHelp; +} + +IRC_COMMAND_INIT(MutatorsIRCCommand) + +// Rotation IRC Command + +void RotationIRCCommand::create() +{ + this->addTrigger("rotation"_jrs); + this->addTrigger("maprotation"_jrs); + this->addTrigger("maps"_jrs); + this->addTrigger("rot"_jrs); +} + +void RotationIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters) +{ + Jupiter::IRC::Client::Channel *chan = source->getChannel(channel); + if (chan != nullptr) + { + const Jupiter::ReadableString *map; + int type = chan->getType(); + Jupiter::String list; + size_t index = 0; + for (unsigned int i = 0; i != RenX::getCore()->getServerCount(); i++) + { + RenX::Server *server = RenX::getCore()->getServer(i); + if (server->isLogChanType(type)) + { + list = STRING_LITERAL_AS_REFERENCE(IRCCOLOR "03[Rotation]" IRCNORMAL); + for (index = 0; index != server->maps.size(); ++index) + { + map = server->maps.get(index); + if (server->getMap().equalsi(*map)) + list += STRING_LITERAL_AS_REFERENCE(" " IRCBOLD "[") + *server->maps.get(index) + STRING_LITERAL_AS_REFERENCE("]" IRCBOLD); + else + list += " "_jrs + *server->maps.get(index); + } + if (index == 0) + source->sendMessage(channel, "No maps in rotation"_jrs); + else + source->sendMessage(channel, list); + } + } + if (list.isEmpty()) + source->sendMessage(channel, "Error: Channel not attached to any connected Renegade X servers."_jrs); + } +} + +const Jupiter::ReadableString &RotationIRCCommand::getHelp(const Jupiter::ReadableString &) +{ + static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Provides a list of maps in the server rotation. Syntax: Rotation"); + return defaultHelp; +} + +IRC_COMMAND_INIT(RotationIRCCommand) + +// Map IRC Command + +void MapIRCCommand::create() +{ + this->addTrigger("map"_jrs); +} + +void MapIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters) +{ + Jupiter::IRC::Client::Channel *chan = source->getChannel(channel); + if (chan != nullptr) + { + int type = chan->getType(); + bool match = false; + for (unsigned int i = 0; i != RenX::getCore()->getServerCount(); i++) + { + RenX::Server *server = RenX::getCore()->getServer(i); + if (server->isLogChanType(type)) + { + match = true; + source->sendMessage(channel, "Current Map: "_jrs + server->getMap()); + } + } + if (match == false) + source->sendMessage(channel, "Error: Channel not attached to any connected Renegade X servers."_jrs); + } +} + +const Jupiter::ReadableString &MapIRCCommand::getHelp(const Jupiter::ReadableString &) +{ + static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Fetches the current map. Syntax: Map"); + return defaultHelp; +} + +IRC_COMMAND_INIT(MapIRCCommand) + // Steam IRC Command void SteamIRCCommand::create() @@ -1269,19 +1400,21 @@ void SetMapIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &c Jupiter::IRC::Client::Channel *chan = source->getChannel(channel); if (chan != nullptr) { + const Jupiter::ReadableString *map_name = nullptr; int type = chan->getType(); - bool match = false; for (unsigned int i = 0; i != RenX::getCore()->getServerCount(); i++) { RenX::Server *server = RenX::getCore()->getServer(i); if (server->isLogChanType(type)) { - match = true; - if (server->setMap(parameters) == false) - source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Error: Server does not support setmap.")); + map_name = server->getMapName(parameters); + if (map_name == nullptr) + source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Error: Map not in rotation.")); + else if (server->setMap(*map_name) == false) + source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Error: Transmission error.")); } } - if (match == false) + if (map_name == nullptr) source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Error: Channel not attached to any connected Renegade X servers.")); } } diff --git a/RenX.Commands/RenX_Commands.h b/RenX.Commands/RenX_Commands.h index 5979730..b0bbc2d 100644 --- a/RenX.Commands/RenX_Commands.h +++ b/RenX.Commands/RenX_Commands.h @@ -62,6 +62,9 @@ GENERIC_IRC_COMMAND(PlayersIRCCommand) GENERIC_IRC_COMMAND(PlayerTableIRCCommand) GENERIC_IRC_COMMAND(PlayerInfoIRCCommand) GENERIC_IRC_COMMAND(BuildingInfoIRCCommand) +GENERIC_IRC_COMMAND(MutatorsIRCCommand) +GENERIC_IRC_COMMAND(RotationIRCCommand) +GENERIC_IRC_COMMAND(MapIRCCommand) GENERIC_IRC_COMMAND(SteamIRCCommand) GENERIC_IRC_COMMAND(KillDeathRatioIRCCommand) GENERIC_IRC_COMMAND(ShowModsIRCCommand) diff --git a/RenX.Core/RenX_Server.cpp b/RenX.Core/RenX_Server.cpp index cd7efd7..7e7452f 100644 --- a/RenX.Core/RenX_Server.cpp +++ b/RenX.Core/RenX_Server.cpp @@ -37,7 +37,7 @@ int RenX::Server::think() { if (RenX::Server::maxAttempts < 0 || RenX::Server::attempts < RenX::Server::maxAttempts) { - if (time(0) >= RenX::Server::lastAttempt + RenX::Server::delay) + if (std::chrono::steady_clock::now() >= RenX::Server::lastAttempt + RenX::Server::delay) { if (RenX::Server::connect()) RenX::Server::sendLogChan(IRCCOLOR "03[RenX]" IRCCOLOR " Socket successfully reconnected to Renegade-X server."); @@ -243,6 +243,28 @@ RenX::BuildingInfo *RenX::Server::getBuildingByName(const Jupiter::ReadableStrin return nullptr; } +bool RenX::Server::hasMapInRotation(const Jupiter::ReadableString &name) const +{ + size_t index = RenX::Server::maps.size(); + while (index != 0) + if (RenX::Server::maps.get(--index)->equalsi(name)) + return true; + return false; +} + +const Jupiter::ReadableString *RenX::Server::getMapName(const Jupiter::ReadableString &name) const +{ + size_t index = RenX::Server::maps.size(); + const Jupiter::ReadableString *map_name; + while (index != 0) + { + map_name = RenX::Server::maps.get(--index); + if (map_name->findi(name) != Jupiter::INVALID_INDEX) + return map_name; + } + return nullptr; +} + const Jupiter::ReadableString &RenX::Server::getCurrentRCONCommand() const { return RenX::Server::lastCommand; @@ -621,12 +643,12 @@ unsigned short RenX::Server::getSocketPort() const return RenX::Server::sock.getPort(); } -time_t RenX::Server::getLastAttempt() const +std::chrono::steady_clock::time_point RenX::Server::getLastAttempt() const { return RenX::Server::lastAttempt; } -time_t RenX::Server::getDelay() const +std::chrono::milliseconds RenX::Server::getDelay() const { return RenX::Server::delay; } @@ -924,7 +946,7 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) } } }; - auto onPostGameOver = [this](RenX::WinType winType, RenX::TeamType team, int gScore, int nScore) + auto onMapChange = [this]() { this->firstAction = false; this->firstKill = false; @@ -1440,15 +1462,31 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) { if (this->lastCommandParams.isEmpty()) { - // "Port" | Port | "Name" | Name | "Passworded" | "True"/"False" | "Level" | Level + // "Port" | Port | "Name" | Name | "Level" | Level | "Players" | Players | "Bots" | Bots buff.shiftRight(1); this->port = static_cast(buff.getToken(1, RenX::DelimC).asUnsignedInt(10)); this->serverName = buff.getToken(3, RenX::DelimC); - this->passworded = buff.getToken(5, RenX::DelimC).asBool(); - this->map = buff.getToken(7, RenX::DelimC); + this->map = buff.getToken(5, RenX::DelimC); buff.shiftLeft(1); } } + else if (this->lastCommand.equalsi("gameinfo"_jrs)) + { + // "PlayerLimit" | PlayerLimit | "VehicleLimit" | VehicleLimit | "MineLimit" | MineLimit | "TimeLimit" | TimeLimit | "bPassworded" | bPassworded | "bSteamRequired" | bSteamRequired | "bPrivateMessageTeamOnly" | bPrivateMessageTeamOnly | "bAllowPrivateMessaging" | bAllowPrivateMessaging | "bAutoBalanceTeams" | bAutoBalanceTeams | "bSpawnCrates" | bSpawnCrates | "CrateRespawnAfterPickup" | CrateRespawnAfterPickup + buff.shiftRight(1); + this->playerLimit = buff.getToken(1, RenX::DelimC).asInt(); + this->vehicleLimit = buff.getToken(3, RenX::DelimC).asInt(); + this->mineLimit = buff.getToken(5, RenX::DelimC).asInt(); + this->timeLimit = buff.getToken(7, RenX::DelimC).asInt(); + this->passworded = buff.getToken(9, RenX::DelimC).asBool(); + this->steamRequired = buff.getToken(11, RenX::DelimC).asBool(); + this->privateMessageTeamOnly = buff.getToken(13, RenX::DelimC).asBool(); + this->allowPrivateMessaging = buff.getToken(15, RenX::DelimC).asBool(); + this->autoBalanceTeams = buff.getToken(17, RenX::DelimC).asBool(); + this->spawnCrates = buff.getToken(19, RenX::DelimC).asBool(); + this->crateRespawnAfterPickup = buff.getToken(21, RenX::DelimC).asDouble(); + buff.shiftLeft(1); + } else if (this->lastCommand.equalsi("mutatorlist"_jrs)) { // "The following mutators are loaded:" [ | Mutator [ | Mutator [ ... ] ] ] @@ -1466,6 +1504,14 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) } buff.shiftLeft(1); } + else if (this->lastCommand.equalsi("rotation"_jrs)) + { + // Map + buff.shiftRight(1); + if (this->hasMapInRotation(buff) == false) + this->maps.add(new Jupiter::StringS(buff)); + buff.shiftLeft(1); + } else if (this->lastCommand.equalsi("changename")) { buff.shiftRight(1); @@ -1475,6 +1521,7 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) for (size_t i = 0; i < xPlugins.size(); i++) xPlugins.get(i)->RenX_OnNameChange(this, player, newName); player->name = newName; + buff.shiftLeft(1); } break; case 'l': @@ -1939,7 +1986,6 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) onPreGameOver(winType, team, gScore, nScore); for (size_t i = 0; i < xPlugins.size(); i++) xPlugins.get(i)->RenX_OnGameOver(this, winType, team, gScore, nScore); - onPostGameOver(winType, team, gScore, nScore); } else if (winTieToken.equals("tie")) { @@ -1947,7 +1993,6 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) int nScore = buff.getToken(5, RenX::DelimC).getToken(1, '=').asInt(); for (size_t i = 0; i < xPlugins.size(); i++) xPlugins.get(i)->RenX_OnGameOver(this, RenX::WinType::Tie, RenX::TeamType::None, gScore, nScore); - onPostGameOver(WinType::Tie, RenX::TeamType::None, gScore, nScore); } } else @@ -2365,6 +2410,7 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) for (size_t i = 0; i < xPlugins.size(); i++) xPlugins.get(i)->RenX_OnMapChange(this, map, seamless); this->map = map; + onMapChange(); } else if (subHeader.equals("Loaded;")) { @@ -2466,7 +2512,9 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) { RenX::Server::sock.send("s\n"_jrs); RenX::Server::send("serverinfo"_jrs); + RenX::Server::send("gameinfo"_jrs); RenX::Server::send("mutatorlist"_jrs); + RenX::Server::send("rotation"_jrs); RenX::Server::fetchClientList(); RenX::Server::updateBuildingList(); @@ -2518,7 +2566,7 @@ void RenX::Server::disconnect(RenX::DisconnectReason reason) bool RenX::Server::connect() { - RenX::Server::lastAttempt = time(0); + RenX::Server::lastAttempt = std::chrono::steady_clock::now(); if (RenX::Server::sock.connect(RenX::Server::hostname.c_str(), RenX::Server::port, RenX::Server::clientHostname.isEmpty() ? nullptr : RenX::Server::clientHostname.c_str())) { RenX::Server::sock.setBlocking(false); @@ -2550,6 +2598,9 @@ void RenX::Server::wipeData() xPlugins.get(index)->RenX_OnPlayerDelete(this, player); delete player; } + RenX::Server::buildings.emptyAndDelete(); + RenX::Server::mutators.emptyAndDelete(); + RenX::Server::maps.emptyAndDelete(); RenX::Server::awaitingPong = false; RenX::Server::rconVersion = 0; RenX::Server::rconUser.truncate(RenX::Server::rconUser.size()); @@ -2603,7 +2654,7 @@ void RenX::Server::init() RenX::Server::setPrefix(Jupiter::IRC::Client::Config->get(RenX::Server::configSection, STRING_LITERAL_AS_REFERENCE("IRCPrefix"))); RenX::Server::rules = Jupiter::IRC::Client::Config->get(RenX::Server::configSection, STRING_LITERAL_AS_REFERENCE("Rules"), STRING_LITERAL_AS_REFERENCE("Anarchy!")); - RenX::Server::delay = Jupiter::IRC::Client::Config->getInt(RenX::Server::configSection, STRING_LITERAL_AS_REFERENCE("ReconnectDelay"), 10); + RenX::Server::delay = std::chrono::milliseconds(Jupiter::IRC::Client::Config->getInt(RenX::Server::configSection, STRING_LITERAL_AS_REFERENCE("ReconnectDelay"), 10000)); RenX::Server::maxAttempts = Jupiter::IRC::Client::Config->getInt(RenX::Server::configSection, STRING_LITERAL_AS_REFERENCE("MaxReconnectAttempts"), -1); RenX::Server::rconBan = Jupiter::IRC::Client::Config->getBool(RenX::Server::configSection, STRING_LITERAL_AS_REFERENCE("RCONBan"), false); RenX::Server::localSteamBan = Jupiter::IRC::Client::Config->getBool(RenX::Server::configSection, STRING_LITERAL_AS_REFERENCE("LocalSteamBan"), true); diff --git a/RenX.Core/RenX_Server.h b/RenX.Core/RenX_Server.h index 9c0415d..37ffcff 100644 --- a/RenX.Core/RenX_Server.h +++ b/RenX.Core/RenX_Server.h @@ -85,6 +85,7 @@ namespace RenX Jupiter::DLList players; /** A list of players in the server */ Jupiter::ArrayList buildings; /** A list of buildings in the server */ Jupiter::ArrayList mutators; /** A list of buildings the server is running */ + Jupiter::ArrayList maps; /** A list of maps in the server's rotation */ Jupiter::INIFile varData; /** This may be replaced later with a more dedicated type. */ /** @@ -208,6 +209,22 @@ namespace RenX */ RenX::BuildingInfo *getBuildingByName(const Jupiter::ReadableString &name) const; + /** + * @brief Checks if a map name is in the rotation. + * + * @param name Name of map to search for + * @return True if the map exists, false otherwise. + */ + bool hasMapInRotation(const Jupiter::ReadableString &name) const; + + /** + * @brief Searches for a map based on a part of its name. + * + * @param name Part of the map's name to search for + * @return A map's full name if it exists, nullptr otherwise. + */ + const Jupiter::ReadableString *getMapName(const Jupiter::ReadableString &name) const; + /** * @brief Fetches the RCON command currently being processed. * @@ -609,14 +626,14 @@ namespace RenX * * @return Time of the last connection attempt. */ - time_t getLastAttempt() const; + std::chrono::steady_clock::time_point getLastAttempt() const; /** * @brief Fetches the time delay between connection attempts. * * @return Time delay between connection attempts. */ - time_t getDelay() const; + std::chrono::milliseconds getDelay() const; /** * @brief Checks if the server has a game password. @@ -856,7 +873,6 @@ namespace RenX bool pure = false; bool connected = false; bool seamless = false; - bool passworded = false; bool needsCList = false; bool silenceParts = false; bool silenceJoins = false; @@ -865,9 +881,20 @@ namespace RenX bool firstDeath = false; bool firstAction = false; bool awaitingPong = false; - unsigned int rconVersion = 0; - time_t lastAttempt = 0; + bool passworded = false; + bool steamRequired = false; + bool privateMessageTeamOnly = false; + bool allowPrivateMessaging = true; + bool autoBalanceTeams = true; + bool spawnCrates = true; int attempts = 0; + int playerLimit = 0; + int vehicleLimit = 0; + int mineLimit = 0; + int timeLimit = 0; + unsigned int rconVersion = 0; + double crateRespawnAfterPickup = 0.0; + std::chrono::steady_clock::time_point lastAttempt = std::chrono::steady_clock::now(); std::chrono::steady_clock::time_point gameStart = std::chrono::steady_clock::now(); std::chrono::steady_clock::time_point lastClientListUpdate = std::chrono::steady_clock::now(); std::chrono::steady_clock::time_point lastBuildingListUpdate = std::chrono::steady_clock::now(); @@ -881,8 +908,8 @@ namespace RenX unsigned short port; int logChanType; int adminLogChanType; - time_t delay; int maxAttempts; + std::chrono::milliseconds delay; std::chrono::milliseconds clientUpdateRate; std::chrono::milliseconds buildingUpdateRate; std::chrono::milliseconds pingRate; diff --git a/RenX.HybridUUID/RenX_HybridUUID.h b/RenX.HybridUUID/RenX_HybridUUID.h index 16b49ea..805e4f2 100644 --- a/RenX.HybridUUID/RenX_HybridUUID.h +++ b/RenX.HybridUUID/RenX_HybridUUID.h @@ -34,7 +34,7 @@ public: // Jupiter::Plugin ~RenX_HybridUUIDPlugin(); private: - STRING_LITERAL_AS_NAMED_REFERENCE(name, "RenX_TemplatePlugin"); + STRING_LITERAL_AS_NAMED_REFERENCE(name, "RenX.HybridUUID"); }; #endif // _RENX_HYBRIDUUID_H_HEADER \ No newline at end of file diff --git a/RenX.NicknameUUID/RenX_NicknameUUID.h b/RenX.NicknameUUID/RenX_NicknameUUID.h index 6a7d7d8..729b27d 100644 --- a/RenX.NicknameUUID/RenX_NicknameUUID.h +++ b/RenX.NicknameUUID/RenX_NicknameUUID.h @@ -34,7 +34,7 @@ public: // Jupiter::Plugin ~RenX_NicknameUUIDPlugin(); private: - STRING_LITERAL_AS_NAMED_REFERENCE(name, "RenX_TemplatePlugin"); + STRING_LITERAL_AS_NAMED_REFERENCE(name, "RenX.NicknameUUID"); }; #endif // _RENX_NICKNAMEUUID_H_HEADER \ No newline at end of file