Rework idle timeout, now server side (#2259)
* Server side idle timeout Initial commit for server side idle timeout counter. This adds a new int value that is updated when room/game/mod/admin commands occur and is checked during the regular ping timout function that if the users new "idle" value exceeds the idleclienttimeout value defined in the servers configuration file the user is logged out. The user will receive a warning at the 90% time frame mark about being idle. * Use round instead of ceil Travis fix for older xcode issue's. * Fixed requested items Mis-spelleed function, added header, added warning message sent check value. Also corrected the protobuf declaration file for event_notifyuser * Moved bool to protected * Re-Ordered Declarations * Removed most stylistic items Resolved most noted things. * Remove client side idle timeout Removed client side idle timeout functionality
This commit is contained in:
parent
1cebe030f6
commit
6962777ded
23 changed files with 65 additions and 86 deletions
|
@ -398,16 +398,12 @@ UserInterfaceSettingsPage::UserInterfaceSettingsPage()
|
|||
annotateTokensCheckBox.setChecked(settingsCache->getAnnotateTokens());
|
||||
connect(&annotateTokensCheckBox, SIGNAL(stateChanged(int)), settingsCache, SLOT(setAnnotateTokens(int)));
|
||||
|
||||
idleClientTimeOutCheckBox.setChecked(settingsCache->getIdleClientTimeOutEnabled());
|
||||
connect(&idleClientTimeOutCheckBox, SIGNAL(stateChanged(int)), settingsCache, SLOT(setIdleClientTimeOutEnabled(int)));
|
||||
|
||||
QGridLayout *generalGrid = new QGridLayout;
|
||||
generalGrid->addWidget(¬ificationsEnabledCheckBox, 0, 0);
|
||||
generalGrid->addWidget(&specNotificationsEnabledCheckBox, 1, 0);
|
||||
generalGrid->addWidget(&doubleClickToPlayCheckBox, 2, 0);
|
||||
generalGrid->addWidget(&playToStackCheckBox, 3, 0);
|
||||
generalGrid->addWidget(&annotateTokensCheckBox, 4, 0);
|
||||
generalGrid->addWidget(&idleClientTimeOutCheckBox, 5, 0);
|
||||
|
||||
generalGroupBox = new QGroupBox;
|
||||
generalGroupBox->setLayout(generalGrid);
|
||||
|
@ -442,7 +438,6 @@ void UserInterfaceSettingsPage::retranslateUi()
|
|||
annotateTokensCheckBox.setText(tr("Annotate card text on tokens"));
|
||||
animationGroupBox->setTitle(tr("Animation settings"));
|
||||
tapAnimationCheckBox.setText(tr("&Tap/untap animation"));
|
||||
idleClientTimeOutCheckBox.setText(tr("Disconnect from server if idle for 1 hour"));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -112,7 +112,6 @@ private:
|
|||
QCheckBox playToStackCheckBox;
|
||||
QCheckBox annotateTokensCheckBox;
|
||||
QCheckBox tapAnimationCheckBox;
|
||||
QCheckBox idleClientTimeOutCheckBox;
|
||||
QGroupBox *generalGroupBox;
|
||||
QGroupBox *animationGroupBox;
|
||||
|
||||
|
|
|
@ -30,11 +30,6 @@ RemoteClient::RemoteClient(QObject *parent)
|
|||
timer->setInterval(keepalive * 1000);
|
||||
connect(timer, SIGNAL(timeout()), this, SLOT(ping()));
|
||||
|
||||
int idlekeepalive = settingsCache->getIdleKeepAlive();
|
||||
idleTimer = new QTimer(this);
|
||||
idleTimer->setInterval(idlekeepalive * 1000);
|
||||
connect(idleTimer, SIGNAL(timeout()), this, SLOT(doIdleTimeOut()));
|
||||
connect(this, SIGNAL(resetIdleTimerClock()), idleTimer, SLOT(start()));
|
||||
|
||||
socket = new QTcpSocket(this);
|
||||
socket->setSocketOption(QAbstractSocket::LowDelayOption, 1);
|
||||
|
@ -66,7 +61,6 @@ void RemoteClient::slotConnected()
|
|||
{
|
||||
timeRunning = lastDataReceived = 0;
|
||||
timer->start();
|
||||
idleTimer->start();
|
||||
|
||||
// dirty hack to be compatible with v14 server
|
||||
sendCommandContainer(CommandContainer());
|
||||
|
@ -308,7 +302,6 @@ void RemoteClient::doActivateToServer(const QString &_token)
|
|||
void RemoteClient::doDisconnectFromServer()
|
||||
{
|
||||
timer->stop();
|
||||
idleTimer->stop();
|
||||
|
||||
messageInProgress = false;
|
||||
handshakeStarted = false;
|
||||
|
@ -387,17 +380,3 @@ QString RemoteClient::getSrvClientID(const QString _hostname)
|
|||
QString uniqueServerClientID = QCryptographicHash::hash(srvClientID.toUtf8(), QCryptographicHash::Sha1).toHex().right(15);
|
||||
return uniqueServerClientID;
|
||||
}
|
||||
|
||||
void RemoteClient::doIdleTimeOut()
|
||||
{
|
||||
if (settingsCache->getIdleClientTimeOutEnabled()) {
|
||||
doDisconnectFromServer();
|
||||
emit idleTimeout();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void RemoteClient::resetIdleTimer()
|
||||
{
|
||||
emit resetIdleTimerClock();
|
||||
}
|
||||
|
|
|
@ -11,8 +11,6 @@ class RemoteClient : public AbstractClient {
|
|||
signals:
|
||||
void maxPingTime(int seconds, int maxSeconds);
|
||||
void serverTimeout();
|
||||
void idleTimeout();
|
||||
void resetIdleTimerClock();
|
||||
void loginError(Response::ResponseCode resp, QString reasonStr, quint32 endTime, QList<QString> missingFeatures);
|
||||
void registerError(Response::ResponseCode resp, QString reasonStr, quint32 endTime);
|
||||
void activateError();
|
||||
|
@ -39,7 +37,6 @@ private slots:
|
|||
void doLogin();
|
||||
void doDisconnectFromServer();
|
||||
void doActivateToServer(const QString &_token);
|
||||
void doIdleTimeOut();
|
||||
|
||||
private:
|
||||
static const int maxTimeout = 10;
|
||||
|
@ -51,7 +48,6 @@ private:
|
|||
int messageLength;
|
||||
|
||||
QTimer *timer;
|
||||
QTimer *idleTimer;
|
||||
QTcpSocket *socket;
|
||||
QString lastHostname;
|
||||
int lastPort;
|
||||
|
@ -66,7 +62,6 @@ public:
|
|||
void registerToServer(const QString &hostname, unsigned int port, const QString &_userName, const QString &_password, const QString &_email, const int _gender, const QString &_country, const QString &_realname);
|
||||
void activateToServer(const QString &_token);
|
||||
void disconnectFromServer();
|
||||
void resetIdleTimer();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -162,7 +162,6 @@ SettingsCache::SettingsCache()
|
|||
notifyAboutUpdates = settings->value("personal/updatenotification", true).toBool();
|
||||
lang = settings->value("personal/lang").toString();
|
||||
keepalive = settings->value("personal/keepalive", 5).toInt();
|
||||
idlekeepalive = settings->value("personal/idlekeepalive", 3600).toInt();
|
||||
|
||||
deckPath = getSafeConfigPath("paths/decks", dataPath + "/decks/");
|
||||
replaysPath = getSafeConfigPath("paths/replays", dataPath + "/replays/");
|
||||
|
@ -250,7 +249,6 @@ SettingsCache::SettingsCache()
|
|||
spectatorsCanSeeEverything = settings->value("game/spectatorscanseeeverything", false).toBool();
|
||||
rememberGameSettings = settings->value("game/remembergamesettings", true).toBool();
|
||||
clientID = settings->value("personal/clientid", "notset").toString();
|
||||
idleClientTimeOutEnabled = settings->value("interface/idleClientTimeOutEnabled", true).toBool();
|
||||
}
|
||||
|
||||
void SettingsCache::setCardInfoViewMode(const int _viewMode) {
|
||||
|
@ -392,12 +390,6 @@ void SettingsCache::setAnnotateTokens(int _annotateTokens)
|
|||
settings->setValue("interface/annotatetokens", annotateTokens);
|
||||
}
|
||||
|
||||
void SettingsCache::setIdleClientTimeOutEnabled(int _idleClientTimeOutEnabled)
|
||||
{
|
||||
idleClientTimeOutEnabled = _idleClientTimeOutEnabled;
|
||||
settings->setValue("interface/idleClientTimeOutEnabled", idleClientTimeOutEnabled);
|
||||
}
|
||||
|
||||
void SettingsCache::setTabGameSplitterSizes(const QByteArray &_tabGameSplitterSizes)
|
||||
{
|
||||
tabGameSplitterSizes = _tabGameSplitterSizes;
|
||||
|
|
|
@ -64,7 +64,6 @@ private:
|
|||
bool doubleClickToPlay;
|
||||
bool playToStack;
|
||||
bool annotateTokens;
|
||||
bool idleClientTimeOutEnabled;
|
||||
QByteArray tabGameSplitterSizes;
|
||||
bool displayCardNames;
|
||||
bool horizontalHand;
|
||||
|
@ -106,7 +105,6 @@ private:
|
|||
bool spectatorsCanTalk;
|
||||
bool spectatorsCanSeeEverything;
|
||||
int keepalive;
|
||||
int idlekeepalive;
|
||||
void translateLegacySettings();
|
||||
QString getSafeConfigPath(QString configEntry, QString defaultPath) const;
|
||||
QString getSafeConfigFilePath(QString configEntry, QString defaultPath) const;
|
||||
|
@ -132,7 +130,6 @@ public:
|
|||
bool getNotificationsEnabled() const { return notificationsEnabled; }
|
||||
bool getSpectatorNotificationsEnabled() const { return spectatorNotificationsEnabled; }
|
||||
bool getNotifyAboutUpdates() const { return notifyAboutUpdates; }
|
||||
bool getIdleClientTimeOutEnabled() const { return idleClientTimeOutEnabled; }
|
||||
|
||||
bool getDoubleClickToPlay() const { return doubleClickToPlay; }
|
||||
bool getPlayToStack() const { return playToStack; }
|
||||
|
@ -183,7 +180,6 @@ public:
|
|||
bool getSpectatorsCanSeeEverything() const { return spectatorsCanSeeEverything; }
|
||||
bool getRememberGameSettings() const { return rememberGameSettings; }
|
||||
int getKeepAlive() const { return keepalive; }
|
||||
int getIdleKeepAlive() const { return idlekeepalive; }
|
||||
void setClientID(QString clientID);
|
||||
QString getClientID() { return clientID; }
|
||||
ShortcutsSettings& shortcuts() const { return *shortcutsSettings; }
|
||||
|
@ -209,7 +205,6 @@ public slots:
|
|||
void setDoubleClickToPlay(int _doubleClickToPlay);
|
||||
void setPlayToStack(int _playToStack);
|
||||
void setAnnotateTokens(int _annotateTokens);
|
||||
void setIdleClientTimeOutEnabled(int _idleClientTimeOutEnabled);
|
||||
void setTabGameSplitterSizes(const QByteArray &_tabGameSplitterSizes);
|
||||
void setDisplayCardNames(int _displayCardNames);
|
||||
void setHorizontalHand(int _horizontalHand);
|
||||
|
|
|
@ -547,7 +547,6 @@ void TabGame::replayFinished()
|
|||
|
||||
void TabGame::replayStartButtonClicked()
|
||||
{
|
||||
emit notIdle();
|
||||
replayStartButton->setEnabled(false);
|
||||
replayPauseButton->setEnabled(true);
|
||||
replayFastForwardButton->setEnabled(true);
|
||||
|
@ -557,7 +556,6 @@ void TabGame::replayStartButtonClicked()
|
|||
|
||||
void TabGame::replayPauseButtonClicked()
|
||||
{
|
||||
emit notIdle();
|
||||
replayStartButton->setEnabled(true);
|
||||
replayPauseButton->setEnabled(false);
|
||||
replayFastForwardButton->setEnabled(false);
|
||||
|
@ -567,7 +565,6 @@ void TabGame::replayPauseButtonClicked()
|
|||
|
||||
void TabGame::replayFastForwardButtonToggled(bool checked)
|
||||
{
|
||||
emit notIdle();
|
||||
timelineWidget->setTimeScaleFactor(checked ? 10.0 : 1.0);
|
||||
}
|
||||
|
||||
|
@ -597,7 +594,6 @@ void TabGame::actGameInfo()
|
|||
|
||||
void TabGame::actConcede()
|
||||
{
|
||||
emit notIdle();
|
||||
if (QMessageBox::question(this, tr("Concede"), tr("Are you sure you want to concede this game?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No) != QMessageBox::Yes)
|
||||
return;
|
||||
|
||||
|
@ -606,7 +602,6 @@ void TabGame::actConcede()
|
|||
|
||||
void TabGame::actLeaveGame()
|
||||
{
|
||||
emit notIdle();
|
||||
if (!gameClosed) {
|
||||
if (!spectator)
|
||||
if (QMessageBox::question(this, tr("Leave game"), tr("Are you sure you want to leave this game?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No) != QMessageBox::Yes)
|
||||
|
@ -630,7 +625,6 @@ void TabGame::actSay()
|
|||
sendGameCommand(cmd);
|
||||
sayEdit->clear();
|
||||
}
|
||||
emit notIdle();
|
||||
}
|
||||
|
||||
void TabGame::actPhaseAction()
|
||||
|
@ -784,7 +778,6 @@ AbstractClient *TabGame::getClientForPlayer(int playerId) const
|
|||
|
||||
void TabGame::sendGameCommand(PendingCommand *pend, int playerId)
|
||||
{
|
||||
emit notIdle();
|
||||
AbstractClient *client = getClientForPlayer(playerId);
|
||||
if (!client)
|
||||
return;
|
||||
|
@ -795,7 +788,6 @@ void TabGame::sendGameCommand(PendingCommand *pend, int playerId)
|
|||
|
||||
void TabGame::sendGameCommand(const google::protobuf::Message &command, int playerId)
|
||||
{
|
||||
emit notIdle();
|
||||
AbstractClient *client = getClientForPlayer(playerId);
|
||||
if (!client)
|
||||
return;
|
||||
|
|
|
@ -65,7 +65,6 @@ private:
|
|||
bool state;
|
||||
signals:
|
||||
void stateChanged();
|
||||
void notIdle();
|
||||
public:
|
||||
ToggleButton(QWidget *parent = 0);
|
||||
bool getState() const { return state; }
|
||||
|
|
|
@ -99,7 +99,6 @@ void TabMessage::sendMessage()
|
|||
client->sendCommand(pend);
|
||||
|
||||
sayEdit->clear();
|
||||
emit notIdle();
|
||||
}
|
||||
|
||||
void TabMessage::messageSent(const Response &response)
|
||||
|
|
|
@ -26,7 +26,6 @@ private:
|
|||
signals:
|
||||
void talkClosing(TabMessage *tab);
|
||||
void maximizeClient();
|
||||
void notIdle();
|
||||
private slots:
|
||||
void sendMessage();
|
||||
void actLeave();
|
||||
|
|
|
@ -199,7 +199,6 @@ void TabRoom::sendMessage()
|
|||
sendRoomCommand(pend);
|
||||
sayEdit->clear();
|
||||
}
|
||||
emit notIdle();
|
||||
}
|
||||
|
||||
void TabRoom::sayFinished(const Response &response)
|
||||
|
|
|
@ -342,12 +342,10 @@ void TabSupervisor::gameJoined(const Event_GameJoined &event)
|
|||
connect(tab, SIGNAL(gameClosing(TabGame *)), this, SLOT(gameLeft(TabGame *)));
|
||||
connect(tab, SIGNAL(openMessageDialog(const QString &, bool)), this, SLOT(addMessageTab(const QString &, bool)));
|
||||
connect(tab, SIGNAL(openDeckEditor(const DeckLoader *)), this, SLOT(addDeckEditorTab(const DeckLoader *)));
|
||||
connect(tab, SIGNAL(notIdle()), this, SLOT(resetIdleTimer()));
|
||||
int tabIndex = myAddTab(tab);
|
||||
addCloseButtonToTab(tab, tabIndex);
|
||||
gameTabs.insert(event.game_info().game_id(), tab);
|
||||
setCurrentWidget(tab);
|
||||
emit idleTimerReset();
|
||||
}
|
||||
|
||||
void TabSupervisor::localGameJoined(const Event_GameJoined &event)
|
||||
|
@ -391,7 +389,6 @@ void TabSupervisor::addRoomTab(const ServerInfo_Room &info, bool setCurrent)
|
|||
roomTabs.insert(info.room_id(), tab);
|
||||
if (setCurrent)
|
||||
setCurrentWidget(tab);
|
||||
emit idleTimerReset();
|
||||
}
|
||||
|
||||
void TabSupervisor::roomLeft(TabRoom *tab)
|
||||
|
@ -444,7 +441,6 @@ TabMessage *TabSupervisor::addMessageTab(const QString &receiverName, bool focus
|
|||
tab = new TabMessage(this, client, *userInfo, otherUser);
|
||||
connect(tab, SIGNAL(talkClosing(TabMessage *)), this, SLOT(talkLeft(TabMessage *)));
|
||||
connect(tab, SIGNAL(maximizeClient()), this, SLOT(maximizeMainWindow()));
|
||||
connect(tab, SIGNAL(notIdle()), this, SLOT(resetIdleTimer()));
|
||||
int tabIndex = myAddTab(tab);
|
||||
addCloseButtonToTab(tab, tabIndex);
|
||||
messageTabs.insert(receiverName, tab);
|
||||
|
@ -583,6 +579,8 @@ void TabSupervisor::processNotifyUserEvent(const Event_NotifyUser &event)
|
|||
{
|
||||
|
||||
switch ((Event_NotifyUser::NotificationType) event.type()) {
|
||||
case Event_NotifyUser::UNKNOWN: QMessageBox::information(this, tr("Unknown Event"), tr("The server has sent you a message that your client does not understand.\nThis message might mean there is a new version of Cockatrice available or this server is running a custom or pre-release version.\n\nTo update your client, go to Help -> Update Cockatrice.")); break;
|
||||
case Event_NotifyUser::IDLEWARNING: QMessageBox::information(this, tr("Idle Timeout"), tr("You are about to be logged out due to inactivity.")); break;
|
||||
case Event_NotifyUser::PROMOTED: QMessageBox::information(this, tr("Promotion"), tr("You have been promoted to moderator. Please log out and back in for changes to take effect.")); break;
|
||||
case Event_NotifyUser::WARNING: {
|
||||
if (!QString::fromStdString(event.warning_reason()).simplified().isEmpty())
|
||||
|
@ -593,8 +591,3 @@ void TabSupervisor::processNotifyUserEvent(const Event_NotifyUser &event)
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
void TabSupervisor::resetIdleTimer()
|
||||
{
|
||||
emit idleTimerReset();
|
||||
}
|
|
@ -83,7 +83,6 @@ signals:
|
|||
void localGameEnded();
|
||||
void adminLockChanged(bool lock);
|
||||
void showWindowIfHidden();
|
||||
void idleTimerReset();
|
||||
public slots:
|
||||
TabDeckEditor *addDeckEditorTab(const DeckLoader *deckToOpen);
|
||||
void openReplay(GameReplay *replay);
|
||||
|
@ -109,7 +108,6 @@ private slots:
|
|||
void processGameEventContainer(const GameEventContainer &cont);
|
||||
void processUserMessageEvent(const Event_UserMessage &event);
|
||||
void processNotifyUserEvent(const Event_NotifyUser &event);
|
||||
void resetIdleTimer();
|
||||
};
|
||||
|
||||
#endif
|
|
@ -321,17 +321,6 @@ void MainWindow::serverTimeout()
|
|||
actConnect();
|
||||
}
|
||||
|
||||
void MainWindow::idleTimeout()
|
||||
{
|
||||
QMessageBox::critical(this, tr("Inactivity Timeout"), tr("You have been signed out due to inactivity."));
|
||||
actConnect();
|
||||
}
|
||||
|
||||
void MainWindow::idleTimerReset()
|
||||
{
|
||||
client->resetIdleTimer();
|
||||
}
|
||||
|
||||
void MainWindow::loginError(Response::ResponseCode r, QString reasonStr, quint32 endTime, QList<QString> missingFeatures)
|
||||
{
|
||||
switch (r) {
|
||||
|
@ -665,7 +654,6 @@ MainWindow::MainWindow(QWidget *parent)
|
|||
connect(client, SIGNAL(loginError(Response::ResponseCode, QString, quint32, QList<QString>)), this, SLOT(loginError(Response::ResponseCode, QString, quint32, QList<QString>)));
|
||||
connect(client, SIGNAL(socketError(const QString &)), this, SLOT(socketError(const QString &)));
|
||||
connect(client, SIGNAL(serverTimeout()), this, SLOT(serverTimeout()));
|
||||
connect(client, SIGNAL(idleTimeout()), this, SLOT(idleTimeout()));
|
||||
connect(client, SIGNAL(statusChanged(ClientStatus)), this, SLOT(statusChanged(ClientStatus)));
|
||||
connect(client, SIGNAL(protocolVersionMismatch(int, int)), this, SLOT(protocolVersionMismatch(int, int)));
|
||||
connect(client, SIGNAL(userInfoChanged(const ServerInfo_User &)), this, SLOT(userInfoReceived(const ServerInfo_User &)), Qt::BlockingQueuedConnection);
|
||||
|
@ -687,7 +675,6 @@ MainWindow::MainWindow(QWidget *parent)
|
|||
connect(tabSupervisor, SIGNAL(setMenu(QList<QMenu *>)), this, SLOT(updateTabMenu(QList<QMenu *>)));
|
||||
connect(tabSupervisor, SIGNAL(localGameEnded()), this, SLOT(localGameEnded()));
|
||||
connect(tabSupervisor, SIGNAL(showWindowIfHidden()), this, SLOT(showWindowIfHidden()));
|
||||
connect(tabSupervisor, SIGNAL(idleTimerReset()), this, SLOT(idleTimerReset()));
|
||||
tabSupervisor->addDeckEditorTab(0);
|
||||
|
||||
setCentralWidget(tabSupervisor);
|
||||
|
|
|
@ -46,8 +46,6 @@ private slots:
|
|||
void processConnectionClosedEvent(const Event_ConnectionClosed &event);
|
||||
void processServerShutdownEvent(const Event_ServerShutdown &event);
|
||||
void serverTimeout();
|
||||
void idleTimerReset();
|
||||
void idleTimeout();
|
||||
void loginError(Response::ResponseCode r, QString reasonStr, quint32 endTime, QList<QString> missingFeatures);
|
||||
void registerError(Response::ResponseCode r, QString reasonStr, quint32 endTime);
|
||||
void activateError();
|
||||
|
|
|
@ -20,6 +20,7 @@ void FeatureSet::initalizeFeatureList(QMap<QString, bool> &featureList) {
|
|||
featureList.insert("room_chat_history", false);
|
||||
featureList.insert("client_warnings", false);
|
||||
featureList.insert("mod_log_lookup", false);
|
||||
featureList.insert("idle_client", false);
|
||||
}
|
||||
|
||||
void FeatureSet::enableRequiredFeature(QMap<QString, bool> &featureList, QString featureName){
|
||||
|
|
|
@ -3,8 +3,10 @@ import "session_event.proto";
|
|||
message Event_NotifyUser {
|
||||
|
||||
enum NotificationType {
|
||||
UNKNOWN = 0; // Default enum value if no "type" is defined when used
|
||||
PROMOTED = 1;
|
||||
WARNING = 2;
|
||||
IDLEWARNING = 3;
|
||||
}
|
||||
|
||||
extend SessionEvent {
|
||||
|
|
|
@ -64,6 +64,7 @@ public:
|
|||
virtual bool getClientIDRequiredEnabled() const { return false; }
|
||||
virtual bool getRegOnlyServerEnabled() const { return false; }
|
||||
virtual bool getMaxUserLimitEnabled() const { return false; }
|
||||
virtual int getIdleClientTimeout() const { return 0; }
|
||||
virtual int getClientKeepAlive() const { return 0; }
|
||||
virtual int getMaxGameInactivityTime() const { return 9999999; }
|
||||
virtual int getMaxPlayerInactivityTime() const { return 9999999; }
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include <QDebug>
|
||||
#include <QDateTime>
|
||||
#include <math.h>
|
||||
#include "server_protocolhandler.h"
|
||||
#include "server_database_interface.h"
|
||||
#include "server_room.h"
|
||||
|
@ -19,6 +20,7 @@
|
|||
#include "pb/event_game_joined.pb.h"
|
||||
#include "pb/event_room_say.pb.h"
|
||||
#include "pb/serverinfo_user.pb.h"
|
||||
#include "pb/event_notify_user.pb.h"
|
||||
#include <google/protobuf/descriptor.h>
|
||||
#include "featureset.h"
|
||||
|
||||
|
@ -31,8 +33,11 @@ Server_ProtocolHandler::Server_ProtocolHandler(Server *_server, Server_DatabaseI
|
|||
authState(NotLoggedIn),
|
||||
acceptsUserListChanges(false),
|
||||
acceptsRoomListChanges(false),
|
||||
idleClientWarningSent(false),
|
||||
timeRunning(0),
|
||||
lastDataReceived(0)
|
||||
lastDataReceived(0),
|
||||
lastActionReceived(0)
|
||||
|
||||
{
|
||||
connect(server, SIGNAL(pingClockTimeout()), this, SLOT(pingClockTimeout()));
|
||||
}
|
||||
|
@ -171,6 +176,8 @@ Response::ResponseCode Server_ProtocolHandler::processRoomCommandContainer(const
|
|||
if (!room)
|
||||
return Response::RespNotInRoom;
|
||||
|
||||
resetIdleTimer();
|
||||
|
||||
Response::ResponseCode finalResponseCode = Response::RespOk;
|
||||
for (int i = cont.room_command_size() - 1; i >= 0; --i) {
|
||||
Response::ResponseCode resp = Response::RespInvalidCommand;
|
||||
|
@ -240,6 +247,8 @@ Response::ResponseCode Server_ProtocolHandler::processGameCommandContainer(const
|
|||
if (!player)
|
||||
return Response::RespNotInRoom;
|
||||
|
||||
resetIdleTimer();
|
||||
|
||||
int commandCountingInterval = server->getCommandCountingInterval();
|
||||
int maxCommandCountPerInterval = server->getMaxCommandCountPerInterval();
|
||||
GameEventStorage ges;
|
||||
|
@ -280,6 +289,8 @@ Response::ResponseCode Server_ProtocolHandler::processModeratorCommandContainer(
|
|||
if (!(userInfo->user_level() & ServerInfo_User::IsModerator))
|
||||
return Response::RespLoginNeeded;
|
||||
|
||||
resetIdleTimer();
|
||||
|
||||
Response::ResponseCode finalResponseCode = Response::RespOk;
|
||||
for (int i = cont.moderator_command_size() - 1; i >= 0; --i) {
|
||||
Response::ResponseCode resp = Response::RespInvalidCommand;
|
||||
|
@ -301,6 +312,8 @@ Response::ResponseCode Server_ProtocolHandler::processAdminCommandContainer(cons
|
|||
if (!(userInfo->user_level() & ServerInfo_User::IsAdmin))
|
||||
return Response::RespLoginNeeded;
|
||||
|
||||
resetIdleTimer();
|
||||
|
||||
Response::ResponseCode finalResponseCode = Response::RespOk;
|
||||
for (int i = cont.admin_command_size() - 1; i >= 0; --i) {
|
||||
Response::ResponseCode resp = Response::RespInvalidCommand;
|
||||
|
@ -373,6 +386,24 @@ void Server_ProtocolHandler::pingClockTimeout()
|
|||
|
||||
if (timeRunning - lastDataReceived > server->getMaxPlayerInactivityTime())
|
||||
prepareDestroy();
|
||||
|
||||
if (QString::fromStdString(userInfo->privlevel()).toLower() == "none") {
|
||||
if ((server->getIdleClientTimeout() > 0) && (idleClientWarningSent)) {
|
||||
if (timeRunning - lastActionReceived > server->getIdleClientTimeout()) {
|
||||
prepareDestroy();
|
||||
}
|
||||
}
|
||||
|
||||
if (((timeRunning - lastActionReceived) >= ceil(server->getIdleClientTimeout() *.9)) && (!idleClientWarningSent)) {
|
||||
Event_NotifyUser event;
|
||||
event.set_type(Event_NotifyUser::IDLEWARNING);
|
||||
SessionEvent *se = prepareSessionEvent(event);
|
||||
sendProtocolItem(*se);
|
||||
delete se;
|
||||
idleClientWarningSent = true;
|
||||
}
|
||||
}
|
||||
|
||||
++timeRunning;
|
||||
}
|
||||
|
||||
|
@ -728,3 +759,9 @@ Response::ResponseCode Server_ProtocolHandler::cmdJoinGame(const Command_JoinGam
|
|||
|
||||
return room->processJoinGameCommand(cmd, rc, this);
|
||||
}
|
||||
|
||||
void Server_ProtocolHandler::resetIdleTimer()
|
||||
{
|
||||
lastActionReceived = timeRunning;
|
||||
idleClientWarningSent = false;
|
||||
}
|
||||
|
|
|
@ -52,10 +52,11 @@ protected:
|
|||
AuthenticationResult authState;
|
||||
bool acceptsUserListChanges;
|
||||
bool acceptsRoomListChanges;
|
||||
bool idleClientWarningSent;
|
||||
virtual void logDebugMessage(const QString & /* message */) { }
|
||||
private:
|
||||
QList<int> messageSizeOverTime, messageCountOverTime, commandCountOverTime;
|
||||
int timeRunning, lastDataReceived;
|
||||
int timeRunning, lastDataReceived, lastActionReceived;
|
||||
QTimer *pingClock;
|
||||
|
||||
virtual void transmitProtocolItem(const ServerMessage &item) = 0;
|
||||
|
@ -81,6 +82,8 @@ private:
|
|||
virtual Response::ResponseCode processExtendedModeratorCommand(int /* cmdType */, const ModeratorCommand & /* cmd */, ResponseContainer & /* rc */) { return Response::RespFunctionNotAllowed; }
|
||||
Response::ResponseCode processAdminCommandContainer(const CommandContainer &cont, ResponseContainer &rc);
|
||||
virtual Response::ResponseCode processExtendedAdminCommand(int /* cmdType */, const AdminCommand & /* cmd */, ResponseContainer & /* rc */) { return Response::RespFunctionNotAllowed; }
|
||||
|
||||
void resetIdleTimer();
|
||||
private slots:
|
||||
void pingClockTimeout();
|
||||
public slots:
|
||||
|
|
|
@ -71,6 +71,10 @@ requiredfeatures=""
|
|||
; to choose from. Example: "Flaming,Foul Language"
|
||||
officialwarnings="Flamming,Spamming,Causing Drama,Abusive Language"
|
||||
|
||||
; Maximum time in seconds a player can stay connected but idle. Default is 3600 (0 = disabled)
|
||||
; Clients will be notified at the 90% time period of pending disconnection if they do not take action.
|
||||
idleclienttimeout=3600
|
||||
|
||||
[authentication]
|
||||
|
||||
; Servatrice can authenticate users connecting. It currently supports 3 different authentication methods:
|
||||
|
|
|
@ -405,6 +405,13 @@ bool Servatrice::initServer()
|
|||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (getIdleClientTimeout() > 0) {
|
||||
qDebug() << "Idle client timeout value: " << getIdleClientTimeout();
|
||||
if (getIdleClientTimeout() < 300)
|
||||
qDebug() << "WARNING: It is not recommended to set the IdleClientTimeout value very low. Doing so will cause clients to very quickly be disconnected. Many players when connected may be searching for card details outside the client in the middle of matches or possibly drafting outside the client and short time out values will remove these players.";
|
||||
}
|
||||
|
||||
setRequiredFeatures(getRequiredFeatures());
|
||||
return true;
|
||||
}
|
||||
|
@ -815,3 +822,7 @@ QString Servatrice::getISLNetworkSSLKeyFile() const {
|
|||
int Servatrice::getISLNetworkPort() const {
|
||||
return settingsCache->value("servernetwork/port", 14747).toInt();
|
||||
}
|
||||
|
||||
int Servatrice::getIdleClientTimeout() const {
|
||||
return settingsCache->value("server/idleclienttimeout", 3600).toInt();
|
||||
}
|
|
@ -189,6 +189,7 @@ public:
|
|||
bool getRegistrationEnabled() const;
|
||||
bool getRequireEmailForRegistrationEnabled() const;
|
||||
bool getRequireEmailActivationEnabled() const;
|
||||
int getIdleClientTimeout() const;
|
||||
int getServerID() const;
|
||||
int getMaxGameInactivityTime() const;
|
||||
int getMaxPlayerInactivityTime() const;
|
||||
|
|
Loading…
Reference in a new issue