diff --git a/cockatrice/src/window_main.cpp b/cockatrice/src/window_main.cpp index c4fc9c52..47dccd51 100644 --- a/cockatrice/src/window_main.cpp +++ b/cockatrice/src/window_main.cpp @@ -316,6 +316,9 @@ void MainWindow::loginError(Response::ResponseCode r, QString reasonStr, quint32 actRegister(); } break; + case Response::RespClientIdRequired: + QMessageBox::critical(this, tr("Error"), tr("This server requires client ID's. Your client is either failing to generate an ID or you are running a modified client.\nPlease close and reopen your client to try again.")); + break; case Response::RespAccountNotActivated: { bool ok = false; QString token = QInputDialog::getText(this, tr("Account activation"), tr("Your account has not been activated yet.\nYou need to provide the activation token received in the activation email"), QLineEdit::Normal, QString(), &ok); diff --git a/common/pb/response.proto b/common/pb/response.proto index cc1948be..ae4ff040 100644 --- a/common/pb/response.proto +++ b/common/pb/response.proto @@ -35,7 +35,7 @@ message Response { RespActivationAccepted = 31; // Server accepted a reg user activation token RespActivationFailed = 32; // Server didn't accept a reg user activation token RespRegistrationAcceptedNeedsActivation = 33; // Server accepted cient registration, but it will need token activation - RespClientIDRequired = 34; // Server requires client to generate and send its client id before allowing access + RespClientIdRequired = 34; // Server requires client to generate and send its client id before allowing access } enum ResponseType { JOIN_ROOM = 1000; diff --git a/common/server.cpp b/common/server.cpp index 0fef1dc6..e07db95e 100644 --- a/common/server.cpp +++ b/common/server.cpp @@ -172,6 +172,8 @@ AuthenticationResult Server::loginUser(Server_ProtocolHandler *session, QString if (clientid.isEmpty()){ // client id is empty, either out dated client or client has been modified + if (getClientIdRequired()) + return ClientIdRequired; } else { // update users database table with client id diff --git a/common/server.h b/common/server.h index adf1c3c1..46008fb0 100644 --- a/common/server.h +++ b/common/server.h @@ -28,7 +28,7 @@ class GameEventContainer; class CommandContainer; class Command_JoinGame; -enum AuthenticationResult { NotLoggedIn, PasswordRight, UnknownUser, WouldOverwriteOldSession, UserIsBanned, UsernameInvalid, RegistrationRequired, UserIsInactive }; +enum AuthenticationResult { NotLoggedIn, PasswordRight, UnknownUser, WouldOverwriteOldSession, UserIsBanned, UsernameInvalid, RegistrationRequired, UserIsInactive, ClientIdRequired }; class Server : public QObject { @@ -56,6 +56,7 @@ public: virtual QString getLoginMessage() const { return QString(); } virtual bool getGameShouldPing() const { return false; } + virtual bool getClientIdRequired() const { return false; } virtual int getPingClockInterval() const { return 0; } virtual int getMaxGameInactivityTime() const { return 9999999; } virtual int getMaxPlayerInactivityTime() const { return 9999999; } diff --git a/common/server_protocolhandler.cpp b/common/server_protocolhandler.cpp index e87fd8fb..073a3d95 100644 --- a/common/server_protocolhandler.cpp +++ b/common/server_protocolhandler.cpp @@ -409,6 +409,7 @@ Response::ResponseCode Server_ProtocolHandler::cmdLogin(const Command_Login &cmd return Response::RespUsernameInvalid; } case RegistrationRequired: return Response::RespRegistrationRequired; + case ClientIdRequired: return Response::RespClientIdRequired; case UserIsInactive: return Response::RespAccountNotActivated; default: authState = res; } diff --git a/servatrice/servatrice.ini.example b/servatrice/servatrice.ini.example index f0388863..313001c7 100644 --- a/servatrice/servatrice.ini.example +++ b/servatrice/servatrice.ini.example @@ -46,6 +46,9 @@ clientkeepalive=1 ; considered disconnected; default is 15 max_player_inactivity_time=15 +; More modern clients generate client IDs based on specific client side information. Enable this option to +' require that clients report the client ID in order to log into the server. Default is false +requireclientid=false [authentication] diff --git a/servatrice/src/servatrice.cpp b/servatrice/src/servatrice.cpp index d30a8aaa..45b763fb 100644 --- a/servatrice/src/servatrice.cpp +++ b/servatrice/src/servatrice.cpp @@ -142,8 +142,9 @@ bool Servatrice::initServer() { serverName = settingsCache->value("server/name", "My Cockatrice server").toString(); serverId = settingsCache->value("server/id", 0).toInt(); + clientIdRequired = settingsCache->value("server/requireclientid",0).toBool(); bool regServerOnly = settingsCache->value("authentication/regonly", 0).toBool(); - + const QString authenticationMethodStr = settingsCache->value("authentication/method").toString(); if (authenticationMethodStr == "sql") { qDebug() << "Authenticating method: sql"; @@ -160,7 +161,8 @@ bool Servatrice::initServer() qDebug() << "Authenticating method: none"; authenticationMethod = AuthenticationNone; } - + + qDebug() << "Client ID Required: " << clientIdRequired; bool maxUserLimitEnabled = settingsCache->value("security/enable_max_user_limit", false).toBool(); qDebug() << "Maximum user limit enabled: " << maxUserLimitEnabled; diff --git a/servatrice/src/servatrice.h b/servatrice/src/servatrice.h index a0421cd5..9e46e5bb 100644 --- a/servatrice/src/servatrice.h +++ b/servatrice/src/servatrice.h @@ -120,7 +120,7 @@ private: QString shutdownReason; int shutdownMinutes; QTimer *shutdownTimer; - bool isFirstShutdownMessage; + bool isFirstShutdownMessage, clientIdRequired; mutable QMutex serverListMutex; QList serverList; @@ -137,6 +137,7 @@ public: QString getServerName() const { return serverName; } QString getLoginMessage() const { QMutexLocker locker(&loginMessageMutex); return loginMessage; } bool getGameShouldPing() const { return true; } + bool getClientIdRequired() const { return clientIdRequired; } int getPingClockInterval() const { return pingClockInterval; } int getMaxGameInactivityTime() const { return maxGameInactivityTime; } int getMaxPlayerInactivityTime() const { return maxPlayerInactivityTime; }