diff --git a/config.lua.dist b/config.lua.dist index 2870da2237..bb8b7f8404 100644 --- a/config.lua.dist +++ b/config.lua.dist @@ -19,6 +19,7 @@ expFromPlayersLevelRange = 75 -- Connection Config -- NOTE: maxPlayers set to 0 means no limit -- NOTE: allowWalkthrough is only applicable to players +-- NOTE: statusCountMaxPlayersPerIp allows you to only count up to X players per IP in status response (0 = disabled) ip = "127.0.0.1" bindOnlyGlobalAddress = false loginProtocolPort = 7171 @@ -31,6 +32,7 @@ allowClones = false allowWalkthrough = true serverName = "Forgotten" statusTimeout = 5000 +statusCountMaxPlayersPerIp = 0 replaceKickOnLogin = true maxPacketsPerSecond = 25 diff --git a/src/configmanager.cpp b/src/configmanager.cpp index fdc9195b71..f5b723fe1a 100644 --- a/src/configmanager.cpp +++ b/src/configmanager.cpp @@ -261,6 +261,7 @@ bool ConfigManager::load() integer[PROTECTION_LEVEL] = getGlobalNumber(L, "protectionLevel", 1); integer[DEATH_LOSE_PERCENT] = getGlobalNumber(L, "deathLosePercent", -1); integer[STATUSQUERY_TIMEOUT] = getGlobalNumber(L, "statusTimeout", 5000); + integer[STATUS_COUNT_MAX_PLAYERS_PER_IP] = getGlobalNumber(L, "statusCountMaxPlayersPerIp", 0); integer[FRAG_TIME] = getGlobalNumber(L, "timeToDecreaseFrags", 24 * 60 * 60); integer[WHITE_SKULL_TIME] = getGlobalNumber(L, "whiteSkullTime", 15 * 60); integer[STAIRHOP_DELAY] = getGlobalNumber(L, "stairJumpExhaustion", 2000); diff --git a/src/protocolstatus.cpp b/src/protocolstatus.cpp index d8370c9a93..fe34e44523 100644 --- a/src/protocolstatus.cpp +++ b/src/protocolstatus.cpp @@ -101,6 +101,24 @@ void ProtocolStatus::sendStatusString() owner.append_attribute("email") = g_config.getString(ConfigManager::OWNER_EMAIL).c_str(); pugi::xml_node players = tsqp.append_child("players"); + + uint32_t reportableOnlinePlayerCount = 0; + uint32_t maxPlayersPerIp = getNumber(ConfigManager::STATUS_COUNT_MAX_PLAYERS_PER_IP); + if (maxPlayersPerIp > 0) { + std::map playersPerIp; + for (const auto& it : g_game.getPlayers()) { + if (!it.second->getIP().is_unspecified()) { + ++playersPerIp[it.second->getIP()]; + } + } + + for (auto&& [ip, players] : playersPerIp) { + reportableOnlinePlayerCount += std::min(players, maxPlayersPerIp); + } + } else { + reportableOnlinePlayerCount = g_game.getPlayersOnline(); + } + players.append_attribute("online") = std::to_string(g_game.getPlayersOnline()).c_str(); players.append_attribute("max") = std::to_string(g_config.getNumber(ConfigManager::MAX_PLAYERS)).c_str(); players.append_attribute("peak") = std::to_string(g_game.getPlayersRecord()).c_str();