Total Max User Restriction
Syntax correction.
This commit is contained in:
parent
aa540f7968
commit
a9acb3f1cc
9 changed files with 61 additions and 3 deletions
|
@ -27,6 +27,7 @@ public:
|
||||||
AuthenticationResult checkUserPassword(Server_ProtocolHandler *handler, const QString &user, const QString &password, QString &reasonStr, int &secondsLeft);
|
AuthenticationResult checkUserPassword(Server_ProtocolHandler *handler, const QString &user, const QString &password, QString &reasonStr, int &secondsLeft);
|
||||||
int getNextGameId() { return localServer->getNextLocalGameId(); }
|
int getNextGameId() { return localServer->getNextLocalGameId(); }
|
||||||
int getNextReplayId() { return -1; }
|
int getNextReplayId() { return -1; }
|
||||||
|
int getActiveUserCount() { return 0; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -71,6 +71,7 @@ void MainWindow::processConnectionClosedEvent(const Event_ConnectionClosed &even
|
||||||
client->disconnectFromServer();
|
client->disconnectFromServer();
|
||||||
QString reasonStr;
|
QString reasonStr;
|
||||||
switch (event.reason()) {
|
switch (event.reason()) {
|
||||||
|
case Event_ConnectionClosed::USER_LIMIT_REACHED: reasonStr = tr("The server has reached its maximum user capacity, please check back later."); break;
|
||||||
case Event_ConnectionClosed::TOO_MANY_CONNECTIONS: reasonStr = tr("There are too many concurrent connections from your address."); break;
|
case Event_ConnectionClosed::TOO_MANY_CONNECTIONS: reasonStr = tr("There are too many concurrent connections from your address."); break;
|
||||||
case Event_ConnectionClosed::BANNED: {
|
case Event_ConnectionClosed::BANNED: {
|
||||||
reasonStr = tr("Banned by moderator");
|
reasonStr = tr("Banned by moderator");
|
||||||
|
|
|
@ -10,6 +10,7 @@ message Event_ConnectionClosed {
|
||||||
TOO_MANY_CONNECTIONS = 3;
|
TOO_MANY_CONNECTIONS = 3;
|
||||||
BANNED = 4;
|
BANNED = 4;
|
||||||
USERNAMEINVALID = 5;
|
USERNAMEINVALID = 5;
|
||||||
|
USER_LIMIT_REACHED = 6;
|
||||||
}
|
}
|
||||||
optional CloseReason reason = 1;
|
optional CloseReason reason = 1;
|
||||||
optional string reason_str = 2;
|
optional string reason_str = 2;
|
||||||
|
|
|
@ -31,6 +31,7 @@ public slots:
|
||||||
public:
|
public:
|
||||||
virtual int getNextGameId() = 0;
|
virtual int getNextGameId() = 0;
|
||||||
virtual int getNextReplayId() = 0;
|
virtual int getNextReplayId() = 0;
|
||||||
|
virtual int getActiveUserCount() = 0;
|
||||||
|
|
||||||
virtual void clearSessionTables() { }
|
virtual void clearSessionTables() { }
|
||||||
virtual void lockSessionTables() { }
|
virtual void lockSessionTables() { }
|
||||||
|
|
|
@ -188,6 +188,11 @@ max_game_inactivity_time=120
|
||||||
|
|
||||||
|
|
||||||
[security]
|
[security]
|
||||||
|
; You may want to restrict the number of users that can connect to your server at any given time.
|
||||||
|
enable_max_user_limit=false
|
||||||
|
|
||||||
|
; Maximum number of users that can connect to the server, default is 500.
|
||||||
|
max_users_total=500
|
||||||
|
|
||||||
; Maximum number of users that can connect from the same IP address; useful to avoid bots, default is 4
|
; Maximum number of users that can connect from the same IP address; useful to avoid bots, default is 4
|
||||||
max_users_per_address=4
|
max_users_per_address=4
|
||||||
|
|
|
@ -160,6 +160,14 @@ bool Servatrice::initServer()
|
||||||
authenticationMethod = AuthenticationNone;
|
authenticationMethod = AuthenticationNone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool maxUserLimitEnabled = settingsCache->value("security/enable_max_user_limit", false).toBool();
|
||||||
|
qDebug() << "Maximum user limit enabled: " << maxUserLimitEnabled;
|
||||||
|
|
||||||
|
if (maxUserLimitEnabled){
|
||||||
|
int maxUserLimit = settingsCache->value("security/max_users_total", 500).toInt();
|
||||||
|
qDebug() << "Maximum user limit: " << maxUserLimit;
|
||||||
|
}
|
||||||
|
|
||||||
bool registrationEnabled = settingsCache->value("registration/enabled", false).toBool();
|
bool registrationEnabled = settingsCache->value("registration/enabled", false).toBool();
|
||||||
bool requireEmailForRegistration = settingsCache->value("registration/requireemail", true).toBool();
|
bool requireEmailForRegistration = settingsCache->value("registration/requireemail", true).toBool();
|
||||||
|
|
||||||
|
|
|
@ -805,3 +805,23 @@ bool Servatrice_DatabaseInterface::changeUserPassword(const QString &user, const
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Servatrice_DatabaseInterface::getActiveUserCount()
|
||||||
|
{
|
||||||
|
int userCount = 0;
|
||||||
|
|
||||||
|
if (!checkSql())
|
||||||
|
return userCount;
|
||||||
|
|
||||||
|
QSqlQuery *query = prepareQuery("select count(*) from {prefix}_sessions where id_server = :serverid AND end_time is NULL");
|
||||||
|
query->bindValue(":serverid", server->getServerId());
|
||||||
|
if (!execSqlQuery(query)){
|
||||||
|
return userCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (query->next()){
|
||||||
|
userCount = query->value(0).toInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
return userCount;
|
||||||
|
}
|
|
@ -58,6 +58,7 @@ public:
|
||||||
|
|
||||||
int getNextGameId();
|
int getNextGameId();
|
||||||
int getNextReplayId();
|
int getNextReplayId();
|
||||||
|
int getActiveUserCount();
|
||||||
qint64 startSession(const QString &userName, const QString &address);
|
qint64 startSession(const QString &userName, const QString &address);
|
||||||
void endSession(qint64 sessionId);
|
void endSession(qint64 sessionId);
|
||||||
void clearSessionTables();
|
void clearSessionTables();
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
#include <QSqlQuery>
|
#include <QSqlQuery>
|
||||||
#include <QHostAddress>
|
#include <QHostAddress>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
@ -121,13 +122,32 @@ bool ServerSocketInterface::initSession()
|
||||||
sendProtocolItem(*identSe);
|
sendProtocolItem(*identSe);
|
||||||
delete identSe;
|
delete identSe;
|
||||||
|
|
||||||
int maxUsers = servatrice->getMaxUsersPerAddress();
|
//limit the number of total users based on configuration settings
|
||||||
|
bool enforceUserLimit = settingsCache->value("security/enable_max_user_limit", false).toBool();
|
||||||
|
if (enforceUserLimit){
|
||||||
|
int userLimit = settingsCache->value("security/max_users_total", 500).toInt();
|
||||||
|
int playerCount = (databaseInterface->getActiveUserCount() + 1);
|
||||||
|
if (playerCount > userLimit){
|
||||||
|
std::cerr << "Max Users Total Limit Reached, please increase the max_users_total setting." << std::endl;
|
||||||
|
logger->logMessage(QString("Max Users Total Limit Reached, please increase the max_users_total setting."), this);
|
||||||
|
Event_ConnectionClosed event;
|
||||||
|
event.set_reason(Event_ConnectionClosed::USER_LIMIT_REACHED);
|
||||||
|
SessionEvent *se = prepareSessionEvent(event);
|
||||||
|
sendProtocolItem(*se);
|
||||||
|
delete se;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
std::cerr << "Player Count: " << playerCount << " / " << userLimit << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//allow unlimited number of connections from the trusted sources
|
//allow unlimited number of connections from the trusted sources
|
||||||
QString trustedSources = settingsCache->value("server/trusted_sources","127.0.0.1,::1").toString();
|
QString trustedSources = settingsCache->value("security/trusted_sources","127.0.0.1,::1").toString();
|
||||||
if (trustedSources.contains(socket->peerAddress().toString(),Qt::CaseInsensitive))
|
if (trustedSources.contains(socket->peerAddress().toString(),Qt::CaseInsensitive))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
int maxUsers = servatrice->getMaxUsersPerAddress();
|
||||||
if ((maxUsers > 0) && (servatrice->getUsersWithAddress(socket->peerAddress()) >= maxUsers)) {
|
if ((maxUsers > 0) && (servatrice->getUsersWithAddress(socket->peerAddress()) >= maxUsers)) {
|
||||||
Event_ConnectionClosed event;
|
Event_ConnectionClosed event;
|
||||||
event.set_reason(Event_ConnectionClosed::TOO_MANY_CONNECTIONS);
|
event.set_reason(Event_ConnectionClosed::TOO_MANY_CONNECTIONS);
|
||||||
|
|
Loading…
Reference in a new issue