Total Max User Restriction

Syntax correction.
This commit is contained in:
woogerboy21 2015-07-12 22:32:55 -04:00
parent aa540f7968
commit a9acb3f1cc
9 changed files with 61 additions and 3 deletions

View file

@ -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

View file

@ -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");

View file

@ -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;

View file

@ -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() { }

View file

@ -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

View file

@ -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();

View file

@ -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;
}

View file

@ -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();

View file

@ -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>
@ -120,14 +121,33 @@ bool ServerSocketInterface::initSession()
SessionEvent *identSe = prepareSessionEvent(identEvent); SessionEvent *identSe = prepareSessionEvent(identEvent);
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);