diff --git a/src/Components/Modules/Dedicated.cpp b/src/Components/Modules/Dedicated.cpp index 7ff6330c..68223880 100644 --- a/src/Components/Modules/Dedicated.cpp +++ b/src/Components/Modules/Dedicated.cpp @@ -3,6 +3,7 @@ namespace Components { SteamID Dedicated::PlayerGuids[18][2]; + Dvar::Var Dedicated::SVRandomMapRotation; bool Dedicated::IsEnabled() { @@ -119,6 +120,41 @@ namespace Components Game::Com_Error(code, message); } + void Dedicated::RandomizeMapRotation() + { + auto rotation = Dvar::Var("sv_mapRotation").get(); + + const auto tokens = Utils::String::Explode(rotation, ' '); + std::vector> mapRotationPair; + + for (auto i = 0u; i < (tokens.size() - 1); i += 2) + { + if (i + 1 >= tokens.size()) break; + + const std::string key = tokens[i]; + const std::string value = tokens[i + 1]; + mapRotationPair.push_back(std::make_pair(key, value)); + } + + const auto seed = Utils::Cryptography::Rand::GenerateInt(); + std::shuffle(std::begin(mapRotationPair), std::end(mapRotationPair), std::default_random_engine(seed)); + + // Rebuild map rotation using the randomized key/values + rotation.clear(); + for (auto j = 0u; j < mapRotationPair.size(); j++) + { + std::pair pair = mapRotationPair[j]; + rotation.append(pair.first); + rotation.append(" "); + rotation.append(pair.second); + + if (j != mapRotationPair.size() - 1) + rotation.append(" "); + } + + Dvar::Var("sv_mapRotationCurrent").set(rotation); + } + void Dedicated::MapRotate() { if (!Dedicated::IsEnabled() && Dvar::Var("sv_dontrotate").get()) @@ -134,9 +170,10 @@ namespace Components } Logger::Print("Rotating map...\n"); + const auto mapRotation = Dvar::Var("sv_mapRotation").get(); // if nothing, just restart - if (Dvar::Var("sv_mapRotation").get().empty()) + if (mapRotation.empty()) { Logger::Print("No rotation defined, restarting map.\n"); @@ -152,14 +189,23 @@ namespace Components return; } - // first, check if the string contains nothing + // First, check if the string contains nothing if (Dvar::Var("sv_mapRotationCurrent").get().empty()) { Logger::Print("Current map rotation has finished, reloading...\n"); - Dvar::Var("sv_mapRotationCurrent").set(Dvar::Var("sv_mapRotation").get()); + + if (Dedicated::SVRandomMapRotation.get()) + { + Logger::Print("Randomizing map rotaion\n"); + Dedicated::RandomizeMapRotation(); + } + else + { + Dvar::Var("sv_mapRotationCurrent").set(mapRotation); + } } - std::string rotation = Dvar::Var("sv_mapRotationCurrent").get(); + auto rotation = Dvar::Var("sv_mapRotationCurrent").get(); auto tokens = Utils::String::Explode(rotation, ' '); @@ -346,6 +392,7 @@ namespace Components Dvar::OnInit([]() { + Dedicated::SVRandomMapRotation = Dvar::Register("sv_randomMapRotation", false, Game::dvar_flag::DVAR_FLAG_SAVED, "Randomize map rotation when true"); Dvar::Register("sv_sayName", "^7Console", Game::dvar_flag::DVAR_FLAG_NONE, "The name to pose as for 'say' commands"); Dvar::Register("sv_motd", "", Game::dvar_flag::DVAR_FLAG_NONE, "A custom message of the day for servers"); diff --git a/src/Components/Modules/Dedicated.hpp b/src/Components/Modules/Dedicated.hpp index 162e1a8f..aaf51f0d 100644 --- a/src/Components/Modules/Dedicated.hpp +++ b/src/Components/Modules/Dedicated.hpp @@ -15,6 +15,9 @@ namespace Components static void Heartbeat(); private: + static Dvar::Var SVRandomMapRotation; + + static void RandomizeMapRotation(); static void MapRotate(); static void InitDedicatedServer(); diff --git a/src/STDInclude.hpp b/src/STDInclude.hpp index 208e0cab..4ae48092 100644 --- a/src/STDInclude.hpp +++ b/src/STDInclude.hpp @@ -42,10 +42,9 @@ #include #include #include - -// Experimental C++17 features #include #include +#include #pragma warning(pop)