Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Tekaoh
2020-05-13 18:50:48 +00:00
16 changed files with 144 additions and 55 deletions
@@ -275,9 +275,9 @@ m_timeCharacterMatchStatisticsNextRefresh(0)
connectToMessage("TaskConnectionOpened");
connectToMessage("RandomNameRequest"); // from connection server
connectToMessage("RandomNameResponse"); // from game server
connectToMessage("VerifyAndLockNameRequest"); // from connection server
connectToMessage("VerifyAndLockNameResponse"); // from game server
connectToMessage("VerifyAndLockNameRequest"); // from connection server
connectToMessage("VerifyAndLockNameResponse"); // from game server
//Object Messages
connectToMessage("RequestObjectMessage");
connectToMessage("RequestChunkMessage");
@@ -386,7 +386,7 @@ m_timeCharacterMatchStatisticsNextRefresh(0)
connectToMessage("RestartServerByRoleMessage");
connectToMessage("ExcommunicateGameServerMessage");
connectToMessage("RestartPlanetMessage");
// Cluster state
connectToMessage("UpdateClusterLockedAndSecretState");
@@ -432,7 +432,7 @@ m_timeCharacterMatchStatisticsNextRefresh(0)
CentralServer::~CentralServer()
{
ConsoleManager::remove();
CentralCSHandler::remove();
ms_sceneToHostMap.clear();
@@ -1315,7 +1315,7 @@ void CentralServer::receiveMessage(const MessageDispatch::Emitter & source, cons
Archive::ReadIterator ri = static_cast<const GameNetworkMessage &>(message).getByteStream().begin();
GenericValueTypeMessage <TransferCharacterData> reply(ri);
// If this request has a CS Tool Id associated with it, it is an admin request for the CSTool,
// and so we should send it directly to the connection server, and not depend on a
// and so we should send it directly to the connection server, and not depend on a
// transfer server existing.
if (reply.getValue().getCSToolId() > 0) {
@@ -2634,7 +2634,7 @@ void CentralServer::removeGameServer(GameServerConnection const *gameServer)
ExcommunicateGameServerMessage const excommunicateMessage(pid, 0, "");
sendToAllGameServersExceptDBProcess(excommunicateMessage, true);
}
else
else
{
DEBUG_WARNING(true, ("A game server crashed but our process ID ptr is nullptr."));
}
@@ -2697,7 +2697,7 @@ void CentralServer::run(void)
setup.port = ConfigCentralServer::getCommodityServerServicePort();
setup.bindInterface = ConfigCentralServer::getCommodityServerServiceBindInterface();
s_commodityServerService = new Service(ConnectionAllocator<ServerConnection>(), setup);
setup.port = ConfigCentralServer::getLoginServicePort();
if (ConfigCentralServer::getDevelopmentMode())
cserver.connectToLoginServer();
@@ -2709,7 +2709,7 @@ void CentralServer::run(void)
// connect to the task manager
cserver.m_taskManager = new TaskConnection("127.0.0.1", ConfigCentralServer::getTaskManagerPort());
unsigned long startTime = Clock::timeMs();
unsigned long nextLoadingLogTime=0;
unsigned long nextPingTime=0;
@@ -2743,7 +2743,7 @@ void CentralServer::run(void)
{
unsigned long lastFrameTime = 0;
unsigned long frameStartTime = Clock::timeMs();
PROFILER_AUTO_BLOCK_DEFINE("main loop");
bool barrierReached = true;
@@ -2847,7 +2847,7 @@ void CentralServer::update()
static int shutdownCheckLoopCount = 0;
m_curTime = static_cast<uint32>(time(0));
// Tell the LoginServers if necessary
if ((++loopCount > ConfigCentralServer::getUpdatePlayerCountFrequency()))
{
@@ -2877,7 +2877,7 @@ void CentralServer::update()
const short port[1] = { (short)ConfigCentralServer::getAuctionPort() };
std::string s_id = ConfigCentralServer::getAuctionIDPrefix();
s_id += ConfigCentralServer::getClusterName();
s_id += ConfigCentralServer::getClusterName();
const char *identifier[1];
identifier[ 0 ] = s_id.c_str();
@@ -2914,7 +2914,7 @@ void CentralServer::sendPopulationUpdateToLoginServer()
m_totalTutorialSceneCount = 0;
m_totalFalconSceneCount = 0;
ConnectionServerConnectionList::const_iterator i;
for (i=m_connectionServerConnections.begin(); i!=m_connectionServerConnections.end(); ++i)
{
@@ -2939,7 +2939,7 @@ void CentralServer::sendPopulationUpdateToLoginServer()
void CentralServer::sendMetricsToWebAPI()
{
static const std::string metricsURL(ConfigCentralServer::getMetricsDataURL());
if (!metricsURL.empty())
{
StellaBellum::webAPI api(metricsURL);
@@ -2952,23 +2952,25 @@ void CentralServer::sendMetricsToWebAPI()
api.addJsonData<int>("lastLoadingStateTime", m_lastLoadingStateTime);
api.addJsonData<int>("clusterStartupTime", m_clusterStartupTime);
api.addJsonData<int>("timeClusterWentIntoLoadingState", m_timeClusterWentIntoLoadingState);
api.addJsonData<int>("webUpdateIntervalSeconds", ConfigCentralServer::getWebUpdateIntervalSeconds());
api.addJsonData<std::string>("secretKey", ConfigCentralServer::getMetricsSecretKey());
#ifdef _DEBUG
if (api.submit()) {
bool status = api.getNullableValue<bool>("status");
if (status)
{
std::string message = api.getString("message");
if (message.empty())
{
message = "No message returned.";
}
WARNING(true, ("Error sending stats: %s", message.c_str()));
}
WARNING(true, ("Success sending server stats to API."));
}
else
@@ -3200,7 +3202,7 @@ void CentralServer::startPlanetServer(const std::string & host, const std::strin
portBase += 100;
options += " gameServerDebuggingPortBase=";
options += buffer;
TaskSpawnProcess spawn(host.empty() ? std::string("any") : host, "PlanetServer", options, spawnDelay);
CentralServer::getInstance().sendTaskMessage(spawn);
m_pendingPlanetServers[sceneId] = std::make_pair(std::make_pair(host, options), ::time(nullptr));
@@ -3218,7 +3220,7 @@ void CentralServer::startPlanetServer(const std::string & host, const std::strin
getInstance().m_transferServerConnection = 0;
s_retryTransferServerConnection = false;
}
if(getInstance().m_stationPlayersCollectorConnection != nullptr && ! isPreloadFinished())
{
getInstance().m_stationPlayersCollectorConnection->disconnect();
@@ -3923,7 +3925,7 @@ void CentralServer::checkShutdownProcess()
if( m_curTime>=m_shutdownTotalTime && !warn30 )
{
LOG("CentralServerShutdown",("Shutdown Phase %d: Broadcasting 30sec disconnect warning message to players.", m_shutdownPhase));
ConGenericMessage const msg("game any systemMessage You will be disconnected in 30sec so the server can perform a final save before shutting down. Please find a safe place to logout now.", 0);
ConGenericMessage const msg("game any systemMessage You will be disconnected in 30 seconds so the server can perform a final save before shutting down. Please find a safe place to logout now.", 0);
IGNORE_RETURN(sendToRandomGameServer(msg));
warn30 = true;
@@ -3931,7 +3933,7 @@ void CentralServer::checkShutdownProcess()
else if( m_curTime >= (m_shutdownTotalTime+20) && !warn10 )
{
LOG("CentralServerShutdown",("Shutdown Phase %d: Broadcasting 10sec disconnect warning message to players.", m_shutdownPhase));
ConGenericMessage const msg("game any systemMessage You will be disconnected in 10sec so the server can perform a final save before shutting down. Please find a safe place to logout now.", 0);
ConGenericMessage const msg("game any systemMessage You will be disconnected in 10 seconds so the server can perform a final save before shutting down. Please find a safe place to logout now.", 0);
IGNORE_RETURN(sendToRandomGameServer(msg));
warn10 = true;
}
@@ -4133,7 +4135,7 @@ std::pair<std::map<int, std::pair<std::string, int> > const *, std::map<int, std
}
refreshTime = m_timeLastLoginTimeStatisticsRefresh;
return std::make_pair(&m_lastLoginTimeStatistics, &m_createTimeStatistics);
}
@@ -16,7 +16,7 @@
ConfigCentralServer::Data * ConfigCentralServer::data = 0;
#define KEY_INT(a,b) (data->a = ConfigFile::getKeyInt("CentralServer", #a, b))
#define KEY_BOOL(a,b) (data->a = ConfigFile::getKeyBool("CentralServer", #a, b))
#define KEY_BOOL(a,b) (data->a = ConfigFile::getKeyBool("CentralServer", #a, b))
#define KEY_STRING(a,b) (data->a = ConfigFile::getKeyString("CentralServer", #a, b))
//-----------------------------------------------------------------------
@@ -110,7 +110,7 @@ void ConfigCentralServer::install(void)
KEY_STRING (transferServerAddress, "127.0.0.1");
KEY_INT (transferServerPort, 0); // TransferServer listens on 50005, default to "off"
KEY_STRING (stationPlayersCollectorAddress, "127.0.0.1");
KEY_INT (stationPlayersCollectorPort, 0); // StationPlayersCollector listens on 50010, default to "off"
KEY_INT (stationPlayersCollectorPort, 0); // StationPlayersCollector listens on 50010, default to "off"
KEY_BOOL (allowZeroConnectionServerPort, true);
KEY_INT (clusterWideDataLockTimeout, 300); // seconds
KEY_STRING (commodityServerServiceBindInterface, "");
@@ -129,6 +129,7 @@ void ConfigCentralServer::install(void)
KEY_INT (maxTimeToWaitForPlanetServerStartSeconds, 5*60); // seconds
KEY_STRING (metricsDataURL, "");
KEY_INT (webUpdateIntervalSeconds, 5);
KEY_STRING (metricsSecretKey, "");
int index = 0;
char const * result = 0;
@@ -74,6 +74,7 @@ public:
const char * metricsDataURL;
int webUpdateIntervalSeconds;
const char * metricsSecretKey;
};
static const unsigned short getChatServicePort ();
@@ -137,7 +138,7 @@ public:
static const char * getAuctionServer();
static int getAuctionPort();
static const char * getAuctionIDPrefix();
static bool getDisconnectDuplicateConnectionsOnOtherGalaxies();
static bool getRequestDbSaveOnPlanetServerCrash();
@@ -146,13 +147,14 @@ public:
static const char * getMetricsDataURL();
static int getWebUpdateIntervalSeconds();
static const char * getMetricsSecretKey();
private:
static Data * data;
};
//-----------------------------------------------------------------------
inline const unsigned short ConfigCentralServer::getChatServicePort()
inline const unsigned short ConfigCentralServer::getChatServicePort()
{
return static_cast<unsigned short>(data->chatServicePort);
}
@@ -173,7 +175,7 @@ inline const unsigned short ConfigCentralServer::getConnectionServicePort()
//-----------------------------------------------------------------------
inline const unsigned short ConfigCentralServer::getCustomerServicePort()
inline const unsigned short ConfigCentralServer::getCustomerServicePort()
{
return static_cast<unsigned short>(data->customerServicePort);
}
@@ -529,6 +531,13 @@ inline int ConfigCentralServer::getWebUpdateIntervalSeconds()
return data->webUpdateIntervalSeconds;
}
// ----------------------------------------------------------------------
inline const char * ConfigCentralServer::getMetricsSecretKey()
{
return data->metricsSecretKey;
}
// ======================================================================
#endif // _ConfigCentralServer_H
@@ -21,6 +21,7 @@
#include "sharedFoundation/CrcConstexpr.hpp"
#include "Session/CommonAPI/CommonAPI.h"
#include "webAPI.h"
#include "jsonWebAPI.h"
@@ -170,7 +171,7 @@ void ClientConnection::validateClient(const std::string & id, const std::string
}
// hash username into station id
StationId suid = atoi(lcaseId.c_str());
StationId suid = atoi(lcaseId.c_str());
if (suid == 0)
{
std::hash<std::string> h;
@@ -181,7 +182,7 @@ void ClientConnection::validateClient(const std::string & id, const std::string
int authOK = 0;
std::string authURL(ConfigLoginServer::getExternalAuthUrl());
if (!authURL.empty())
if (!authURL.empty())
{
if(ConfigLoginServer::getUseJsonWebApi())
{
@@ -191,6 +192,7 @@ void ClientConnection::validateClient(const std::string & id, const std::string
api.addJsonData<std::string>("user_password", trimmedKey);
api.addJsonData<long>("stationID", suid);
api.addJsonData<std::string>("ip", getRemoteAddress());
api.addJsonData<std::string>("secretKey", ConfigLoginServer::getExternalAuthSecretKey());
if (api.submit())
{
@@ -206,15 +208,15 @@ void ClientConnection::validateClient(const std::string & id, const std::string
}
}
else
{
{
ErrorMessage err("Login Failed", "request failed");
this->send(err, true);
}
}
}
else
{
std::ostringstream postBuf;
postBuf << "user_name=" << trimmedId << "&user_password=" << trimmedKey << "&stationID=" << suid << "&ip=" << getRemoteAddress();
postBuf << "user_name=" << trimmedId << "&user_password=" << trimmedKey << "&stationID=" << suid << "&ip=" << getRemoteAddress() << "&secretKey=" << ConfigLoginServer::getExternalAuthSecretKey();
std::string response = webAPI::simplePost(authURL, std::string(postBuf.str()), "");
if (response == "success") {
@@ -232,7 +234,7 @@ void ClientConnection::validateClient(const std::string & id, const std::string
authOK = 1;
}
if (authOK)
if (authOK)
{
LoginServer::getInstance().onValidateClient(suid, lcaseId, this, true, NULL, 0xFFFFFFFF, 0xFFFFFFFF);
}
@@ -285,4 +287,3 @@ StationId ClientConnection::getRequestedAdminSuid() const {
}
// ======================================================================
@@ -118,6 +118,7 @@ void ConfigLoginServer::install(void)
KEY_BOOL(useJsonWebApi, false);
KEY_BOOL(useExternalAuth, false);
KEY_STRING(externalAuthURL, "");
KEY_STRING(externalAuthSecretKey, "");
KEY_BOOL(useOldSuidGenerator, false);
int index = 0;
@@ -66,11 +66,12 @@ class ConfigLoginServer
int csToolPort;
bool requireSecureLoginForCsTool;
bool useOldSuidGenerator;
bool useExternalAuth;
bool useJsonWebApi;
const char * externalAuthURL;
const char * externalAuthSecretKey;
};
static const uint16 getCentralServicePort();
@@ -137,6 +138,7 @@ class ConfigLoginServer
static bool getUseExternalAuth();
static bool getUseJsonWebApi();
static const char * getExternalAuthUrl();
static const char * getExternalAuthSecretKey();
static bool getUseOldSuidGenerator();
// has character creation for this cluster been disabled through config option
@@ -502,6 +504,10 @@ inline const char * ConfigLoginServer::getExternalAuthUrl()
return data->externalAuthURL;
}
inline const char * ConfigLoginServer::getExternalAuthSecretKey()
{
return data->externalAuthSecretKey;
}
inline bool ConfigLoginServer::getUseOldSuidGenerator()
{
@@ -82,6 +82,7 @@ void ConfigTaskManager::install(void)
KEY_INT (maximumClockDriftToleranceSeconds, 10); // seconds
KEY_INT (systemTimeCheckIntervalSeconds, 60); // seconds
KEY_INT (clockDriftFatalIntervalSeconds, 1*60*60); // seconds
KEY_BOOL (allowPreferredServerOnMasterNode, false);
int index = 0;
char const * result = 0;
@@ -39,6 +39,7 @@ class ConfigTaskManager
int maximumClockDriftToleranceSeconds;
int systemTimeCheckIntervalSeconds;
int clockDriftFatalIntervalSeconds;
bool allowPreferredServerOnMasterNode;
};
static const bool getAutoStart ();
@@ -68,7 +69,7 @@ class ConfigTaskManager
static int getMaximumClockDriftToleranceSeconds();
static int getSystemTimeCheckIntervalSeconds();
static int getClockDriftFatalIntervalSeconds();
static const bool getAllowPreferredServerOnMasterNode();
static void install ();
static void remove ();
@@ -270,4 +271,11 @@ inline int ConfigTaskManager::getClockDriftFatalIntervalSeconds()
// ----------------------------------------------------------------------
inline const bool ConfigTaskManager::getAllowPreferredServerOnMasterNode()
{
return data->allowPreferredServerOnMasterNode;
}
// ----------------------------------------------------------------------
#endif // _ConfigTaskManager_H
@@ -146,19 +146,33 @@ ManagerConnection *LocatorNamespace::getPreferredServer(std::string const &proce
{
ServerEntry &e = *i;
if ((e.m_label != s_masterNodeLabel) && (e.hasAvailableLoad(cost)))
{
{
for (std::vector<PreferredNode>::const_iterator j = s_preferredNodes.begin(); j != s_preferredNodes.end(); ++j)
if ((*j).m_nodeLabel == e.m_label && (*j).match(processName, options))
return e.m_connection;
}
}
}
}
return 0;
}
// ----------------------------------------------------------------------
ManagerConnection *LocatorNamespace::getUnpreferredServer(float cost)
bool Locator::isMasterNodePreferred(std::string const &processName, std::string const &options, float cost)
{
if(!ConfigTaskManager::getAllowPreferredServerOnMasterNode())
return false;
for (std::vector<PreferredNode>::const_iterator j = s_preferredNodes.begin(); j != s_preferredNodes.end(); ++j)
if ((*j).m_nodeLabel == s_masterNodeLabel && (*j).match(processName, options))
return true;
return false;
}
// ----------------------------------------------------------------------
ManagerConnection *LocatorNamespace::getUnpreferredServer(float cost)
{
// Find a node other than the master node that can afford to run the process
// and is a not marked as a preferred node for anything; if more than one
// node qualifies, return the node with the lowest load
@@ -190,8 +204,8 @@ ManagerConnection *LocatorNamespace::getUnpreferredServer(float cost)
// ----------------------------------------------------------------------
ManagerConnection *Locator::getBestServer(std::string const &processName, std::string const &options, float cost)
{
if (s_serverList.empty())
{
if (s_serverList.empty())
return 0;
// first, look for a preferred node for this process
@@ -24,6 +24,7 @@ public:
static void install();
static void closed(std::string const &label, ManagerConnection const *oldConnection);
static ManagerConnection *getBestServer(std::string const &processName, std::string const &options, float cost);
static bool isMasterNodePreferred(std::string const &processName, std::string const &options, float cost);
static float getMyLoad();
static float getMyMaximumLoad();
static float getServerLoad(std::string const &label);
@@ -84,7 +84,7 @@ void ManagerConnection::onConnectionClosed()
void ManagerConnection::onConnectionOpened()
{
DEBUG_REPORT_LOG(true, ("Manager connection opened\n"));
DEBUG_REPORT_LOG(true, ("Manager connection opened for %s \n", getRemoteAddress().c_str()));
TaskConnectionIdMessage id(TaskConnectionIdMessage::TaskManager, TaskManager::getNodeLabel(), ConfigTaskManager::getClusterName());
send(id);
s_managerConnectionCount++;
@@ -613,7 +613,6 @@ unsigned long TaskManager::startServer(const std::string & processName, const st
}
const ProcessEntry pe = (*f).second;
// does the process run on this box?
if(pe.targetHost == "local" || pe.targetHost == getNodeLabel() || nodeLabel == getNodeLabel() || nodeLabel == "local")
{
@@ -646,10 +645,14 @@ unsigned long TaskManager::startServer(const std::string & processName, const st
// select a task manager on which to spawn the server
// find the best target
float cost = getLoadForProcess(pe.processName);
ManagerConnection * conn = Locator::getBestServer(pe.processName, options, cost);
if(!conn)
if(Locator::isMasterNodePreferred(pe.processName, options, cost))
{
pid = startServerLocal(pe, options);
}
ManagerConnection * conn = Locator::getBestServer(pe.processName, options, cost);
if(!conn && !pid)
{
if(ManagerConnection::getConnectionCount() < 1)
pid = startServerLocal(pe, options);
else
@@ -666,7 +669,7 @@ unsigned long TaskManager::startServer(const std::string & processName, const st
s_queuedSpawnRequests.push_back(r);
}
}
else
else if(!pid)
{
std::string label = "uninitialized label";
if(conn->getNodeLabel())
@@ -49,7 +49,7 @@ include_directories(
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedLog/include/public
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedMath/include/public
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedMathArchive/include/public
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedMessageDispatch/include/public
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedNetwork/include/public
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedNetworkMessages/include/public
@@ -60,6 +60,7 @@ include_directories(
${SWG_EXTERNALS_SOURCE_DIR}/ours/library/localizationArchive/include/public
${SWG_EXTERNALS_SOURCE_DIR}/ours/library/unicode/include
${SWG_EXTERNALS_SOURCE_DIR}/ours/library/unicodeArchive/include/public
${SWG_EXTERNALS_SOURCE_DIR}/3rd/library/webAPI
)
add_library(serverUtility STATIC
@@ -3,6 +3,8 @@
//-----------------------------------------------------------------------
#include "ConfigServerUtility.h"
#include "serverUtility/FirstServerUtility.h"
#include "serverUtility/AdminAccountManager.h"
@@ -10,6 +12,8 @@
#include "sharedUtility/DataTable.h"
#include "sharedUtility/DataTableManager.h"
#include "webAPI.h"
#include <string>
//-----------------------------------------------------------------------
@@ -69,6 +73,14 @@ int AdminAccountManager::getAdminLevel(const std::string & account)
int level = 0;
DEBUG_FATAL(!ms_installed, ("AdminAccountManager not installed"));
if(ConfigServerUtility::isExternalAdminLevelsEnabled()){
std::ostringstream postBuffer;
postBuffer << "user_name=" << account << "&secretKey=" << ConfigServerUtility::getExternalAdminLevelsSecretKey();
std::string response = webAPI::simplePost(ConfigServerUtility::getExternalAdminLevelsURL(), std::string(postBuffer.str()), "");
level = std::stoi(response);
return level;
}
int columnNumber = ms_adminTable->findColumnNumber("AdminAccounts");
DEBUG_FATAL(columnNumber == -1, ("Error loading admin table...no account column"));
int row = ms_adminTable->searchColumnString( columnNumber, account);
@@ -113,8 +125,8 @@ bool AdminAccountManager::isInternalIp(const std::string & addr)
size_t xpos = ipAddr.find ('x');
//if no X is found, do a straight compare
if ( (xpos == 0 || xpos == std::string::npos)
&& ipAddr.compare(addr) == 0
if ( (xpos == 0 || xpos == std::string::npos)
&& ipAddr.compare(addr) == 0
)
{
retval = true;
@@ -125,7 +137,7 @@ bool AdminAccountManager::isInternalIp(const std::string & addr)
else if (xpos - 1 > addr.size())
retval = false;
//compare substring
//compare substring
else if (ipAddr.compare(0, xpos - 1, addr, 0, xpos - 1) == 0)
{
retval = true;
@@ -17,6 +17,9 @@ namespace ConfigServerUtilityNamespace
int serverMaxChatLogLines;
int playerMaxChatLogLines;
bool chatLogManagerLoggingEnabled;
bool externalAdminLevelsEnabled;
const char * externalAdminLevelsURL;
const char * externalAdminLevelsSecretKey;
}
using namespace ConfigServerUtilityNamespace;
@@ -75,6 +78,27 @@ bool ConfigServerUtility::isChatLogManagerLoggingEnabled()
//-----------------------------------------------------------------------
bool ConfigServerUtility::isExternalAdminLevelsEnabled()
{
return externalAdminLevelsEnabled;
}
//-----------------------------------------------------------------------
const char * ConfigServerUtility::getExternalAdminLevelsURL()
{
return externalAdminLevelsURL;
}
//-----------------------------------------------------------------------
const char * ConfigServerUtility::getExternalAdminLevelsSecretKey()
{
return externalAdminLevelsSecretKey;
}
//-----------------------------------------------------------------------
void ConfigServerUtility::install()
{
KEY_INT(spawnCookie, 0);
@@ -82,6 +106,9 @@ void ConfigServerUtility::install()
KEY_INT(serverMaxChatLogLines, 5000);
KEY_INT(playerMaxChatLogLines, 200);
KEY_BOOL(chatLogManagerLoggingEnabled, false);
KEY_BOOL(externalAdminLevelsEnabled, false);
KEY_STRING(externalAdminLevelsURL, "http://localhost/");
KEY_STRING(externalAdminLevelsSecretKey, "");
}
//-----------------------------------------------------------------------
@@ -91,4 +118,3 @@ void ConfigServerUtility::remove()
}
//-----------------------------------------------------------------------
@@ -17,6 +17,9 @@ public:
static int getServerMaxChatLogLines();
static int getPlayerMaxChatLogLines();
static bool isChatLogManagerLoggingEnabled();
static bool isExternalAdminLevelsEnabled();
static const char * getExternalAdminLevelsURL();
static const char * getExternalAdminLevelsSecretKey();
static void install();
static void remove();