improved banning and deck hashing
This commit is contained in:
parent
9fe8f6fc03
commit
632e9bbff3
22 changed files with 211 additions and 92 deletions
|
@ -84,7 +84,6 @@ void AbstractCardItem::transformPainter(QPainter *painter, const QSizeF &transla
|
||||||
|
|
||||||
void AbstractCardItem::paintPicture(QPainter *painter, const QSizeF &translatedSize, int angle)
|
void AbstractCardItem::paintPicture(QPainter *painter, const QSizeF &translatedSize, int angle)
|
||||||
{
|
{
|
||||||
QRectF totalBoundingRect = painter->combinedTransform().mapRect(boundingRect());
|
|
||||||
qreal scaleFactor = translatedSize.width() / boundingRect().width();
|
qreal scaleFactor = translatedSize.width() / boundingRect().width();
|
||||||
|
|
||||||
QPixmap *translatedPixmap = info->getPixmap(translatedSize.toSize());
|
QPixmap *translatedPixmap = info->getPixmap(translatedSize.toSize());
|
||||||
|
|
|
@ -257,6 +257,7 @@ QModelIndex DeckListModel::addCard(const QString &cardName, const QString &zoneN
|
||||||
cardNode->setNumber(cardNode->getNumber() + 1);
|
cardNode->setNumber(cardNode->getNumber() + 1);
|
||||||
QModelIndex ind = nodeToIndex(cardNode);
|
QModelIndex ind = nodeToIndex(cardNode);
|
||||||
emitRecursiveUpdates(ind);
|
emitRecursiveUpdates(ind);
|
||||||
|
deckList->updateDeckHash();
|
||||||
return ind;
|
return ind;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,6 @@ void DeckViewCardDragItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
||||||
{
|
{
|
||||||
setCursor(Qt::OpenHandCursor);
|
setCursor(Qt::OpenHandCursor);
|
||||||
DeckViewScene *sc = static_cast<DeckViewScene *>(scene());
|
DeckViewScene *sc = static_cast<DeckViewScene *>(scene());
|
||||||
QPointF sp = pos();
|
|
||||||
sc->removeItem(this);
|
sc->removeItem(this);
|
||||||
|
|
||||||
if (currentZone) {
|
if (currentZone) {
|
||||||
|
|
|
@ -27,6 +27,7 @@ public:
|
||||||
LocalServerInterface(LocalServer *_server);
|
LocalServerInterface(LocalServer *_server);
|
||||||
~LocalServerInterface();
|
~LocalServerInterface();
|
||||||
|
|
||||||
|
QString getAddress() const { return QString(); }
|
||||||
void sendProtocolItem(ProtocolItem *item, bool deleteItem = true);
|
void sendProtocolItem(ProtocolItem *item, bool deleteItem = true);
|
||||||
signals:
|
signals:
|
||||||
void itemToClient(ProtocolItem *item);
|
void itemToClient(ProtocolItem *item);
|
||||||
|
|
|
@ -9,7 +9,7 @@ extern CardDatabase *db;
|
||||||
|
|
||||||
extern QTranslator *translator;
|
extern QTranslator *translator;
|
||||||
const QString translationPrefix = "cockatrice";
|
const QString translationPrefix = "cockatrice";
|
||||||
const QString versionString = "0.20110921";
|
const QString versionString = "0.20111101";
|
||||||
|
|
||||||
void installNewTranslator();
|
void installNewTranslator();
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,7 @@ public:
|
||||||
void stop();
|
void stop();
|
||||||
int getGameCount() const { return gameTabs.size(); }
|
int getGameCount() const { return gameTabs.size(); }
|
||||||
TabUserLists *getUserListsTab() const { return tabUserLists; }
|
TabUserLists *getUserListsTab() const { return tabUserLists; }
|
||||||
|
ServerInfo_User *getUserInfo() const { return userInfo; }
|
||||||
bool getAdminLocked() const;
|
bool getAdminLocked() const;
|
||||||
int getUserLevel() const;
|
int getUserLevel() const;
|
||||||
signals:
|
signals:
|
||||||
|
|
|
@ -13,24 +13,72 @@
|
||||||
#include <QInputDialog>
|
#include <QInputDialog>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QSpinBox>
|
#include <QSpinBox>
|
||||||
|
#include <QRadioButton>
|
||||||
#include <QPlainTextEdit>
|
#include <QPlainTextEdit>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#include <QHBoxLayout>
|
#include <QHBoxLayout>
|
||||||
|
#include <QCheckBox>
|
||||||
|
#include <QMessageBox>
|
||||||
|
|
||||||
BanDialog::BanDialog(QWidget *parent)
|
BanDialog::BanDialog(ServerInfo_User *info, QWidget *parent)
|
||||||
: QDialog(parent)
|
: QDialog(parent)
|
||||||
{
|
{
|
||||||
QLabel *durationLabel = new QLabel(tr("Please enter the duration of the ban (in minutes).\nEnter 0 for an indefinite ban."));
|
setAttribute(Qt::WA_DeleteOnClose);
|
||||||
durationEdit = new QSpinBox;
|
|
||||||
durationEdit->setMinimum(0);
|
nameBanCheckBox = new QCheckBox(tr("ban &user name"));
|
||||||
durationEdit->setValue(5);
|
nameBanCheckBox->setChecked(true);
|
||||||
durationEdit->setMaximum(99999999);
|
nameBanEdit = new QLineEdit(info->getName());
|
||||||
|
ipBanCheckBox = new QCheckBox(tr("ban &IP address"));
|
||||||
|
ipBanCheckBox->setChecked(true);
|
||||||
|
ipBanEdit = new QLineEdit(info->getAddress());
|
||||||
|
QGridLayout *banTypeGrid = new QGridLayout;
|
||||||
|
banTypeGrid->addWidget(nameBanCheckBox, 0, 0);
|
||||||
|
banTypeGrid->addWidget(nameBanEdit, 0, 1);
|
||||||
|
banTypeGrid->addWidget(ipBanCheckBox, 1, 0);
|
||||||
|
banTypeGrid->addWidget(ipBanEdit, 1, 1);
|
||||||
|
QGroupBox *banTypeGroupBox = new QGroupBox(tr("Ban type"));
|
||||||
|
banTypeGroupBox->setLayout(banTypeGrid);
|
||||||
|
|
||||||
|
permanentRadio = new QRadioButton(tr("&permanent ban"));
|
||||||
|
temporaryRadio = new QRadioButton(tr("&temporary ban"));
|
||||||
|
temporaryRadio->setChecked(true);
|
||||||
|
connect(temporaryRadio, SIGNAL(toggled(bool)), this, SLOT(enableTemporaryEdits(bool)));
|
||||||
|
daysLabel = new QLabel(tr("&Days:"));
|
||||||
|
daysEdit = new QSpinBox;
|
||||||
|
daysEdit->setMinimum(0);
|
||||||
|
daysEdit->setValue(0);
|
||||||
|
daysEdit->setMaximum(10000);
|
||||||
|
daysLabel->setBuddy(daysEdit);
|
||||||
|
hoursLabel = new QLabel(tr("&Hours:"));
|
||||||
|
hoursEdit = new QSpinBox;
|
||||||
|
hoursEdit->setMinimum(0);
|
||||||
|
hoursEdit->setValue(0);
|
||||||
|
hoursEdit->setMaximum(24);
|
||||||
|
hoursLabel->setBuddy(hoursEdit);
|
||||||
|
minutesLabel = new QLabel(tr("&Minutes:"));
|
||||||
|
minutesEdit = new QSpinBox;
|
||||||
|
minutesEdit->setMinimum(0);
|
||||||
|
minutesEdit->setValue(5);
|
||||||
|
minutesEdit->setMaximum(60);
|
||||||
|
minutesLabel->setBuddy(minutesEdit);
|
||||||
|
QGridLayout *durationLayout = new QGridLayout;
|
||||||
|
durationLayout->addWidget(permanentRadio, 0, 0, 1, 6);
|
||||||
|
durationLayout->addWidget(temporaryRadio, 1, 0, 1, 6);
|
||||||
|
durationLayout->addWidget(daysLabel, 2, 0);
|
||||||
|
durationLayout->addWidget(daysEdit, 2, 1);
|
||||||
|
durationLayout->addWidget(hoursLabel, 2, 2);
|
||||||
|
durationLayout->addWidget(hoursEdit, 2, 3);
|
||||||
|
durationLayout->addWidget(minutesLabel, 2, 4);
|
||||||
|
durationLayout->addWidget(minutesEdit, 2, 5);
|
||||||
|
QGroupBox *durationGroupBox = new QGroupBox(tr("Duration of the ban"));
|
||||||
|
durationGroupBox->setLayout(durationLayout);
|
||||||
|
|
||||||
QLabel *reasonLabel = new QLabel(tr("Please enter the reason for the ban.\nThis is only saved for moderators and cannot be seen by the banned person."));
|
QLabel *reasonLabel = new QLabel(tr("Please enter the reason for the ban.\nThis is only saved for moderators and cannot be seen by the banned person."));
|
||||||
reasonEdit = new QPlainTextEdit;
|
reasonEdit = new QPlainTextEdit;
|
||||||
|
|
||||||
QPushButton *okButton = new QPushButton(tr("&OK"));
|
QPushButton *okButton = new QPushButton(tr("&OK"));
|
||||||
okButton->setAutoDefault(true);
|
okButton->setAutoDefault(true);
|
||||||
connect(okButton, SIGNAL(clicked()), this, SLOT(accept()));
|
connect(okButton, SIGNAL(clicked()), this, SLOT(okClicked()));
|
||||||
QPushButton *cancelButton = new QPushButton(tr("&Cancel"));
|
QPushButton *cancelButton = new QPushButton(tr("&Cancel"));
|
||||||
connect(cancelButton, SIGNAL(clicked()), this, SLOT(reject()));
|
connect(cancelButton, SIGNAL(clicked()), this, SLOT(reject()));
|
||||||
|
|
||||||
|
@ -40,8 +88,8 @@ BanDialog::BanDialog(QWidget *parent)
|
||||||
buttonLayout->addWidget(cancelButton);
|
buttonLayout->addWidget(cancelButton);
|
||||||
|
|
||||||
QVBoxLayout *vbox = new QVBoxLayout;
|
QVBoxLayout *vbox = new QVBoxLayout;
|
||||||
vbox->addWidget(durationLabel);
|
vbox->addWidget(banTypeGroupBox);
|
||||||
vbox->addWidget(durationEdit);
|
vbox->addWidget(durationGroupBox);
|
||||||
vbox->addWidget(reasonLabel);
|
vbox->addWidget(reasonLabel);
|
||||||
vbox->addWidget(reasonEdit);
|
vbox->addWidget(reasonEdit);
|
||||||
vbox->addLayout(buttonLayout);
|
vbox->addLayout(buttonLayout);
|
||||||
|
@ -50,9 +98,38 @@ BanDialog::BanDialog(QWidget *parent)
|
||||||
setWindowTitle(tr("Ban user from server"));
|
setWindowTitle(tr("Ban user from server"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BanDialog::okClicked()
|
||||||
|
{
|
||||||
|
if (!nameBanCheckBox->isChecked() && !ipBanCheckBox->isChecked()) {
|
||||||
|
QMessageBox::critical(this, tr("Error"), tr("You have to select a name-based or IP-based ban, or both."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
accept();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BanDialog::enableTemporaryEdits(bool enabled)
|
||||||
|
{
|
||||||
|
daysLabel->setEnabled(enabled);
|
||||||
|
daysEdit->setEnabled(enabled);
|
||||||
|
hoursLabel->setEnabled(enabled);
|
||||||
|
hoursEdit->setEnabled(enabled);
|
||||||
|
minutesLabel->setEnabled(enabled);
|
||||||
|
minutesEdit->setEnabled(enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString BanDialog::getBanName() const
|
||||||
|
{
|
||||||
|
return nameBanCheckBox->isChecked() ? nameBanEdit->text() : QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString BanDialog::getBanIP() const
|
||||||
|
{
|
||||||
|
return ipBanCheckBox->isChecked() ? ipBanEdit->text() : QString();
|
||||||
|
}
|
||||||
|
|
||||||
int BanDialog::getMinutes() const
|
int BanDialog::getMinutes() const
|
||||||
{
|
{
|
||||||
return durationEdit->value();
|
return permanentRadio->isChecked() ? 0 : (daysEdit->value() * 24 * 60 + hoursEdit->value() * 60 + minutesEdit->value());
|
||||||
}
|
}
|
||||||
|
|
||||||
QString BanDialog::getReason() const
|
QString BanDialog::getReason() const
|
||||||
|
@ -242,6 +319,24 @@ void UserList::gamesOfUserReceived(ProtocolResponse *resp)
|
||||||
selector->show();
|
selector->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UserList::banUser_processUserInfoResponse(ProtocolResponse *r)
|
||||||
|
{
|
||||||
|
Response_GetUserInfo *response = qobject_cast<Response_GetUserInfo *>(r);
|
||||||
|
if (!response)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// The dialog needs to be non-modal in order to not block the event queue of the client.
|
||||||
|
BanDialog *dlg = new BanDialog(response->getUserInfo(), this);
|
||||||
|
connect(dlg, SIGNAL(accepted()), this, SLOT(banUser_dialogFinished()));
|
||||||
|
dlg->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UserList::banUser_dialogFinished()
|
||||||
|
{
|
||||||
|
BanDialog *dlg = static_cast<BanDialog *>(sender());
|
||||||
|
client->sendCommand(new Command_BanFromServer(dlg->getBanName(), dlg->getBanIP(), dlg->getMinutes(), dlg->getReason()));
|
||||||
|
}
|
||||||
|
|
||||||
void UserList::showContextMenu(const QPoint &pos, const QModelIndex &index)
|
void UserList::showContextMenu(const QPoint &pos, const QModelIndex &index)
|
||||||
{
|
{
|
||||||
const QString &userName = index.sibling(index.row(), 2).data(Qt::UserRole).toString();
|
const QString &userName = index.sibling(index.row(), 2).data(Qt::UserRole).toString();
|
||||||
|
@ -279,6 +374,14 @@ void UserList::showContextMenu(const QPoint &pos, const QModelIndex &index)
|
||||||
menu->addSeparator();
|
menu->addSeparator();
|
||||||
menu->addAction(aBan);
|
menu->addAction(aBan);
|
||||||
}
|
}
|
||||||
|
if (userName == tabSupervisor->getUserInfo()->getName()) {
|
||||||
|
aChat->setEnabled(false);
|
||||||
|
aAddToBuddyList->setEnabled(false);
|
||||||
|
aRemoveFromBuddyList->setEnabled(false);
|
||||||
|
aAddToIgnoreList->setEnabled(false);
|
||||||
|
aRemoveFromIgnoreList->setEnabled(false);
|
||||||
|
aBan->setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
QAction *actionClicked = menu->exec(pos);
|
QAction *actionClicked = menu->exec(pos);
|
||||||
if (actionClicked == aDetails) {
|
if (actionClicked == aDetails) {
|
||||||
|
@ -300,9 +403,9 @@ void UserList::showContextMenu(const QPoint &pos, const QModelIndex &index)
|
||||||
else if (actionClicked == aRemoveFromIgnoreList)
|
else if (actionClicked == aRemoveFromIgnoreList)
|
||||||
client->sendCommand(new Command_RemoveFromList("ignore", userName));
|
client->sendCommand(new Command_RemoveFromList("ignore", userName));
|
||||||
else if (actionClicked == aBan) {
|
else if (actionClicked == aBan) {
|
||||||
BanDialog dlg(this);
|
Command_GetUserInfo *command = new Command_GetUserInfo(userName);
|
||||||
if (dlg.exec())
|
connect(command, SIGNAL(finished(ProtocolResponse *)), this, SLOT(banUser_processUserInfoResponse(ProtocolResponse *)));
|
||||||
client->sendCommand(new Command_BanFromServer(userName, dlg.getMinutes(), dlg.getReason()));
|
client->sendCommand(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete menu;
|
delete menu;
|
||||||
|
|
|
@ -10,17 +10,29 @@ class QTreeWidget;
|
||||||
class ServerInfo_User;
|
class ServerInfo_User;
|
||||||
class AbstractClient;
|
class AbstractClient;
|
||||||
class TabSupervisor;
|
class TabSupervisor;
|
||||||
|
class QLabel;
|
||||||
|
class QCheckBox;
|
||||||
class QSpinBox;
|
class QSpinBox;
|
||||||
|
class QRadioButton;
|
||||||
class QPlainTextEdit;
|
class QPlainTextEdit;
|
||||||
class ProtocolResponse;
|
class ProtocolResponse;
|
||||||
|
|
||||||
class BanDialog : public QDialog {
|
class BanDialog : public QDialog {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
private:
|
private:
|
||||||
QSpinBox *durationEdit;
|
QLabel *daysLabel, *hoursLabel, *minutesLabel;
|
||||||
|
QCheckBox *nameBanCheckBox, *ipBanCheckBox;
|
||||||
|
QLineEdit *nameBanEdit, *ipBanEdit;
|
||||||
|
QSpinBox *daysEdit, *hoursEdit, *minutesEdit;
|
||||||
|
QRadioButton *permanentRadio, *temporaryRadio;
|
||||||
QPlainTextEdit *reasonEdit;
|
QPlainTextEdit *reasonEdit;
|
||||||
|
private slots:
|
||||||
|
void okClicked();
|
||||||
|
void enableTemporaryEdits(bool enabled);
|
||||||
public:
|
public:
|
||||||
BanDialog(QWidget *parent = 0);
|
BanDialog(ServerInfo_User *info, QWidget *parent = 0);
|
||||||
|
QString getBanName() const;
|
||||||
|
QString getBanIP() const;
|
||||||
int getMinutes() const;
|
int getMinutes() const;
|
||||||
QString getReason() const;
|
QString getReason() const;
|
||||||
};
|
};
|
||||||
|
@ -53,6 +65,8 @@ private:
|
||||||
void setUserOnline(QTreeWidgetItem *user, bool online);
|
void setUserOnline(QTreeWidgetItem *user, bool online);
|
||||||
private slots:
|
private slots:
|
||||||
void userClicked(QTreeWidgetItem *item, int column);
|
void userClicked(QTreeWidgetItem *item, int column);
|
||||||
|
void banUser_processUserInfoResponse(ProtocolResponse *resp);
|
||||||
|
void banUser_dialogFinished();
|
||||||
void gamesOfUserReceived(ProtocolResponse *resp);
|
void gamesOfUserReceived(ProtocolResponse *resp);
|
||||||
signals:
|
signals:
|
||||||
void openMessageDialog(const QString &userName, bool focus);
|
void openMessageDialog(const QString &userName, bool focus);
|
||||||
|
|
|
@ -565,7 +565,13 @@ void DeckList::updateDeckHash()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cardList.sort();
|
cardList.sort();
|
||||||
deckHash = QCryptographicHash::hash(cardList.join(";").toUtf8(), QCryptographicHash::Sha1).toBase64().left(10);
|
QByteArray deckHashArray = QCryptographicHash::hash(cardList.join(";").toUtf8(), QCryptographicHash::Sha1);
|
||||||
|
quint64 number = (((quint64) (unsigned char) deckHashArray[0]) << 32)
|
||||||
|
+ (((quint64) (unsigned char) deckHashArray[1]) << 24)
|
||||||
|
+ (((quint64) (unsigned char) deckHashArray[2] << 16))
|
||||||
|
+ (((quint64) (unsigned char) deckHashArray[3]) << 8)
|
||||||
|
+ (quint64) (unsigned char) deckHashArray[4];
|
||||||
|
deckHash = QString::number(number, 32).rightJustified(8, '0');
|
||||||
|
|
||||||
emit deckHashChanged();
|
emit deckHashChanged();
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,22 +12,24 @@ CardToMove::CardToMove(int _cardId, bool _faceDown, const QString &_pt, bool _ta
|
||||||
insertItem(new SerializableItem_Bool("tapped", _tapped));
|
insertItem(new SerializableItem_Bool("tapped", _tapped));
|
||||||
}
|
}
|
||||||
|
|
||||||
ServerInfo_User::ServerInfo_User(const QString &_name, int _userLevel, const QString &_realName, Gender _gender, const QString &_country, const QByteArray &_avatarBmp)
|
ServerInfo_User::ServerInfo_User(const QString &_name, int _userLevel, const QString &_address, const QString &_realName, Gender _gender, const QString &_country, const QByteArray &_avatarBmp)
|
||||||
: SerializableItem_Map("user")
|
: SerializableItem_Map("user")
|
||||||
{
|
{
|
||||||
insertItem(new SerializableItem_String("name", _name));
|
insertItem(new SerializableItem_String("name", _name));
|
||||||
insertItem(new SerializableItem_Int("userlevel", _userLevel));
|
insertItem(new SerializableItem_Int("userlevel", _userLevel));
|
||||||
|
insertItem(new SerializableItem_String("address", _address));
|
||||||
insertItem(new SerializableItem_String("real_name", _realName));
|
insertItem(new SerializableItem_String("real_name", _realName));
|
||||||
insertItem(new SerializableItem_Int("gender", _gender));
|
insertItem(new SerializableItem_Int("gender", _gender));
|
||||||
insertItem(new SerializableItem_String("country", _country));
|
insertItem(new SerializableItem_String("country", _country));
|
||||||
insertItem(new SerializableItem_ByteArray("avatar_bmp", _avatarBmp));
|
insertItem(new SerializableItem_ByteArray("avatar_bmp", _avatarBmp));
|
||||||
}
|
}
|
||||||
|
|
||||||
ServerInfo_User::ServerInfo_User(const ServerInfo_User *other, bool complete)
|
ServerInfo_User::ServerInfo_User(const ServerInfo_User *other, bool complete, bool moderatorInfo)
|
||||||
: SerializableItem_Map("user")
|
: SerializableItem_Map("user")
|
||||||
{
|
{
|
||||||
insertItem(new SerializableItem_String("name", other->getName()));
|
insertItem(new SerializableItem_String("name", other->getName()));
|
||||||
insertItem(new SerializableItem_Int("userlevel", other->getUserLevel()));
|
insertItem(new SerializableItem_Int("userlevel", other->getUserLevel()));
|
||||||
|
insertItem(new SerializableItem_String("address", moderatorInfo ? other->getAddress() : QString()));
|
||||||
insertItem(new SerializableItem_String("real_name", other->getRealName()));
|
insertItem(new SerializableItem_String("real_name", other->getRealName()));
|
||||||
insertItem(new SerializableItem_Int("gender", other->getGender()));
|
insertItem(new SerializableItem_Int("gender", other->getGender()));
|
||||||
insertItem(new SerializableItem_String("country", other->getCountry()));
|
insertItem(new SerializableItem_String("country", other->getCountry()));
|
||||||
|
|
|
@ -50,13 +50,15 @@ public:
|
||||||
Male = 0,
|
Male = 0,
|
||||||
Female = 1
|
Female = 1
|
||||||
};
|
};
|
||||||
ServerInfo_User(const QString &_name = QString(), int _userLevel = IsNothing, const QString &_realName = QString(), Gender _gender = GenderUnknown, const QString &_country = QString(), const QByteArray &_avatarBmp = QByteArray());
|
ServerInfo_User(const QString &_name = QString(), int _userLevel = IsNothing, const QString &_address = QString(), const QString &_realName = QString(), Gender _gender = GenderUnknown, const QString &_country = QString(), const QByteArray &_avatarBmp = QByteArray());
|
||||||
ServerInfo_User(const ServerInfo_User *other, bool complete = true);
|
ServerInfo_User(const ServerInfo_User *other, bool complete = true, bool moderatorInfo = false);
|
||||||
static SerializableItem *newItem() { return new ServerInfo_User; }
|
static SerializableItem *newItem() { return new ServerInfo_User; }
|
||||||
QString getName() const { return static_cast<SerializableItem_String *>(itemMap.value("name"))->getData(); }
|
QString getName() const { return static_cast<SerializableItem_String *>(itemMap.value("name"))->getData(); }
|
||||||
void setName(const QString &_name) { static_cast<SerializableItem_String *>(itemMap.value("name"))->setData(_name); }
|
void setName(const QString &_name) { static_cast<SerializableItem_String *>(itemMap.value("name"))->setData(_name); }
|
||||||
int getUserLevel() const { return static_cast<SerializableItem_Int *>(itemMap.value("userlevel"))->getData(); }
|
int getUserLevel() const { return static_cast<SerializableItem_Int *>(itemMap.value("userlevel"))->getData(); }
|
||||||
void setUserLevel(int _userLevel) { static_cast<SerializableItem_Int *>(itemMap.value("userlevel"))->setData(_userLevel); }
|
void setUserLevel(int _userLevel) { static_cast<SerializableItem_Int *>(itemMap.value("userlevel"))->setData(_userLevel); }
|
||||||
|
QString getAddress() const { return static_cast<SerializableItem_String *>(itemMap.value("address"))->getData(); }
|
||||||
|
void setAddress(const QString &_address) { static_cast<SerializableItem_String *>(itemMap.value("address"))->setData(_address); }
|
||||||
QString getRealName() const { return static_cast<SerializableItem_String *>(itemMap.value("real_name"))->getData(); }
|
QString getRealName() const { return static_cast<SerializableItem_String *>(itemMap.value("real_name"))->getData(); }
|
||||||
Gender getGender() const { return static_cast<Gender>(static_cast<SerializableItem_Int *>(itemMap.value("gender"))->getData()); }
|
Gender getGender() const { return static_cast<Gender>(static_cast<SerializableItem_Int *>(itemMap.value("gender"))->getData()); }
|
||||||
QString getCountry() const { return static_cast<SerializableItem_String *>(itemMap.value("country"))->getData(); }
|
QString getCountry() const { return static_cast<SerializableItem_String *>(itemMap.value("country"))->getData(); }
|
||||||
|
|
|
@ -489,10 +489,11 @@ Command_ShutdownServer::Command_ShutdownServer(const QString &_reason, int _minu
|
||||||
insertItem(new SerializableItem_String("reason", _reason));
|
insertItem(new SerializableItem_String("reason", _reason));
|
||||||
insertItem(new SerializableItem_Int("minutes", _minutes));
|
insertItem(new SerializableItem_Int("minutes", _minutes));
|
||||||
}
|
}
|
||||||
Command_BanFromServer::Command_BanFromServer(const QString &_userName, int _minutes, const QString &_reason)
|
Command_BanFromServer::Command_BanFromServer(const QString &_userName, const QString &_address, int _minutes, const QString &_reason)
|
||||||
: ModeratorCommand("ban_from_server")
|
: ModeratorCommand("ban_from_server")
|
||||||
{
|
{
|
||||||
insertItem(new SerializableItem_String("user_name", _userName));
|
insertItem(new SerializableItem_String("user_name", _userName));
|
||||||
|
insertItem(new SerializableItem_String("address", _address));
|
||||||
insertItem(new SerializableItem_Int("minutes", _minutes));
|
insertItem(new SerializableItem_Int("minutes", _minutes));
|
||||||
insertItem(new SerializableItem_String("reason", _reason));
|
insertItem(new SerializableItem_String("reason", _reason));
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,4 +81,4 @@
|
||||||
6:mulligan:i,number
|
6:mulligan:i,number
|
||||||
7:update_server_message
|
7:update_server_message
|
||||||
7:shutdown_server:s,reason:i,minutes
|
7:shutdown_server:s,reason:i,minutes
|
||||||
8:ban_from_server:s,user_name:i,minutes:s,reason
|
8:ban_from_server:s,user_name:s,address:i,minutes:s,reason
|
|
@ -743,8 +743,9 @@ public:
|
||||||
class Command_BanFromServer : public ModeratorCommand {
|
class Command_BanFromServer : public ModeratorCommand {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
Command_BanFromServer(const QString &_userName = QString(), int _minutes = -1, const QString &_reason = QString());
|
Command_BanFromServer(const QString &_userName = QString(), const QString &_address = QString(), int _minutes = -1, const QString &_reason = QString());
|
||||||
QString getUserName() const { return static_cast<SerializableItem_String *>(itemMap.value("user_name"))->getData(); };
|
QString getUserName() const { return static_cast<SerializableItem_String *>(itemMap.value("user_name"))->getData(); };
|
||||||
|
QString getAddress() const { return static_cast<SerializableItem_String *>(itemMap.value("address"))->getData(); };
|
||||||
int getMinutes() const { return static_cast<SerializableItem_Int *>(itemMap.value("minutes"))->getData(); };
|
int getMinutes() const { return static_cast<SerializableItem_Int *>(itemMap.value("minutes"))->getData(); };
|
||||||
QString getReason() const { return static_cast<SerializableItem_String *>(itemMap.value("reason"))->getData(); };
|
QString getReason() const { return static_cast<SerializableItem_String *>(itemMap.value("reason"))->getData(); };
|
||||||
static SerializableItem *newItem() { return new Command_BanFromServer; }
|
static SerializableItem *newItem() { return new Command_BanFromServer; }
|
||||||
|
|
|
@ -57,6 +57,7 @@ AuthenticationResult Server::loginUser(Server_ProtocolHandler *session, QString
|
||||||
return authState;
|
return authState;
|
||||||
|
|
||||||
ServerInfo_User *data = getUserData(name);
|
ServerInfo_User *data = getUserData(name);
|
||||||
|
data->setAddress(session->getAddress());
|
||||||
name = data->getName(); // Compensate for case indifference
|
name = data->getName(); // Compensate for case indifference
|
||||||
|
|
||||||
if (authState == PasswordRight) {
|
if (authState == PasswordRight) {
|
||||||
|
|
|
@ -402,7 +402,7 @@ ResponseCode Server_ProtocolHandler::cmdGetUserInfo(Command_GetUserInfo *cmd, Co
|
||||||
Server_ProtocolHandler *handler = server->getUsers().value(cmd->getUserName());
|
Server_ProtocolHandler *handler = server->getUsers().value(cmd->getUserName());
|
||||||
if (!handler)
|
if (!handler)
|
||||||
return RespNameNotFound;
|
return RespNameNotFound;
|
||||||
result = new ServerInfo_User(handler->getUserInfo());
|
result = new ServerInfo_User(handler->getUserInfo(), true, userInfo->getUserLevel() & ServerInfo_User::IsModerator);
|
||||||
}
|
}
|
||||||
|
|
||||||
cont->setResponse(new Response_GetUserInfo(cont->getCmdId(), RespOk, result));
|
cont->setResponse(new Response_GetUserInfo(cont->getCmdId(), RespOk, result));
|
||||||
|
|
|
@ -106,6 +106,7 @@ public:
|
||||||
bool getAcceptsUserListChanges() const { return acceptsUserListChanges; }
|
bool getAcceptsUserListChanges() const { return acceptsUserListChanges; }
|
||||||
bool getAcceptsRoomListChanges() const { return acceptsRoomListChanges; }
|
bool getAcceptsRoomListChanges() const { return acceptsRoomListChanges; }
|
||||||
ServerInfo_User *getUserInfo() const { return userInfo; }
|
ServerInfo_User *getUserInfo() const { return userInfo; }
|
||||||
|
virtual QString getAddress() const = 0;
|
||||||
void setUserInfo(ServerInfo_User *_userInfo) { userInfo = _userInfo; }
|
void setUserInfo(ServerInfo_User *_userInfo) { userInfo = _userInfo; }
|
||||||
const QMap<QString, ServerInfo_User *> &getBuddyList() const { return buddyList; }
|
const QMap<QString, ServerInfo_User *> &getBuddyList() const { return buddyList; }
|
||||||
const QMap<QString, ServerInfo_User *> &getIgnoreList() const { return ignoreList; }
|
const QMap<QString, ServerInfo_User *> &getIgnoreList() const { return ignoreList; }
|
||||||
|
|
|
@ -105,7 +105,7 @@ CREATE TABLE IF NOT EXISTS `cockatrice_users` (
|
||||||
`name` varchar(35) NOT NULL,
|
`name` varchar(35) NOT NULL,
|
||||||
`realname` varchar(255) NOT NULL,
|
`realname` varchar(255) NOT NULL,
|
||||||
`gender` char(1) NOT NULL,
|
`gender` char(1) NOT NULL,
|
||||||
`password` varchar(255) NOT NULL,
|
`password_sha512` char(120) NOT NULL,
|
||||||
`email` varchar(255) NOT NULL,
|
`email` varchar(255) NOT NULL,
|
||||||
`country` char(2) NOT NULL,
|
`country` char(2) NOT NULL,
|
||||||
`avatar_bmp` blob NOT NULL,
|
`avatar_bmp` blob NOT NULL,
|
||||||
|
@ -149,7 +149,8 @@ CREATE TABLE `cockatrice_buddylist` (
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
CREATE TABLE `cockatrice_bans` (
|
CREATE TABLE `cockatrice_bans` (
|
||||||
`id_user` int(7) unsigned zerofill NOT NULL,
|
`user_name` varchar(255) unsigned zerofill NOT NULL,
|
||||||
|
`ip_address` varchar(255) NOT NULL,
|
||||||
`id_admin` int(7) unsigned zerofill NOT NULL,
|
`id_admin` int(7) unsigned zerofill NOT NULL,
|
||||||
`time_from` datetime NOT NULL,
|
`time_from` datetime NOT NULL,
|
||||||
`minutes` int(6) NOT NULL,
|
`minutes` int(6) NOT NULL,
|
||||||
|
|
|
@ -50,10 +50,6 @@ Servatrice::Servatrice(QSettings *_settings, QObject *parent)
|
||||||
connect(pingClock, SIGNAL(timeout()), this, SIGNAL(pingClockTimeout()));
|
connect(pingClock, SIGNAL(timeout()), this, SIGNAL(pingClockTimeout()));
|
||||||
pingClock->start(1000);
|
pingClock->start(1000);
|
||||||
|
|
||||||
banTimeoutClock = new QTimer(this);
|
|
||||||
connect(banTimeoutClock, SIGNAL(timeout()), this, SLOT(updateBanTimer()));
|
|
||||||
banTimeoutClock->start(60000);
|
|
||||||
|
|
||||||
ProtocolItem::initializeHash();
|
ProtocolItem::initializeHash();
|
||||||
|
|
||||||
serverId = settings->value("server/id", 0).toInt();
|
serverId = settings->value("server/id", 0).toInt();
|
||||||
|
@ -171,13 +167,6 @@ bool Servatrice::execSqlQuery(QSqlQuery &query)
|
||||||
|
|
||||||
AuthenticationResult Servatrice::checkUserPassword(Server_ProtocolHandler *handler, const QString &user, const QString &password)
|
AuthenticationResult Servatrice::checkUserPassword(Server_ProtocolHandler *handler, const QString &user, const QString &password)
|
||||||
{
|
{
|
||||||
serverMutex.lock();
|
|
||||||
QHostAddress address = static_cast<ServerSocketInterface *>(handler)->getPeerAddress();
|
|
||||||
for (int i = 0; i < addressBanList.size(); ++i)
|
|
||||||
if (address == addressBanList[i].first)
|
|
||||||
return PasswordWrong;
|
|
||||||
serverMutex.unlock();
|
|
||||||
|
|
||||||
QMutexLocker locker(&dbMutex);
|
QMutexLocker locker(&dbMutex);
|
||||||
const QString method = settings->value("authentication/method").toString();
|
const QString method = settings->value("authentication/method").toString();
|
||||||
if (method == "none")
|
if (method == "none")
|
||||||
|
@ -185,8 +174,23 @@ AuthenticationResult Servatrice::checkUserPassword(Server_ProtocolHandler *handl
|
||||||
else if (method == "sql") {
|
else if (method == "sql") {
|
||||||
checkSql();
|
checkSql();
|
||||||
|
|
||||||
|
QSqlQuery ipBanQuery;
|
||||||
|
ipBanQuery.prepare("select time_to_sec(timediff(now(), date_add(b.time_from, interval b.minutes minute))) < 0, b.minutes <=> 0 from " + dbPrefix + "_bans b where b.time_from = (select max(c.time_from) from " + dbPrefix + "_bans c where c.ip_address = :address) and b.ip_address = :address2");
|
||||||
|
ipBanQuery.bindValue(":address", static_cast<ServerSocketInterface *>(handler)->getPeerAddress().toString());
|
||||||
|
ipBanQuery.bindValue(":address2", static_cast<ServerSocketInterface *>(handler)->getPeerAddress().toString());
|
||||||
|
if (!execSqlQuery(ipBanQuery)) {
|
||||||
|
qDebug("Login denied: SQL error");
|
||||||
|
return PasswordWrong;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ipBanQuery.next())
|
||||||
|
if (ipBanQuery.value(0).toInt() || ipBanQuery.value(1).toInt()) {
|
||||||
|
qDebug("Login denied: banned by address");
|
||||||
|
return PasswordWrong;
|
||||||
|
}
|
||||||
|
|
||||||
QSqlQuery query;
|
QSqlQuery query;
|
||||||
query.prepare("select a.password_sha512, time_to_sec(timediff(now(), date_add(b.time_from, interval b.minutes minute))) < 0, b.minutes <=> 0 from " + dbPrefix + "_users a left join " + dbPrefix + "_bans b on b.id_user = a.id and b.time_from = (select max(c.time_from) from " + dbPrefix + "_bans c where c.id_user = a.id) where a.name = :name and a.active = 1");
|
query.prepare("select a.password_sha512, time_to_sec(timediff(now(), date_add(b.time_from, interval b.minutes minute))) < 0, b.minutes <=> 0 from " + dbPrefix + "_users a left join " + dbPrefix + "_bans b on b.user_name = a.name and b.time_from = (select max(c.time_from) from " + dbPrefix + "_bans c where c.user_name = a.name) where a.name = :name and a.active = 1");
|
||||||
query.bindValue(":name", user);
|
query.bindValue(":name", user);
|
||||||
if (!execSqlQuery(query)) {
|
if (!execSqlQuery(query)) {
|
||||||
qDebug("Login denied: SQL error");
|
qDebug("Login denied: SQL error");
|
||||||
|
@ -195,7 +199,7 @@ AuthenticationResult Servatrice::checkUserPassword(Server_ProtocolHandler *handl
|
||||||
|
|
||||||
if (query.next()) {
|
if (query.next()) {
|
||||||
if (query.value(1).toInt() || query.value(2).toInt()) {
|
if (query.value(1).toInt() || query.value(2).toInt()) {
|
||||||
qDebug("Login denied: banned");
|
qDebug("Login denied: banned by name");
|
||||||
return PasswordWrong;
|
return PasswordWrong;
|
||||||
}
|
}
|
||||||
if (query.value(0).toString() == PasswordHasher::computeHash(password, query.value(0).toString().left(16))) {
|
if (query.value(0).toString() == PasswordHasher::computeHash(password, query.value(0).toString().left(16))) {
|
||||||
|
@ -257,6 +261,7 @@ ServerInfo_User *Servatrice::evalUserQueryResult(const QSqlQuery &query, bool co
|
||||||
return new ServerInfo_User(
|
return new ServerInfo_User(
|
||||||
name,
|
name,
|
||||||
userLevel,
|
userLevel,
|
||||||
|
QString(),
|
||||||
realName,
|
realName,
|
||||||
gender,
|
gender,
|
||||||
country,
|
country,
|
||||||
|
@ -341,16 +346,6 @@ QMap<QString, ServerInfo_User *> Servatrice::getIgnoreList(const QString &name)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Servatrice::updateBanTimer()
|
|
||||||
{
|
|
||||||
QMutexLocker locker(&serverMutex);
|
|
||||||
for (int i = 0; i < addressBanList.size(); )
|
|
||||||
if (--(addressBanList[i].second) <= 0)
|
|
||||||
addressBanList.removeAt(i);
|
|
||||||
else
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Servatrice::updateLoginMessage()
|
void Servatrice::updateLoginMessage()
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&dbMutex);
|
QMutexLocker locker(&dbMutex);
|
||||||
|
@ -424,4 +419,4 @@ void Servatrice::shutdownTimeout()
|
||||||
deleteLater();
|
deleteLater();
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString Servatrice::versionString = "Servatrice 0.20111004";
|
const QString Servatrice::versionString = "Servatrice 0.20111101";
|
||||||
|
|
|
@ -49,7 +49,6 @@ class Servatrice : public Server
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
private slots:
|
private slots:
|
||||||
void statusUpdate();
|
void statusUpdate();
|
||||||
void updateBanTimer();
|
|
||||||
void shutdownTimeout();
|
void shutdownTimeout();
|
||||||
public:
|
public:
|
||||||
QMutex dbMutex;
|
QMutex dbMutex;
|
||||||
|
@ -75,13 +74,12 @@ public:
|
||||||
int getUsersWithAddress(const QHostAddress &address) const;
|
int getUsersWithAddress(const QHostAddress &address) const;
|
||||||
QMap<QString, ServerInfo_User *> getBuddyList(const QString &name);
|
QMap<QString, ServerInfo_User *> getBuddyList(const QString &name);
|
||||||
QMap<QString, ServerInfo_User *> getIgnoreList(const QString &name);
|
QMap<QString, ServerInfo_User *> getIgnoreList(const QString &name);
|
||||||
void addAddressBan(const QHostAddress &address, int minutes) { addressBanList.append(QPair<QHostAddress, int>(address, minutes)); }
|
|
||||||
void scheduleShutdown(const QString &reason, int minutes);
|
void scheduleShutdown(const QString &reason, int minutes);
|
||||||
protected:
|
protected:
|
||||||
bool userExists(const QString &user);
|
bool userExists(const QString &user);
|
||||||
AuthenticationResult checkUserPassword(Server_ProtocolHandler *handler, const QString &user, const QString &password);
|
AuthenticationResult checkUserPassword(Server_ProtocolHandler *handler, const QString &user, const QString &password);
|
||||||
private:
|
private:
|
||||||
QTimer *pingClock, *statusUpdateClock, *banTimeoutClock;
|
QTimer *pingClock, *statusUpdateClock;
|
||||||
QTcpServer *tcpServer;
|
QTcpServer *tcpServer;
|
||||||
QString loginMessage;
|
QString loginMessage;
|
||||||
QString dbPrefix;
|
QString dbPrefix;
|
||||||
|
@ -89,7 +87,6 @@ private:
|
||||||
int serverId;
|
int serverId;
|
||||||
bool threaded;
|
bool threaded;
|
||||||
int uptime;
|
int uptime;
|
||||||
QList<QPair<QHostAddress, int> > addressBanList;
|
|
||||||
int maxGameInactivityTime, maxPlayerInactivityTime;
|
int maxGameInactivityTime, maxPlayerInactivityTime;
|
||||||
int maxUsersPerAddress, messageCountingInterval, maxMessageCountPerInterval, maxMessageSizePerInterval, maxGamesPerUser;
|
int maxUsersPerAddress, messageCountingInterval, maxMessageCountPerInterval, maxMessageSizePerInterval, maxGamesPerUser;
|
||||||
ServerInfo_User *evalUserQueryResult(const QSqlQuery &query, bool complete);
|
ServerInfo_User *evalUserQueryResult(const QSqlQuery &query, bool complete);
|
||||||
|
|
|
@ -464,50 +464,43 @@ ResponseCode ServerSocketInterface::cmdDeckDownload(Command_DeckDownload *cmd, C
|
||||||
// MODERATOR FUNCTIONS.
|
// MODERATOR FUNCTIONS.
|
||||||
// May be called by admins and moderators. Permission is checked by the calling function.
|
// May be called by admins and moderators. Permission is checked by the calling function.
|
||||||
|
|
||||||
ResponseCode ServerSocketInterface::cmdUpdateServerMessage(Command_UpdateServerMessage * /*cmd*/, CommandContainer * /*cont*/)
|
ResponseCode ServerSocketInterface::cmdBanFromServer(Command_BanFromServer *cmd, CommandContainer * /*cont*/)
|
||||||
{
|
{
|
||||||
servatrice->updateLoginMessage();
|
QString userName = cmd->getUserName();
|
||||||
|
QString address = cmd->getAddress();
|
||||||
|
int minutes = cmd->getMinutes();
|
||||||
|
|
||||||
|
servatrice->dbMutex.lock();
|
||||||
|
QSqlQuery query;
|
||||||
|
query.prepare("insert into " + servatrice->getDbPrefix() + "_bans (user_name, ip_address, id_admin, time_from, minutes, reason) values(:user_name, :ip_address, :id_admin, NOW(), :minutes, :reason)");
|
||||||
|
query.bindValue(":user_name", userName);
|
||||||
|
query.bindValue(":ip_address", address);
|
||||||
|
query.bindValue(":id_admin", getUserIdInDB(userInfo->getName()));
|
||||||
|
query.bindValue(":minutes", minutes);
|
||||||
|
query.bindValue(":reason", cmd->getReason() + "\n");
|
||||||
|
servatrice->execSqlQuery(query);
|
||||||
|
servatrice->dbMutex.unlock();
|
||||||
|
|
||||||
|
ServerSocketInterface *user = static_cast<ServerSocketInterface *>(server->getUsers().value(userName));
|
||||||
|
if (user) {
|
||||||
|
user->sendProtocolItem(new Event_ConnectionClosed("banned"));
|
||||||
|
user->deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
return RespOk;
|
return RespOk;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ADMIN FUNCTIONS.
|
// ADMIN FUNCTIONS.
|
||||||
// Permission is checked by the calling function.
|
// Permission is checked by the calling function.
|
||||||
|
|
||||||
|
ResponseCode ServerSocketInterface::cmdUpdateServerMessage(Command_UpdateServerMessage * /*cmd*/, CommandContainer * /*cont*/)
|
||||||
|
{
|
||||||
|
servatrice->updateLoginMessage();
|
||||||
|
return RespOk;
|
||||||
|
}
|
||||||
|
|
||||||
ResponseCode ServerSocketInterface::cmdShutdownServer(Command_ShutdownServer *cmd, CommandContainer * /*cont*/)
|
ResponseCode ServerSocketInterface::cmdShutdownServer(Command_ShutdownServer *cmd, CommandContainer * /*cont*/)
|
||||||
{
|
{
|
||||||
servatrice->scheduleShutdown(cmd->getReason(), cmd->getMinutes());
|
servatrice->scheduleShutdown(cmd->getReason(), cmd->getMinutes());
|
||||||
return RespOk;
|
return RespOk;
|
||||||
}
|
}
|
||||||
|
|
||||||
ResponseCode ServerSocketInterface::cmdBanFromServer(Command_BanFromServer *cmd, CommandContainer * /*cont*/)
|
|
||||||
{
|
|
||||||
QString userName = cmd->getUserName();
|
|
||||||
if (!server->getUsers().contains(userName))
|
|
||||||
return RespNameNotFound;
|
|
||||||
|
|
||||||
int minutes = cmd->getMinutes();
|
|
||||||
|
|
||||||
ServerSocketInterface *user = static_cast<ServerSocketInterface *>(server->getUsers().value(userName));
|
|
||||||
if (user->getUserInfo()->getUserLevel() & ServerInfo_User::IsRegistered) {
|
|
||||||
// Registered users can be banned by name.
|
|
||||||
QMutexLocker locker(&servatrice->dbMutex);
|
|
||||||
QSqlQuery query;
|
|
||||||
query.prepare("insert into " + servatrice->getDbPrefix() + "_bans (id_user, id_admin, time_from, minutes, reason) values(:id_user, :id_admin, NOW(), :minutes, :reason)");
|
|
||||||
query.bindValue(":id_user", getUserIdInDB(userName));
|
|
||||||
query.bindValue(":id_admin", getUserIdInDB(userInfo->getName()));
|
|
||||||
query.bindValue(":minutes", minutes);
|
|
||||||
query.bindValue(":reason", cmd->getReason() + "\n");
|
|
||||||
servatrice->execSqlQuery(query);
|
|
||||||
} else {
|
|
||||||
// Unregistered users must be banned by IP address.
|
|
||||||
// Indefinite address bans are not reasonable -> default to 30 minutes.
|
|
||||||
if (minutes == 0)
|
|
||||||
minutes = 30;
|
|
||||||
servatrice->addAddressBan(user->getPeerAddress(), minutes);
|
|
||||||
}
|
|
||||||
|
|
||||||
user->sendProtocolItem(new Event_ConnectionClosed("banned"));
|
|
||||||
user->deleteLater();
|
|
||||||
|
|
||||||
return RespOk;
|
|
||||||
}
|
|
||||||
|
|
|
@ -76,6 +76,7 @@ public:
|
||||||
ServerSocketInterface(Servatrice *_server, QTcpSocket *_socket, QObject *parent = 0);
|
ServerSocketInterface(Servatrice *_server, QTcpSocket *_socket, QObject *parent = 0);
|
||||||
~ServerSocketInterface();
|
~ServerSocketInterface();
|
||||||
QHostAddress getPeerAddress() const { return socket->peerAddress(); }
|
QHostAddress getPeerAddress() const { return socket->peerAddress(); }
|
||||||
|
QString getAddress() const { return socket->peerAddress().toString(); }
|
||||||
|
|
||||||
void sendProtocolItem(ProtocolItem *item, bool deleteItem = true);
|
void sendProtocolItem(ProtocolItem *item, bool deleteItem = true);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue