Cleanup server running variable information (#2239)

* Created first round of helper functions

Started to go through server init function and move statically defined
variables that the server uses into helper functions to allow for
dynamic changing while the server is up rather than requiring a restart.

* Completed Helper Function Creation

Completed adding all the helper functions along with updated the virtual
server function calls and renamed helper functions to match settings
cached ini value names for clarity.

* Comment Cleanup

Removed lines commented out throughout previous changes as well as
cleaned up variable declarations that are no longer needed with helper
functions that query the settingsCache

* Added featureset dynamic refreshing

Added slots/functions/calls for updating the required feature sets
dynamically.

* Created first round of helper functions

Started to go through server init function and move statically defined
variables that the server uses into helper functions to allow for
dynamic changing while the server is up rather than requiring a restart.
This commit is contained in:
woogerboy21 2016-10-31 05:30:12 -04:00 committed by ctrlaltca
parent 3498b16e01
commit 21a34eaaa1
9 changed files with 279 additions and 170 deletions

View file

@ -115,7 +115,7 @@ AuthenticationResult Server::loginUser(Server_ProtocolHandler *session, QString
} else if (authState == UnknownUser) { } else if (authState == UnknownUser) {
// Change user name so that no two users have the same names, // Change user name so that no two users have the same names,
// don't interfere with registered user names though. // don't interfere with registered user names though.
if (getRegOnlyServer()) { if (getRegOnlyServerEnabled()) {
qDebug("Login denied: registration required"); qDebug("Login denied: registration required");
databaseInterface->unlockSessionTables(); databaseInterface->unlockSessionTables();
return RegistrationRequired; return RegistrationRequired;
@ -155,7 +155,7 @@ AuthenticationResult Server::loginUser(Server_ProtocolHandler *session, QString
if (clientid.isEmpty()){ if (clientid.isEmpty()){
// client id is empty, either out dated client or client has been modified // client id is empty, either out dated client or client has been modified
if (getClientIdRequired()) if (getClientIDRequiredEnabled())
return ClientIdRequired; return ClientIdRequired;
} }
else { else {

View file

@ -58,12 +58,13 @@ public:
void removeClient(Server_ProtocolHandler *player); void removeClient(Server_ProtocolHandler *player);
QList<QString> getOnlineModeratorList(); QList<QString> getOnlineModeratorList();
virtual QString getLoginMessage() const { return QString(); } virtual QString getLoginMessage() const { return QString(); }
virtual QString getRequiredFeatures() const { return QString(); }
virtual bool permitUnregisteredUsers() const { return true; } virtual bool permitUnregisteredUsers() const { return true; }
virtual bool getGameShouldPing() const { return false; } virtual bool getGameShouldPing() const { return false; }
virtual bool getClientIdRequired() const { return false; } virtual bool getClientIDRequiredEnabled() const { return false; }
virtual bool getRegOnlyServer() const { return false; } virtual bool getRegOnlyServerEnabled() const { return false; }
virtual bool getMaxUserLimitEnabled() const { return false; } virtual bool getMaxUserLimitEnabled() const { return false; }
virtual int getPingClockInterval() const { return 0; } virtual int getClientKeepAlive() const { return 0; }
virtual int getMaxGameInactivityTime() const { return 9999999; } virtual int getMaxGameInactivityTime() const { return 9999999; }
virtual int getMaxPlayerInactivityTime() const { return 9999999; } virtual int getMaxPlayerInactivityTime() const { return 9999999; }
virtual int getMessageCountingInterval() const { return 0; } virtual int getMessageCountingInterval() const { return 0; }
@ -72,7 +73,8 @@ public:
virtual int getMaxGamesPerUser() const { return 0; } virtual int getMaxGamesPerUser() const { return 0; }
virtual int getCommandCountingInterval() const { return 0; } virtual int getCommandCountingInterval() const { return 0; }
virtual int getMaxCommandCountPerInterval() const { return 0; } virtual int getMaxCommandCountPerInterval() const { return 0; }
virtual int getMaxUserLimit() const { return 9999999; } virtual int getMaxUserTotal() const { return 9999999; }
virtual int getServerID() const { return 0; }
Server_DatabaseInterface *getDatabaseInterface() const; Server_DatabaseInterface *getDatabaseInterface() const;
int getNextLocalGameId() { QMutexLocker locker(&nextLocalGameIdMutex); return ++nextLocalGameId; } int getNextLocalGameId() { QMutexLocker locker(&nextLocalGameIdMutex); return ++nextLocalGameId; }

View file

@ -348,7 +348,7 @@ void Server_ProtocolHandler::pingClockTimeout()
int cmdcountinterval = server->getCommandCountingInterval(); int cmdcountinterval = server->getCommandCountingInterval();
int msgcountinterval = server->getMessageCountingInterval(); int msgcountinterval = server->getMessageCountingInterval();
int pingclockinterval = server->getPingClockInterval(); int pingclockinterval = server->getClientKeepAlive();
int interval = server->getMessageCountingInterval(); int interval = server->getMessageCountingInterval();
if (interval > 0) { if (interval > 0) {
@ -443,7 +443,7 @@ Response::ResponseCode Server_ProtocolHandler::cmdLogin(const Command_Login &cmd
// limit the number of non-privileged users that can connect to the server based on configuration settings // limit the number of non-privileged users that can connect to the server based on configuration settings
if (QString::fromStdString(userInfo->privlevel()).toLower() == "none") { if (QString::fromStdString(userInfo->privlevel()).toLower() == "none") {
if (server->getMaxUserLimitEnabled()) { if (server->getMaxUserLimitEnabled()) {
if (server->getUsersCount() > server->getMaxUserLimit()) { if (server->getUsersCount() > server->getMaxUserTotal()) {
qDebug() << "Max Users Total Limit Reached, please increase the max_users_total setting."; qDebug() << "Max Users Total Limit Reached, please increase the max_users_total setting.";
return Response::RespServerFull; return Response::RespServerFull;
} }

BIN
servatrice/servatrice.aps Normal file

Binary file not shown.

View file

@ -115,7 +115,7 @@ void IslInterface::initServer()
serverId = serverList[listIndex].id; serverId = serverList[listIndex].id;
Event_ServerCompleteList event; Event_ServerCompleteList event;
event.set_server_id(server->getServerId()); event.set_server_id(server->getServerID());
server->clientsLock.lockForRead(); server->clientsLock.lockForRead();
QMapIterator<QString, Server_ProtocolHandler *> userIterator(server->getUsers()); QMapIterator<QString, Server_ProtocolHandler *> userIterator(server->getUsers());

View file

@ -210,96 +210,61 @@ Servatrice::~Servatrice()
bool Servatrice::initServer() bool Servatrice::initServer()
{ {
serverName = settingsCache->value("server/name", "My Cockatrice server").toString();
serverId = settingsCache->value("server/id", 0).toInt(); serverId = getServerID();
clientIdRequired = settingsCache->value("server/requireclientid",0).toBool(); if (getAuthenticationMethodString() == "sql") {
regServerOnly = settingsCache->value("authentication/regonly", 0).toBool();
const QString authenticationMethodStr = settingsCache->value("authentication/method").toString();
if (authenticationMethodStr == "sql") {
qDebug() << "Authenticating method: sql"; qDebug() << "Authenticating method: sql";
authenticationMethod = AuthenticationSql; authenticationMethod = AuthenticationSql;
} else if(authenticationMethodStr == "password") { } else if(getAuthenticationMethodString() == "password") {
qDebug() << "Authenticating method: password"; qDebug() << "Authenticating method: password";
authenticationMethod = AuthenticationPassword; authenticationMethod = AuthenticationPassword;
} else { } else {
if (regServerOnly) { if (getRegOnlyServerEnabled()) {
qDebug() << "Registration only server enabled but no authentication method defined: Error."; qDebug() << "Registration only server enabled but no authentication method defined: Error.";
return false; return false;
} }
qDebug() << "Authenticating method: none"; qDebug() << "Authenticating method: none";
authenticationMethod = AuthenticationNone; authenticationMethod = AuthenticationNone;
} }
qDebug() << "Store Replays: " << settingsCache->value("game/store_replays", true).toBool(); qDebug() << "Store Replays: " << getStoreReplaysEnabled();
qDebug() << "Client ID Required: " << clientIdRequired; qDebug() << "Client ID Required: " << getClientIDRequiredEnabled();
bool maxUserLimitEnabled = getMaxUserLimitEnabled(); qDebug() << "Maximum user limit enabled: " << getMaxUserLimitEnabled();
qDebug() << "Maximum user limit enabled: " << maxUserLimitEnabled;
if (maxUserLimitEnabled){ if (getMaxUserLimitEnabled()) {
int maxUserLimit = getMaxUserLimit(); qDebug() << "Maximum total user limit: " << getMaxUserTotal();
qDebug() << "Maximum total user limit: " << maxUserLimit; qDebug() << "Maximum tcp user limit: " << getMaxTcpUserLimit();
int maxTcpUserLimit = settingsCache->value("security/max_users_tcp", 500).toInt(); qDebug() << "Maximum websocket user limit: " << getMaxWebSocketUserLimit();
qDebug() << "Maximum tcp user limit: " << maxTcpUserLimit;
int maxWebsocketUserLimit = settingsCache->value("security/max_users_websocket", 500).toInt();
qDebug() << "Maximum websocket user limit: " << maxWebsocketUserLimit;
} }
bool registrationEnabled = settingsCache->value("registration/enabled", false).toBool(); qDebug() << "Accept registered users only: " << getRegOnlyServerEnabled();
bool requireEmailForRegistration = settingsCache->value("registration/requireemail", true).toBool(); qDebug() << "Registration enabled: " << getRegistrationEnabled();
bool requireEmailActivation = settingsCache->value("registration/requireemailactivation", true).toBool(); if (getRegistrationEnabled()) {
qDebug() << "Require email address to register: " << getRequireEmailForRegistrationEnabled();
qDebug() << "Accept registered users only: " << regServerOnly; qDebug() << "Require email activation via token: " << getRequireEmailActivationEnabled();
qDebug() << "Registration enabled: " << registrationEnabled;
if (registrationEnabled)
{
qDebug() << "Require email address to register: " << requireEmailForRegistration;
qDebug() << "Require email activation via token: " << requireEmailActivation;
} }
FeatureSet features; if (getDBTypeString() == "mysql") {
features.initalizeFeatureList(serverRequiredFeatureList);
requiredFeatures = settingsCache->value("server/requiredfeatures","").toString();
QStringList listReqFeatures = requiredFeatures.split(",", QString::SkipEmptyParts);
if (!listReqFeatures.isEmpty())
foreach(QString reqFeature, listReqFeatures)
features.enableRequiredFeature(serverRequiredFeatureList,reqFeature);
qDebug() << "Required client features: " << serverRequiredFeatureList;
QString dbTypeStr = settingsCache->value("database/type").toString();
if (dbTypeStr == "mysql")
databaseType = DatabaseMySql; databaseType = DatabaseMySql;
else } else {
databaseType = DatabaseNone; databaseType = DatabaseNone;
}
servatriceDatabaseInterface = new Servatrice_DatabaseInterface(-1, this); servatriceDatabaseInterface = new Servatrice_DatabaseInterface(-1, this);
setDatabaseInterface(servatriceDatabaseInterface); setDatabaseInterface(servatriceDatabaseInterface);
if (databaseType != DatabaseNone) { if (databaseType != DatabaseNone) {
settingsCache->beginGroup("database"); dbPrefix = getDBPrefixString();
dbPrefix = settingsCache->value("prefix").toString(); bool dbOpened = servatriceDatabaseInterface->initDatabase("QMYSQL",getDBHostNameString(),getDBDatabaseNameString(),getDBUserNameString(),getDBPasswordString());
bool dbOpened =
servatriceDatabaseInterface->initDatabase("QMYSQL",
settingsCache->value("hostname").toString(),
settingsCache->value("database").toString(),
settingsCache->value("user").toString(),
settingsCache->value("password").toString());
settingsCache->endGroup();
if (!dbOpened) { if (!dbOpened) {
qDebug() << "Failed to open database"; qDebug() << "Failed to open database";
return false; return false;
} }
updateServerList(); updateServerList();
qDebug() << "Clearing previous sessions..."; qDebug() << "Clearing previous sessions...";
servatriceDatabaseInterface->clearSessionTables(); servatriceDatabaseInterface->clearSessionTables();
} }
const QString roomMethod = settingsCache->value("rooms/method").toString(); if (getRoomsMethodString() == "sql") {
if (roomMethod == "sql") {
QSqlQuery *query = servatriceDatabaseInterface->prepareQuery("select id, name, descr, permissionlevel, auto_join, join_message, chat_history_size from {prefix}_rooms where id_server = :id_server order by id asc"); QSqlQuery *query = servatriceDatabaseInterface->prepareQuery("select id, name, descr, permissionlevel, auto_join, join_message, chat_history_size from {prefix}_rooms where id_server = :id_server order by id asc");
query->bindValue(":id_server", serverId); query->bindValue(":id_server", serverId);
servatriceDatabaseInterface->execSqlQuery(query); servatriceDatabaseInterface->execSqlQuery(query);
@ -311,8 +276,7 @@ bool Servatrice::initServer()
QStringList gameTypes; QStringList gameTypes;
while (query2->next()) while (query2->next())
gameTypes.append(query2->value(0).toString()); gameTypes.append(query2->value(0).toString());
addRoom(new Server_Room(query->value(0).toInt(),
addRoom(new Server_Room(query->value(0).toInt(),
query->value(6).toInt(), query->value(6).toInt(),
query->value(1).toString(), query->value(1).toString(),
query->value(2).toString(), query->value(2).toString(),
@ -320,14 +284,12 @@ bool Servatrice::initServer()
query->value(4).toInt(), query->value(4).toInt(),
query->value(5).toString(), query->value(5).toString(),
gameTypes, gameTypes,
this this));
));
} }
} else { } else {
int size = settingsCache->beginReadArray("rooms/roomlist"); int size = settingsCache->beginReadArray("rooms/roomlist");
for (int i = 0; i < size; ++i) { for (int i = 0; i < size; ++i) {
settingsCache->setArrayIndex(i); settingsCache->setArrayIndex(i);
QStringList gameTypes; QStringList gameTypes;
int size2 = settingsCache->beginReadArray("game_types"); int size2 = settingsCache->beginReadArray("game_types");
for (int j = 0; j < size2; ++j) { for (int j = 0; j < size2; ++j) {
@ -335,35 +297,13 @@ bool Servatrice::initServer()
gameTypes.append(settingsCache->value("name").toString()); gameTypes.append(settingsCache->value("name").toString());
} }
settingsCache->endArray(); settingsCache->endArray();
Server_Room *newRoom = new Server_Room(i,settingsCache->value("chathistorysize").toInt(),settingsCache->value("name").toString(),settingsCache->value("description").toString(),settingsCache->value("permissionlevel").toString().toLower(),settingsCache->value("autojoin").toBool(),settingsCache->value("joinmessage").toString(),gameTypes,this);
Server_Room *newRoom = new Server_Room(
i,
settingsCache->value("chathistorysize").toInt(),
settingsCache->value("name").toString(),
settingsCache->value("description").toString(),
settingsCache->value("permissionlevel").toString().toLower(),
settingsCache->value("autojoin").toBool(),
settingsCache->value("joinmessage").toString(),
gameTypes,
this
);
addRoom(newRoom); addRoom(newRoom);
} }
if(size==0) if(size==0) {
{
// no room defined in config, add a dummy one // no room defined in config, add a dummy one
Server_Room *newRoom = new Server_Room( Server_Room *newRoom = new Server_Room(0,100,"General room","Play anything here.","none",true,"",QStringList("Standard"),this);
0,
100,
"General room",
"Play anything here.",
"none",
true,
"",
QStringList("Standard"),
this
);
addRoom(newRoom); addRoom(newRoom);
} }
@ -372,25 +312,12 @@ bool Servatrice::initServer()
updateLoginMessage(); updateLoginMessage();
maxGameInactivityTime = settingsCache->value("game/max_game_inactivity_time", 120).toInt(); try { if (getISLNetworkEnabled()) {
maxPlayerInactivityTime = settingsCache->value("server/max_player_inactivity_time", 15).toInt();
pingClockInterval = settingsCache->value("server/clientkeepalive", 1).toInt();
maxUsersPerAddress = settingsCache->value("security/max_users_per_address", 4).toInt();
messageCountingInterval = settingsCache->value("security/message_counting_interval", 10).toInt();
maxMessageCountPerInterval = settingsCache->value("security/max_message_count_per_interval", 15).toInt();
maxMessageSizePerInterval = settingsCache->value("security/max_message_size_per_interval", 1000).toInt();
maxGamesPerUser = settingsCache->value("security/max_games_per_user", 5).toInt();
commandCountingInterval = settingsCache->value("game/command_counting_interval", 10).toInt();
maxCommandCountPerInterval = settingsCache->value("game/max_command_count_per_interval", 20).toInt();
try { if (settingsCache->value("servernetwork/active", 0).toInt()) {
qDebug() << "Connecting to ISL network."; qDebug() << "Connecting to ISL network.";
const QString certFileName = settingsCache->value("servernetwork/ssl_cert").toString();
const QString keyFileName = settingsCache->value("servernetwork/ssl_key").toString();
qDebug() << "Loading certificate..."; qDebug() << "Loading certificate...";
QFile certFile(certFileName); QFile certFile(getISLNetworkSSLCertFile());
if (!certFile.open(QIODevice::ReadOnly)) if (!certFile.open(QIODevice::ReadOnly))
throw QString("Error opening certificate file: %1").arg(certFileName); throw QString("Error opening certificate file: %1").arg(getISLNetworkSSLCertFile());
QSslCertificate cert(&certFile); QSslCertificate cert(&certFile);
const QDateTime currentTime = QDateTime::currentDateTime(); const QDateTime currentTime = QDateTime::currentDateTime();
@ -400,9 +327,9 @@ bool Servatrice::initServer()
throw(QString("Invalid certificate.")); throw(QString("Invalid certificate."));
qDebug() << "Loading private key..."; qDebug() << "Loading private key...";
QFile keyFile(keyFileName); QFile keyFile(getISLNetworkSSLKeyFile());
if (!keyFile.open(QIODevice::ReadOnly)) if (!keyFile.open(QIODevice::ReadOnly))
throw QString("Error opening private key file: %1").arg(keyFileName); throw QString("Error opening private key file: %1").arg(getISLNetworkSSLKeyFile());
QSslKey key(&keyFile, QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey); QSslKey key(&keyFile, QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey);
if (key.isNull()) if (key.isNull())
throw QString("Invalid private key."); throw QString("Invalid private key.");
@ -427,11 +354,9 @@ bool Servatrice::initServer()
QMetaObject::invokeMethod(interface, "initClient", Qt::BlockingQueuedConnection); QMetaObject::invokeMethod(interface, "initClient", Qt::BlockingQueuedConnection);
} }
const int networkPort = settingsCache->value("servernetwork/port", 14747).toInt(); qDebug() << "Starting ISL server on port" << getISLNetworkPort();
qDebug() << "Starting ISL server on port" << networkPort;
islServer = new Servatrice_IslServer(this, cert, key, this); islServer = new Servatrice_IslServer(this, cert, key, this);
if (islServer->listen(QHostAddress::Any, networkPort)) if (islServer->listen(QHostAddress::Any, getISLNetworkPort()))
qDebug() << "ISL server listening."; qDebug() << "ISL server listening.";
else else
throw QString("islServer->listen()"); throw QString("islServer->listen()");
@ -442,25 +367,22 @@ bool Servatrice::initServer()
pingClock = new QTimer(this); pingClock = new QTimer(this);
connect(pingClock, SIGNAL(timeout()), this, SIGNAL(pingClockTimeout())); connect(pingClock, SIGNAL(timeout()), this, SIGNAL(pingClockTimeout()));
pingClock->start(pingClockInterval * 1000); pingClock->start(getClientKeepAlive() * 1000);
int statusUpdateTime = settingsCache->value("server/statusupdate", 15000).toInt();
statusUpdateClock = new QTimer(this); statusUpdateClock = new QTimer(this);
connect(statusUpdateClock, SIGNAL(timeout()), this, SLOT(statusUpdate())); connect(statusUpdateClock, SIGNAL(timeout()), this, SLOT(statusUpdate()));
if (statusUpdateTime != 0) { if (getServerStatusUpdateTime() != 0) {
qDebug() << "Starting status update clock, interval " << statusUpdateTime << " ms"; qDebug() << "Starting status update clock, interval " << getServerStatusUpdateTime() << " ms";
statusUpdateClock->start(statusUpdateTime); statusUpdateClock->start(getServerStatusUpdateTime());
} }
// SOCKET SERVER // SOCKET SERVER
const int numberPools = settingsCache->value("server/number_pools", 1).toInt(); if(getNumberOfTCPPools() > 0)
if(numberPools > 0)
{ {
gameServer = new Servatrice_GameServer(this, numberPools, servatriceDatabaseInterface->getDatabase(), this); gameServer = new Servatrice_GameServer(this, getNumberOfTCPPools(), servatriceDatabaseInterface->getDatabase(), this);
gameServer->setMaxPendingConnections(1000); gameServer->setMaxPendingConnections(1000);
const int gamePort = settingsCache->value("server/port", 4747).toInt(); qDebug() << "Starting server on port" << getServerTCPPort();
qDebug() << "Starting server on port" << gamePort; if (gameServer->listen(QHostAddress::Any, getServerTCPPort()))
if (gameServer->listen(QHostAddress::Any, gamePort))
qDebug() << "Server listening."; qDebug() << "Server listening.";
else { else {
qDebug() << "gameServer->listen(): Error:" << gameServer->errorString(); qDebug() << "gameServer->listen(): Error:" << gameServer->errorString();
@ -470,14 +392,12 @@ bool Servatrice::initServer()
#if QT_VERSION > 0x050300 #if QT_VERSION > 0x050300
// WEBSOCKET SERVER // WEBSOCKET SERVER
const int wesocketNumberPools = settingsCache->value("server/websocket_number_pools", 1).toInt(); if(getNumberOfWebSocketPools() > 0)
if(wesocketNumberPools > 0)
{ {
websocketGameServer = new Servatrice_WebsocketGameServer(this, wesocketNumberPools, servatriceDatabaseInterface->getDatabase(), this); websocketGameServer = new Servatrice_WebsocketGameServer(this, getNumberOfWebSocketPools(), servatriceDatabaseInterface->getDatabase(), this);
websocketGameServer->setMaxPendingConnections(1000); websocketGameServer->setMaxPendingConnections(1000);
const int websocketGamePort = settingsCache->value("server/websocket_port", 4748).toInt(); qDebug() << "Starting websocket server on port" << getServerWebSocketPort();
qDebug() << "Starting websocket server on port" << websocketGamePort; if (websocketGameServer->listen(QHostAddress::Any, getServerWebSocketPort()))
if (websocketGameServer->listen(QHostAddress::Any, websocketGamePort))
qDebug() << "Websocket server listening."; qDebug() << "Websocket server listening.";
else { else {
qDebug() << "websocketGameServer->listen(): Error:" << websocketGameServer->errorString(); qDebug() << "websocketGameServer->listen(): Error:" << websocketGameServer->errorString();
@ -485,6 +405,7 @@ bool Servatrice::initServer()
} }
} }
#endif #endif
setRequiredFeatures(getRequiredFeatures());
return true; return true;
} }
@ -566,6 +487,18 @@ void Servatrice::updateLoginMessage()
} }
} }
void Servatrice::setRequiredFeatures(const QString featureList) {
FeatureSet features;
serverRequiredFeatureList.clear();
features.initalizeFeatureList(serverRequiredFeatureList);
QStringList listReqFeatures = featureList.split(",", QString::SkipEmptyParts);
if (!listReqFeatures.isEmpty())
foreach(QString reqFeature, listReqFeatures)
features.enableRequiredFeature(serverRequiredFeatureList, reqFeature);
qDebug() << "Set required client features to: " << serverRequiredFeatureList;
}
void Servatrice::statusUpdate() void Servatrice::statusUpdate()
{ {
if (!servatriceDatabaseInterface->checkSql()) if (!servatriceDatabaseInterface->checkSql())
@ -595,9 +528,7 @@ void Servatrice::statusUpdate()
servatriceDatabaseInterface->execSqlQuery(query); servatriceDatabaseInterface->execSqlQuery(query);
// send activation emails // send activation emails
bool registrationEnabled = settingsCache->value("registration/enabled", false).toBool(); if (getRegistrationEnabled() && getRequireEmailActivationEnabled())
bool requireEmailActivation = settingsCache->value("registration/requireemailactivation", true).toBool();
if (registrationEnabled && requireEmailActivation)
{ {
QSqlQuery *query = servatriceDatabaseInterface->prepareQuery("select a.name, b.email, b.token from {prefix}_activation_emails a left join {prefix}_users b on a.name = b.name"); QSqlQuery *query = servatriceDatabaseInterface->prepareQuery("select a.name, b.email, b.token from {prefix}_activation_emails a left join {prefix}_users b on a.name = b.name");
if (!servatriceDatabaseInterface->execSqlQuery(query)) if (!servatriceDatabaseInterface->execSqlQuery(query))
@ -682,14 +613,12 @@ void Servatrice::shutdownTimeout()
bool Servatrice::islConnectionExists(int serverId) const bool Servatrice::islConnectionExists(int serverId) const
{ {
// Only call with islLock locked at least for reading // Only call with islLock locked at least for reading
return islInterfaces.contains(serverId); return islInterfaces.contains(serverId);
} }
void Servatrice::addIslInterface(int serverId, IslInterface *interface) void Servatrice::addIslInterface(int serverId, IslInterface *interface)
{ {
// Only call with islLock locked for writing // Only call with islLock locked for writing
islInterfaces.insert(serverId, interface); islInterfaces.insert(serverId, interface);
connect(interface, SIGNAL(externalUserJoined(ServerInfo_User)), this, SLOT(externalUserJoined(ServerInfo_User))); connect(interface, SIGNAL(externalUserJoined(ServerInfo_User)), this, SLOT(externalUserJoined(ServerInfo_User)));
connect(interface, SIGNAL(externalUserLeft(QString)), this, SLOT(externalUserLeft(QString))); connect(interface, SIGNAL(externalUserLeft(QString)), this, SLOT(externalUserLeft(QString)));
@ -706,8 +635,7 @@ void Servatrice::addIslInterface(int serverId, IslInterface *interface)
void Servatrice::removeIslInterface(int serverId) void Servatrice::removeIslInterface(int serverId)
{ {
// Only call with islLock locked for writing // Only call with islLock locked for writing
// XXX we probably need to delete everything that belonged to it... <-- THIS SHOULD BE FIXED FOR ISL FUNCTIONALITY TO WORK COMPLETLY!
// XXX we probably need to delete everything that belonged to it...
islInterfaces.remove(serverId); islInterfaces.remove(serverId);
} }
@ -726,10 +654,164 @@ void Servatrice::doSendIslMessage(const IslMessage &msg, int serverId)
} }
} }
int Servatrice::getMaxUserLimit() const { // start helper functions
int Servatrice::getMaxUserTotal() const {
return settingsCache->value("security/max_users_total", 500).toInt(); return settingsCache->value("security/max_users_total", 500).toInt();
} }
bool Servatrice::getMaxUserLimitEnabled() const { bool Servatrice::getMaxUserLimitEnabled() const {
return settingsCache->value("security/enable_max_user_limit", false).toBool(); return settingsCache->value("security/enable_max_user_limit", false).toBool();
}
QString Servatrice::getServerName() const {
return settingsCache->value("server/name", "My Cockatrice server").toString();
}
int Servatrice::getServerID() const {
return settingsCache->value("server/id", 0).toInt();
}
bool Servatrice::getClientIDRequiredEnabled() const {
return settingsCache->value("server/requireclientid", 0).toBool();
}
bool Servatrice::getRegOnlyServerEnabled() const {
return settingsCache->value("authentication/regonly", 0).toBool();
}
QString Servatrice::getAuthenticationMethodString() const {
return settingsCache->value("authentication/method").toString();
}
bool Servatrice::getStoreReplaysEnabled() const {
return settingsCache->value("game/store_replays", true).toBool();
}
int Servatrice::getMaxTcpUserLimit() const {
return settingsCache->value("security/max_users_tcp", 500).toInt();
}
int Servatrice::getMaxWebSocketUserLimit() const {
return settingsCache->value("security/max_users_websocket", 500).toInt();
}
bool Servatrice::getRegistrationEnabled() const {
return settingsCache->value("registration/enabled", false).toBool();
}
bool Servatrice::getRequireEmailForRegistrationEnabled() const {
return settingsCache->value("registration/requireemail", true).toBool();
}
bool Servatrice::getRequireEmailActivationEnabled() const {
return settingsCache->value("registration/requireemailactivation", true).toBool();
}
QString Servatrice::getRequiredFeatures() const {
return settingsCache->value("server/requiredfeatures", "").toString();
}
QString Servatrice::getDBTypeString() const {
return settingsCache->value("database/type").toString();
}
QString Servatrice::getDBPrefixString() const {
return settingsCache->value("database/prefix").toString();
}
QString Servatrice::getDBHostNameString() const {
return settingsCache->value("database/hostname").toString();
}
QString Servatrice::getDBDatabaseNameString() const {
return settingsCache->value("database/database").toString();
}
QString Servatrice::getDBUserNameString() const {
return settingsCache->value("database/user").toString();
}
QString Servatrice::getDBPasswordString() const {
return settingsCache->value("database/password").toString();
}
QString Servatrice::getRoomsMethodString() const {
return settingsCache->value("rooms/method").toString();
}
int Servatrice::getMaxGameInactivityTime() const {
return settingsCache->value("game/max_game_inactivity_time", 120).toInt();
}
int Servatrice::getMaxPlayerInactivityTime() const {
return settingsCache->value("server/max_player_inactivity_time", 15).toInt();
}
int Servatrice::getClientKeepAlive() const {
return settingsCache->value("server/clientkeepalive", 1).toInt();
}
int Servatrice::getMaxUsersPerAddress() const {
return settingsCache->value("security/max_users_per_address", 4).toInt();
}
int Servatrice::getMessageCountingInterval() const {
return settingsCache->value("security/message_counting_interval", 10).toInt();
}
int Servatrice::getMaxMessageCountPerInterval() const {
return settingsCache->value("security/max_message_count_per_interval", 15).toInt();
}
int Servatrice::getMaxMessageSizePerInterval() const {
return settingsCache->value("security/max_message_size_per_interval", 1000).toInt();
}
int Servatrice::getMaxGamesPerUser() const {
return settingsCache->value("security/max_games_per_user", 5).toInt();
}
int Servatrice::getCommandCountingInterval() const {
return settingsCache->value("game/command_counting_interval", 10).toInt();
}
int Servatrice::getMaxCommandCountPerInterval() const {
return settingsCache->value("game/max_command_count_per_interval", 20).toInt();
}
int Servatrice::getServerStatusUpdateTime() const {
return settingsCache->value("server/statusupdate", 15000).toInt();
}
int Servatrice::getNumberOfTCPPools() const {
return settingsCache->value("server/number_pools", 1).toInt();
}
int Servatrice::getServerTCPPort() const {
return settingsCache->value("server/port", 4747).toInt();
}
int Servatrice::getNumberOfWebSocketPools() const {
return settingsCache->value("server/websocket_number_pools", 1).toInt();
}
int Servatrice::getServerWebSocketPort() const {
return settingsCache->value("server/websocket_port", 4748).toInt();
}
bool Servatrice::getISLNetworkEnabled() const {
return settingsCache->value("servernetwork/active", false).toBool();
}
QString Servatrice::getISLNetworkSSLCertFile() const {
return settingsCache->value("servernetwork/ssl_cert").toString();
}
QString Servatrice::getISLNetworkSSLKeyFile() const {
return settingsCache->value("servernetwork/ssl_key").toString();
}
int Servatrice::getISLNetworkPort() const {
return settingsCache->value("servernetwork/port", 14747).toInt();
} }

View file

@ -122,7 +122,6 @@ private:
Servatrice_WebsocketGameServer *websocketGameServer; Servatrice_WebsocketGameServer *websocketGameServer;
#endif #endif
Servatrice_IslServer *islServer; Servatrice_IslServer *islServer;
QString serverName;
mutable QMutex loginMessageMutex; mutable QMutex loginMessageMutex;
QString loginMessage; QString loginMessage;
QString dbPrefix; QString dbPrefix;
@ -134,51 +133,76 @@ private:
int uptime; int uptime;
QMutex txBytesMutex, rxBytesMutex; QMutex txBytesMutex, rxBytesMutex;
quint64 txBytes, rxBytes; quint64 txBytes, rxBytes;
int maxGameInactivityTime, maxPlayerInactivityTime;
int maxUsersPerAddress, messageCountingInterval, maxMessageCountPerInterval, maxMessageSizePerInterval, maxGamesPerUser, commandCountingInterval, maxCommandCountPerInterval, pingClockInterval;
QString shutdownReason; QString shutdownReason;
int shutdownMinutes; int shutdownMinutes;
int nextShutdownMessageMinutes; int nextShutdownMessageMinutes;
QTimer *shutdownTimer; QTimer *shutdownTimer;
bool isFirstShutdownMessage, clientIdRequired, regServerOnly; bool isFirstShutdownMessage;
mutable QMutex serverListMutex; mutable QMutex serverListMutex;
QList<ServerProperties> serverList; QList<ServerProperties> serverList;
void updateServerList(); void updateServerList();
QMap<int, IslInterface *> islInterfaces; QMap<int, IslInterface *> islInterfaces;
QString getDBPrefixString() const;
QString getDBHostNameString() const;
QString getDBDatabaseNameString() const;
QString getDBUserNameString() const;
QString getDBPasswordString() const;
QString getRoomsMethodString() const;
QString getISLNetworkSSLCertFile() const;
QString getISLNetworkSSLKeyFile() const;
int getServerStatusUpdateTime() const;
int getNumberOfTCPPools() const;
int getServerTCPPort() const;
int getNumberOfWebSocketPools() const;
int getServerWebSocketPort() const;
int getISLNetworkPort() const;
bool getISLNetworkEnabled() const;
public slots: public slots:
void scheduleShutdown(const QString &reason, int minutes); void scheduleShutdown(const QString &reason, int minutes);
void updateLoginMessage(); void updateLoginMessage();
void setRequiredFeatures(const QString featureList);
public: public:
Servatrice(QObject *parent = 0); Servatrice(QObject *parent = 0);
~Servatrice(); ~Servatrice();
bool initServer(); bool initServer();
QMap<QString, bool> getServerRequiredFeatureList() const { return serverRequiredFeatureList; } QMap<QString, bool> getServerRequiredFeatureList() const { return serverRequiredFeatureList; }
QString getOfficialWarningsList() const { return officialWarnings; } QString getOfficialWarningsList() const { return officialWarnings; }
QString getServerName() const { return serverName; } QString getServerName() const;
QString getLoginMessage() const { QMutexLocker locker(&loginMessageMutex); return loginMessage; } QString getLoginMessage() const { QMutexLocker locker(&loginMessageMutex); return loginMessage; }
QString getRequiredFeatures() const { return requiredFeatures; } QString getRequiredFeatures() const;
QString getAuthenticationMethodString() const;
QString getDBTypeString() const;
QString getDbPrefix() const { return dbPrefix; }
AuthenticationMethod getAuthenticationMethod() const { return authenticationMethod; }
bool permitUnregisteredUsers() const { return authenticationMethod != AuthenticationNone; } bool permitUnregisteredUsers() const { return authenticationMethod != AuthenticationNone; }
bool getGameShouldPing() const { return true; } bool getGameShouldPing() const { return true; }
bool getClientIdRequired() const { return clientIdRequired; } bool getClientIDRequiredEnabled() const;
bool getRegOnlyServer() const { return regServerOnly; } bool getRegOnlyServerEnabled() const;
bool getMaxUserLimitEnabled() const; bool getMaxUserLimitEnabled() const;
int getPingClockInterval() const { return pingClockInterval; } bool getStoreReplaysEnabled() const;
int getMaxGameInactivityTime() const { return maxGameInactivityTime; } bool getRegistrationEnabled() const;
int getMaxPlayerInactivityTime() const { return maxPlayerInactivityTime; } bool getRequireEmailForRegistrationEnabled() const;
int getMaxUsersPerAddress() const { return maxUsersPerAddress; } bool getRequireEmailActivationEnabled() const;
int getMessageCountingInterval() const { return messageCountingInterval; } int getServerID() const;
int getMaxMessageCountPerInterval() const { return maxMessageCountPerInterval; } int getMaxGameInactivityTime() const;
int getMaxMessageSizePerInterval() const { return maxMessageSizePerInterval; } int getMaxPlayerInactivityTime() const;
int getMaxGamesPerUser() const { return maxGamesPerUser; } int getClientKeepAlive() const;
int getCommandCountingInterval() const { return commandCountingInterval; } int getMaxUsersPerAddress() const;
int getMaxCommandCountPerInterval() const { return maxCommandCountPerInterval; } int getMessageCountingInterval() const;
int getMaxUserLimit() const; int getMaxMessageCountPerInterval() const;
AuthenticationMethod getAuthenticationMethod() const { return authenticationMethod; } int getMaxMessageSizePerInterval() const;
QString getDbPrefix() const { return dbPrefix; } int getMaxGamesPerUser() const;
int getServerId() const { return serverId; } int getCommandCountingInterval() const;
int getMaxCommandCountPerInterval() const;
int getMaxUserTotal() const;
int getMaxTcpUserLimit() const;
int getMaxWebSocketUserLimit() const;
int getUsersWithAddress(const QHostAddress &address) const; int getUsersWithAddress(const QHostAddress &address) const;
QList<AbstractServerSocketInterface *> getUsersWithAddressAsList(const QHostAddress &address) const; QList<AbstractServerSocketInterface *> getUsersWithAddressAsList(const QHostAddress &address) const;
void incTxBytes(quint64 num); void incTxBytes(quint64 num);

View file

@ -568,7 +568,7 @@ void Servatrice_DatabaseInterface::clearSessionTables()
{ {
lockSessionTables(); lockSessionTables();
QSqlQuery *query = prepareQuery("update {prefix}_sessions set end_time=now() where end_time is null and id_server = :id_server"); QSqlQuery *query = prepareQuery("update {prefix}_sessions set end_time=now() where end_time is null and id_server = :id_server");
query->bindValue(":id_server", server->getServerId()); query->bindValue(":id_server", server->getServerID());
execSqlQuery(query); execSqlQuery(query);
unlockSessionTables(); unlockSessionTables();
} }
@ -590,7 +590,7 @@ bool Servatrice_DatabaseInterface::userSessionExists(const QString &userName)
// Call only after lockSessionTables(). // Call only after lockSessionTables().
QSqlQuery *query = prepareQuery("select 1 from {prefix}_sessions where user_name = :user_name and id_server = :id_server and end_time is null"); QSqlQuery *query = prepareQuery("select 1 from {prefix}_sessions where user_name = :user_name and id_server = :id_server and end_time is null");
query->bindValue(":id_server", server->getServerId()); query->bindValue(":id_server", server->getServerID());
query->bindValue(":user_name", userName); query->bindValue(":user_name", userName);
execSqlQuery(query); execSqlQuery(query);
return query->next(); return query->next();
@ -606,7 +606,7 @@ qint64 Servatrice_DatabaseInterface::startSession(const QString &userName, const
QSqlQuery *query = prepareQuery("insert into {prefix}_sessions (user_name, id_server, ip_address, start_time, clientid, connection_type) values(:user_name, :id_server, :ip_address, NOW(), :client_id, :connection_type)"); QSqlQuery *query = prepareQuery("insert into {prefix}_sessions (user_name, id_server, ip_address, start_time, clientid, connection_type) values(:user_name, :id_server, :ip_address, NOW(), :client_id, :connection_type)");
query->bindValue(":user_name", userName); query->bindValue(":user_name", userName);
query->bindValue(":id_server", server->getServerId()); query->bindValue(":id_server", server->getServerID());
query->bindValue(":ip_address", address); query->bindValue(":ip_address", address);
query->bindValue(":client_id", clientId); query->bindValue(":client_id", clientId);
query->bindValue(":connection_type", connectionType); query->bindValue(":connection_type", connectionType);
@ -880,7 +880,7 @@ int Servatrice_DatabaseInterface::getActiveUserCount(QString connectionType)
text +=" AND connection_type = :connection_type"; text +=" AND connection_type = :connection_type";
QSqlQuery *query = prepareQuery(text); QSqlQuery *query = prepareQuery(text);
query->bindValue(":serverid", server->getServerId()); query->bindValue(":serverid", server->getServerID());
if(!connectionType.isEmpty()) if(!connectionType.isEmpty())
query->bindValue(":connection_type", connectionType); query->bindValue(":connection_type", connectionType);

View file

@ -1021,6 +1021,7 @@ Response::ResponseCode AbstractServerSocketInterface::cmdReloadConfig(const Comm
{ {
logDebugMessage("Received admin command: reloading configuration"); logDebugMessage("Received admin command: reloading configuration");
settingsCache->sync(); settingsCache->sync();
QMetaObject::invokeMethod(server, "setRequiredFeatures", Q_ARG(QString, server->getRequiredFeatures()));
return Response::RespOk; return Response::RespOk;
} }