mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-06-19 05:13:54 -07:00
Clang-format (#3028)
* 1/3 Add .clang-format file and travis compilation check * 2/3 Run clang-format * 3/3 Fix compilation problems due to include reordering * 3bis/3 AfterControlStatement: false
This commit is contained in:
parent
8dbdd24c8e
commit
b29bd9e070
272 changed files with 13378 additions and 9535 deletions
|
|
@ -1,415 +1,447 @@
|
|||
#include "isl_interface.h"
|
||||
#include <QSslSocket>
|
||||
#include "server_logger.h"
|
||||
#include "main.h"
|
||||
#include "server_logger.h"
|
||||
#include "server_protocolhandler.h"
|
||||
#include "server_room.h"
|
||||
#include <QSslSocket>
|
||||
|
||||
#include "get_pb_extension.h"
|
||||
#include "pb/isl_message.pb.h"
|
||||
#include "pb/event_game_joined.pb.h"
|
||||
#include "pb/event_server_complete_list.pb.h"
|
||||
#include "pb/event_user_message.pb.h"
|
||||
#include "pb/event_user_joined.pb.h"
|
||||
#include "pb/event_user_left.pb.h"
|
||||
#include "pb/event_join_room.pb.h"
|
||||
#include "pb/event_leave_room.pb.h"
|
||||
#include "pb/event_room_say.pb.h"
|
||||
#include "pb/event_list_games.pb.h"
|
||||
#include "pb/event_room_say.pb.h"
|
||||
#include "pb/event_server_complete_list.pb.h"
|
||||
#include "pb/event_user_joined.pb.h"
|
||||
#include "pb/event_user_left.pb.h"
|
||||
#include "pb/event_user_message.pb.h"
|
||||
#include "pb/isl_message.pb.h"
|
||||
#include <google/protobuf/descriptor.h>
|
||||
|
||||
void IslInterface::sharedCtor(const QSslCertificate &cert, const QSslKey &privateKey)
|
||||
{
|
||||
socket = new QSslSocket(this);
|
||||
socket->setLocalCertificate(cert);
|
||||
socket->setPrivateKey(privateKey);
|
||||
|
||||
connect(socket, SIGNAL(readyRead()), this, SLOT(readClient()), Qt::QueuedConnection);
|
||||
connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(catchSocketError(QAbstractSocket::SocketError)));
|
||||
connect(this, SIGNAL(outputBufferChanged()), this, SLOT(flushOutputBuffer()), Qt::QueuedConnection);
|
||||
socket = new QSslSocket(this);
|
||||
socket->setLocalCertificate(cert);
|
||||
socket->setPrivateKey(privateKey);
|
||||
|
||||
connect(socket, SIGNAL(readyRead()), this, SLOT(readClient()), Qt::QueuedConnection);
|
||||
connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this,
|
||||
SLOT(catchSocketError(QAbstractSocket::SocketError)));
|
||||
connect(this, SIGNAL(outputBufferChanged()), this, SLOT(flushOutputBuffer()), Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
IslInterface::IslInterface(int _socketDescriptor, const QSslCertificate &cert, const QSslKey &privateKey, Servatrice *_server)
|
||||
: QObject(), socketDescriptor(_socketDescriptor), server(_server), messageInProgress(false)
|
||||
IslInterface::IslInterface(int _socketDescriptor,
|
||||
const QSslCertificate &cert,
|
||||
const QSslKey &privateKey,
|
||||
Servatrice *_server)
|
||||
: QObject(), socketDescriptor(_socketDescriptor), server(_server), messageInProgress(false)
|
||||
{
|
||||
sharedCtor(cert, privateKey);
|
||||
sharedCtor(cert, privateKey);
|
||||
}
|
||||
|
||||
IslInterface::IslInterface(int _serverId, const QString &_peerHostName, const QString &_peerAddress, int _peerPort, const QSslCertificate &_peerCert, const QSslCertificate &cert, const QSslKey &privateKey, Servatrice *_server)
|
||||
: QObject(), serverId(_serverId), peerHostName(_peerHostName), peerAddress(_peerAddress), peerPort(_peerPort), peerCert(_peerCert), server(_server), messageInProgress(false)
|
||||
IslInterface::IslInterface(int _serverId,
|
||||
const QString &_peerHostName,
|
||||
const QString &_peerAddress,
|
||||
int _peerPort,
|
||||
const QSslCertificate &_peerCert,
|
||||
const QSslCertificate &cert,
|
||||
const QSslKey &privateKey,
|
||||
Servatrice *_server)
|
||||
: QObject(), serverId(_serverId), peerHostName(_peerHostName), peerAddress(_peerAddress), peerPort(_peerPort),
|
||||
peerCert(_peerCert), server(_server), messageInProgress(false)
|
||||
{
|
||||
sharedCtor(cert, privateKey);
|
||||
sharedCtor(cert, privateKey);
|
||||
}
|
||||
|
||||
IslInterface::~IslInterface()
|
||||
{
|
||||
logger->logMessage("[ISL] session ended", this);
|
||||
|
||||
flushOutputBuffer();
|
||||
|
||||
// As these signals are connected with Qt::QueuedConnection implicitly,
|
||||
// we don't need to worry about them modifying the lists while we're iterating.
|
||||
|
||||
server->roomsLock.lockForRead();
|
||||
QMapIterator<int, Server_Room *> roomIterator(server->getRooms());
|
||||
while (roomIterator.hasNext()) {
|
||||
Server_Room *room = roomIterator.next().value();
|
||||
room->usersLock.lockForRead();
|
||||
QMapIterator<QString, ServerInfo_User_Container> roomUsers(room->getExternalUsers());
|
||||
while (roomUsers.hasNext()) {
|
||||
roomUsers.next();
|
||||
if (roomUsers.value().getUserInfo()->server_id() == serverId)
|
||||
emit externalRoomUserLeft(room->getId(), roomUsers.key());
|
||||
}
|
||||
room->usersLock.unlock();
|
||||
}
|
||||
server->roomsLock.unlock();
|
||||
|
||||
server->clientsLock.lockForRead();
|
||||
QMapIterator<QString, Server_AbstractUserInterface *> extUsers(server->getExternalUsers());
|
||||
while (extUsers.hasNext()) {
|
||||
extUsers.next();
|
||||
if (extUsers.value()->getUserInfo()->server_id() == serverId)
|
||||
emit externalUserLeft(extUsers.key());
|
||||
}
|
||||
server->clientsLock.unlock();
|
||||
logger->logMessage("[ISL] session ended", this);
|
||||
|
||||
flushOutputBuffer();
|
||||
|
||||
// As these signals are connected with Qt::QueuedConnection implicitly,
|
||||
// we don't need to worry about them modifying the lists while we're iterating.
|
||||
|
||||
server->roomsLock.lockForRead();
|
||||
QMapIterator<int, Server_Room *> roomIterator(server->getRooms());
|
||||
while (roomIterator.hasNext()) {
|
||||
Server_Room *room = roomIterator.next().value();
|
||||
room->usersLock.lockForRead();
|
||||
QMapIterator<QString, ServerInfo_User_Container> roomUsers(room->getExternalUsers());
|
||||
while (roomUsers.hasNext()) {
|
||||
roomUsers.next();
|
||||
if (roomUsers.value().getUserInfo()->server_id() == serverId)
|
||||
emit externalRoomUserLeft(room->getId(), roomUsers.key());
|
||||
}
|
||||
room->usersLock.unlock();
|
||||
}
|
||||
server->roomsLock.unlock();
|
||||
|
||||
server->clientsLock.lockForRead();
|
||||
QMapIterator<QString, Server_AbstractUserInterface *> extUsers(server->getExternalUsers());
|
||||
while (extUsers.hasNext()) {
|
||||
extUsers.next();
|
||||
if (extUsers.value()->getUserInfo()->server_id() == serverId)
|
||||
emit externalUserLeft(extUsers.key());
|
||||
}
|
||||
server->clientsLock.unlock();
|
||||
}
|
||||
|
||||
void IslInterface::initServer()
|
||||
{
|
||||
socket->setSocketDescriptor(socketDescriptor);
|
||||
|
||||
logger->logMessage(QString("[ISL] incoming connection: %1").arg(socket->peerAddress().toString()));
|
||||
|
||||
QList<ServerProperties> serverList = server->getServerList();
|
||||
int listIndex = -1;
|
||||
for (int i = 0; i < serverList.size(); ++i)
|
||||
if (serverList[i].address == socket->peerAddress()) {
|
||||
listIndex = i;
|
||||
break;
|
||||
}
|
||||
if (listIndex == -1) {
|
||||
logger->logMessage(QString("[ISL] address %1 unknown, terminating connection").arg(socket->peerAddress().toString()));
|
||||
deleteLater();
|
||||
return;
|
||||
}
|
||||
|
||||
socket->startServerEncryption();
|
||||
if (!socket->waitForEncrypted(5000)) {
|
||||
QList<QSslError> sslErrors(socket->sslErrors());
|
||||
if (sslErrors.isEmpty())
|
||||
qDebug() << "[ISL] SSL handshake timeout, terminating connection";
|
||||
else
|
||||
qDebug() << "[ISL] SSL errors:" << sslErrors;
|
||||
deleteLater();
|
||||
return;
|
||||
}
|
||||
|
||||
if (serverList[listIndex].cert == socket->peerCertificate())
|
||||
logger->logMessage(QString("[ISL] Peer authenticated as " + serverList[listIndex].hostname));
|
||||
else {
|
||||
logger->logMessage(QString("[ISL] Authentication failed, terminating connection"));
|
||||
deleteLater();
|
||||
return;
|
||||
}
|
||||
serverId = serverList[listIndex].id;
|
||||
|
||||
Event_ServerCompleteList event;
|
||||
event.set_server_id(server->getServerID());
|
||||
|
||||
server->clientsLock.lockForRead();
|
||||
QMapIterator<QString, Server_ProtocolHandler *> userIterator(server->getUsers());
|
||||
while (userIterator.hasNext())
|
||||
event.add_user_list()->CopyFrom(userIterator.next().value()->copyUserInfo(true, true));
|
||||
server->clientsLock.unlock();
|
||||
|
||||
server->roomsLock.lockForRead();
|
||||
QMapIterator<int, Server_Room *> roomIterator(server->getRooms());
|
||||
while (roomIterator.hasNext()) {
|
||||
Server_Room *room = roomIterator.next().value();
|
||||
room->usersLock.lockForRead();
|
||||
room->gamesLock.lockForRead();
|
||||
room->getInfo(*event.add_room_list(), true, true, false);
|
||||
}
|
||||
|
||||
IslMessage message;
|
||||
message.set_message_type(IslMessage::SESSION_EVENT);
|
||||
SessionEvent *sessionEvent = message.mutable_session_event();
|
||||
sessionEvent->GetReflection()->MutableMessage(sessionEvent, event.GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(event);
|
||||
|
||||
server->islLock.lockForWrite();
|
||||
if (server->islConnectionExists(serverId)) {
|
||||
qDebug() << "[ISL] Duplicate connection to #" << serverId << "terminating connection";
|
||||
deleteLater();
|
||||
} else {
|
||||
transmitMessage(message);
|
||||
server->addIslInterface(serverId, this);
|
||||
}
|
||||
server->islLock.unlock();
|
||||
|
||||
roomIterator.toFront();
|
||||
while (roomIterator.hasNext()) {
|
||||
roomIterator.next();
|
||||
roomIterator.value()->gamesLock.unlock();
|
||||
roomIterator.value()->usersLock.unlock();
|
||||
}
|
||||
server->roomsLock.unlock();
|
||||
socket->setSocketDescriptor(socketDescriptor);
|
||||
|
||||
logger->logMessage(QString("[ISL] incoming connection: %1").arg(socket->peerAddress().toString()));
|
||||
|
||||
QList<ServerProperties> serverList = server->getServerList();
|
||||
int listIndex = -1;
|
||||
for (int i = 0; i < serverList.size(); ++i)
|
||||
if (serverList[i].address == socket->peerAddress()) {
|
||||
listIndex = i;
|
||||
break;
|
||||
}
|
||||
if (listIndex == -1) {
|
||||
logger->logMessage(
|
||||
QString("[ISL] address %1 unknown, terminating connection").arg(socket->peerAddress().toString()));
|
||||
deleteLater();
|
||||
return;
|
||||
}
|
||||
|
||||
socket->startServerEncryption();
|
||||
if (!socket->waitForEncrypted(5000)) {
|
||||
QList<QSslError> sslErrors(socket->sslErrors());
|
||||
if (sslErrors.isEmpty())
|
||||
qDebug() << "[ISL] SSL handshake timeout, terminating connection";
|
||||
else
|
||||
qDebug() << "[ISL] SSL errors:" << sslErrors;
|
||||
deleteLater();
|
||||
return;
|
||||
}
|
||||
|
||||
if (serverList[listIndex].cert == socket->peerCertificate())
|
||||
logger->logMessage(QString("[ISL] Peer authenticated as " + serverList[listIndex].hostname));
|
||||
else {
|
||||
logger->logMessage(QString("[ISL] Authentication failed, terminating connection"));
|
||||
deleteLater();
|
||||
return;
|
||||
}
|
||||
serverId = serverList[listIndex].id;
|
||||
|
||||
Event_ServerCompleteList event;
|
||||
event.set_server_id(server->getServerID());
|
||||
|
||||
server->clientsLock.lockForRead();
|
||||
QMapIterator<QString, Server_ProtocolHandler *> userIterator(server->getUsers());
|
||||
while (userIterator.hasNext())
|
||||
event.add_user_list()->CopyFrom(userIterator.next().value()->copyUserInfo(true, true));
|
||||
server->clientsLock.unlock();
|
||||
|
||||
server->roomsLock.lockForRead();
|
||||
QMapIterator<int, Server_Room *> roomIterator(server->getRooms());
|
||||
while (roomIterator.hasNext()) {
|
||||
Server_Room *room = roomIterator.next().value();
|
||||
room->usersLock.lockForRead();
|
||||
room->gamesLock.lockForRead();
|
||||
room->getInfo(*event.add_room_list(), true, true, false);
|
||||
}
|
||||
|
||||
IslMessage message;
|
||||
message.set_message_type(IslMessage::SESSION_EVENT);
|
||||
SessionEvent *sessionEvent = message.mutable_session_event();
|
||||
sessionEvent->GetReflection()
|
||||
->MutableMessage(sessionEvent, event.GetDescriptor()->FindExtensionByName("ext"))
|
||||
->CopyFrom(event);
|
||||
|
||||
server->islLock.lockForWrite();
|
||||
if (server->islConnectionExists(serverId)) {
|
||||
qDebug() << "[ISL] Duplicate connection to #" << serverId << "terminating connection";
|
||||
deleteLater();
|
||||
} else {
|
||||
transmitMessage(message);
|
||||
server->addIslInterface(serverId, this);
|
||||
}
|
||||
server->islLock.unlock();
|
||||
|
||||
roomIterator.toFront();
|
||||
while (roomIterator.hasNext()) {
|
||||
roomIterator.next();
|
||||
roomIterator.value()->gamesLock.unlock();
|
||||
roomIterator.value()->usersLock.unlock();
|
||||
}
|
||||
server->roomsLock.unlock();
|
||||
}
|
||||
|
||||
void IslInterface::initClient()
|
||||
{
|
||||
QList<QSslError> expectedErrors;
|
||||
expectedErrors.append(QSslError(QSslError::SelfSignedCertificate, peerCert));
|
||||
socket->ignoreSslErrors(expectedErrors);
|
||||
|
||||
qDebug() << "[ISL] Connecting to #" << serverId << ":" << peerAddress << ":" << peerPort;
|
||||
QList<QSslError> expectedErrors;
|
||||
expectedErrors.append(QSslError(QSslError::SelfSignedCertificate, peerCert));
|
||||
socket->ignoreSslErrors(expectedErrors);
|
||||
|
||||
socket->connectToHostEncrypted(peerAddress, peerPort, peerHostName);
|
||||
if (!socket->waitForConnected(5000)) {
|
||||
qDebug() << "[ISL] Socket error:" << socket->errorString();
|
||||
deleteLater();
|
||||
return;
|
||||
}
|
||||
if (!socket->waitForEncrypted(5000)) {
|
||||
QList<QSslError> sslErrors(socket->sslErrors());
|
||||
if (sslErrors.isEmpty())
|
||||
qDebug() << "[ISL] SSL handshake timeout, terminating connection";
|
||||
else
|
||||
qDebug() << "[ISL] SSL errors:" << sslErrors;
|
||||
deleteLater();
|
||||
return;
|
||||
}
|
||||
|
||||
server->islLock.lockForWrite();
|
||||
if (server->islConnectionExists(serverId)) {
|
||||
qDebug() << "[ISL] Duplicate connection to #" << serverId << "terminating connection";
|
||||
deleteLater();
|
||||
return;
|
||||
}
|
||||
|
||||
server->addIslInterface(serverId, this);
|
||||
server->islLock.unlock();
|
||||
qDebug() << "[ISL] Connecting to #" << serverId << ":" << peerAddress << ":" << peerPort;
|
||||
|
||||
socket->connectToHostEncrypted(peerAddress, peerPort, peerHostName);
|
||||
if (!socket->waitForConnected(5000)) {
|
||||
qDebug() << "[ISL] Socket error:" << socket->errorString();
|
||||
deleteLater();
|
||||
return;
|
||||
}
|
||||
if (!socket->waitForEncrypted(5000)) {
|
||||
QList<QSslError> sslErrors(socket->sslErrors());
|
||||
if (sslErrors.isEmpty())
|
||||
qDebug() << "[ISL] SSL handshake timeout, terminating connection";
|
||||
else
|
||||
qDebug() << "[ISL] SSL errors:" << sslErrors;
|
||||
deleteLater();
|
||||
return;
|
||||
}
|
||||
|
||||
server->islLock.lockForWrite();
|
||||
if (server->islConnectionExists(serverId)) {
|
||||
qDebug() << "[ISL] Duplicate connection to #" << serverId << "terminating connection";
|
||||
deleteLater();
|
||||
return;
|
||||
}
|
||||
|
||||
server->addIslInterface(serverId, this);
|
||||
server->islLock.unlock();
|
||||
}
|
||||
|
||||
void IslInterface::flushOutputBuffer()
|
||||
{
|
||||
QMutexLocker locker(&outputBufferMutex);
|
||||
if (outputBuffer.isEmpty())
|
||||
return;
|
||||
server->incTxBytes(outputBuffer.size());
|
||||
socket->write(outputBuffer);
|
||||
socket->flush();
|
||||
outputBuffer.clear();
|
||||
QMutexLocker locker(&outputBufferMutex);
|
||||
if (outputBuffer.isEmpty())
|
||||
return;
|
||||
server->incTxBytes(outputBuffer.size());
|
||||
socket->write(outputBuffer);
|
||||
socket->flush();
|
||||
outputBuffer.clear();
|
||||
}
|
||||
|
||||
void IslInterface::readClient()
|
||||
{
|
||||
QByteArray data = socket->readAll();
|
||||
server->incRxBytes(data.size());
|
||||
inputBuffer.append(data);
|
||||
|
||||
do {
|
||||
if (!messageInProgress) {
|
||||
if (inputBuffer.size() >= 4) {
|
||||
messageLength = (((quint32) (unsigned char) inputBuffer[0]) << 24)
|
||||
+ (((quint32) (unsigned char) inputBuffer[1]) << 16)
|
||||
+ (((quint32) (unsigned char) inputBuffer[2]) << 8)
|
||||
+ ((quint32) (unsigned char) inputBuffer[3]);
|
||||
inputBuffer.remove(0, 4);
|
||||
messageInProgress = true;
|
||||
} else
|
||||
return;
|
||||
}
|
||||
if (inputBuffer.size() < messageLength)
|
||||
return;
|
||||
|
||||
IslMessage newMessage;
|
||||
newMessage.ParseFromArray(inputBuffer.data(), messageLength);
|
||||
inputBuffer.remove(0, messageLength);
|
||||
messageInProgress = false;
|
||||
|
||||
processMessage(newMessage);
|
||||
} while (!inputBuffer.isEmpty());
|
||||
QByteArray data = socket->readAll();
|
||||
server->incRxBytes(data.size());
|
||||
inputBuffer.append(data);
|
||||
|
||||
do {
|
||||
if (!messageInProgress) {
|
||||
if (inputBuffer.size() >= 4) {
|
||||
messageLength = (((quint32)(unsigned char)inputBuffer[0]) << 24) +
|
||||
(((quint32)(unsigned char)inputBuffer[1]) << 16) +
|
||||
(((quint32)(unsigned char)inputBuffer[2]) << 8) +
|
||||
((quint32)(unsigned char)inputBuffer[3]);
|
||||
inputBuffer.remove(0, 4);
|
||||
messageInProgress = true;
|
||||
} else
|
||||
return;
|
||||
}
|
||||
if (inputBuffer.size() < messageLength)
|
||||
return;
|
||||
|
||||
IslMessage newMessage;
|
||||
newMessage.ParseFromArray(inputBuffer.data(), messageLength);
|
||||
inputBuffer.remove(0, messageLength);
|
||||
messageInProgress = false;
|
||||
|
||||
processMessage(newMessage);
|
||||
} while (!inputBuffer.isEmpty());
|
||||
}
|
||||
|
||||
void IslInterface::catchSocketError(QAbstractSocket::SocketError socketError)
|
||||
{
|
||||
qDebug() << "[ISL] Socket error:" << socketError;
|
||||
|
||||
server->islLock.lockForWrite();
|
||||
server->removeIslInterface(serverId);
|
||||
server->islLock.unlock();
|
||||
|
||||
deleteLater();
|
||||
qDebug() << "[ISL] Socket error:" << socketError;
|
||||
|
||||
server->islLock.lockForWrite();
|
||||
server->removeIslInterface(serverId);
|
||||
server->islLock.unlock();
|
||||
|
||||
deleteLater();
|
||||
}
|
||||
|
||||
void IslInterface::transmitMessage(const IslMessage &item)
|
||||
{
|
||||
QByteArray buf;
|
||||
unsigned int size = item.ByteSize();
|
||||
buf.resize(size + 4);
|
||||
item.SerializeToArray(buf.data() + 4, size);
|
||||
buf.data()[3] = (unsigned char) size;
|
||||
buf.data()[2] = (unsigned char) (size >> 8);
|
||||
buf.data()[1] = (unsigned char) (size >> 16);
|
||||
buf.data()[0] = (unsigned char) (size >> 24);
|
||||
|
||||
outputBufferMutex.lock();
|
||||
outputBuffer.append(buf);
|
||||
outputBufferMutex.unlock();
|
||||
emit outputBufferChanged();
|
||||
QByteArray buf;
|
||||
unsigned int size = item.ByteSize();
|
||||
buf.resize(size + 4);
|
||||
item.SerializeToArray(buf.data() + 4, size);
|
||||
buf.data()[3] = (unsigned char)size;
|
||||
buf.data()[2] = (unsigned char)(size >> 8);
|
||||
buf.data()[1] = (unsigned char)(size >> 16);
|
||||
buf.data()[0] = (unsigned char)(size >> 24);
|
||||
|
||||
outputBufferMutex.lock();
|
||||
outputBuffer.append(buf);
|
||||
outputBufferMutex.unlock();
|
||||
emit outputBufferChanged();
|
||||
}
|
||||
|
||||
void IslInterface::sessionEvent_ServerCompleteList(const Event_ServerCompleteList &event)
|
||||
{
|
||||
for (int i = 0; i < event.user_list_size(); ++i) {
|
||||
ServerInfo_User temp(event.user_list(i));
|
||||
temp.set_server_id(serverId);
|
||||
emit externalUserJoined(temp);
|
||||
}
|
||||
for (int i = 0; i < event.room_list_size(); ++i) {
|
||||
const ServerInfo_Room &room = event.room_list(i);
|
||||
for (int j = 0; j < room.user_list_size(); ++j) {
|
||||
ServerInfo_User userInfo(room.user_list(j));
|
||||
userInfo.set_server_id(serverId);
|
||||
emit externalRoomUserJoined(room.room_id(), userInfo);
|
||||
}
|
||||
for (int j = 0; j < room.game_list_size(); ++j) {
|
||||
ServerInfo_Game gameInfo(room.game_list(j));
|
||||
gameInfo.set_server_id(serverId);
|
||||
emit externalRoomGameListChanged(room.room_id(), gameInfo);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < event.user_list_size(); ++i) {
|
||||
ServerInfo_User temp(event.user_list(i));
|
||||
temp.set_server_id(serverId);
|
||||
emit externalUserJoined(temp);
|
||||
}
|
||||
for (int i = 0; i < event.room_list_size(); ++i) {
|
||||
const ServerInfo_Room &room = event.room_list(i);
|
||||
for (int j = 0; j < room.user_list_size(); ++j) {
|
||||
ServerInfo_User userInfo(room.user_list(j));
|
||||
userInfo.set_server_id(serverId);
|
||||
emit externalRoomUserJoined(room.room_id(), userInfo);
|
||||
}
|
||||
for (int j = 0; j < room.game_list_size(); ++j) {
|
||||
ServerInfo_Game gameInfo(room.game_list(j));
|
||||
gameInfo.set_server_id(serverId);
|
||||
emit externalRoomGameListChanged(room.room_id(), gameInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void IslInterface::sessionEvent_UserJoined(const Event_UserJoined &event)
|
||||
{
|
||||
ServerInfo_User userInfo(event.user_info());
|
||||
userInfo.set_server_id(serverId);
|
||||
emit externalUserJoined(userInfo);
|
||||
ServerInfo_User userInfo(event.user_info());
|
||||
userInfo.set_server_id(serverId);
|
||||
emit externalUserJoined(userInfo);
|
||||
}
|
||||
|
||||
void IslInterface::sessionEvent_UserLeft(const Event_UserLeft &event)
|
||||
{
|
||||
emit externalUserLeft(QString::fromStdString(event.name()));
|
||||
emit externalUserLeft(QString::fromStdString(event.name()));
|
||||
}
|
||||
|
||||
void IslInterface::roomEvent_UserJoined(int roomId, const Event_JoinRoom &event)
|
||||
{
|
||||
ServerInfo_User userInfo(event.user_info());
|
||||
userInfo.set_server_id(serverId);
|
||||
emit externalRoomUserJoined(roomId, userInfo);
|
||||
ServerInfo_User userInfo(event.user_info());
|
||||
userInfo.set_server_id(serverId);
|
||||
emit externalRoomUserJoined(roomId, userInfo);
|
||||
}
|
||||
|
||||
void IslInterface::roomEvent_UserLeft(int roomId, const Event_LeaveRoom &event)
|
||||
{
|
||||
emit externalRoomUserLeft(roomId, QString::fromStdString(event.name()));
|
||||
emit externalRoomUserLeft(roomId, QString::fromStdString(event.name()));
|
||||
}
|
||||
|
||||
void IslInterface::roomEvent_Say(int roomId, const Event_RoomSay &event)
|
||||
{
|
||||
emit externalRoomSay(roomId, QString::fromStdString(event.name()), QString::fromStdString(event.message()));
|
||||
emit externalRoomSay(roomId, QString::fromStdString(event.name()), QString::fromStdString(event.message()));
|
||||
}
|
||||
|
||||
void IslInterface::roomEvent_ListGames(int roomId, const Event_ListGames &event)
|
||||
{
|
||||
for (int i = 0; i < event.game_list_size(); ++i) {
|
||||
ServerInfo_Game gameInfo(event.game_list(i));
|
||||
gameInfo.set_server_id(serverId);
|
||||
emit externalRoomGameListChanged(roomId, gameInfo);
|
||||
}
|
||||
for (int i = 0; i < event.game_list_size(); ++i) {
|
||||
ServerInfo_Game gameInfo(event.game_list(i));
|
||||
gameInfo.set_server_id(serverId);
|
||||
emit externalRoomGameListChanged(roomId, gameInfo);
|
||||
}
|
||||
}
|
||||
|
||||
void IslInterface::roomCommand_JoinGame(const Command_JoinGame &cmd, int cmdId, int roomId, qint64 sessionId)
|
||||
{
|
||||
emit joinGameCommandReceived(cmd, cmdId, roomId, serverId, sessionId);
|
||||
emit joinGameCommandReceived(cmd, cmdId, roomId, serverId, sessionId);
|
||||
}
|
||||
|
||||
void IslInterface::processSessionEvent(const SessionEvent &event, qint64 sessionId)
|
||||
{
|
||||
switch (getPbExtension(event)) {
|
||||
case SessionEvent::SERVER_COMPLETE_LIST: sessionEvent_ServerCompleteList(event.GetExtension(Event_ServerCompleteList::ext)); break;
|
||||
case SessionEvent::USER_JOINED: sessionEvent_UserJoined(event.GetExtension(Event_UserJoined::ext)); break;
|
||||
case SessionEvent::USER_LEFT: sessionEvent_UserLeft(event.GetExtension(Event_UserLeft::ext)); break;
|
||||
case SessionEvent::GAME_JOINED: {
|
||||
QReadLocker clientsLocker(&server->clientsLock);
|
||||
Server_AbstractUserInterface *client = server->getUsersBySessionId().value(sessionId);
|
||||
if (!client) {
|
||||
qDebug() << "IslInterface::processSessionEvent: session id" << sessionId << "not found";
|
||||
break;
|
||||
}
|
||||
const Event_GameJoined &gameJoined = event.GetExtension(Event_GameJoined::ext);
|
||||
client->playerAddedToGame(gameJoined.game_info().game_id(), gameJoined.game_info().room_id(), gameJoined.player_id());
|
||||
client->sendProtocolItem(event);
|
||||
break;
|
||||
}
|
||||
case SessionEvent::USER_MESSAGE:
|
||||
case SessionEvent::REPLAY_ADDED: {
|
||||
QReadLocker clientsLocker(&server->clientsLock);
|
||||
Server_AbstractUserInterface *client = server->getUsersBySessionId().value(sessionId);
|
||||
if (!client) {
|
||||
qDebug() << "IslInterface::processSessionEvent: session id" << sessionId << "not found";
|
||||
break;
|
||||
}
|
||||
|
||||
client->sendProtocolItem(event);
|
||||
break;
|
||||
}
|
||||
default: ;
|
||||
}
|
||||
switch (getPbExtension(event)) {
|
||||
case SessionEvent::SERVER_COMPLETE_LIST:
|
||||
sessionEvent_ServerCompleteList(event.GetExtension(Event_ServerCompleteList::ext));
|
||||
break;
|
||||
case SessionEvent::USER_JOINED:
|
||||
sessionEvent_UserJoined(event.GetExtension(Event_UserJoined::ext));
|
||||
break;
|
||||
case SessionEvent::USER_LEFT:
|
||||
sessionEvent_UserLeft(event.GetExtension(Event_UserLeft::ext));
|
||||
break;
|
||||
case SessionEvent::GAME_JOINED: {
|
||||
QReadLocker clientsLocker(&server->clientsLock);
|
||||
Server_AbstractUserInterface *client = server->getUsersBySessionId().value(sessionId);
|
||||
if (!client) {
|
||||
qDebug() << "IslInterface::processSessionEvent: session id" << sessionId << "not found";
|
||||
break;
|
||||
}
|
||||
const Event_GameJoined &gameJoined = event.GetExtension(Event_GameJoined::ext);
|
||||
client->playerAddedToGame(gameJoined.game_info().game_id(), gameJoined.game_info().room_id(),
|
||||
gameJoined.player_id());
|
||||
client->sendProtocolItem(event);
|
||||
break;
|
||||
}
|
||||
case SessionEvent::USER_MESSAGE:
|
||||
case SessionEvent::REPLAY_ADDED: {
|
||||
QReadLocker clientsLocker(&server->clientsLock);
|
||||
Server_AbstractUserInterface *client = server->getUsersBySessionId().value(sessionId);
|
||||
if (!client) {
|
||||
qDebug() << "IslInterface::processSessionEvent: session id" << sessionId << "not found";
|
||||
break;
|
||||
}
|
||||
|
||||
client->sendProtocolItem(event);
|
||||
break;
|
||||
}
|
||||
default:;
|
||||
}
|
||||
}
|
||||
|
||||
void IslInterface::processRoomEvent(const RoomEvent &event)
|
||||
{
|
||||
switch (getPbExtension(event)) {
|
||||
case RoomEvent::JOIN_ROOM: roomEvent_UserJoined(event.room_id(), event.GetExtension(Event_JoinRoom::ext)); break;
|
||||
case RoomEvent::LEAVE_ROOM: roomEvent_UserLeft(event.room_id(), event.GetExtension(Event_LeaveRoom::ext)); break;
|
||||
case RoomEvent::ROOM_SAY: roomEvent_Say(event.room_id(), event.GetExtension(Event_RoomSay::ext)); break;
|
||||
case RoomEvent::LIST_GAMES: roomEvent_ListGames(event.room_id(), event.GetExtension(Event_ListGames::ext)); break;
|
||||
default: ;
|
||||
}
|
||||
switch (getPbExtension(event)) {
|
||||
case RoomEvent::JOIN_ROOM:
|
||||
roomEvent_UserJoined(event.room_id(), event.GetExtension(Event_JoinRoom::ext));
|
||||
break;
|
||||
case RoomEvent::LEAVE_ROOM:
|
||||
roomEvent_UserLeft(event.room_id(), event.GetExtension(Event_LeaveRoom::ext));
|
||||
break;
|
||||
case RoomEvent::ROOM_SAY:
|
||||
roomEvent_Say(event.room_id(), event.GetExtension(Event_RoomSay::ext));
|
||||
break;
|
||||
case RoomEvent::LIST_GAMES:
|
||||
roomEvent_ListGames(event.room_id(), event.GetExtension(Event_ListGames::ext));
|
||||
break;
|
||||
default:;
|
||||
}
|
||||
}
|
||||
|
||||
void IslInterface::processRoomCommand(const CommandContainer &cont, qint64 sessionId)
|
||||
{
|
||||
for (int i = 0; i < cont.room_command_size(); ++i) {
|
||||
const RoomCommand &roomCommand = cont.room_command(i);
|
||||
switch (static_cast<RoomCommand::RoomCommandType>(getPbExtension(roomCommand))) {
|
||||
case RoomCommand::JOIN_GAME: roomCommand_JoinGame(roomCommand.GetExtension(Command_JoinGame::ext), cont.cmd_id(), cont.room_id(), sessionId);
|
||||
default: ;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < cont.room_command_size(); ++i) {
|
||||
const RoomCommand &roomCommand = cont.room_command(i);
|
||||
switch (static_cast<RoomCommand::RoomCommandType>(getPbExtension(roomCommand))) {
|
||||
case RoomCommand::JOIN_GAME:
|
||||
roomCommand_JoinGame(roomCommand.GetExtension(Command_JoinGame::ext), cont.cmd_id(), cont.room_id(),
|
||||
sessionId);
|
||||
default:;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void IslInterface::processMessage(const IslMessage &item)
|
||||
{
|
||||
qDebug() << QString::fromStdString(item.DebugString());
|
||||
|
||||
switch (item.message_type()) {
|
||||
case IslMessage::ROOM_COMMAND_CONTAINER: {
|
||||
processRoomCommand(item.room_command(), item.session_id());
|
||||
break;
|
||||
}
|
||||
case IslMessage::GAME_COMMAND_CONTAINER: {
|
||||
emit gameCommandContainerReceived(item.game_command(), item.player_id(), serverId, item.session_id());
|
||||
break;
|
||||
}
|
||||
case IslMessage::SESSION_EVENT: {
|
||||
processSessionEvent(item.session_event(), item.session_id());
|
||||
break;
|
||||
}
|
||||
case IslMessage::RESPONSE: {
|
||||
emit responseReceived(item.response(), item.session_id());
|
||||
break;
|
||||
}
|
||||
case IslMessage::GAME_EVENT_CONTAINER: {
|
||||
emit gameEventContainerReceived(item.game_event_container(), item.session_id());
|
||||
break;
|
||||
}
|
||||
case IslMessage::ROOM_EVENT: {
|
||||
processRoomEvent(item.room_event());
|
||||
break;
|
||||
}
|
||||
default: ;
|
||||
}
|
||||
qDebug() << QString::fromStdString(item.DebugString());
|
||||
|
||||
switch (item.message_type()) {
|
||||
case IslMessage::ROOM_COMMAND_CONTAINER: {
|
||||
processRoomCommand(item.room_command(), item.session_id());
|
||||
break;
|
||||
}
|
||||
case IslMessage::GAME_COMMAND_CONTAINER: {
|
||||
emit gameCommandContainerReceived(item.game_command(), item.player_id(), serverId, item.session_id());
|
||||
break;
|
||||
}
|
||||
case IslMessage::SESSION_EVENT: {
|
||||
processSessionEvent(item.session_event(), item.session_id());
|
||||
break;
|
||||
}
|
||||
case IslMessage::RESPONSE: {
|
||||
emit responseReceived(item.response(), item.session_id());
|
||||
break;
|
||||
}
|
||||
case IslMessage::GAME_EVENT_CONTAINER: {
|
||||
emit gameEventContainerReceived(item.game_event_container(), item.session_id());
|
||||
break;
|
||||
}
|
||||
case IslMessage::ROOM_EVENT: {
|
||||
processRoomEvent(item.room_event());
|
||||
break;
|
||||
}
|
||||
default:;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
#ifndef ISL_INTERFACE_H
|
||||
#define ISL_INTERFACE_H
|
||||
|
||||
#include "pb/serverinfo_game.pb.h"
|
||||
#include "pb/serverinfo_room.pb.h"
|
||||
#include "pb/serverinfo_user.pb.h"
|
||||
#include "servatrice.h"
|
||||
#include <QSslCertificate>
|
||||
#include <QWaitCondition>
|
||||
#include "pb/serverinfo_user.pb.h"
|
||||
#include "pb/serverinfo_room.pb.h"
|
||||
#include "pb/serverinfo_game.pb.h"
|
||||
|
||||
class Servatrice;
|
||||
class QSslSocket;
|
||||
|
|
@ -23,66 +23,76 @@ class Event_RoomSay;
|
|||
class Event_ListGames;
|
||||
class Command_JoinGame;
|
||||
|
||||
class IslInterface : public QObject {
|
||||
Q_OBJECT
|
||||
class IslInterface : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
void readClient();
|
||||
void catchSocketError(QAbstractSocket::SocketError socketError);
|
||||
void flushOutputBuffer();
|
||||
void readClient();
|
||||
void catchSocketError(QAbstractSocket::SocketError socketError);
|
||||
void flushOutputBuffer();
|
||||
signals:
|
||||
void outputBufferChanged();
|
||||
|
||||
void externalUserJoined(ServerInfo_User userInfo);
|
||||
void externalUserLeft(QString userName);
|
||||
void externalRoomUserJoined(int roomId, ServerInfo_User userInfo);
|
||||
void externalRoomUserLeft(int roomId, QString userName);
|
||||
void externalRoomSay(int roomId, QString userName, QString message);
|
||||
void externalRoomGameListChanged(int roomId, ServerInfo_Game gameInfo);
|
||||
void joinGameCommandReceived(const Command_JoinGame &cmd, int cmdId, int roomId, int serverId, qint64 sessionId);
|
||||
void gameCommandContainerReceived(const CommandContainer &cont, int playerId, int serverId, qint64 sessionId);
|
||||
void responseReceived(const Response &resp, qint64 sessionId);
|
||||
void gameEventContainerReceived(const GameEventContainer &cont, qint64 sessionId);
|
||||
void outputBufferChanged();
|
||||
|
||||
void externalUserJoined(ServerInfo_User userInfo);
|
||||
void externalUserLeft(QString userName);
|
||||
void externalRoomUserJoined(int roomId, ServerInfo_User userInfo);
|
||||
void externalRoomUserLeft(int roomId, QString userName);
|
||||
void externalRoomSay(int roomId, QString userName, QString message);
|
||||
void externalRoomGameListChanged(int roomId, ServerInfo_Game gameInfo);
|
||||
void joinGameCommandReceived(const Command_JoinGame &cmd, int cmdId, int roomId, int serverId, qint64 sessionId);
|
||||
void gameCommandContainerReceived(const CommandContainer &cont, int playerId, int serverId, qint64 sessionId);
|
||||
void responseReceived(const Response &resp, qint64 sessionId);
|
||||
void gameEventContainerReceived(const GameEventContainer &cont, qint64 sessionId);
|
||||
|
||||
private:
|
||||
int serverId;
|
||||
int socketDescriptor;
|
||||
QString peerHostName, peerAddress;
|
||||
int peerPort;
|
||||
QSslCertificate peerCert;
|
||||
|
||||
QMutex outputBufferMutex;
|
||||
Servatrice *server;
|
||||
QSslSocket *socket;
|
||||
|
||||
QByteArray inputBuffer, outputBuffer;
|
||||
bool messageInProgress;
|
||||
int messageLength;
|
||||
|
||||
void sessionEvent_ServerCompleteList(const Event_ServerCompleteList &event);
|
||||
void sessionEvent_UserJoined(const Event_UserJoined &event);
|
||||
void sessionEvent_UserLeft(const Event_UserLeft &event);
|
||||
|
||||
void roomEvent_UserJoined(int roomId, const Event_JoinRoom &event);
|
||||
void roomEvent_UserLeft(int roomId, const Event_LeaveRoom &event);
|
||||
void roomEvent_Say(int roomId, const Event_RoomSay &event);
|
||||
void roomEvent_ListGames(int roomId, const Event_ListGames &event);
|
||||
|
||||
void roomCommand_JoinGame(const Command_JoinGame &cmd, int cmdId, int roomId, qint64 sessionId);
|
||||
|
||||
void processSessionEvent(const SessionEvent &event, qint64 sessionId);
|
||||
void processRoomEvent(const RoomEvent &event);
|
||||
void processRoomCommand(const CommandContainer &cont, qint64 sessionId);
|
||||
|
||||
void processMessage(const IslMessage &item);
|
||||
void sharedCtor(const QSslCertificate &cert, const QSslKey &privateKey);
|
||||
int serverId;
|
||||
int socketDescriptor;
|
||||
QString peerHostName, peerAddress;
|
||||
int peerPort;
|
||||
QSslCertificate peerCert;
|
||||
|
||||
QMutex outputBufferMutex;
|
||||
Servatrice *server;
|
||||
QSslSocket *socket;
|
||||
|
||||
QByteArray inputBuffer, outputBuffer;
|
||||
bool messageInProgress;
|
||||
int messageLength;
|
||||
|
||||
void sessionEvent_ServerCompleteList(const Event_ServerCompleteList &event);
|
||||
void sessionEvent_UserJoined(const Event_UserJoined &event);
|
||||
void sessionEvent_UserLeft(const Event_UserLeft &event);
|
||||
|
||||
void roomEvent_UserJoined(int roomId, const Event_JoinRoom &event);
|
||||
void roomEvent_UserLeft(int roomId, const Event_LeaveRoom &event);
|
||||
void roomEvent_Say(int roomId, const Event_RoomSay &event);
|
||||
void roomEvent_ListGames(int roomId, const Event_ListGames &event);
|
||||
|
||||
void roomCommand_JoinGame(const Command_JoinGame &cmd, int cmdId, int roomId, qint64 sessionId);
|
||||
|
||||
void processSessionEvent(const SessionEvent &event, qint64 sessionId);
|
||||
void processRoomEvent(const RoomEvent &event);
|
||||
void processRoomCommand(const CommandContainer &cont, qint64 sessionId);
|
||||
|
||||
void processMessage(const IslMessage &item);
|
||||
void sharedCtor(const QSslCertificate &cert, const QSslKey &privateKey);
|
||||
public slots:
|
||||
void initServer();
|
||||
void initClient();
|
||||
void initServer();
|
||||
void initClient();
|
||||
|
||||
public:
|
||||
IslInterface(int socketDescriptor, const QSslCertificate &cert, const QSslKey &privateKey, Servatrice *_server);
|
||||
IslInterface(int _serverId, const QString &peerHostName, const QString &peerAddress, int peerPort, const QSslCertificate &peerCert, const QSslCertificate &cert, const QSslKey &privateKey, Servatrice *_server);
|
||||
~IslInterface();
|
||||
|
||||
void transmitMessage(const IslMessage &item);
|
||||
IslInterface(int socketDescriptor, const QSslCertificate &cert, const QSslKey &privateKey, Servatrice *_server);
|
||||
IslInterface(int _serverId,
|
||||
const QString &peerHostName,
|
||||
const QString &peerAddress,
|
||||
int peerPort,
|
||||
const QSslCertificate &peerCert,
|
||||
const QSslCertificate &cert,
|
||||
const QSslKey &privateKey,
|
||||
Servatrice *_server);
|
||||
~IslInterface();
|
||||
|
||||
void transmitMessage(const IslMessage &item);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -18,25 +18,24 @@
|
|||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#include <QCommandLineParser>
|
||||
#include <QCoreApplication>
|
||||
#include <QDateTime>
|
||||
#include <QMetaType>
|
||||
#include <QTextCodec>
|
||||
#include <QtGlobal>
|
||||
#include <iostream>
|
||||
#include <QMetaType>
|
||||
#include <QDateTime>
|
||||
#include <QCommandLineParser>
|
||||
|
||||
|
||||
#include "passwordhasher.h"
|
||||
#include "rng_sfmt.h"
|
||||
#include "servatrice.h"
|
||||
#include "server_logger.h"
|
||||
#include "settingscache.h"
|
||||
#include "signalhandler.h"
|
||||
#include "smtpclient.h"
|
||||
#include "rng_sfmt.h"
|
||||
#include "version_string.h"
|
||||
#include <google/protobuf/stubs/common.h>
|
||||
|
||||
|
||||
RNG_Abstract *rng;
|
||||
ServerLogger *logger;
|
||||
QThread *loggerThread;
|
||||
|
|
@ -55,157 +54,157 @@ void myMessageOutput2(QtMsgType type, const QMessageLogContext &, const QString
|
|||
|
||||
void testRNG()
|
||||
{
|
||||
const int n = 500000;
|
||||
std::cerr << "Testing random number generator (n = " << n << " * bins)..." << std::endl;
|
||||
|
||||
const int min = 1;
|
||||
const int minMax = 2;
|
||||
const int maxMax = 10;
|
||||
|
||||
QVector<QVector<int> > numbers(maxMax - minMax + 1);
|
||||
QVector<double> chisq(maxMax - minMax + 1);
|
||||
for (int max = minMax; max <= maxMax; ++max) {
|
||||
numbers[max - minMax] = rng->makeNumbersVector(n * (max - min + 1), min, max);
|
||||
chisq[max - minMax] = rng->testRandom(numbers[max - minMax]);
|
||||
}
|
||||
for (int i = 0; i <= maxMax - min; ++i) {
|
||||
std::cerr << (min + i);
|
||||
for (int j = 0; j < numbers.size(); ++j) {
|
||||
if (i < numbers[j].size())
|
||||
std::cerr << "\t" << numbers[j][i];
|
||||
else
|
||||
std::cerr << "\t";
|
||||
}
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
std::cerr << std::endl << "Chi^2 =";
|
||||
for (int j = 0; j < chisq.size(); ++j)
|
||||
std::cerr << "\t" << QString::number(chisq[j], 'f', 3).toStdString();
|
||||
std::cerr << std::endl << "k =";
|
||||
for (int j = 0; j < chisq.size(); ++j)
|
||||
std::cerr << "\t" << (j - min + minMax);
|
||||
std::cerr << std::endl << std::endl;
|
||||
const int n = 500000;
|
||||
std::cerr << "Testing random number generator (n = " << n << " * bins)..." << std::endl;
|
||||
|
||||
const int min = 1;
|
||||
const int minMax = 2;
|
||||
const int maxMax = 10;
|
||||
|
||||
QVector<QVector<int>> numbers(maxMax - minMax + 1);
|
||||
QVector<double> chisq(maxMax - minMax + 1);
|
||||
for (int max = minMax; max <= maxMax; ++max) {
|
||||
numbers[max - minMax] = rng->makeNumbersVector(n * (max - min + 1), min, max);
|
||||
chisq[max - minMax] = rng->testRandom(numbers[max - minMax]);
|
||||
}
|
||||
for (int i = 0; i <= maxMax - min; ++i) {
|
||||
std::cerr << (min + i);
|
||||
for (int j = 0; j < numbers.size(); ++j) {
|
||||
if (i < numbers[j].size())
|
||||
std::cerr << "\t" << numbers[j][i];
|
||||
else
|
||||
std::cerr << "\t";
|
||||
}
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
std::cerr << std::endl << "Chi^2 =";
|
||||
for (int j = 0; j < chisq.size(); ++j)
|
||||
std::cerr << "\t" << QString::number(chisq[j], 'f', 3).toStdString();
|
||||
std::cerr << std::endl << "k =";
|
||||
for (int j = 0; j < chisq.size(); ++j)
|
||||
std::cerr << "\t" << (j - min + minMax);
|
||||
std::cerr << std::endl << std::endl;
|
||||
}
|
||||
|
||||
void testHash()
|
||||
{
|
||||
const int n = 5000;
|
||||
std::cerr << "Benchmarking password hash function (n =" << n << ")..." << std::endl;
|
||||
QDateTime startTime = QDateTime::currentDateTime();
|
||||
for (int i = 0; i < n; ++i)
|
||||
PasswordHasher::computeHash("aaaaaa", "aaaaaaaaaaaaaaaa");
|
||||
QDateTime endTime = QDateTime::currentDateTime();
|
||||
std::cerr << startTime.secsTo(endTime) << "secs" << std::endl;
|
||||
const int n = 5000;
|
||||
std::cerr << "Benchmarking password hash function (n =" << n << ")..." << std::endl;
|
||||
QDateTime startTime = QDateTime::currentDateTime();
|
||||
for (int i = 0; i < n; ++i)
|
||||
PasswordHasher::computeHash("aaaaaa", "aaaaaaaaaaaaaaaa");
|
||||
QDateTime endTime = QDateTime::currentDateTime();
|
||||
std::cerr << startTime.secsTo(endTime) << "secs" << std::endl;
|
||||
}
|
||||
|
||||
void myMessageOutput(QtMsgType /*type*/, const QMessageLogContext &, const QString &msg)
|
||||
{
|
||||
logger->logMessage(msg);
|
||||
logger->logMessage(msg);
|
||||
}
|
||||
|
||||
void myMessageOutput2(QtMsgType /*type*/, const QMessageLogContext &, const QString &msg)
|
||||
{
|
||||
logger->logMessage(msg);
|
||||
std::cerr << msg.toStdString() << std::endl;
|
||||
logger->logMessage(msg);
|
||||
std::cerr << msg.toStdString() << std::endl;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QCoreApplication app(argc, argv);
|
||||
app.setOrganizationName("Cockatrice");
|
||||
app.setApplicationName("Servatrice");
|
||||
app.setApplicationVersion(VERSION_STRING);
|
||||
QCoreApplication app(argc, argv);
|
||||
app.setOrganizationName("Cockatrice");
|
||||
app.setApplicationName("Servatrice");
|
||||
app.setApplicationVersion(VERSION_STRING);
|
||||
|
||||
bool testRandom = false;
|
||||
bool testHashFunction = false;
|
||||
bool logToConsole = false;
|
||||
QString configPath;
|
||||
bool testRandom = false;
|
||||
bool testHashFunction = false;
|
||||
bool logToConsole = false;
|
||||
QString configPath;
|
||||
|
||||
QCommandLineParser parser;
|
||||
parser.addHelpOption();
|
||||
parser.addVersionOption();
|
||||
QCommandLineParser parser;
|
||||
parser.addHelpOption();
|
||||
parser.addVersionOption();
|
||||
|
||||
QCommandLineOption testRandomOpt("test-random", "Test PRNG (chi^2)");
|
||||
parser.addOption(testRandomOpt);
|
||||
QCommandLineOption testRandomOpt("test-random", "Test PRNG (chi^2)");
|
||||
parser.addOption(testRandomOpt);
|
||||
|
||||
QCommandLineOption testHashFunctionOpt("test-hash", "Test password hash function");
|
||||
parser.addOption(testHashFunctionOpt);
|
||||
QCommandLineOption testHashFunctionOpt("test-hash", "Test password hash function");
|
||||
parser.addOption(testHashFunctionOpt);
|
||||
|
||||
QCommandLineOption logToConsoleOpt("log-to-console", "Write server logs to console");
|
||||
parser.addOption(logToConsoleOpt);
|
||||
QCommandLineOption logToConsoleOpt("log-to-console", "Write server logs to console");
|
||||
parser.addOption(logToConsoleOpt);
|
||||
|
||||
QCommandLineOption configPathOpt("config", "Read server configuration from <file>", "file", "");
|
||||
parser.addOption(configPathOpt);
|
||||
QCommandLineOption configPathOpt("config", "Read server configuration from <file>", "file", "");
|
||||
parser.addOption(configPathOpt);
|
||||
|
||||
parser.process(app);
|
||||
parser.process(app);
|
||||
|
||||
testRandom = parser.isSet(testRandomOpt);
|
||||
testHashFunction = parser.isSet(testHashFunctionOpt);
|
||||
logToConsole = parser.isSet(logToConsoleOpt);
|
||||
configPath = parser.value(configPathOpt);
|
||||
testRandom = parser.isSet(testRandomOpt);
|
||||
testHashFunction = parser.isSet(testHashFunctionOpt);
|
||||
logToConsole = parser.isSet(logToConsoleOpt);
|
||||
configPath = parser.value(configPathOpt);
|
||||
|
||||
|
||||
qRegisterMetaType<QList<int> >("QList<int>");
|
||||
qRegisterMetaType<QList<int>>("QList<int>");
|
||||
|
||||
configPath = SettingsCache::guessConfigurationPath(configPath);
|
||||
qWarning() << "Using configuration file: " << configPath;
|
||||
settingsCache = new SettingsCache(configPath);
|
||||
|
||||
loggerThread = new QThread;
|
||||
loggerThread->setObjectName("logger");
|
||||
logger = new ServerLogger(logToConsole);
|
||||
logger->moveToThread(loggerThread);
|
||||
|
||||
loggerThread->start();
|
||||
QMetaObject::invokeMethod(logger, "startLog", Qt::BlockingQueuedConnection, Q_ARG(QString, settingsCache->value("server/logfile", QString("server.log")).toString()));
|
||||
configPath = SettingsCache::guessConfigurationPath(configPath);
|
||||
qWarning() << "Using configuration file: " << configPath;
|
||||
settingsCache = new SettingsCache(configPath);
|
||||
|
||||
if (logToConsole)
|
||||
qInstallMessageHandler(myMessageOutput);
|
||||
else
|
||||
qInstallMessageHandler(myMessageOutput2);
|
||||
loggerThread = new QThread;
|
||||
loggerThread->setObjectName("logger");
|
||||
logger = new ServerLogger(logToConsole);
|
||||
logger->moveToThread(loggerThread);
|
||||
|
||||
signalhandler = new SignalHandler();
|
||||
loggerThread->start();
|
||||
QMetaObject::invokeMethod(logger, "startLog", Qt::BlockingQueuedConnection,
|
||||
Q_ARG(QString, settingsCache->value("server/logfile", QString("server.log")).toString()));
|
||||
|
||||
rng = new RNG_SFMT;
|
||||
|
||||
std::cerr << "Servatrice " << VERSION_STRING << " starting." << std::endl;
|
||||
std::cerr << "-------------------------" << std::endl;
|
||||
|
||||
PasswordHasher::initialize();
|
||||
|
||||
if (testRandom)
|
||||
testRNG();
|
||||
if (testHashFunction)
|
||||
testHash();
|
||||
if (logToConsole)
|
||||
qInstallMessageHandler(myMessageOutput);
|
||||
else
|
||||
qInstallMessageHandler(myMessageOutput2);
|
||||
|
||||
smtpClient = new SmtpClient();
|
||||
|
||||
Servatrice *server = new Servatrice();
|
||||
QObject::connect(server, SIGNAL(destroyed()), &app, SLOT(quit()), Qt::QueuedConnection);
|
||||
int retval = 0;
|
||||
if (server->initServer()) {
|
||||
std::cerr << "-------------------------" << std::endl;
|
||||
std::cerr << "Server initialized." << std::endl;
|
||||
signalhandler = new SignalHandler();
|
||||
|
||||
qInstallMessageHandler(myMessageOutput);
|
||||
rng = new RNG_SFMT;
|
||||
|
||||
retval = app.exec();
|
||||
|
||||
std::cerr << "Server quit." << std::endl;
|
||||
std::cerr << "-------------------------" << std::endl;
|
||||
}
|
||||
|
||||
delete smtpClient;
|
||||
delete rng;
|
||||
delete signalhandler;
|
||||
delete settingsCache;
|
||||
|
||||
logger->deleteLater();
|
||||
loggerThread->wait();
|
||||
delete loggerThread;
|
||||
std::cerr << "Servatrice " << VERSION_STRING << " starting." << std::endl;
|
||||
std::cerr << "-------------------------" << std::endl;
|
||||
|
||||
// Delete all global objects allocated by libprotobuf.
|
||||
google::protobuf::ShutdownProtobufLibrary();
|
||||
PasswordHasher::initialize();
|
||||
|
||||
return retval;
|
||||
if (testRandom)
|
||||
testRNG();
|
||||
if (testHashFunction)
|
||||
testHash();
|
||||
|
||||
smtpClient = new SmtpClient();
|
||||
|
||||
Servatrice *server = new Servatrice();
|
||||
QObject::connect(server, SIGNAL(destroyed()), &app, SLOT(quit()), Qt::QueuedConnection);
|
||||
int retval = 0;
|
||||
if (server->initServer()) {
|
||||
std::cerr << "-------------------------" << std::endl;
|
||||
std::cerr << "Server initialized." << std::endl;
|
||||
|
||||
qInstallMessageHandler(myMessageOutput);
|
||||
|
||||
retval = app.exec();
|
||||
|
||||
std::cerr << "Server quit." << std::endl;
|
||||
std::cerr << "-------------------------" << std::endl;
|
||||
}
|
||||
|
||||
delete smtpClient;
|
||||
delete rng;
|
||||
delete signalhandler;
|
||||
delete settingsCache;
|
||||
|
||||
logger->deleteLater();
|
||||
loggerThread->wait();
|
||||
delete loggerThread;
|
||||
|
||||
// Delete all global objects allocated by libprotobuf.
|
||||
google::protobuf::ShutdownProtobufLibrary();
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#include "passwordhasher.h"
|
||||
|
||||
#include <QCryptographicHash>
|
||||
#include "rng_sfmt.h"
|
||||
#include <QCryptographicHash>
|
||||
|
||||
void PasswordHasher::initialize()
|
||||
{
|
||||
|
|
@ -23,10 +23,9 @@ QString PasswordHasher::computeHash(const QString &password, const QString &salt
|
|||
|
||||
QString PasswordHasher::generateRandomSalt(const int len)
|
||||
{
|
||||
static const char alphanum[] =
|
||||
"0123456789"
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz";
|
||||
static const char alphanum[] = "0123456789"
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz";
|
||||
|
||||
QString ret;
|
||||
int size = sizeof(alphanum) - 1;
|
||||
|
|
|
|||
|
|
@ -3,12 +3,13 @@
|
|||
|
||||
#include <QObject>
|
||||
|
||||
class PasswordHasher {
|
||||
class PasswordHasher
|
||||
{
|
||||
public:
|
||||
static void initialize();
|
||||
static QString computeHash(const QString &password, const QString &salt);
|
||||
static QString generateRandomSalt(const int len = 16);
|
||||
static QString generateActivationToken();
|
||||
static void initialize();
|
||||
static QString computeHash(const QString &password, const QString &salt);
|
||||
static QString generateRandomSalt(const int len = 16);
|
||||
static QString generateActivationToken();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -17,32 +17,34 @@
|
|||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#include <QSqlQuery>
|
||||
#include <QFile>
|
||||
#include <QTimer>
|
||||
#include <QDateTime>
|
||||
#include <QDebug>
|
||||
#include <QString>
|
||||
#include <iostream>
|
||||
#include "servatrice.h"
|
||||
#include "servatrice_database_interface.h"
|
||||
#include "servatrice_connection_pool.h"
|
||||
#include "server_room.h"
|
||||
#include "settingscache.h"
|
||||
#include "serversocketinterface.h"
|
||||
#include "isl_interface.h"
|
||||
#include "server_logger.h"
|
||||
#include "main.h"
|
||||
#include "decklist.h"
|
||||
#include "smtpclient.h"
|
||||
#include "featureset.h"
|
||||
#include "isl_interface.h"
|
||||
#include "main.h"
|
||||
#include "pb/event_connection_closed.pb.h"
|
||||
#include "pb/event_server_message.pb.h"
|
||||
#include "pb/event_server_shutdown.pb.h"
|
||||
#include "pb/event_connection_closed.pb.h"
|
||||
#include "featureset.h"
|
||||
#include "servatrice_connection_pool.h"
|
||||
#include "servatrice_database_interface.h"
|
||||
#include "server_logger.h"
|
||||
#include "server_room.h"
|
||||
#include "serversocketinterface.h"
|
||||
#include "settingscache.h"
|
||||
#include "smtpclient.h"
|
||||
#include <QDateTime>
|
||||
#include <QDebug>
|
||||
#include <QFile>
|
||||
#include <QSqlQuery>
|
||||
#include <QString>
|
||||
#include <QTimer>
|
||||
#include <iostream>
|
||||
|
||||
Servatrice_GameServer::Servatrice_GameServer(Servatrice *_server, int _numberPools, const QSqlDatabase &_sqlDatabase, QObject *parent)
|
||||
: QTcpServer(parent),
|
||||
server(_server)
|
||||
Servatrice_GameServer::Servatrice_GameServer(Servatrice *_server,
|
||||
int _numberPools,
|
||||
const QSqlDatabase &_sqlDatabase,
|
||||
QObject *parent)
|
||||
: QTcpServer(parent), server(_server)
|
||||
{
|
||||
for (int i = 0; i < _numberPools; ++i) {
|
||||
Servatrice_DatabaseInterface *newDatabaseInterface = new Servatrice_DatabaseInterface(i, server);
|
||||
|
|
@ -55,7 +57,8 @@ Servatrice_GameServer::Servatrice_GameServer(Servatrice *_server, int _numberPoo
|
|||
server->addDatabaseInterface(newThread, newDatabaseInterface);
|
||||
|
||||
newThread->start();
|
||||
QMetaObject::invokeMethod(newDatabaseInterface, "initDatabase", Qt::BlockingQueuedConnection, Q_ARG(QSqlDatabase, _sqlDatabase));
|
||||
QMetaObject::invokeMethod(newDatabaseInterface, "initDatabase", Qt::BlockingQueuedConnection,
|
||||
Q_ARG(QSqlDatabase, _sqlDatabase));
|
||||
|
||||
connectionPools.append(newPool);
|
||||
}
|
||||
|
|
@ -103,12 +106,15 @@ Servatrice_ConnectionPool *Servatrice_GameServer::findLeastUsedConnectionPool()
|
|||
#if QT_VERSION > 0x050300
|
||||
#define WEBSOCKET_POOL_NUMBER 999
|
||||
|
||||
Servatrice_WebsocketGameServer::Servatrice_WebsocketGameServer(Servatrice *_server, int /* _numberPools */, const QSqlDatabase &_sqlDatabase, QObject *parent)
|
||||
: QWebSocketServer("Servatrice", QWebSocketServer::NonSecureMode, parent),
|
||||
server(_server)
|
||||
Servatrice_WebsocketGameServer::Servatrice_WebsocketGameServer(Servatrice *_server,
|
||||
int /* _numberPools */,
|
||||
const QSqlDatabase &_sqlDatabase,
|
||||
QObject *parent)
|
||||
: QWebSocketServer("Servatrice", QWebSocketServer::NonSecureMode, parent), server(_server)
|
||||
{
|
||||
// Qt limitation: websockets can't be moved to another thread
|
||||
Servatrice_DatabaseInterface *newDatabaseInterface = new Servatrice_DatabaseInterface(WEBSOCKET_POOL_NUMBER, server);
|
||||
Servatrice_DatabaseInterface *newDatabaseInterface =
|
||||
new Servatrice_DatabaseInterface(WEBSOCKET_POOL_NUMBER, server);
|
||||
Servatrice_ConnectionPool *newPool = new Servatrice_ConnectionPool(newDatabaseInterface);
|
||||
|
||||
server->addDatabaseInterface(thread(), newDatabaseInterface);
|
||||
|
|
@ -134,7 +140,7 @@ void Servatrice_WebsocketGameServer::onNewConnection()
|
|||
Servatrice_ConnectionPool *pool = findLeastUsedConnectionPool();
|
||||
|
||||
WebsocketServerSocketInterface *ssi = new WebsocketServerSocketInterface(server, pool->getDatabaseInterface());
|
||||
// ssi->moveToThread(pool->thread());
|
||||
// ssi->moveToThread(pool->thread());
|
||||
pool->addClient();
|
||||
connect(ssi, SIGNAL(destroyed()), pool, SLOT(removeClient()));
|
||||
|
||||
|
|
@ -172,8 +178,7 @@ void Servatrice_IslServer::incomingConnection(qintptr socketDescriptor)
|
|||
QMetaObject::invokeMethod(interface, "initServer", Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
Servatrice::Servatrice(QObject *parent)
|
||||
: Server(parent), uptime(0), shutdownTimer(0), isFirstShutdownMessage(true)
|
||||
Servatrice::Servatrice(QObject *parent) : Server(parent), uptime(0), shutdownTimer(0), isFirstShutdownMessage(true)
|
||||
{
|
||||
qRegisterMetaType<QSqlDatabase>("QSqlDatabase");
|
||||
}
|
||||
|
|
@ -182,7 +187,7 @@ Servatrice::~Servatrice()
|
|||
{
|
||||
gameServer->close();
|
||||
|
||||
// clients live in other threads, we need to lock them
|
||||
// clients live in other threads, we need to lock them
|
||||
clientsLock.lockForRead();
|
||||
for (int i = 0; i < clients.size(); ++i)
|
||||
QMetaObject::invokeMethod(clients.at(i), "prepareDestroy", Qt::QueuedConnection);
|
||||
|
|
@ -194,7 +199,10 @@ Servatrice::~Servatrice()
|
|||
class SleeperThread : public QThread
|
||||
{
|
||||
public:
|
||||
static void msleep(unsigned long msecs) { QThread::usleep(msecs); }
|
||||
static void msleep(unsigned long msecs)
|
||||
{
|
||||
QThread::usleep(msecs);
|
||||
}
|
||||
};
|
||||
|
||||
do {
|
||||
|
|
@ -210,12 +218,12 @@ Servatrice::~Servatrice()
|
|||
|
||||
bool Servatrice::initServer()
|
||||
{
|
||||
|
||||
|
||||
serverId = getServerID();
|
||||
if (getAuthenticationMethodString() == "sql") {
|
||||
qDebug() << "Authenticating method: sql";
|
||||
authenticationMethod = AuthenticationSql;
|
||||
} else if(getAuthenticationMethodString() == "password") {
|
||||
} else if (getAuthenticationMethodString() == "password") {
|
||||
qDebug() << "Authenticating method: password";
|
||||
authenticationMethod = AuthenticationPassword;
|
||||
} else {
|
||||
|
|
@ -244,11 +252,15 @@ bool Servatrice::initServer()
|
|||
qDebug() << "Email blacklist: " << emailBlackListFilters;
|
||||
qDebug() << "Require email address to register: " << getRequireEmailForRegistrationEnabled();
|
||||
qDebug() << "Require email activation via token: " << getRequireEmailActivationEnabled();
|
||||
if (getMaxAccountsPerEmail()) { qDebug() << "Maximum number of accounts per email: " << getMaxAccountsPerEmail(); } else { qDebug() << "Maximum number of accounts per email: unlimited"; }
|
||||
if (getMaxAccountsPerEmail()) {
|
||||
qDebug() << "Maximum number of accounts per email: " << getMaxAccountsPerEmail();
|
||||
} else {
|
||||
qDebug() << "Maximum number of accounts per email: unlimited";
|
||||
}
|
||||
qDebug() << "Enable Internal SMTP Client: " << getEnableInternalSMTPClient();
|
||||
if (!getEnableInternalSMTPClient())
|
||||
{
|
||||
qDebug() << "WARNING: Registrations are enabled but internal SMTP client is disabled. Users activation emails will not be automatically mailed to users!";
|
||||
if (!getEnableInternalSMTPClient()) {
|
||||
qDebug() << "WARNING: Registrations are enabled but internal SMTP client is disabled. Users activation "
|
||||
"emails will not be automatically mailed to users!";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -274,7 +286,8 @@ bool Servatrice::initServer()
|
|||
|
||||
if (databaseType != DatabaseNone) {
|
||||
dbPrefix = getDBPrefixString();
|
||||
bool dbOpened = servatriceDatabaseInterface->initDatabase("QMYSQL",getDBHostNameString(),getDBDatabaseNameString(),getDBUserNameString(),getDBPasswordString());
|
||||
bool dbOpened = servatriceDatabaseInterface->initDatabase(
|
||||
"QMYSQL", getDBHostNameString(), getDBDatabaseNameString(), getDBUserNameString(), getDBPasswordString());
|
||||
if (!dbOpened) {
|
||||
qDebug() << "Failed to open database";
|
||||
return false;
|
||||
|
|
@ -285,27 +298,24 @@ bool Servatrice::initServer()
|
|||
}
|
||||
|
||||
if (getRoomsMethodString() == "sql") {
|
||||
QSqlQuery *query = servatriceDatabaseInterface->prepareQuery("select id, name, descr, permissionlevel, privlevel, auto_join, join_message, chat_history_size from {prefix}_rooms where id_server = :id_server order by id asc");
|
||||
QSqlQuery *query = servatriceDatabaseInterface->prepareQuery(
|
||||
"select id, name, descr, permissionlevel, privlevel, auto_join, join_message, chat_history_size from "
|
||||
"{prefix}_rooms where id_server = :id_server order by id asc");
|
||||
query->bindValue(":id_server", serverId);
|
||||
servatriceDatabaseInterface->execSqlQuery(query);
|
||||
while (query->next()) {
|
||||
QSqlQuery *query2 = servatriceDatabaseInterface->prepareQuery("select name from {prefix}_rooms_gametypes where id_room = :id_room AND id_server = :id_server");
|
||||
QSqlQuery *query2 = servatriceDatabaseInterface->prepareQuery(
|
||||
"select name from {prefix}_rooms_gametypes where id_room = :id_room AND id_server = :id_server");
|
||||
query2->bindValue(":id_server", serverId);
|
||||
query2->bindValue(":id_room", query->value(0).toInt());
|
||||
servatriceDatabaseInterface->execSqlQuery(query2);
|
||||
QStringList gameTypes;
|
||||
while (query2->next())
|
||||
gameTypes.append(query2->value(0).toString());
|
||||
addRoom(new Server_Room(query->value(0).toInt(),
|
||||
query->value(7).toInt(),
|
||||
query->value(1).toString(),
|
||||
query->value(2).toString(),
|
||||
query->value(3).toString().toLower(),
|
||||
query->value(4).toString().toLower(),
|
||||
query->value(5).toInt(),
|
||||
query->value(6).toString(),
|
||||
gameTypes,
|
||||
this));
|
||||
addRoom(new Server_Room(query->value(0).toInt(), query->value(7).toInt(), query->value(1).toString(),
|
||||
query->value(2).toString(), query->value(3).toString().toLower(),
|
||||
query->value(4).toString().toLower(), query->value(5).toInt(),
|
||||
query->value(6).toString(), gameTypes, this));
|
||||
}
|
||||
} else {
|
||||
int size = settingsCache->beginReadArray("rooms/roomlist");
|
||||
|
|
@ -313,18 +323,24 @@ bool Servatrice::initServer()
|
|||
settingsCache->setArrayIndex(i);
|
||||
QStringList gameTypes;
|
||||
int size2 = settingsCache->beginReadArray("game_types");
|
||||
for (int j = 0; j < size2; ++j) {
|
||||
for (int j = 0; j < size2; ++j) {
|
||||
settingsCache->setArrayIndex(j);
|
||||
gameTypes.append(settingsCache->value("name").toString());
|
||||
}
|
||||
settingsCache->endArray();
|
||||
Server_Room *newRoom = new Server_Room(i,settingsCache->value("chathistorysize").toInt(),settingsCache->value("name").toString(),settingsCache->value("description").toString(),settingsCache->value("permissionlevel").toString().toLower(),settingsCache->value("privilegelevel").toString().toLower(),settingsCache->value("autojoin").toBool(),settingsCache->value("joinmessage").toString(),gameTypes,this);
|
||||
Server_Room *newRoom = new Server_Room(
|
||||
i, settingsCache->value("chathistorysize").toInt(), settingsCache->value("name").toString(),
|
||||
settingsCache->value("description").toString(),
|
||||
settingsCache->value("permissionlevel").toString().toLower(),
|
||||
settingsCache->value("privilegelevel").toString().toLower(), settingsCache->value("autojoin").toBool(),
|
||||
settingsCache->value("joinmessage").toString(), gameTypes, this);
|
||||
addRoom(newRoom);
|
||||
}
|
||||
|
||||
if(size==0) {
|
||||
if (size == 0) {
|
||||
// no room defined in config, add a dummy one
|
||||
Server_Room *newRoom = new Server_Room(0,100,"General room","Play anything here.","none","none",true,"",QStringList("Standard"),this);
|
||||
Server_Room *newRoom = new Server_Room(0, 100, "General room", "Play anything here.", "none", "none", true,
|
||||
"", QStringList("Standard"), this);
|
||||
addRoom(newRoom);
|
||||
}
|
||||
|
||||
|
|
@ -333,55 +349,56 @@ bool Servatrice::initServer()
|
|||
|
||||
updateLoginMessage();
|
||||
|
||||
try { if (getISLNetworkEnabled()) {
|
||||
qDebug() << "Connecting to ISL network.";
|
||||
qDebug() << "Loading certificate...";
|
||||
QFile certFile(getISLNetworkSSLCertFile());
|
||||
if (!certFile.open(QIODevice::ReadOnly))
|
||||
throw QString("Error opening certificate file: %1").arg(getISLNetworkSSLCertFile());
|
||||
QSslCertificate cert(&certFile);
|
||||
try {
|
||||
if (getISLNetworkEnabled()) {
|
||||
qDebug() << "Connecting to ISL network.";
|
||||
qDebug() << "Loading certificate...";
|
||||
QFile certFile(getISLNetworkSSLCertFile());
|
||||
if (!certFile.open(QIODevice::ReadOnly))
|
||||
throw QString("Error opening certificate file: %1").arg(getISLNetworkSSLCertFile());
|
||||
QSslCertificate cert(&certFile);
|
||||
|
||||
const QDateTime currentTime = QDateTime::currentDateTime();
|
||||
if(currentTime < cert.effectiveDate() ||
|
||||
currentTime > cert.expiryDate() ||
|
||||
cert.isBlacklisted())
|
||||
throw(QString("Invalid certificate."));
|
||||
const QDateTime currentTime = QDateTime::currentDateTime();
|
||||
if (currentTime < cert.effectiveDate() || currentTime > cert.expiryDate() || cert.isBlacklisted())
|
||||
throw(QString("Invalid certificate."));
|
||||
|
||||
qDebug() << "Loading private key...";
|
||||
QFile keyFile(getISLNetworkSSLKeyFile());
|
||||
if (!keyFile.open(QIODevice::ReadOnly))
|
||||
throw QString("Error opening private key file: %1").arg(getISLNetworkSSLKeyFile());
|
||||
QSslKey key(&keyFile, QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey);
|
||||
if (key.isNull())
|
||||
throw QString("Invalid private key.");
|
||||
qDebug() << "Loading private key...";
|
||||
QFile keyFile(getISLNetworkSSLKeyFile());
|
||||
if (!keyFile.open(QIODevice::ReadOnly))
|
||||
throw QString("Error opening private key file: %1").arg(getISLNetworkSSLKeyFile());
|
||||
QSslKey key(&keyFile, QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey);
|
||||
if (key.isNull())
|
||||
throw QString("Invalid private key.");
|
||||
|
||||
QMutableListIterator<ServerProperties> serverIterator(serverList);
|
||||
while (serverIterator.hasNext()) {
|
||||
const ServerProperties &prop = serverIterator.next();
|
||||
if (prop.cert == cert) {
|
||||
serverIterator.remove();
|
||||
continue;
|
||||
QMutableListIterator<ServerProperties> serverIterator(serverList);
|
||||
while (serverIterator.hasNext()) {
|
||||
const ServerProperties &prop = serverIterator.next();
|
||||
if (prop.cert == cert) {
|
||||
serverIterator.remove();
|
||||
continue;
|
||||
}
|
||||
|
||||
QThread *thread = new QThread;
|
||||
thread->setObjectName("isl_" + QString::number(prop.id));
|
||||
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
|
||||
|
||||
IslInterface *interface = new IslInterface(prop.id, prop.hostname, prop.address.toString(),
|
||||
prop.controlPort, prop.cert, cert, key, this);
|
||||
interface->moveToThread(thread);
|
||||
connect(interface, SIGNAL(destroyed()), thread, SLOT(quit()));
|
||||
|
||||
thread->start();
|
||||
QMetaObject::invokeMethod(interface, "initClient", Qt::BlockingQueuedConnection);
|
||||
}
|
||||
|
||||
QThread *thread = new QThread;
|
||||
thread->setObjectName("isl_" + QString::number(prop.id));
|
||||
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
|
||||
|
||||
IslInterface *interface = new IslInterface(prop.id, prop.hostname, prop.address.toString(), prop.controlPort, prop.cert, cert, key, this);
|
||||
interface->moveToThread(thread);
|
||||
connect(interface, SIGNAL(destroyed()), thread, SLOT(quit()));
|
||||
|
||||
thread->start();
|
||||
QMetaObject::invokeMethod(interface, "initClient", Qt::BlockingQueuedConnection);
|
||||
qDebug() << "Starting ISL server on port" << getISLNetworkPort();
|
||||
islServer = new Servatrice_IslServer(this, cert, key, this);
|
||||
if (islServer->listen(QHostAddress::Any, getISLNetworkPort()))
|
||||
qDebug() << "ISL server listening.";
|
||||
else
|
||||
throw QString("islServer->listen()");
|
||||
}
|
||||
|
||||
qDebug() << "Starting ISL server on port" << getISLNetworkPort();
|
||||
islServer = new Servatrice_IslServer(this, cert, key, this);
|
||||
if (islServer->listen(QHostAddress::Any, getISLNetworkPort()))
|
||||
qDebug() << "ISL server listening.";
|
||||
else
|
||||
throw QString("islServer->listen()");
|
||||
} } catch (QString error) {
|
||||
} catch (QString error) {
|
||||
qDebug() << "ERROR --" << error;
|
||||
return false;
|
||||
}
|
||||
|
|
@ -398,9 +415,9 @@ bool Servatrice::initServer()
|
|||
}
|
||||
|
||||
// SOCKET SERVER
|
||||
if(getNumberOfTCPPools() > 0)
|
||||
{
|
||||
gameServer = new Servatrice_GameServer(this, getNumberOfTCPPools(), servatriceDatabaseInterface->getDatabase(), this);
|
||||
if (getNumberOfTCPPools() > 0) {
|
||||
gameServer =
|
||||
new Servatrice_GameServer(this, getNumberOfTCPPools(), servatriceDatabaseInterface->getDatabase(), this);
|
||||
gameServer->setMaxPendingConnections(1000);
|
||||
qDebug() << "Starting server on port" << getServerTCPPort();
|
||||
if (gameServer->listen(QHostAddress::Any, getServerTCPPort()))
|
||||
|
|
@ -413,9 +430,9 @@ bool Servatrice::initServer()
|
|||
|
||||
#if QT_VERSION > 0x050300
|
||||
// WEBSOCKET SERVER
|
||||
if(getNumberOfWebSocketPools() > 0)
|
||||
{
|
||||
websocketGameServer = new Servatrice_WebsocketGameServer(this, getNumberOfWebSocketPools(), servatriceDatabaseInterface->getDatabase(), this);
|
||||
if (getNumberOfWebSocketPools() > 0) {
|
||||
websocketGameServer = new Servatrice_WebsocketGameServer(this, getNumberOfWebSocketPools(),
|
||||
servatriceDatabaseInterface->getDatabase(), this);
|
||||
websocketGameServer->setMaxPendingConnections(1000);
|
||||
qDebug() << "Starting websocket server on port" << getServerWebSocketPort();
|
||||
if (websocketGameServer->listen(QHostAddress::Any, getServerWebSocketPort()))
|
||||
|
|
@ -430,7 +447,10 @@ bool Servatrice::initServer()
|
|||
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.";
|
||||
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());
|
||||
|
|
@ -449,12 +469,21 @@ void Servatrice::updateServerList()
|
|||
serverListMutex.lock();
|
||||
serverList.clear();
|
||||
|
||||
QSqlQuery *query = servatriceDatabaseInterface->prepareQuery("select id, ssl_cert, hostname, address, game_port, control_port from {prefix}_servers order by id asc");
|
||||
QSqlQuery *query = servatriceDatabaseInterface->prepareQuery(
|
||||
"select id, ssl_cert, hostname, address, game_port, control_port from {prefix}_servers order by id asc");
|
||||
servatriceDatabaseInterface->execSqlQuery(query);
|
||||
while (query->next()) {
|
||||
ServerProperties prop(query->value(0).toInt(), QSslCertificate(query->value(1).toString().toUtf8()), query->value(2).toString(), QHostAddress(query->value(3).toString()), query->value(4).toInt(), query->value(5).toInt());
|
||||
ServerProperties prop(query->value(0).toInt(), QSslCertificate(query->value(1).toString().toUtf8()),
|
||||
query->value(2).toString(), QHostAddress(query->value(3).toString()),
|
||||
query->value(4).toInt(), query->value(5).toInt());
|
||||
serverList.append(prop);
|
||||
qDebug() << QString("#%1 CERT=%2 NAME=%3 IP=%4:%5 CPORT=%6").arg(prop.id).arg(QString(prop.cert.digest().toHex())).arg(prop.hostname).arg(prop.address.toString()).arg(prop.gamePort).arg(prop.controlPort);
|
||||
qDebug() << QString("#%1 CERT=%2 NAME=%3 IP=%4:%5 CPORT=%6")
|
||||
.arg(prop.id)
|
||||
.arg(QString(prop.cert.digest().toHex()))
|
||||
.arg(prop.hostname)
|
||||
.arg(prop.address.toString())
|
||||
.arg(prop.gamePort)
|
||||
.arg(prop.controlPort);
|
||||
}
|
||||
|
||||
serverListMutex.unlock();
|
||||
|
|
@ -474,8 +503,8 @@ int Servatrice::getUsersWithAddress(const QHostAddress &address) const
|
|||
int result = 0;
|
||||
QReadLocker locker(&clientsLock);
|
||||
for (int i = 0; i < clients.size(); ++i)
|
||||
if (static_cast<AbstractServerSocketInterface *>(clients[i])->getPeerAddress() == address)
|
||||
++result;
|
||||
if (static_cast<AbstractServerSocketInterface *>(clients[i])->getPeerAddress() == address)
|
||||
++result;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
@ -495,7 +524,8 @@ void Servatrice::updateLoginMessage()
|
|||
if (!servatriceDatabaseInterface->checkSql())
|
||||
return;
|
||||
|
||||
QSqlQuery *query = servatriceDatabaseInterface->prepareQuery("select message from {prefix}_servermessages where id_server = :id_server order by timest desc limit 1");
|
||||
QSqlQuery *query = servatriceDatabaseInterface->prepareQuery(
|
||||
"select message from {prefix}_servermessages where id_server = :id_server order by timest desc limit 1");
|
||||
query->bindValue(":id_server", serverId);
|
||||
if (servatriceDatabaseInterface->execSqlQuery(query))
|
||||
if (query->next()) {
|
||||
|
|
@ -515,14 +545,15 @@ void Servatrice::updateLoginMessage()
|
|||
}
|
||||
}
|
||||
|
||||
void Servatrice::setRequiredFeatures(const QString featureList) {
|
||||
void Servatrice::setRequiredFeatures(const QString featureList)
|
||||
{
|
||||
FeatureSet features;
|
||||
serverRequiredFeatureList.clear();
|
||||
features.initalizeFeatureList(serverRequiredFeatureList);
|
||||
QStringList listReqFeatures = featureList.split(",", QString::SkipEmptyParts);
|
||||
if (!listReqFeatures.isEmpty())
|
||||
foreach(QString reqFeature, listReqFeatures)
|
||||
features.enableRequiredFeature(serverRequiredFeatureList, reqFeature);
|
||||
foreach (QString reqFeature, listReqFeatures)
|
||||
features.enableRequiredFeature(serverRequiredFeatureList, reqFeature);
|
||||
|
||||
qDebug() << "Set required client features to: " << serverRequiredFeatureList;
|
||||
}
|
||||
|
|
@ -546,7 +577,9 @@ void Servatrice::statusUpdate()
|
|||
rxBytes = 0;
|
||||
rxBytesMutex.unlock();
|
||||
|
||||
QSqlQuery *query = servatriceDatabaseInterface->prepareQuery("insert into {prefix}_uptime (id_server, timest, uptime, users_count, games_count, tx_bytes, rx_bytes) values(:id, NOW(), :uptime, :users_count, :games_count, :tx, :rx)");
|
||||
QSqlQuery *query = servatriceDatabaseInterface->prepareQuery(
|
||||
"insert into {prefix}_uptime (id_server, timest, uptime, users_count, games_count, tx_bytes, rx_bytes) "
|
||||
"values(:id, NOW(), :uptime, :users_count, :games_count, :tx, :rx)");
|
||||
query->bindValue(":id", serverId);
|
||||
query->bindValue(":uptime", uptime);
|
||||
query->bindValue(":users_count", uc);
|
||||
|
|
@ -555,44 +588,45 @@ void Servatrice::statusUpdate()
|
|||
query->bindValue(":rx", rx);
|
||||
servatriceDatabaseInterface->execSqlQuery(query);
|
||||
|
||||
if (getRegistrationEnabled() && getEnableInternalSMTPClient())
|
||||
{
|
||||
if (getRequireEmailActivationEnabled())
|
||||
{
|
||||
QSqlQuery *query = servatriceDatabaseInterface->prepareQuery("select a.name, b.email, b.token from {prefix}_activation_emails a left join {prefix}_users b on a.name = b.name");
|
||||
if (getRegistrationEnabled() && getEnableInternalSMTPClient()) {
|
||||
if (getRequireEmailActivationEnabled()) {
|
||||
QSqlQuery *query = servatriceDatabaseInterface->prepareQuery("select a.name, b.email, b.token from "
|
||||
"{prefix}_activation_emails a left join "
|
||||
"{prefix}_users b on a.name = b.name");
|
||||
if (!servatriceDatabaseInterface->execSqlQuery(query))
|
||||
return;
|
||||
|
||||
QSqlQuery *queryDelete = servatriceDatabaseInterface->prepareQuery("delete from {prefix}_activation_emails where name = :name");
|
||||
QSqlQuery *queryDelete =
|
||||
servatriceDatabaseInterface->prepareQuery("delete from {prefix}_activation_emails where name = :name");
|
||||
|
||||
while (query->next()) {
|
||||
const QString userName = query->value(0).toString();
|
||||
const QString emailAddress = query->value(1).toString();
|
||||
const QString token = query->value(2).toString();
|
||||
|
||||
if (smtpClient->enqueueActivationTokenMail(userName, emailAddress, token))
|
||||
{
|
||||
if (smtpClient->enqueueActivationTokenMail(userName, emailAddress, token)) {
|
||||
queryDelete->bindValue(":name", userName);
|
||||
servatriceDatabaseInterface->execSqlQuery(queryDelete);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (getEnableForgotPassword())
|
||||
{
|
||||
QSqlQuery *query = servatriceDatabaseInterface->prepareQuery("select a.name, b.email, b.token from {prefix}_forgot_password a left join {prefix}_users b on a.name = b.name where a.emailed = 0");
|
||||
if (getEnableForgotPassword()) {
|
||||
QSqlQuery *query = servatriceDatabaseInterface->prepareQuery(
|
||||
"select a.name, b.email, b.token from {prefix}_forgot_password a left join {prefix}_users b on a.name "
|
||||
"= b.name where a.emailed = 0");
|
||||
if (!servatriceDatabaseInterface->execSqlQuery(query))
|
||||
return;
|
||||
|
||||
QSqlQuery *queryDelete = servatriceDatabaseInterface->prepareQuery("update {prefix}_forgot_password set emailed = 1 where name = :name");
|
||||
QSqlQuery *queryDelete = servatriceDatabaseInterface->prepareQuery(
|
||||
"update {prefix}_forgot_password set emailed = 1 where name = :name");
|
||||
|
||||
while (query->next()) {
|
||||
const QString userName = query->value(0).toString();
|
||||
const QString emailAddress = query->value(1).toString();
|
||||
const QString token = query->value(2).toString();
|
||||
|
||||
if (smtpClient->enqueueForgotPasswordTokenMail(userName, emailAddress, token))
|
||||
{
|
||||
if (smtpClient->enqueueForgotPasswordTokenMail(userName, emailAddress, token)) {
|
||||
queryDelete->bindValue(":name", userName);
|
||||
servatriceDatabaseInterface->execSqlQuery(queryDelete);
|
||||
}
|
||||
|
|
@ -673,20 +707,28 @@ void Servatrice::addIslInterface(int serverId, IslInterface *interface)
|
|||
islInterfaces.insert(serverId, interface);
|
||||
connect(interface, SIGNAL(externalUserJoined(ServerInfo_User)), this, SLOT(externalUserJoined(ServerInfo_User)));
|
||||
connect(interface, SIGNAL(externalUserLeft(QString)), this, SLOT(externalUserLeft(QString)));
|
||||
connect(interface, SIGNAL(externalRoomUserJoined(int, ServerInfo_User)), this, SLOT(externalRoomUserJoined(int, ServerInfo_User)));
|
||||
connect(interface, SIGNAL(externalRoomUserJoined(int, ServerInfo_User)), this,
|
||||
SLOT(externalRoomUserJoined(int, ServerInfo_User)));
|
||||
connect(interface, SIGNAL(externalRoomUserLeft(int, QString)), this, SLOT(externalRoomUserLeft(int, QString)));
|
||||
connect(interface, SIGNAL(externalRoomSay(int, QString, QString)), this, SLOT(externalRoomSay(int, QString, QString)));
|
||||
connect(interface, SIGNAL(externalRoomGameListChanged(int, ServerInfo_Game)), this, SLOT(externalRoomGameListChanged(int, ServerInfo_Game)));
|
||||
connect(interface, SIGNAL(joinGameCommandReceived(Command_JoinGame, int, int, int, qint64)), this, SLOT(externalJoinGameCommandReceived(Command_JoinGame, int, int, int, qint64)));
|
||||
connect(interface, SIGNAL(gameCommandContainerReceived(CommandContainer, int, int, qint64)), this, SLOT(externalGameCommandContainerReceived(CommandContainer, int, int, qint64)));
|
||||
connect(interface, SIGNAL(responseReceived(Response, qint64)), this, SLOT(externalResponseReceived(Response, qint64)));
|
||||
connect(interface, SIGNAL(gameEventContainerReceived(GameEventContainer, qint64)), this, SLOT(externalGameEventContainerReceived(GameEventContainer, qint64)));
|
||||
connect(interface, SIGNAL(externalRoomSay(int, QString, QString)), this,
|
||||
SLOT(externalRoomSay(int, QString, QString)));
|
||||
connect(interface, SIGNAL(externalRoomGameListChanged(int, ServerInfo_Game)), this,
|
||||
SLOT(externalRoomGameListChanged(int, ServerInfo_Game)));
|
||||
connect(interface, SIGNAL(joinGameCommandReceived(Command_JoinGame, int, int, int, qint64)), this,
|
||||
SLOT(externalJoinGameCommandReceived(Command_JoinGame, int, int, int, qint64)));
|
||||
connect(interface, SIGNAL(gameCommandContainerReceived(CommandContainer, int, int, qint64)), this,
|
||||
SLOT(externalGameCommandContainerReceived(CommandContainer, int, int, qint64)));
|
||||
connect(interface, SIGNAL(responseReceived(Response, qint64)), this,
|
||||
SLOT(externalResponseReceived(Response, qint64)));
|
||||
connect(interface, SIGNAL(gameEventContainerReceived(GameEventContainer, qint64)), this,
|
||||
SLOT(externalGameEventContainerReceived(GameEventContainer, qint64)));
|
||||
}
|
||||
|
||||
void Servatrice::removeIslInterface(int serverId)
|
||||
{
|
||||
// Only call with islLock locked for writing
|
||||
// XXX we probably need to delete everything that belonged to it... <-- THIS SHOULD BE FIXED FOR ISL FUNCTIONALITY TO WORK COMPLETLY!
|
||||
// XXX we probably need to delete everything that belonged to it... <-- THIS SHOULD BE FIXED FOR ISL FUNCTIONALITY
|
||||
// TO WORK COMPLETLY!
|
||||
islInterfaces.remove(serverId);
|
||||
}
|
||||
|
||||
|
|
@ -707,206 +749,257 @@ void Servatrice::doSendIslMessage(const IslMessage &msg, int serverId)
|
|||
|
||||
// start helper functions
|
||||
|
||||
int Servatrice::getMaxUserTotal() const {
|
||||
int Servatrice::getMaxUserTotal() const
|
||||
{
|
||||
return settingsCache->value("security/max_users_total", 500).toInt();
|
||||
}
|
||||
|
||||
bool Servatrice::getMaxUserLimitEnabled() const {
|
||||
bool Servatrice::getMaxUserLimitEnabled() const
|
||||
{
|
||||
return settingsCache->value("security/enable_max_user_limit", false).toBool();
|
||||
}
|
||||
|
||||
QString Servatrice::getServerName() const {
|
||||
QString Servatrice::getServerName() const
|
||||
{
|
||||
return settingsCache->value("server/name", "My Cockatrice server").toString();
|
||||
}
|
||||
|
||||
int Servatrice::getServerID() const {
|
||||
int Servatrice::getServerID() const
|
||||
{
|
||||
return settingsCache->value("server/id", 0).toInt();
|
||||
}
|
||||
|
||||
bool Servatrice::getClientIDRequiredEnabled() const {
|
||||
bool Servatrice::getClientIDRequiredEnabled() const
|
||||
{
|
||||
return settingsCache->value("server/requireclientid", 0).toBool();
|
||||
}
|
||||
|
||||
bool Servatrice::getRegOnlyServerEnabled() const {
|
||||
bool Servatrice::getRegOnlyServerEnabled() const
|
||||
{
|
||||
return settingsCache->value("authentication/regonly", 0).toBool();
|
||||
}
|
||||
|
||||
QString Servatrice::getAuthenticationMethodString() const {
|
||||
QString Servatrice::getAuthenticationMethodString() const
|
||||
{
|
||||
return settingsCache->value("authentication/method").toString();
|
||||
}
|
||||
|
||||
bool Servatrice::getStoreReplaysEnabled() const {
|
||||
bool Servatrice::getStoreReplaysEnabled() const
|
||||
{
|
||||
return settingsCache->value("game/store_replays", true).toBool();
|
||||
}
|
||||
|
||||
int Servatrice::getMaxTcpUserLimit() const {
|
||||
int Servatrice::getMaxTcpUserLimit() const
|
||||
{
|
||||
return settingsCache->value("security/max_users_tcp", 500).toInt();
|
||||
}
|
||||
|
||||
int Servatrice::getMaxWebSocketUserLimit() const {
|
||||
int Servatrice::getMaxWebSocketUserLimit() const
|
||||
{
|
||||
return settingsCache->value("security/max_users_websocket", 500).toInt();
|
||||
}
|
||||
|
||||
bool Servatrice::getRegistrationEnabled() const {
|
||||
bool Servatrice::getRegistrationEnabled() const
|
||||
{
|
||||
return settingsCache->value("registration/enabled", false).toBool();
|
||||
}
|
||||
|
||||
bool Servatrice::getRequireEmailForRegistrationEnabled() const {
|
||||
bool Servatrice::getRequireEmailForRegistrationEnabled() const
|
||||
{
|
||||
return settingsCache->value("registration/requireemail", true).toBool();
|
||||
}
|
||||
|
||||
bool Servatrice::getRequireEmailActivationEnabled() const {
|
||||
bool Servatrice::getRequireEmailActivationEnabled() const
|
||||
{
|
||||
return settingsCache->value("registration/requireemailactivation", true).toBool();
|
||||
}
|
||||
|
||||
QString Servatrice::getRequiredFeatures() const {
|
||||
QString Servatrice::getRequiredFeatures() const
|
||||
{
|
||||
return settingsCache->value("server/requiredfeatures", "").toString();
|
||||
}
|
||||
|
||||
QString Servatrice::getDBTypeString() const {
|
||||
QString Servatrice::getDBTypeString() const
|
||||
{
|
||||
return settingsCache->value("database/type").toString();
|
||||
}
|
||||
|
||||
QString Servatrice::getDBPrefixString() const {
|
||||
QString Servatrice::getDBPrefixString() const
|
||||
{
|
||||
return settingsCache->value("database/prefix").toString();
|
||||
}
|
||||
|
||||
QString Servatrice::getDBHostNameString() const {
|
||||
QString Servatrice::getDBHostNameString() const
|
||||
{
|
||||
return settingsCache->value("database/hostname").toString();
|
||||
}
|
||||
|
||||
QString Servatrice::getDBDatabaseNameString() const {
|
||||
QString Servatrice::getDBDatabaseNameString() const
|
||||
{
|
||||
return settingsCache->value("database/database").toString();
|
||||
}
|
||||
|
||||
QString Servatrice::getDBUserNameString() const {
|
||||
QString Servatrice::getDBUserNameString() const
|
||||
{
|
||||
return settingsCache->value("database/user").toString();
|
||||
}
|
||||
|
||||
QString Servatrice::getDBPasswordString() const {
|
||||
QString Servatrice::getDBPasswordString() const
|
||||
{
|
||||
return settingsCache->value("database/password").toString();
|
||||
}
|
||||
|
||||
QString Servatrice::getRoomsMethodString() const {
|
||||
QString Servatrice::getRoomsMethodString() const
|
||||
{
|
||||
return settingsCache->value("rooms/method").toString();
|
||||
}
|
||||
|
||||
int Servatrice::getMaxGameInactivityTime() const {
|
||||
int Servatrice::getMaxGameInactivityTime() const
|
||||
{
|
||||
return settingsCache->value("game/max_game_inactivity_time", 120).toInt();
|
||||
}
|
||||
|
||||
int Servatrice::getMaxPlayerInactivityTime() const {
|
||||
int Servatrice::getMaxPlayerInactivityTime() const
|
||||
{
|
||||
return settingsCache->value("server/max_player_inactivity_time", 15).toInt();
|
||||
}
|
||||
|
||||
int Servatrice::getClientKeepAlive() const {
|
||||
int Servatrice::getClientKeepAlive() const
|
||||
{
|
||||
return settingsCache->value("server/clientkeepalive", 1).toInt();
|
||||
}
|
||||
|
||||
int Servatrice::getMaxUsersPerAddress() const {
|
||||
int Servatrice::getMaxUsersPerAddress() const
|
||||
{
|
||||
return settingsCache->value("security/max_users_per_address", 4).toInt();
|
||||
}
|
||||
|
||||
int Servatrice::getMessageCountingInterval() const {
|
||||
int Servatrice::getMessageCountingInterval() const
|
||||
{
|
||||
return settingsCache->value("security/message_counting_interval", 10).toInt();
|
||||
}
|
||||
|
||||
int Servatrice::getMaxMessageCountPerInterval() const {
|
||||
int Servatrice::getMaxMessageCountPerInterval() const
|
||||
{
|
||||
return settingsCache->value("security/max_message_count_per_interval", 15).toInt();
|
||||
}
|
||||
|
||||
int Servatrice::getMaxMessageSizePerInterval() const {
|
||||
int Servatrice::getMaxMessageSizePerInterval() const
|
||||
{
|
||||
return settingsCache->value("security/max_message_size_per_interval", 1000).toInt();
|
||||
}
|
||||
|
||||
int Servatrice::getMaxGamesPerUser() const {
|
||||
int Servatrice::getMaxGamesPerUser() const
|
||||
{
|
||||
return settingsCache->value("security/max_games_per_user", 5).toInt();
|
||||
}
|
||||
|
||||
int Servatrice::getCommandCountingInterval() const {
|
||||
int Servatrice::getCommandCountingInterval() const
|
||||
{
|
||||
return settingsCache->value("game/command_counting_interval", 10).toInt();
|
||||
}
|
||||
|
||||
int Servatrice::getMaxCommandCountPerInterval() const {
|
||||
int Servatrice::getMaxCommandCountPerInterval() const
|
||||
{
|
||||
return settingsCache->value("game/max_command_count_per_interval", 20).toInt();
|
||||
}
|
||||
|
||||
int Servatrice::getServerStatusUpdateTime() const {
|
||||
int Servatrice::getServerStatusUpdateTime() const
|
||||
{
|
||||
return settingsCache->value("server/statusupdate", 15000).toInt();
|
||||
}
|
||||
|
||||
int Servatrice::getNumberOfTCPPools() const {
|
||||
int Servatrice::getNumberOfTCPPools() const
|
||||
{
|
||||
return settingsCache->value("server/number_pools", 1).toInt();
|
||||
}
|
||||
|
||||
int Servatrice::getServerTCPPort() const {
|
||||
int Servatrice::getServerTCPPort() const
|
||||
{
|
||||
return settingsCache->value("server/port", 4747).toInt();
|
||||
}
|
||||
|
||||
int Servatrice::getNumberOfWebSocketPools() const {
|
||||
int Servatrice::getNumberOfWebSocketPools() const
|
||||
{
|
||||
return settingsCache->value("server/websocket_number_pools", 1).toInt();
|
||||
}
|
||||
|
||||
int Servatrice::getServerWebSocketPort() const {
|
||||
int Servatrice::getServerWebSocketPort() const
|
||||
{
|
||||
return settingsCache->value("server/websocket_port", 4748).toInt();
|
||||
}
|
||||
|
||||
bool Servatrice::getISLNetworkEnabled() const {
|
||||
bool Servatrice::getISLNetworkEnabled() const
|
||||
{
|
||||
return settingsCache->value("servernetwork/active", false).toBool();
|
||||
}
|
||||
|
||||
QString Servatrice::getISLNetworkSSLCertFile() const {
|
||||
QString Servatrice::getISLNetworkSSLCertFile() const
|
||||
{
|
||||
return settingsCache->value("servernetwork/ssl_cert").toString();
|
||||
}
|
||||
|
||||
QString Servatrice::getISLNetworkSSLKeyFile() const {
|
||||
QString Servatrice::getISLNetworkSSLKeyFile() const
|
||||
{
|
||||
return settingsCache->value("servernetwork/ssl_key").toString();
|
||||
}
|
||||
|
||||
int Servatrice::getISLNetworkPort() const {
|
||||
int Servatrice::getISLNetworkPort() const
|
||||
{
|
||||
return settingsCache->value("servernetwork/port", 14747).toInt();
|
||||
}
|
||||
|
||||
int Servatrice::getIdleClientTimeout() const {
|
||||
int Servatrice::getIdleClientTimeout() const
|
||||
{
|
||||
return settingsCache->value("server/idleclienttimeout", 3600).toInt();
|
||||
}
|
||||
|
||||
bool Servatrice::getEnableLogQuery() const {
|
||||
bool Servatrice::getEnableLogQuery() const
|
||||
{
|
||||
return settingsCache->value("logging/enablelogquery", false).toBool();
|
||||
}
|
||||
|
||||
int Servatrice::getMaxAccountsPerEmail() const {
|
||||
int Servatrice::getMaxAccountsPerEmail() const
|
||||
{
|
||||
return settingsCache->value("registration/maxaccountsperemail", 0).toInt();
|
||||
}
|
||||
|
||||
bool Servatrice::getEnableInternalSMTPClient() const {
|
||||
bool Servatrice::getEnableInternalSMTPClient() const
|
||||
{
|
||||
return settingsCache->value("smtp/enableinternalsmtpclient", true).toBool();
|
||||
}
|
||||
|
||||
bool Servatrice::getEnableForgotPassword() const {
|
||||
bool Servatrice::getEnableForgotPassword() const
|
||||
{
|
||||
return settingsCache->value("forgotpassword/enable", false).toBool();
|
||||
}
|
||||
|
||||
int Servatrice::getForgotPasswordTokenLife() const {
|
||||
int Servatrice::getForgotPasswordTokenLife() const
|
||||
{
|
||||
return settingsCache->value("forgotpassword/tokenlife", 60).toInt();
|
||||
}
|
||||
|
||||
bool Servatrice::getEnableForgotPasswordChallenge() const {
|
||||
bool Servatrice::getEnableForgotPasswordChallenge() const
|
||||
{
|
||||
return settingsCache->value("forgotpassword/enablechallenge", false).toBool();
|
||||
}
|
||||
|
||||
QString Servatrice::getEmailBlackList() const {
|
||||
|
||||
QString Servatrice::getEmailBlackList() const
|
||||
{
|
||||
return settingsCache->value("registration/emailproviderblacklist").toString();
|
||||
}
|
||||
|
||||
bool Servatrice::getEnableAudit() const {
|
||||
bool Servatrice::getEnableAudit() const
|
||||
{
|
||||
return settingsCache->value("audit/enable_audit", true).toBool();
|
||||
}
|
||||
|
||||
bool Servatrice::getEnableRegistrationAudit() const {
|
||||
bool Servatrice::getEnableRegistrationAudit() const
|
||||
{
|
||||
return settingsCache->value("audit/enable_registration_audit", true).toBool();
|
||||
}
|
||||
|
||||
bool Servatrice::getEnableForgotPasswordAudit() const {
|
||||
bool Servatrice::getEnableForgotPasswordAudit() const
|
||||
{
|
||||
return settingsCache->value("audit/enable_forgotpassword_audit", true).toBool();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,17 +22,16 @@
|
|||
|
||||
#include <QTcpServer>
|
||||
#if QT_VERSION > 0x050300
|
||||
#include <QWebSocketServer>
|
||||
#include <QWebSocketServer>
|
||||
#endif
|
||||
#include <QMutex>
|
||||
#include <QSslCertificate>
|
||||
#include <QSslKey>
|
||||
#include "server.h"
|
||||
#include <QHostAddress>
|
||||
#include <QMetaType>
|
||||
#include <QMutex>
|
||||
#include <QReadWriteLock>
|
||||
#include <QSqlDatabase>
|
||||
#include <QMetaType>
|
||||
#include "server.h"
|
||||
|
||||
#include <QSslCertificate>
|
||||
#include <QSslKey>
|
||||
|
||||
Q_DECLARE_METATYPE(QSqlDatabase)
|
||||
|
||||
|
|
@ -47,28 +46,37 @@ class AbstractServerSocketInterface;
|
|||
class IslInterface;
|
||||
class FeatureSet;
|
||||
|
||||
class Servatrice_GameServer : public QTcpServer {
|
||||
class Servatrice_GameServer : public QTcpServer
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
Servatrice *server;
|
||||
QList<Servatrice_ConnectionPool *> connectionPools;
|
||||
|
||||
public:
|
||||
Servatrice_GameServer(Servatrice *_server, int _numberPools, const QSqlDatabase &_sqlDatabase, QObject *parent = 0);
|
||||
~Servatrice_GameServer();
|
||||
|
||||
protected:
|
||||
void incomingConnection(qintptr socketDescriptor);
|
||||
Servatrice_ConnectionPool *findLeastUsedConnectionPool();
|
||||
};
|
||||
|
||||
#if QT_VERSION > 0x050300
|
||||
class Servatrice_WebsocketGameServer : public QWebSocketServer {
|
||||
class Servatrice_WebsocketGameServer : public QWebSocketServer
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
Servatrice *server;
|
||||
QList<Servatrice_ConnectionPool *> connectionPools;
|
||||
|
||||
public:
|
||||
Servatrice_WebsocketGameServer(Servatrice *_server, int _numberPools, const QSqlDatabase &_sqlDatabase, QObject *parent = 0);
|
||||
Servatrice_WebsocketGameServer(Servatrice *_server,
|
||||
int _numberPools,
|
||||
const QSqlDatabase &_sqlDatabase,
|
||||
QObject *parent = 0);
|
||||
~Servatrice_WebsocketGameServer();
|
||||
|
||||
protected:
|
||||
Servatrice_ConnectionPool *findLeastUsedConnectionPool();
|
||||
protected slots:
|
||||
|
|
@ -76,20 +84,29 @@ protected slots:
|
|||
};
|
||||
#endif
|
||||
|
||||
class Servatrice_IslServer : public QTcpServer {
|
||||
class Servatrice_IslServer : public QTcpServer
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
Servatrice *server;
|
||||
QSslCertificate cert;
|
||||
QSslKey privateKey;
|
||||
|
||||
public:
|
||||
Servatrice_IslServer(Servatrice *_server, const QSslCertificate &_cert, const QSslKey &_privateKey, QObject *parent = 0)
|
||||
: QTcpServer(parent), server(_server), cert(_cert), privateKey(_privateKey) { }
|
||||
Servatrice_IslServer(Servatrice *_server,
|
||||
const QSslCertificate &_cert,
|
||||
const QSslKey &_privateKey,
|
||||
QObject *parent = 0)
|
||||
: QTcpServer(parent), server(_server), cert(_cert), privateKey(_privateKey)
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
void incomingConnection(qintptr socketDescriptor);
|
||||
};
|
||||
|
||||
class ServerProperties {
|
||||
class ServerProperties
|
||||
{
|
||||
public:
|
||||
int id;
|
||||
QSslCertificate cert;
|
||||
|
|
@ -98,22 +115,40 @@ public:
|
|||
int gamePort;
|
||||
int controlPort;
|
||||
|
||||
ServerProperties(int _id, const QSslCertificate &_cert, const QString &_hostname, const QHostAddress &_address, int _gamePort, int _controlPort)
|
||||
: id(_id), cert(_cert), hostname(_hostname), address(_address), gamePort(_gamePort), controlPort(_controlPort) { }
|
||||
ServerProperties(int _id,
|
||||
const QSslCertificate &_cert,
|
||||
const QString &_hostname,
|
||||
const QHostAddress &_address,
|
||||
int _gamePort,
|
||||
int _controlPort)
|
||||
: id(_id), cert(_cert), hostname(_hostname), address(_address), gamePort(_gamePort), controlPort(_controlPort)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class Servatrice : public Server
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum AuthenticationMethod { AuthenticationNone, AuthenticationSql, AuthenticationPassword };
|
||||
enum AuthenticationMethod
|
||||
{
|
||||
AuthenticationNone,
|
||||
AuthenticationSql,
|
||||
AuthenticationPassword
|
||||
};
|
||||
private slots:
|
||||
void statusUpdate();
|
||||
void shutdownTimeout();
|
||||
|
||||
protected:
|
||||
void doSendIslMessage(const IslMessage &msg, int serverId);
|
||||
|
||||
private:
|
||||
enum DatabaseType { DatabaseNone, DatabaseMySql };
|
||||
enum DatabaseType
|
||||
{
|
||||
DatabaseNone,
|
||||
DatabaseMySql
|
||||
};
|
||||
AuthenticationMethod authenticationMethod;
|
||||
DatabaseType databaseType;
|
||||
QTimer *pingClock, *statusUpdateClock;
|
||||
|
|
@ -167,22 +202,45 @@ public slots:
|
|||
void scheduleShutdown(const QString &reason, int minutes);
|
||||
void updateLoginMessage();
|
||||
void setRequiredFeatures(const QString featureList);
|
||||
|
||||
public:
|
||||
Servatrice(QObject *parent = 0);
|
||||
~Servatrice();
|
||||
bool initServer();
|
||||
QMap<QString, bool> getServerRequiredFeatureList() const { return serverRequiredFeatureList; }
|
||||
QString getOfficialWarningsList() const { return officialWarnings; }
|
||||
QMap<QString, bool> getServerRequiredFeatureList() const
|
||||
{
|
||||
return serverRequiredFeatureList;
|
||||
}
|
||||
QString getOfficialWarningsList() const
|
||||
{
|
||||
return officialWarnings;
|
||||
}
|
||||
QString getServerName() const;
|
||||
QString getLoginMessage() const { QMutexLocker locker(&loginMessageMutex); return loginMessage; }
|
||||
QString getLoginMessage() const
|
||||
{
|
||||
QMutexLocker locker(&loginMessageMutex);
|
||||
return loginMessage;
|
||||
}
|
||||
QString getRequiredFeatures() const;
|
||||
QString getAuthenticationMethodString() const;
|
||||
QString getDBTypeString() const;
|
||||
QString getDbPrefix() const { return dbPrefix; }
|
||||
QString getDbPrefix() const
|
||||
{
|
||||
return dbPrefix;
|
||||
}
|
||||
QString getEmailBlackList() const;
|
||||
AuthenticationMethod getAuthenticationMethod() const { return authenticationMethod; }
|
||||
bool permitUnregisteredUsers() const { return authenticationMethod != AuthenticationNone; }
|
||||
bool getGameShouldPing() const { return true; }
|
||||
AuthenticationMethod getAuthenticationMethod() const
|
||||
{
|
||||
return authenticationMethod;
|
||||
}
|
||||
bool permitUnregisteredUsers() const
|
||||
{
|
||||
return authenticationMethod != AuthenticationNone;
|
||||
}
|
||||
bool getGameShouldPing() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
bool getClientIDRequiredEnabled() const;
|
||||
bool getRegOnlyServerEnabled() const;
|
||||
bool getMaxUserLimitEnabled() const;
|
||||
|
|
|
|||
|
|
@ -3,13 +3,12 @@
|
|||
#include <QThread>
|
||||
|
||||
Servatrice_ConnectionPool::Servatrice_ConnectionPool(Servatrice_DatabaseInterface *_databaseInterface)
|
||||
: databaseInterface(_databaseInterface),
|
||||
clientCount(0)
|
||||
: databaseInterface(_databaseInterface), clientCount(0)
|
||||
{
|
||||
}
|
||||
|
||||
Servatrice_ConnectionPool::~Servatrice_ConnectionPool()
|
||||
{
|
||||
delete databaseInterface;
|
||||
thread()->quit();
|
||||
delete databaseInterface;
|
||||
thread()->quit();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,29 +1,46 @@
|
|||
#ifndef SERVATRICE_CONNECTION_POOL_H
|
||||
#define SERVATRICE_CONNECTION_POOL_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QMutex>
|
||||
#include <QMutexLocker>
|
||||
#include <QObject>
|
||||
|
||||
class Servatrice_DatabaseInterface;
|
||||
|
||||
class Servatrice_ConnectionPool : public QObject {
|
||||
Q_OBJECT
|
||||
class Servatrice_ConnectionPool : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
Servatrice_DatabaseInterface *databaseInterface;
|
||||
bool threaded;
|
||||
mutable QMutex clientCountMutex;
|
||||
int clientCount;
|
||||
Servatrice_DatabaseInterface *databaseInterface;
|
||||
bool threaded;
|
||||
mutable QMutex clientCountMutex;
|
||||
int clientCount;
|
||||
|
||||
public:
|
||||
Servatrice_ConnectionPool(Servatrice_DatabaseInterface *_databaseInterface);
|
||||
~Servatrice_ConnectionPool();
|
||||
|
||||
Servatrice_DatabaseInterface *getDatabaseInterface() const { return databaseInterface; }
|
||||
|
||||
int getClientCount() const { QMutexLocker locker(&clientCountMutex); return clientCount; }
|
||||
void addClient() { QMutexLocker locker(&clientCountMutex); ++clientCount; }
|
||||
Servatrice_ConnectionPool(Servatrice_DatabaseInterface *_databaseInterface);
|
||||
~Servatrice_ConnectionPool();
|
||||
|
||||
Servatrice_DatabaseInterface *getDatabaseInterface() const
|
||||
{
|
||||
return databaseInterface;
|
||||
}
|
||||
|
||||
int getClientCount() const
|
||||
{
|
||||
QMutexLocker locker(&clientCountMutex);
|
||||
return clientCount;
|
||||
}
|
||||
void addClient()
|
||||
{
|
||||
QMutexLocker locker(&clientCountMutex);
|
||||
++clientCount;
|
||||
}
|
||||
public slots:
|
||||
void removeClient() { QMutexLocker locker(&clientCountMutex); --clientCount; }
|
||||
void removeClient()
|
||||
{
|
||||
QMutexLocker locker(&clientCountMutex);
|
||||
--clientCount;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,20 +1,18 @@
|
|||
#include "servatrice.h"
|
||||
#include "servatrice_database_interface.h"
|
||||
#include "decklist.h"
|
||||
#include "passwordhasher.h"
|
||||
#include "pb/game_replay.pb.h"
|
||||
#include "servatrice.h"
|
||||
#include "serversocketinterface.h"
|
||||
#include "settingscache.h"
|
||||
#include "decklist.h"
|
||||
#include "pb/game_replay.pb.h"
|
||||
#include <QChar>
|
||||
#include <QDateTime>
|
||||
#include <QDebug>
|
||||
#include <QSqlError>
|
||||
#include <QSqlQuery>
|
||||
#include <QDateTime>
|
||||
#include <QChar>
|
||||
|
||||
Servatrice_DatabaseInterface::Servatrice_DatabaseInterface(int _instanceId, Servatrice *_server)
|
||||
: instanceId(_instanceId),
|
||||
sqlDatabase(QSqlDatabase()),
|
||||
server(_server)
|
||||
: instanceId(_instanceId), sqlDatabase(QSqlDatabase()), server(_server)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -35,8 +33,10 @@ void Servatrice_DatabaseInterface::initDatabase(const QSqlDatabase &_sqlDatabase
|
|||
}
|
||||
}
|
||||
|
||||
bool Servatrice_DatabaseInterface::initDatabase(const QString &type, const QString &hostName,
|
||||
const QString &databaseName, const QString &userName,
|
||||
bool Servatrice_DatabaseInterface::initDatabase(const QString &type,
|
||||
const QString &hostName,
|
||||
const QString &databaseName,
|
||||
const QString &userName,
|
||||
const QString &password)
|
||||
{
|
||||
sqlDatabase = QSqlDatabase::addDatabase(type, "main");
|
||||
|
|
@ -62,23 +62,34 @@ bool Servatrice_DatabaseInterface::openDatabase()
|
|||
|
||||
QSqlQuery *versionQuery = prepareQuery("select version from {prefix}_schema_version limit 1");
|
||||
if (!execSqlQuery(versionQuery)) {
|
||||
qCritical() << QString("[%1] Error opening database: unable to load database schema version (hint: ensure the cockatrice_schema_version exists)").arg(poolStr);
|
||||
qCritical() << QString("[%1] Error opening database: unable to load database schema version (hint: ensure the "
|
||||
"cockatrice_schema_version exists)")
|
||||
.arg(poolStr);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (versionQuery->next()) {
|
||||
const int dbversion = versionQuery->value(0).toInt();
|
||||
const int expectedversion = DATABASE_SCHEMA_VERSION;
|
||||
if(dbversion < expectedversion)
|
||||
{
|
||||
qCritical() << QString("[%1] Error opening database: the database schema version is too old, you need to run the migrations to update it from version %2 to version %3").arg(poolStr).arg(dbversion).arg(expectedversion);
|
||||
if (dbversion < expectedversion) {
|
||||
qCritical() << QString("[%1] Error opening database: the database schema version is too old, you need to "
|
||||
"run the migrations to update it from version %2 to version %3")
|
||||
.arg(poolStr)
|
||||
.arg(dbversion)
|
||||
.arg(expectedversion);
|
||||
return false;
|
||||
} else if(dbversion > expectedversion) {
|
||||
qCritical() << QString("[%1] Error opening database: the database schema version %2 is too new, you need to update servatrice (this servatrice actually uses version %3)").arg(poolStr).arg(dbversion).arg(expectedversion);
|
||||
} else if (dbversion > expectedversion) {
|
||||
qCritical() << QString("[%1] Error opening database: the database schema version %2 is too new, you need "
|
||||
"to update servatrice (this servatrice actually uses version %3)")
|
||||
.arg(poolStr)
|
||||
.arg(dbversion)
|
||||
.arg(expectedversion);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
qCritical() << QString("[%1] Error opening database: unable to load database schema version (hint: ensure the cockatrice_schema_version contains a single record)").arg(poolStr);
|
||||
qCritical() << QString("[%1] Error opening database: unable to load database schema version (hint: ensure the "
|
||||
"cockatrice_schema_version contains a single record)")
|
||||
.arg(poolStr);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -98,14 +109,14 @@ bool Servatrice_DatabaseInterface::checkSql()
|
|||
return true;
|
||||
}
|
||||
|
||||
QSqlQuery * Servatrice_DatabaseInterface::prepareQuery(const QString &queryText)
|
||||
QSqlQuery *Servatrice_DatabaseInterface::prepareQuery(const QString &queryText)
|
||||
{
|
||||
if(preparedStatements.contains(queryText))
|
||||
if (preparedStatements.contains(queryText))
|
||||
return preparedStatements.value(queryText);
|
||||
|
||||
QString prefixedQueryText = queryText;
|
||||
prefixedQueryText.replace("{prefix}", server->getDbPrefix());
|
||||
QSqlQuery * query = new QSqlQuery(sqlDatabase);
|
||||
QSqlQuery *query = new QSqlQuery(sqlDatabase);
|
||||
query->prepare(prefixedQueryText);
|
||||
|
||||
preparedStatements.insert(queryText, query);
|
||||
|
|
@ -121,10 +132,10 @@ bool Servatrice_DatabaseInterface::execSqlQuery(QSqlQuery *query)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool Servatrice_DatabaseInterface::usernameIsValid(const QString &user, QString & error)
|
||||
bool Servatrice_DatabaseInterface::usernameIsValid(const QString &user, QString &error)
|
||||
{
|
||||
int minNameLength = settingsCache->value("users/minnamelength", 6).toInt();
|
||||
if(minNameLength < 1)
|
||||
if (minNameLength < 1)
|
||||
minNameLength = 1;
|
||||
int maxNameLength = settingsCache->value("users/maxnamelength", 12).toInt();
|
||||
bool allowLowercase = settingsCache->value("users/allowlowercase", true).toBool();
|
||||
|
|
@ -137,7 +148,16 @@ bool Servatrice_DatabaseInterface::usernameIsValid(const QString &user, QString
|
|||
disallowedWords.removeDuplicates();
|
||||
QString disallowedRegExpStr = settingsCache->value("users/disallowedregexp", "").toString();
|
||||
|
||||
error = QString("%1|%2|%3|%4|%5|%6|%7|%8|%9").arg(minNameLength).arg(maxNameLength).arg(allowLowercase).arg(allowUppercase).arg(allowNumerics).arg(allowPunctuationPrefix).arg(allowedPunctuation).arg(disallowedWordsStr).arg(disallowedRegExpStr);
|
||||
error = QString("%1|%2|%3|%4|%5|%6|%7|%8|%9")
|
||||
.arg(minNameLength)
|
||||
.arg(maxNameLength)
|
||||
.arg(allowLowercase)
|
||||
.arg(allowUppercase)
|
||||
.arg(allowNumerics)
|
||||
.arg(allowPunctuationPrefix)
|
||||
.arg(allowedPunctuation)
|
||||
.arg(disallowedWordsStr)
|
||||
.arg(disallowedRegExpStr);
|
||||
|
||||
if (user.length() < minNameLength || user.length() > maxNameLength)
|
||||
return false;
|
||||
|
|
@ -146,11 +166,13 @@ bool Servatrice_DatabaseInterface::usernameIsValid(const QString &user, QString
|
|||
return false;
|
||||
|
||||
for (const QString &word : disallowedWords) {
|
||||
if (user.contains(word, Qt::CaseInsensitive)) return false;
|
||||
if (user.contains(word, Qt::CaseInsensitive))
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const QRegExp ®Exp : settingsCache->disallowedRegExp) {
|
||||
if (regExp.exactMatch(user)) return false;
|
||||
if (regExp.exactMatch(user))
|
||||
return false;
|
||||
}
|
||||
|
||||
QString regEx("[");
|
||||
|
|
@ -158,7 +180,7 @@ bool Servatrice_DatabaseInterface::usernameIsValid(const QString &user, QString
|
|||
regEx.append("a-z");
|
||||
if (allowUppercase)
|
||||
regEx.append("A-Z");
|
||||
if(allowNumerics)
|
||||
if (allowNumerics)
|
||||
regEx.append("0-9");
|
||||
regEx.append(QRegExp::escape(allowedPunctuation));
|
||||
regEx.append("]+");
|
||||
|
|
@ -167,7 +189,14 @@ bool Servatrice_DatabaseInterface::usernameIsValid(const QString &user, QString
|
|||
return re.exactMatch(user);
|
||||
}
|
||||
|
||||
bool Servatrice_DatabaseInterface::registerUser(const QString &userName, const QString &realName, ServerInfo_User_Gender const &gender, const QString &password, const QString &emailAddress, const QString &country, QString &token, bool active)
|
||||
bool Servatrice_DatabaseInterface::registerUser(const QString &userName,
|
||||
const QString &realName,
|
||||
ServerInfo_User_Gender const &gender,
|
||||
const QString &password,
|
||||
const QString &emailAddress,
|
||||
const QString &country,
|
||||
QString &token,
|
||||
bool active)
|
||||
{
|
||||
if (!checkSql())
|
||||
return false;
|
||||
|
|
@ -175,10 +204,13 @@ bool Servatrice_DatabaseInterface::registerUser(const QString &userName, const Q
|
|||
QString passwordSha512 = PasswordHasher::computeHash(password, PasswordHasher::generateRandomSalt());
|
||||
token = active ? QString() : PasswordHasher::generateActivationToken();
|
||||
|
||||
QSqlQuery *query = prepareQuery("insert into {prefix}_users "
|
||||
"(name, realname, gender, password_sha512, email, country, registrationDate, active, token, admin, avatar_bmp, clientid, privlevel, privlevelStartDate, privlevelEndDate) "
|
||||
"values "
|
||||
"(:userName, :realName, :gender, :password_sha512, :email, :country, UTC_TIMESTAMP(), :active, :token, 0, '', '', 'NONE', UTC_TIMESTAMP(), UTC_TIMESTAMP())");
|
||||
QSqlQuery *query =
|
||||
prepareQuery("insert into {prefix}_users "
|
||||
"(name, realname, gender, password_sha512, email, country, registrationDate, active, token, "
|
||||
"admin, avatar_bmp, clientid, privlevel, privlevelStartDate, privlevelEndDate) "
|
||||
"values "
|
||||
"(:userName, :realName, :gender, :password_sha512, :email, :country, UTC_TIMESTAMP(), :active, "
|
||||
":token, 0, '', '', 'NONE', UTC_TIMESTAMP(), UTC_TIMESTAMP())");
|
||||
query->bindValue(":userName", userName);
|
||||
query->bindValue(":realName", realName);
|
||||
query->bindValue(":gender", getGenderChar(gender));
|
||||
|
|
@ -201,20 +233,21 @@ bool Servatrice_DatabaseInterface::activateUser(const QString &userName, const Q
|
|||
if (!checkSql())
|
||||
return false;
|
||||
|
||||
QSqlQuery *activateQuery = prepareQuery("select name from {prefix}_users where active=0 and name=:username and token=:token");
|
||||
QSqlQuery *activateQuery =
|
||||
prepareQuery("select name from {prefix}_users where active=0 and name=:username and token=:token");
|
||||
|
||||
activateQuery->bindValue(":username", userName);
|
||||
activateQuery->bindValue(":token", token);
|
||||
if (!execSqlQuery(activateQuery)) {
|
||||
qDebug() << "Account activation failed: SQL error." << activateQuery->lastError()<< " sql: " << activateQuery->lastQuery();
|
||||
qDebug() << "Account activation failed: SQL error." << activateQuery->lastError()
|
||||
<< " sql: " << activateQuery->lastQuery();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (activateQuery->next()) {
|
||||
const QString name = activateQuery->value(0).toString();
|
||||
// redundant check
|
||||
if(name == userName)
|
||||
{
|
||||
if (name == userName) {
|
||||
|
||||
QSqlQuery *query = prepareQuery("update {prefix}_users set active=1 where name = :userName");
|
||||
query->bindValue(":userName", userName);
|
||||
|
|
@ -244,58 +277,69 @@ QChar Servatrice_DatabaseInterface::getGenderChar(ServerInfo_User_Gender const &
|
|||
}
|
||||
}
|
||||
|
||||
AuthenticationResult Servatrice_DatabaseInterface::checkUserPassword(Server_ProtocolHandler *handler, const QString &user, const QString &password, const QString &clientId, QString &reasonStr, int &banSecondsLeft)
|
||||
AuthenticationResult Servatrice_DatabaseInterface::checkUserPassword(Server_ProtocolHandler *handler,
|
||||
const QString &user,
|
||||
const QString &password,
|
||||
const QString &clientId,
|
||||
QString &reasonStr,
|
||||
int &banSecondsLeft)
|
||||
{
|
||||
switch (server->getAuthenticationMethod()) {
|
||||
case Servatrice::AuthenticationNone: return UnknownUser;
|
||||
case Servatrice::AuthenticationPassword: {
|
||||
QString configPassword = settingsCache->value("authentication/password").toString();
|
||||
if (configPassword == password)
|
||||
return PasswordRight;
|
||||
|
||||
return NotLoggedIn;
|
||||
}
|
||||
case Servatrice::AuthenticationSql: {
|
||||
if (!checkSql())
|
||||
case Servatrice::AuthenticationNone:
|
||||
return UnknownUser;
|
||||
case Servatrice::AuthenticationPassword: {
|
||||
QString configPassword = settingsCache->value("authentication/password").toString();
|
||||
if (configPassword == password)
|
||||
return PasswordRight;
|
||||
|
||||
if (!usernameIsValid(user, reasonStr))
|
||||
return UsernameInvalid;
|
||||
|
||||
if (checkUserIsBanned(handler->getAddress(), user, clientId, reasonStr, banSecondsLeft))
|
||||
return UserIsBanned;
|
||||
|
||||
QSqlQuery *passwordQuery = prepareQuery("select password_sha512, active from {prefix}_users where name = :name");
|
||||
passwordQuery->bindValue(":name", user);
|
||||
if (!execSqlQuery(passwordQuery)) {
|
||||
qDebug("Login denied: SQL error");
|
||||
return NotLoggedIn;
|
||||
}
|
||||
case Servatrice::AuthenticationSql: {
|
||||
if (!checkSql())
|
||||
return UnknownUser;
|
||||
|
||||
if (passwordQuery->next()) {
|
||||
const QString correctPassword = passwordQuery->value(0).toString();
|
||||
const bool userIsActive = passwordQuery->value(1).toBool();
|
||||
if(!userIsActive) {
|
||||
qDebug("Login denied: user not active");
|
||||
return UserIsInactive;
|
||||
}
|
||||
if (correctPassword == PasswordHasher::computeHash(password, correctPassword.left(16))) {
|
||||
qDebug("Login accepted: password right");
|
||||
return PasswordRight;
|
||||
} else {
|
||||
qDebug("Login denied: password wrong");
|
||||
if (!usernameIsValid(user, reasonStr))
|
||||
return UsernameInvalid;
|
||||
|
||||
if (checkUserIsBanned(handler->getAddress(), user, clientId, reasonStr, banSecondsLeft))
|
||||
return UserIsBanned;
|
||||
|
||||
QSqlQuery *passwordQuery =
|
||||
prepareQuery("select password_sha512, active from {prefix}_users where name = :name");
|
||||
passwordQuery->bindValue(":name", user);
|
||||
if (!execSqlQuery(passwordQuery)) {
|
||||
qDebug("Login denied: SQL error");
|
||||
return NotLoggedIn;
|
||||
}
|
||||
} else {
|
||||
qDebug("Login accepted: unknown user");
|
||||
return UnknownUser;
|
||||
|
||||
if (passwordQuery->next()) {
|
||||
const QString correctPassword = passwordQuery->value(0).toString();
|
||||
const bool userIsActive = passwordQuery->value(1).toBool();
|
||||
if (!userIsActive) {
|
||||
qDebug("Login denied: user not active");
|
||||
return UserIsInactive;
|
||||
}
|
||||
if (correctPassword == PasswordHasher::computeHash(password, correctPassword.left(16))) {
|
||||
qDebug("Login accepted: password right");
|
||||
return PasswordRight;
|
||||
} else {
|
||||
qDebug("Login denied: password wrong");
|
||||
return NotLoggedIn;
|
||||
}
|
||||
} else {
|
||||
qDebug("Login accepted: unknown user");
|
||||
return UnknownUser;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return UnknownUser;
|
||||
}
|
||||
|
||||
bool Servatrice_DatabaseInterface::checkUserIsBanned(const QString &ipAddress, const QString &userName, const QString &clientId, QString &banReason, int &banSecondsRemaining)
|
||||
bool Servatrice_DatabaseInterface::checkUserIsBanned(const QString &ipAddress,
|
||||
const QString &userName,
|
||||
const QString &clientId,
|
||||
QString &banReason,
|
||||
int &banSecondsRemaining)
|
||||
{
|
||||
if (server->getAuthenticationMethod() != Servatrice::AuthenticationSql)
|
||||
return false;
|
||||
|
|
@ -305,27 +349,29 @@ bool Servatrice_DatabaseInterface::checkUserIsBanned(const QString &ipAddress, c
|
|||
return false;
|
||||
}
|
||||
|
||||
return
|
||||
checkUserIsIpBanned(ipAddress, banReason, banSecondsRemaining) || checkUserIsNameBanned(userName, banReason, banSecondsRemaining) || checkUserIsIdBanned(clientId, banReason, banSecondsRemaining);
|
||||
|
||||
return checkUserIsIpBanned(ipAddress, banReason, banSecondsRemaining) ||
|
||||
checkUserIsNameBanned(userName, banReason, banSecondsRemaining) ||
|
||||
checkUserIsIdBanned(clientId, banReason, banSecondsRemaining);
|
||||
}
|
||||
|
||||
bool Servatrice_DatabaseInterface::checkUserIsIdBanned(const QString &clientId, QString &banReason, int &banSecondsRemaining)
|
||||
bool Servatrice_DatabaseInterface::checkUserIsIdBanned(const QString &clientId,
|
||||
QString &banReason,
|
||||
int &banSecondsRemaining)
|
||||
{
|
||||
if (clientId.isEmpty())
|
||||
return false;
|
||||
|
||||
QSqlQuery *idBanQuery = prepareQuery(
|
||||
"select"
|
||||
" timestampdiff(second, now(), date_add(b.time_from, interval b.minutes minute)),"
|
||||
" b.minutes <=> 0,"
|
||||
" b.visible_reason"
|
||||
" from {prefix}_bans b"
|
||||
" where"
|
||||
" b.time_from = (select max(c.time_from)"
|
||||
" from {prefix}_bans c"
|
||||
" where c.clientid = :id)"
|
||||
" and b.clientid = :id2");
|
||||
QSqlQuery *idBanQuery =
|
||||
prepareQuery("select"
|
||||
" timestampdiff(second, now(), date_add(b.time_from, interval b.minutes minute)),"
|
||||
" b.minutes <=> 0,"
|
||||
" b.visible_reason"
|
||||
" from {prefix}_bans b"
|
||||
" where"
|
||||
" b.time_from = (select max(c.time_from)"
|
||||
" from {prefix}_bans c"
|
||||
" where c.clientid = :id)"
|
||||
" and b.clientid = :id2");
|
||||
|
||||
idBanQuery->bindValue(":id", clientId);
|
||||
idBanQuery->bindValue(":id2", clientId);
|
||||
|
|
@ -347,10 +393,14 @@ bool Servatrice_DatabaseInterface::checkUserIsIdBanned(const QString &clientId,
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool Servatrice_DatabaseInterface::checkUserIsNameBanned(const QString &userName, QString &banReason, int &banSecondsRemaining)
|
||||
bool Servatrice_DatabaseInterface::checkUserIsNameBanned(const QString &userName,
|
||||
QString &banReason,
|
||||
int &banSecondsRemaining)
|
||||
{
|
||||
QSqlQuery *nameBanQuery = prepareQuery("select timestampdiff(second, now(), date_add(b.time_from, interval b.minutes minute)), b.minutes <=> 0, b.visible_reason from {prefix}_bans b where b.time_from = (select max(c.time_from) from {prefix}_bans c where c.user_name = :name2) and b.user_name = :name1");
|
||||
QSqlQuery *nameBanQuery =
|
||||
prepareQuery("select timestampdiff(second, now(), date_add(b.time_from, interval b.minutes minute)), b.minutes "
|
||||
"<=> 0, b.visible_reason from {prefix}_bans b where b.time_from = (select max(c.time_from) from "
|
||||
"{prefix}_bans c where c.user_name = :name2) and b.user_name = :name1");
|
||||
nameBanQuery->bindValue(":name1", userName);
|
||||
nameBanQuery->bindValue(":name2", userName);
|
||||
if (!execSqlQuery(nameBanQuery)) {
|
||||
|
|
@ -371,19 +421,21 @@ bool Servatrice_DatabaseInterface::checkUserIsNameBanned(const QString &userName
|
|||
return false;
|
||||
}
|
||||
|
||||
bool Servatrice_DatabaseInterface::checkUserIsIpBanned(const QString &ipAddress, QString &banReason, int &banSecondsRemaining)
|
||||
bool Servatrice_DatabaseInterface::checkUserIsIpBanned(const QString &ipAddress,
|
||||
QString &banReason,
|
||||
int &banSecondsRemaining)
|
||||
{
|
||||
QSqlQuery *ipBanQuery = prepareQuery(
|
||||
"select"
|
||||
" timestampdiff(second, now(), date_add(b.time_from, interval b.minutes minute)),"
|
||||
" b.minutes <=> 0,"
|
||||
" b.visible_reason"
|
||||
" from {prefix}_bans b"
|
||||
" where"
|
||||
" b.time_from = (select max(c.time_from)"
|
||||
" from {prefix}_bans c"
|
||||
" where c.ip_address = :address)"
|
||||
" and b.ip_address = :address2");
|
||||
QSqlQuery *ipBanQuery =
|
||||
prepareQuery("select"
|
||||
" timestampdiff(second, now(), date_add(b.time_from, interval b.minutes minute)),"
|
||||
" b.minutes <=> 0,"
|
||||
" b.visible_reason"
|
||||
" from {prefix}_bans b"
|
||||
" where"
|
||||
" b.time_from = (select max(c.time_from)"
|
||||
" from {prefix}_bans c"
|
||||
" where c.ip_address = :address)"
|
||||
" and b.ip_address = :address2");
|
||||
|
||||
ipBanQuery->bindValue(":address", ipAddress);
|
||||
ipBanQuery->bindValue(":address2", ipAddress);
|
||||
|
|
@ -458,7 +510,8 @@ bool Servatrice_DatabaseInterface::isInBuddyList(const QString &whoseList, const
|
|||
int id1 = getUserIdInDB(whoseList);
|
||||
int id2 = getUserIdInDB(who);
|
||||
|
||||
QSqlQuery *query = prepareQuery("select 1 from {prefix}_buddylist where id_user1 = :id_user1 and id_user2 = :id_user2");
|
||||
QSqlQuery *query =
|
||||
prepareQuery("select 1 from {prefix}_buddylist where id_user1 = :id_user1 and id_user2 = :id_user2");
|
||||
query->bindValue(":id_user1", id1);
|
||||
query->bindValue(":id_user2", id2);
|
||||
if (!execSqlQuery(query))
|
||||
|
|
@ -477,7 +530,8 @@ bool Servatrice_DatabaseInterface::isInIgnoreList(const QString &whoseList, cons
|
|||
int id1 = getUserIdInDB(whoseList);
|
||||
int id2 = getUserIdInDB(who);
|
||||
|
||||
QSqlQuery *query = prepareQuery("select 1 from {prefix}_ignorelist where id_user1 = :id_user1 and id_user2 = :id_user2");
|
||||
QSqlQuery *query =
|
||||
prepareQuery("select 1 from {prefix}_ignorelist where id_user1 = :id_user1 and id_user2 = :id_user2");
|
||||
query->bindValue(":id_user1", id1);
|
||||
query->bindValue(":id_user2", id2);
|
||||
if (!execSqlQuery(query))
|
||||
|
|
@ -551,7 +605,9 @@ ServerInfo_User Servatrice_DatabaseInterface::getUserData(const QString &name, b
|
|||
if (!checkSql())
|
||||
return result;
|
||||
|
||||
QSqlQuery *query = prepareQuery("select id, name, admin, country, privlevel, gender, realname, avatar_bmp, registrationDate, email, clientid from {prefix}_users where name = :name and active = 1");
|
||||
QSqlQuery *query =
|
||||
prepareQuery("select id, name, admin, country, privlevel, gender, realname, avatar_bmp, registrationDate, "
|
||||
"email, clientid from {prefix}_users where name = :name and active = 1");
|
||||
query->bindValue(":name", name);
|
||||
if (!execSqlQuery(query))
|
||||
return result;
|
||||
|
|
@ -560,15 +616,15 @@ ServerInfo_User Servatrice_DatabaseInterface::getUserData(const QString &name, b
|
|||
return evalUserQueryResult(query, true, withId);
|
||||
else
|
||||
return result;
|
||||
}
|
||||
else
|
||||
} else
|
||||
return result;
|
||||
}
|
||||
|
||||
void Servatrice_DatabaseInterface::clearSessionTables()
|
||||
{
|
||||
lockSessionTables();
|
||||
QSqlQuery *query = prepareQuery("update {prefix}_sessions set end_time=now() where end_time is null and id_server = :id_server");
|
||||
QSqlQuery *query =
|
||||
prepareQuery("update {prefix}_sessions set end_time=now() where end_time is null and id_server = :id_server");
|
||||
query->bindValue(":id_server", server->getServerID());
|
||||
execSqlQuery(query);
|
||||
unlockSessionTables();
|
||||
|
|
@ -590,14 +646,18 @@ bool Servatrice_DatabaseInterface::userSessionExists(const QString &userName)
|
|||
{
|
||||
// Call only after lockSessionTables().
|
||||
|
||||
QSqlQuery *query = prepareQuery("select 1 from {prefix}_sessions where user_name = :user_name and id_server = :id_server and end_time is null");
|
||||
QSqlQuery *query = prepareQuery(
|
||||
"select 1 from {prefix}_sessions where user_name = :user_name and id_server = :id_server and end_time is null");
|
||||
query->bindValue(":id_server", server->getServerID());
|
||||
query->bindValue(":user_name", userName);
|
||||
execSqlQuery(query);
|
||||
return query->next();
|
||||
}
|
||||
|
||||
qint64 Servatrice_DatabaseInterface::startSession(const QString &userName, const QString &address, const QString &clientId, const QString & connectionType)
|
||||
qint64 Servatrice_DatabaseInterface::startSession(const QString &userName,
|
||||
const QString &address,
|
||||
const QString &clientId,
|
||||
const QString &connectionType)
|
||||
{
|
||||
if (server->getAuthenticationMethod() == Servatrice::AuthenticationNone)
|
||||
return -1;
|
||||
|
|
@ -605,7 +665,9 @@ qint64 Servatrice_DatabaseInterface::startSession(const QString &userName, const
|
|||
if (!checkSql())
|
||||
return -1;
|
||||
|
||||
QSqlQuery *query = prepareQuery("insert into {prefix}_sessions (user_name, id_server, ip_address, start_time, clientid, connection_type) values(:user_name, :id_server, :ip_address, NOW(), :client_id, :connection_type)");
|
||||
QSqlQuery *query = prepareQuery("insert into {prefix}_sessions (user_name, id_server, ip_address, start_time, "
|
||||
"clientid, connection_type) values(:user_name, :id_server, :ip_address, NOW(), "
|
||||
":client_id, :connection_type)");
|
||||
query->bindValue(":user_name", userName);
|
||||
query->bindValue(":id_server", server->getServerID());
|
||||
query->bindValue(":ip_address", address);
|
||||
|
|
@ -642,7 +704,9 @@ QMap<QString, ServerInfo_User> Servatrice_DatabaseInterface::getBuddyList(const
|
|||
if (server->getAuthenticationMethod() == Servatrice::AuthenticationSql) {
|
||||
checkSql();
|
||||
|
||||
QSqlQuery *query = prepareQuery("select a.id, a.name, a.admin, a.country, a.privlevel from {prefix}_users a left join {prefix}_buddylist b on a.id = b.id_user2 left join {prefix}_users c on b.id_user1 = c.id where c.name = :name");
|
||||
QSqlQuery *query = prepareQuery("select a.id, a.name, a.admin, a.country, a.privlevel from {prefix}_users a "
|
||||
"left join {prefix}_buddylist b on a.id = b.id_user2 left join {prefix}_users "
|
||||
"c on b.id_user1 = c.id where c.name = :name");
|
||||
query->bindValue(":name", name);
|
||||
if (!execSqlQuery(query))
|
||||
return result;
|
||||
|
|
@ -662,7 +726,9 @@ QMap<QString, ServerInfo_User> Servatrice_DatabaseInterface::getIgnoreList(const
|
|||
if (server->getAuthenticationMethod() == Servatrice::AuthenticationSql) {
|
||||
checkSql();
|
||||
|
||||
QSqlQuery *query = prepareQuery("select a.id, a.name, a.admin, a.country, a.privlevel from {prefix}_users a left join {prefix}_ignorelist b on a.id = b.id_user2 left join {prefix}_users c on b.id_user1 = c.id where c.name = :name");
|
||||
QSqlQuery *query = prepareQuery("select a.id, a.name, a.admin, a.country, a.privlevel from {prefix}_users a "
|
||||
"left join {prefix}_ignorelist b on a.id = b.id_user2 left join {prefix}_users "
|
||||
"c on b.id_user1 = c.id where c.name = :name");
|
||||
query->bindValue(":name", name);
|
||||
if (!execSqlQuery(query))
|
||||
return result;
|
||||
|
|
@ -700,12 +766,17 @@ int Servatrice_DatabaseInterface::getNextReplayId()
|
|||
return query->lastInsertId().toInt();
|
||||
}
|
||||
|
||||
void Servatrice_DatabaseInterface::storeGameInformation(const QString &roomName, const QStringList &roomGameTypes, const ServerInfo_Game &gameInfo, const QSet<QString> &allPlayersEver, const QSet<QString> &allSpectatorsEver, const QList<GameReplay *> &replayList)
|
||||
void Servatrice_DatabaseInterface::storeGameInformation(const QString &roomName,
|
||||
const QStringList &roomGameTypes,
|
||||
const ServerInfo_Game &gameInfo,
|
||||
const QSet<QString> &allPlayersEver,
|
||||
const QSet<QString> &allSpectatorsEver,
|
||||
const QList<GameReplay *> &replayList)
|
||||
{
|
||||
if (!checkSql())
|
||||
return;
|
||||
|
||||
if (!settingsCache->value("game/store_replays", 1).toBool() )
|
||||
if (!settingsCache->value("game/store_replays", 1).toBool())
|
||||
return;
|
||||
|
||||
QVariantList gameIds1, playerNames, gameIds2, userIds, replayNames;
|
||||
|
|
@ -733,14 +804,16 @@ void Servatrice_DatabaseInterface::storeGameInformation(const QString &roomName,
|
|||
blob.resize(size);
|
||||
replayList[i]->SerializeToArray(blob.data(), size);
|
||||
|
||||
replayIds.append(QVariant((qulonglong) replayList[i]->replay_id()));
|
||||
replayIds.append(QVariant((qulonglong)replayList[i]->replay_id()));
|
||||
replayGameIds.append(gameInfo.game_id());
|
||||
replayDurations.append(replayList[i]->duration_seconds());
|
||||
replayBlobs.append(blob);
|
||||
}
|
||||
|
||||
{
|
||||
QSqlQuery *query = prepareQuery("update {prefix}_games set room_name=:room_name, descr=:descr, creator_name=:creator_name, password=:password, game_types=:game_types, player_count=:player_count, time_finished=now() where id=:id_game");
|
||||
QSqlQuery *query = prepareQuery("update {prefix}_games set room_name=:room_name, descr=:descr, "
|
||||
"creator_name=:creator_name, password=:password, game_types=:game_types, "
|
||||
"player_count=:player_count, time_finished=now() where id=:id_game");
|
||||
query->bindValue(":room_name", roomName);
|
||||
query->bindValue(":id_game", gameInfo.game_id());
|
||||
query->bindValue(":descr", QString::fromStdString(gameInfo.description()));
|
||||
|
|
@ -752,13 +825,15 @@ void Servatrice_DatabaseInterface::storeGameInformation(const QString &roomName,
|
|||
return;
|
||||
}
|
||||
{
|
||||
QSqlQuery *query = prepareQuery("insert into {prefix}_games_players (id_game, player_name) values (:id_game, :player_name)");
|
||||
QSqlQuery *query =
|
||||
prepareQuery("insert into {prefix}_games_players (id_game, player_name) values (:id_game, :player_name)");
|
||||
query->bindValue(":id_game", gameIds1);
|
||||
query->bindValue(":player_name", playerNames);
|
||||
query->execBatch();
|
||||
}
|
||||
{
|
||||
QSqlQuery *query = prepareQuery("update {prefix}_replays set id_game=:id_game, duration=:duration, replay=:replay where id=:id_replay");
|
||||
QSqlQuery *query = prepareQuery(
|
||||
"update {prefix}_replays set id_game=:id_game, duration=:duration, replay=:replay where id=:id_replay");
|
||||
query->bindValue(":id_replay", replayIds);
|
||||
query->bindValue(":id_game", replayGameIds);
|
||||
query->bindValue(":duration", replayDurations);
|
||||
|
|
@ -766,7 +841,8 @@ void Servatrice_DatabaseInterface::storeGameInformation(const QString &roomName,
|
|||
query->execBatch();
|
||||
}
|
||||
{
|
||||
QSqlQuery *query = prepareQuery("insert into {prefix}_replays_access (id_game, id_player, replay_name) values (:id_game, :id_player, :replay_name)");
|
||||
QSqlQuery *query = prepareQuery("insert into {prefix}_replays_access (id_game, id_player, replay_name) values "
|
||||
"(:id_game, :id_player, :replay_name)");
|
||||
query->bindValue(":id_game", gameIds2);
|
||||
query->bindValue(":id_player", userIds);
|
||||
query->bindValue(":replay_name", replayNames);
|
||||
|
|
@ -778,7 +854,8 @@ DeckList *Servatrice_DatabaseInterface::getDeckFromDatabase(int deckId, int user
|
|||
{
|
||||
checkSql();
|
||||
|
||||
QSqlQuery *query = prepareQuery("select content from {prefix}_decklist_files where id = :id and id_user = :id_user");
|
||||
QSqlQuery *query =
|
||||
prepareQuery("select content from {prefix}_decklist_files where id = :id and id_user = :id_user");
|
||||
query->bindValue(":id", deckId);
|
||||
query->bindValue(":id_user", userId);
|
||||
execSqlQuery(query);
|
||||
|
|
@ -791,28 +868,33 @@ DeckList *Servatrice_DatabaseInterface::getDeckFromDatabase(int deckId, int user
|
|||
return deck;
|
||||
}
|
||||
|
||||
void Servatrice_DatabaseInterface::logMessage(const int senderId, const QString &senderName, const QString &senderIp, const QString &logMessage, LogMessage_TargetType targetType, const int targetId, const QString &targetName)
|
||||
void Servatrice_DatabaseInterface::logMessage(const int senderId,
|
||||
const QString &senderName,
|
||||
const QString &senderIp,
|
||||
const QString &logMessage,
|
||||
LogMessage_TargetType targetType,
|
||||
const int targetId,
|
||||
const QString &targetName)
|
||||
{
|
||||
QString targetTypeString;
|
||||
switch(targetType)
|
||||
{
|
||||
switch (targetType) {
|
||||
case MessageTargetRoom:
|
||||
if(!settingsCache->value("logging/log_user_msg_room", 0).toBool())
|
||||
if (!settingsCache->value("logging/log_user_msg_room", 0).toBool())
|
||||
return;
|
||||
targetTypeString = "room";
|
||||
break;
|
||||
case MessageTargetGame:
|
||||
if(!settingsCache->value("logging/log_user_msg_game", 0).toBool())
|
||||
if (!settingsCache->value("logging/log_user_msg_game", 0).toBool())
|
||||
return;
|
||||
targetTypeString = "game";
|
||||
break;
|
||||
case MessageTargetChat:
|
||||
if(!settingsCache->value("logging/log_user_msg_chat", 0).toBool())
|
||||
if (!settingsCache->value("logging/log_user_msg_chat", 0).toBool())
|
||||
return;
|
||||
targetTypeString = "chat";
|
||||
break;
|
||||
case MessageTargetIslRoom:
|
||||
if(!settingsCache->value("logging/log_user_msg_isl", 0).toBool())
|
||||
if (!settingsCache->value("logging/log_user_msg_isl", 0).toBool())
|
||||
return;
|
||||
targetTypeString = "room";
|
||||
break;
|
||||
|
|
@ -820,7 +902,9 @@ void Servatrice_DatabaseInterface::logMessage(const int senderId, const QString
|
|||
return;
|
||||
}
|
||||
|
||||
QSqlQuery *query = prepareQuery("insert into {prefix}_log (log_time, sender_id, sender_name, sender_ip, log_message, target_type, target_id, target_name) values (now(), :sender_id, :sender_name, :sender_ip, :log_message, :target_type, :target_id, :target_name)");
|
||||
QSqlQuery *query = prepareQuery("insert into {prefix}_log (log_time, sender_id, sender_name, sender_ip, "
|
||||
"log_message, target_type, target_id, target_name) values (now(), :sender_id, "
|
||||
":sender_name, :sender_ip, :log_message, :target_type, :target_id, :target_name)");
|
||||
query->bindValue(":sender_id", senderId < 1 ? QVariant() : senderId);
|
||||
query->bindValue(":sender_name", senderName);
|
||||
query->bindValue(":sender_ip", senderIp);
|
||||
|
|
@ -831,9 +915,12 @@ void Servatrice_DatabaseInterface::logMessage(const int senderId, const QString
|
|||
execSqlQuery(query);
|
||||
}
|
||||
|
||||
bool Servatrice_DatabaseInterface::changeUserPassword(const QString &user, const QString &oldPassword, const QString &newPassword, const bool &force = false)
|
||||
bool Servatrice_DatabaseInterface::changeUserPassword(const QString &user,
|
||||
const QString &oldPassword,
|
||||
const QString &newPassword,
|
||||
const bool &force = false)
|
||||
{
|
||||
if(server->getAuthenticationMethod() != Servatrice::AuthenticationSql)
|
||||
if (server->getAuthenticationMethod() != Servatrice::AuthenticationSql)
|
||||
return false;
|
||||
|
||||
if (!checkSql())
|
||||
|
|
@ -879,12 +966,12 @@ int Servatrice_DatabaseInterface::getActiveUserCount(QString connectionType)
|
|||
return userCount;
|
||||
|
||||
QString text = "select count(*) from {prefix}_sessions where id_server = :serverid AND end_time is NULL";
|
||||
if(!connectionType.isEmpty())
|
||||
text +=" AND connection_type = :connection_type";
|
||||
if (!connectionType.isEmpty())
|
||||
text += " AND connection_type = :connection_type";
|
||||
QSqlQuery *query = prepareQuery(text);
|
||||
|
||||
query->bindValue(":serverid", server->getServerID());
|
||||
if(!connectionType.isEmpty())
|
||||
if (!connectionType.isEmpty())
|
||||
query->bindValue(":connection_type", connectionType);
|
||||
|
||||
if (!execSqlQuery(query))
|
||||
|
|
@ -906,15 +993,15 @@ void Servatrice_DatabaseInterface::updateUsersClientID(const QString &userName,
|
|||
query->bindValue(":clientid", userClientID);
|
||||
query->bindValue(":username", userName);
|
||||
execSqlQuery(query);
|
||||
|
||||
}
|
||||
|
||||
void Servatrice_DatabaseInterface::updateUsersLastLoginData(const QString &userName, const QString &clientVersion) {
|
||||
void Servatrice_DatabaseInterface::updateUsersLastLoginData(const QString &userName, const QString &clientVersion)
|
||||
{
|
||||
|
||||
if (!checkSql())
|
||||
return;
|
||||
|
||||
int usersID=0;
|
||||
int usersID = 0;
|
||||
|
||||
QSqlQuery *query = prepareQuery("select id from {prefix}_users where name = :user_name");
|
||||
query->bindValue(":user_name", userName);
|
||||
|
|
@ -939,12 +1026,14 @@ void Servatrice_DatabaseInterface::updateUsersLastLoginData(const QString &userN
|
|||
}
|
||||
|
||||
if (!userCount) {
|
||||
query = prepareQuery("insert into {prefix}_user_analytics (id,client_ver,last_login) values (:user_id,:client_ver,NOW())");
|
||||
query = prepareQuery(
|
||||
"insert into {prefix}_user_analytics (id,client_ver,last_login) values (:user_id,:client_ver,NOW())");
|
||||
query->bindValue(":user_id", usersID);
|
||||
query->bindValue(":client_ver", clientVersion);
|
||||
execSqlQuery(query);
|
||||
} else {
|
||||
query = prepareQuery("update {prefix}_user_analytics set last_login = NOW(), client_ver = :client_ver where id = :user_id");
|
||||
query = prepareQuery(
|
||||
"update {prefix}_user_analytics set last_login = NOW(), client_ver = :client_ver where id = :user_id");
|
||||
query->bindValue(":client_ver", clientVersion);
|
||||
query->bindValue(":user_id", usersID);
|
||||
execSqlQuery(query);
|
||||
|
|
@ -960,7 +1049,9 @@ QList<ServerInfo_Ban> Servatrice_DatabaseInterface::getUserBanHistory(const QStr
|
|||
if (!checkSql())
|
||||
return results;
|
||||
|
||||
QSqlQuery *query = prepareQuery("SELECT A.id_admin, A.time_from, A.minutes, A.reason, A.visible_reason, B.name AS name_admin FROM {prefix}_bans A LEFT JOIN {prefix}_users B ON A.id_admin=B.id WHERE A.user_name = :user_name");
|
||||
QSqlQuery *query =
|
||||
prepareQuery("SELECT A.id_admin, A.time_from, A.minutes, A.reason, A.visible_reason, B.name AS name_admin FROM "
|
||||
"{prefix}_bans A LEFT JOIN {prefix}_users B ON A.id_admin=B.id WHERE A.user_name = :user_name");
|
||||
query->bindValue(":user_name", userName);
|
||||
|
||||
if (!execSqlQuery(query)) {
|
||||
|
|
@ -968,7 +1059,7 @@ QList<ServerInfo_Ban> Servatrice_DatabaseInterface::getUserBanHistory(const QStr
|
|||
return results;
|
||||
}
|
||||
|
||||
while (query->next()){
|
||||
while (query->next()) {
|
||||
banDetails.set_admin_id(QString(query->value(0).toString()).toStdString());
|
||||
banDetails.set_admin_name(QString(query->value(5).toString()).toStdString());
|
||||
banDetails.set_ban_time(QString(query->value(1).toString()).toStdString());
|
||||
|
|
@ -981,13 +1072,18 @@ QList<ServerInfo_Ban> Servatrice_DatabaseInterface::getUserBanHistory(const QStr
|
|||
return results;
|
||||
}
|
||||
|
||||
bool Servatrice_DatabaseInterface::addWarning(const QString userName, const QString adminName, const QString warningReason, const QString clientID)
|
||||
bool Servatrice_DatabaseInterface::addWarning(const QString userName,
|
||||
const QString adminName,
|
||||
const QString warningReason,
|
||||
const QString clientID)
|
||||
{
|
||||
if (!checkSql())
|
||||
return false;
|
||||
|
||||
int userID = getUserIdInDB(userName);
|
||||
QSqlQuery *query = prepareQuery("insert into {prefix}_warnings (user_id,user_name,mod_name,reason,time_of,clientid) values (:user_id,:user_name,:mod_name,:warn_reason,NOW(),:client_id)");
|
||||
QSqlQuery *query =
|
||||
prepareQuery("insert into {prefix}_warnings (user_id,user_name,mod_name,reason,time_of,clientid) values "
|
||||
"(:user_id,:user_name,:mod_name,:warn_reason,NOW(),:client_id)");
|
||||
query->bindValue(":user_id", userID);
|
||||
query->bindValue(":user_name", userName);
|
||||
query->bindValue(":mod_name", adminName);
|
||||
|
|
@ -1010,7 +1106,8 @@ QList<ServerInfo_Warning> Servatrice_DatabaseInterface::getUserWarnHistory(const
|
|||
return results;
|
||||
|
||||
int userID = getUserIdInDB(userName);
|
||||
QSqlQuery *query = prepareQuery("SELECT user_name, mod_name, reason, time_of FROM {prefix}_warnings WHERE user_id = :user_id");
|
||||
QSqlQuery *query =
|
||||
prepareQuery("SELECT user_name, mod_name, reason, time_of FROM {prefix}_warnings WHERE user_id = :user_id");
|
||||
query->bindValue(":user_id", userID);
|
||||
|
||||
if (!execSqlQuery(query)) {
|
||||
|
|
@ -1018,7 +1115,7 @@ QList<ServerInfo_Warning> Servatrice_DatabaseInterface::getUserWarnHistory(const
|
|||
return results;
|
||||
}
|
||||
|
||||
while (query->next()){
|
||||
while (query->next()) {
|
||||
warnDetails.set_user_name(QString(query->value(0).toString()).toStdString());
|
||||
warnDetails.set_admin_name(QString(query->value(1).toString()).toStdString());
|
||||
warnDetails.set_reason(QString(query->value(2).toString()).toStdString());
|
||||
|
|
@ -1029,7 +1126,16 @@ QList<ServerInfo_Warning> Servatrice_DatabaseInterface::getUserWarnHistory(const
|
|||
return results;
|
||||
}
|
||||
|
||||
QList<ServerInfo_ChatMessage> Servatrice_DatabaseInterface::getMessageLogHistory(const QString &user, const QString &ipaddress, const QString &gamename, const QString &gameid, const QString &message, bool &chat, bool &game, bool &room, int &range, int &maxresults)
|
||||
QList<ServerInfo_ChatMessage> Servatrice_DatabaseInterface::getMessageLogHistory(const QString &user,
|
||||
const QString &ipaddress,
|
||||
const QString &gamename,
|
||||
const QString &gameid,
|
||||
const QString &message,
|
||||
bool &chat,
|
||||
bool &game,
|
||||
bool &room,
|
||||
int &range,
|
||||
int &maxresults)
|
||||
{
|
||||
|
||||
QList<ServerInfo_ChatMessage> results;
|
||||
|
|
@ -1084,13 +1190,27 @@ QList<ServerInfo_ChatMessage> Servatrice_DatabaseInterface::getMessageLogHistory
|
|||
queryString.append(" LIMIT :limit_size");
|
||||
|
||||
QSqlQuery *query = prepareQuery(queryString);
|
||||
if (!user.isEmpty()) { query->bindValue(":user_name", user); }
|
||||
if (!ipaddress.isEmpty()) { query->bindValue(":ip_to_find", ipaddress); }
|
||||
if (!gameid.isEmpty()) { query->bindValue(":game_id", gameid); }
|
||||
if (!gamename.isEmpty()) { query->bindValue(":game_name", gamename); }
|
||||
if (!message.isEmpty()) { query->bindValue(":log_message", message); }
|
||||
if (range) { query->bindValue(":range_time", range); }
|
||||
if (maxresults) { query->bindValue(":limit_size", maxresults); }
|
||||
if (!user.isEmpty()) {
|
||||
query->bindValue(":user_name", user);
|
||||
}
|
||||
if (!ipaddress.isEmpty()) {
|
||||
query->bindValue(":ip_to_find", ipaddress);
|
||||
}
|
||||
if (!gameid.isEmpty()) {
|
||||
query->bindValue(":game_id", gameid);
|
||||
}
|
||||
if (!gamename.isEmpty()) {
|
||||
query->bindValue(":game_name", gamename);
|
||||
}
|
||||
if (!message.isEmpty()) {
|
||||
query->bindValue(":log_message", message);
|
||||
}
|
||||
if (range) {
|
||||
query->bindValue(":range_time", range);
|
||||
}
|
||||
if (maxresults) {
|
||||
query->bindValue(":limit_size", maxresults);
|
||||
}
|
||||
|
||||
if (!execSqlQuery(query)) {
|
||||
qDebug("Failed to collect log history information: SQL Error");
|
||||
|
|
@ -1165,7 +1285,8 @@ bool Servatrice_DatabaseInterface::doesForgotPasswordExist(const QString &user)
|
|||
if (!checkSql())
|
||||
return false;
|
||||
|
||||
QSqlQuery *query = prepareQuery("select count(name) from {prefix}_forgot_password where name = :user_name AND requestDate > (now() - interval :minutes minute)");
|
||||
QSqlQuery *query = prepareQuery("select count(name) from {prefix}_forgot_password where name = :user_name AND "
|
||||
"requestDate > (now() - interval :minutes minute)");
|
||||
query->bindValue(":user_name", user);
|
||||
query->bindValue(":minutes", QString::number(server->getForgotPasswordTokenLife()));
|
||||
|
||||
|
|
@ -1179,7 +1300,7 @@ bool Servatrice_DatabaseInterface::doesForgotPasswordExist(const QString &user)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool Servatrice_DatabaseInterface::updateUserToken(const QString & token, const QString &user)
|
||||
bool Servatrice_DatabaseInterface::updateUserToken(const QString &token, const QString &user)
|
||||
{
|
||||
if (!checkSql())
|
||||
return false;
|
||||
|
|
@ -1197,12 +1318,15 @@ bool Servatrice_DatabaseInterface::updateUserToken(const QString & token, const
|
|||
return false;
|
||||
}
|
||||
|
||||
bool Servatrice_DatabaseInterface::validateTableColumnStringData(const QString &table, const QString &column, const QString &_user, const QString &_datatocheck)
|
||||
bool Servatrice_DatabaseInterface::validateTableColumnStringData(const QString &table,
|
||||
const QString &column,
|
||||
const QString &_user,
|
||||
const QString &_datatocheck)
|
||||
{
|
||||
if (!checkSql())
|
||||
return false;
|
||||
|
||||
if (table.isEmpty() || column.isEmpty() ||_user.isEmpty() || _datatocheck.isEmpty())
|
||||
if (table.isEmpty() || column.isEmpty() || _user.isEmpty() || _datatocheck.isEmpty())
|
||||
return false;
|
||||
|
||||
QString formatedQuery = QString("select %1 from %2 where name = :user_name").arg(column).arg(table);
|
||||
|
|
@ -1219,18 +1343,25 @@ bool Servatrice_DatabaseInterface::validateTableColumnStringData(const QString &
|
|||
return false;
|
||||
}
|
||||
|
||||
void Servatrice_DatabaseInterface::addAuditRecord(const QString &user, const QString &ipaddress, const QString &clientid, const QString &action, const QString &details, const bool &results = false)
|
||||
void Servatrice_DatabaseInterface::addAuditRecord(const QString &user,
|
||||
const QString &ipaddress,
|
||||
const QString &clientid,
|
||||
const QString &action,
|
||||
const QString &details,
|
||||
const bool &results = false)
|
||||
{
|
||||
if (!checkSql())
|
||||
return;
|
||||
|
||||
|
||||
if (!server->getEnableAudit())
|
||||
return;
|
||||
|
||||
|
||||
if (user.isEmpty() || ipaddress.isEmpty() || clientid.isEmpty() || action.isEmpty())
|
||||
return;
|
||||
|
||||
QSqlQuery *query = prepareQuery("insert into {prefix}_audit (id_server,name,ip_address,clientid,incidentDate,action,results,details) values (:idserver,:username,:ipaddress,:clientid,NOW(),:action,:results,:details)");
|
||||
|
||||
QSqlQuery *query = prepareQuery("insert into {prefix}_audit "
|
||||
"(id_server,name,ip_address,clientid,incidentDate,action,results,details) values "
|
||||
"(:idserver,:username,:ipaddress,:clientid,NOW(),:action,:results,:details)");
|
||||
query->bindValue(":idserver", server->getServerID());
|
||||
query->bindValue(":username", user);
|
||||
query->bindValue(":ipaddress", ipaddress);
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
#ifndef SERVATRICE_DATABASE_INTERFACE_H
|
||||
#define SERVATRICE_DATABASE_INTERFACE_H
|
||||
|
||||
#include <QChar>
|
||||
#include <QHash>
|
||||
#include <QObject>
|
||||
#include <QSqlDatabase>
|
||||
#include <QHash>
|
||||
#include <QChar>
|
||||
|
||||
#include "server.h"
|
||||
#include "server_database_interface.h"
|
||||
|
|
@ -13,7 +13,8 @@
|
|||
|
||||
class Servatrice;
|
||||
|
||||
class Servatrice_DatabaseInterface : public Server_DatabaseInterface {
|
||||
class Servatrice_DatabaseInterface : public Server_DatabaseInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
int instanceId;
|
||||
|
|
@ -29,7 +30,12 @@ private:
|
|||
bool checkUserIsNameBanned(QString const &userName, QString &banReason, int &banSecondsRemaining);
|
||||
|
||||
protected:
|
||||
AuthenticationResult checkUserPassword(Server_ProtocolHandler *handler, const QString &user, const QString &password, const QString &clientId, QString &reasonStr, int &secondsLeft);
|
||||
AuthenticationResult checkUserPassword(Server_ProtocolHandler *handler,
|
||||
const QString &user,
|
||||
const QString &password,
|
||||
const QString &clientId,
|
||||
QString &reasonStr,
|
||||
int &secondsLeft);
|
||||
|
||||
public slots:
|
||||
void initDatabase(const QSqlDatabase &_sqlDatabase);
|
||||
|
|
@ -37,13 +43,19 @@ public slots:
|
|||
public:
|
||||
Servatrice_DatabaseInterface(int _instanceId, Servatrice *_server);
|
||||
~Servatrice_DatabaseInterface();
|
||||
bool initDatabase(const QString &type, const QString &hostName, const QString &databaseName,
|
||||
const QString &userName, const QString &password);
|
||||
bool initDatabase(const QString &type,
|
||||
const QString &hostName,
|
||||
const QString &databaseName,
|
||||
const QString &userName,
|
||||
const QString &password);
|
||||
bool openDatabase();
|
||||
bool checkSql();
|
||||
QSqlQuery * prepareQuery(const QString &queryText);
|
||||
QSqlQuery *prepareQuery(const QString &queryText);
|
||||
bool execSqlQuery(QSqlQuery *query);
|
||||
const QSqlDatabase &getDatabase() { return sqlDatabase; }
|
||||
const QSqlDatabase &getDatabase()
|
||||
{
|
||||
return sqlDatabase;
|
||||
}
|
||||
|
||||
bool activeUserExists(const QString &user);
|
||||
bool userExists(const QString &user);
|
||||
|
|
@ -53,40 +65,83 @@ public:
|
|||
bool isInBuddyList(const QString &whoseList, const QString &who);
|
||||
bool isInIgnoreList(const QString &whoseList, const QString &who);
|
||||
ServerInfo_User getUserData(const QString &name, bool withId = false);
|
||||
void storeGameInformation(const QString &roomName, const QStringList &roomGameTypes, const ServerInfo_Game &gameInfo,
|
||||
const QSet<QString> &allPlayersEver, const QSet<QString>&allSpectatorsEver, const QList<GameReplay *> &replayList);
|
||||
void storeGameInformation(const QString &roomName,
|
||||
const QStringList &roomGameTypes,
|
||||
const ServerInfo_Game &gameInfo,
|
||||
const QSet<QString> &allPlayersEver,
|
||||
const QSet<QString> &allSpectatorsEver,
|
||||
const QList<GameReplay *> &replayList);
|
||||
DeckList *getDeckFromDatabase(int deckId, int userId);
|
||||
|
||||
int getNextGameId();
|
||||
int getNextReplayId();
|
||||
int getActiveUserCount(QString connectionType = QString());
|
||||
|
||||
qint64 startSession(const QString &userName, const QString &address, const QString &clientId, const QString & connectionType);
|
||||
qint64 startSession(const QString &userName,
|
||||
const QString &address,
|
||||
const QString &clientId,
|
||||
const QString &connectionType);
|
||||
void endSession(qint64 sessionId);
|
||||
void clearSessionTables();
|
||||
void lockSessionTables();
|
||||
void unlockSessionTables();
|
||||
bool userSessionExists(const QString &userName);
|
||||
bool usernameIsValid(const QString &user, QString & error);
|
||||
bool checkUserIsBanned(const QString &ipAddress, const QString &userName, const QString &clientId, QString &banReason, int &banSecondsRemaining);
|
||||
bool usernameIsValid(const QString &user, QString &error);
|
||||
bool checkUserIsBanned(const QString &ipAddress,
|
||||
const QString &userName,
|
||||
const QString &clientId,
|
||||
QString &banReason,
|
||||
int &banSecondsRemaining);
|
||||
int checkNumberOfUserAccounts(const QString &email);
|
||||
bool registerUser(const QString &userName, const QString &realName, ServerInfo_User_Gender const &gender, const QString &password, const QString &emailAddress, const QString &country, QString &token, bool active = false);
|
||||
bool registerUser(const QString &userName,
|
||||
const QString &realName,
|
||||
ServerInfo_User_Gender const &gender,
|
||||
const QString &password,
|
||||
const QString &emailAddress,
|
||||
const QString &country,
|
||||
QString &token,
|
||||
bool active = false);
|
||||
bool activateUser(const QString &userName, const QString &token);
|
||||
void updateUsersClientID(const QString &userName, const QString &userClientID);
|
||||
void updateUsersLastLoginData(const QString &userName, const QString &clientVersion);
|
||||
void logMessage(const int senderId, const QString &senderName, const QString &senderIp, const QString &logMessage, LogMessage_TargetType targetType, const int targetId, const QString &targetName);
|
||||
bool changeUserPassword(const QString &user, const QString &oldPassword, const QString &newPassword, const bool &force);
|
||||
void logMessage(const int senderId,
|
||||
const QString &senderName,
|
||||
const QString &senderIp,
|
||||
const QString &logMessage,
|
||||
LogMessage_TargetType targetType,
|
||||
const int targetId,
|
||||
const QString &targetName);
|
||||
bool
|
||||
changeUserPassword(const QString &user, const QString &oldPassword, const QString &newPassword, const bool &force);
|
||||
QChar getGenderChar(ServerInfo_User_Gender const &gender);
|
||||
QList<ServerInfo_Ban> getUserBanHistory(const QString userName);
|
||||
bool addWarning(const QString userName, const QString adminName, const QString warningReason, const QString clientID);
|
||||
bool
|
||||
addWarning(const QString userName, const QString adminName, const QString warningReason, const QString clientID);
|
||||
QList<ServerInfo_Warning> getUserWarnHistory(const QString userName);
|
||||
QList<ServerInfo_ChatMessage> getMessageLogHistory(const QString &user, const QString &ipaddress, const QString &gamename, const QString &gameid, const QString &message, bool &chat, bool &game, bool &room, int &range, int &maxresults);
|
||||
QList<ServerInfo_ChatMessage> getMessageLogHistory(const QString &user,
|
||||
const QString &ipaddress,
|
||||
const QString &gamename,
|
||||
const QString &gameid,
|
||||
const QString &message,
|
||||
bool &chat,
|
||||
bool &game,
|
||||
bool &room,
|
||||
int &range,
|
||||
int &maxresults);
|
||||
bool addForgotPassword(const QString &user);
|
||||
bool removeForgotPassword(const QString &user);
|
||||
bool doesForgotPasswordExist(const QString &user);
|
||||
bool updateUserToken(const QString &token, const QString &user);
|
||||
bool validateTableColumnStringData(const QString &table, const QString &column, const QString &_user, const QString &_datatocheck);
|
||||
void addAuditRecord(const QString &user, const QString &ipaddress, const QString &clientid, const QString &action, const QString &details, const bool &results);
|
||||
bool validateTableColumnStringData(const QString &table,
|
||||
const QString &column,
|
||||
const QString &_user,
|
||||
const QString &_datatocheck);
|
||||
void addAuditRecord(const QString &user,
|
||||
const QString &ipaddress,
|
||||
const QString &clientid,
|
||||
const QString &action,
|
||||
const QString &details,
|
||||
const bool &results);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
#include "server_logger.h"
|
||||
#include "settingscache.h"
|
||||
#include <QDateTime>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
#include <QDir>
|
||||
#include <QTextStream>
|
||||
#include <QDateTime>
|
||||
#include <iostream>
|
||||
|
||||
ServerLogger::ServerLogger(bool _logToConsole, QObject *parent)
|
||||
|
|
@ -30,9 +30,8 @@ void ServerLogger::startLog(const QString &logFileName)
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
logFile = new QFile(logFileName, this);
|
||||
if(!logFile->open(QIODevice::Append)) {
|
||||
if (!logFile->open(QIODevice::Append)) {
|
||||
std::cerr << "ERROR: can't open() logfile." << std::endl;
|
||||
delete logFile;
|
||||
logFile = 0;
|
||||
|
|
@ -40,7 +39,7 @@ void ServerLogger::startLog(const QString &logFileName)
|
|||
}
|
||||
} else
|
||||
logFile = 0;
|
||||
|
||||
|
||||
connect(this, SIGNAL(sigFlushBuffer()), this, SLOT(flushBuffer()), Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
|
|
@ -48,24 +47,24 @@ void ServerLogger::logMessage(QString message, void *caller)
|
|||
{
|
||||
if (!logFile)
|
||||
return;
|
||||
|
||||
|
||||
QString callerString;
|
||||
if (caller)
|
||||
callerString = QString::number((qulonglong) caller, 16) + " ";
|
||||
|
||||
//filter out all log entries based on values in configuration file
|
||||
bool shouldWeWriteLog = settingsCache->value("server/writelog",1).toBool();
|
||||
callerString = QString::number((qulonglong)caller, 16) + " ";
|
||||
|
||||
// filter out all log entries based on values in configuration file
|
||||
bool shouldWeWriteLog = settingsCache->value("server/writelog", 1).toBool();
|
||||
QString logFilters = settingsCache->value("server/logfilters").toString();
|
||||
QStringList listlogFilters = logFilters.split(",", QString::SkipEmptyParts);
|
||||
bool shouldWeSkipLine = false;
|
||||
|
||||
QStringList listlogFilters = logFilters.split(",", QString::SkipEmptyParts);
|
||||
bool shouldWeSkipLine = false;
|
||||
|
||||
if (!shouldWeWriteLog)
|
||||
return;
|
||||
|
||||
if (!logFilters.trimmed().isEmpty()){
|
||||
if (!logFilters.trimmed().isEmpty()) {
|
||||
shouldWeSkipLine = true;
|
||||
foreach(QString logFilter, listlogFilters){
|
||||
if (message.contains(logFilter, Qt::CaseInsensitive)){
|
||||
foreach (QString logFilter, listlogFilters) {
|
||||
if (message.contains(logFilter, Qt::CaseInsensitive)) {
|
||||
shouldWeSkipLine = false;
|
||||
break;
|
||||
}
|
||||
|
|
@ -85,10 +84,11 @@ void ServerLogger::flushBuffer()
|
|||
{
|
||||
if (flushRunning)
|
||||
return;
|
||||
|
||||
|
||||
flushRunning = true;
|
||||
QTextStream stream(logFile);
|
||||
forever {
|
||||
forever
|
||||
{
|
||||
bufferMutex.lock();
|
||||
if (buffer.isEmpty()) {
|
||||
bufferMutex.unlock();
|
||||
|
|
@ -97,10 +97,10 @@ void ServerLogger::flushBuffer()
|
|||
}
|
||||
QString message = buffer.takeFirst();
|
||||
bufferMutex.unlock();
|
||||
|
||||
|
||||
stream << message << "\n";
|
||||
stream.flush();
|
||||
|
||||
|
||||
if (logToConsole)
|
||||
std::cout << message.toStdString() << std::endl;
|
||||
}
|
||||
|
|
@ -112,7 +112,7 @@ void ServerLogger::rotateLogs()
|
|||
return;
|
||||
|
||||
flushBuffer();
|
||||
|
||||
|
||||
logFile->close();
|
||||
logFile->open(QIODevice::Append);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,34 +1,36 @@
|
|||
#ifndef SERVER_LOGGER_H
|
||||
#define SERVER_LOGGER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QThread>
|
||||
#include <QMutex>
|
||||
#include <QWaitCondition>
|
||||
#include <QObject>
|
||||
#include <QStringList>
|
||||
#include <QThread>
|
||||
#include <QWaitCondition>
|
||||
|
||||
class QFile;
|
||||
class Server_ProtocolHandler;
|
||||
|
||||
class ServerLogger : public QObject {
|
||||
Q_OBJECT
|
||||
class ServerLogger : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ServerLogger(bool _logToConsole, QObject *parent = 0);
|
||||
~ServerLogger();
|
||||
ServerLogger(bool _logToConsole, QObject *parent = 0);
|
||||
~ServerLogger();
|
||||
public slots:
|
||||
void startLog(const QString &logFileName);
|
||||
void logMessage(QString message, void *caller = 0);
|
||||
void rotateLogs();
|
||||
void startLog(const QString &logFileName);
|
||||
void logMessage(QString message, void *caller = 0);
|
||||
void rotateLogs();
|
||||
private slots:
|
||||
void flushBuffer();
|
||||
void flushBuffer();
|
||||
signals:
|
||||
void sigFlushBuffer();
|
||||
void sigFlushBuffer();
|
||||
|
||||
private:
|
||||
bool logToConsole;
|
||||
static QFile *logFile;
|
||||
bool flushRunning;
|
||||
QStringList buffer;
|
||||
QMutex bufferMutex;
|
||||
bool logToConsole;
|
||||
static QFile *logFile;
|
||||
bool flushRunning;
|
||||
QStringList buffer;
|
||||
QMutex bufferMutex;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -22,11 +22,11 @@
|
|||
|
||||
#include <QTcpSocket>
|
||||
#if QT_VERSION > 0x050300
|
||||
#include <QWebSocket>
|
||||
#include <QWebSocket>
|
||||
#endif
|
||||
#include "server_protocolhandler.h"
|
||||
#include <QHostAddress>
|
||||
#include <QMutex>
|
||||
#include "server_protocolhandler.h"
|
||||
|
||||
class Servatrice;
|
||||
class Servatrice_DatabaseInterface;
|
||||
|
|
@ -63,19 +63,21 @@ protected slots:
|
|||
virtual void flushOutputQueue() = 0;
|
||||
signals:
|
||||
void outputQueueChanged();
|
||||
|
||||
protected:
|
||||
void logDebugMessage(const QString &message);
|
||||
bool tooManyRegistrationAttempts(const QString &ipAddress);
|
||||
|
||||
virtual void writeToSocket(QByteArray & data) = 0;
|
||||
virtual void writeToSocket(QByteArray &data) = 0;
|
||||
virtual void flushSocket() = 0;
|
||||
|
||||
Servatrice *servatrice;
|
||||
QList<ServerMessage> outputQueue;
|
||||
QMutex outputQueueMutex;
|
||||
|
||||
private:
|
||||
Servatrice_DatabaseInterface *sqlInterface;
|
||||
|
||||
|
||||
Response::ResponseCode cmdAddToList(const Command_AddToList &cmd, ResponseContainer &rc);
|
||||
Response::ResponseCode cmdRemoveFromList(const Command_RemoveFromList &cmd, ResponseContainer &rc);
|
||||
int getDeckPathId(int basePathId, QStringList path);
|
||||
|
|
@ -104,21 +106,26 @@ private:
|
|||
Response::ResponseCode cmdUpdateServerMessage(const Command_UpdateServerMessage &cmd, ResponseContainer &rc);
|
||||
Response::ResponseCode cmdRegisterAccount(const Command_Register &cmd, ResponseContainer &rc);
|
||||
Response::ResponseCode cmdActivateAccount(const Command_Activate &cmd, ResponseContainer & /* rc */);
|
||||
Response::ResponseCode cmdReloadConfig(const Command_ReloadConfig &/* cmd */, ResponseContainer & /*rc*/);
|
||||
Response::ResponseCode cmdReloadConfig(const Command_ReloadConfig & /* cmd */, ResponseContainer & /*rc*/);
|
||||
Response::ResponseCode cmdAdjustMod(const Command_AdjustMod &cmd, ResponseContainer & /*rc*/);
|
||||
Response::ResponseCode cmdForgotPasswordRequest(const Command_ForgotPasswordRequest &cmd, ResponseContainer &rc);
|
||||
Response::ResponseCode cmdForgotPasswordReset(const Command_ForgotPasswordReset &cmd, ResponseContainer &rc);
|
||||
Response::ResponseCode cmdForgotPasswordChallenge(const Command_ForgotPasswordChallenge &cmd, ResponseContainer &rc);
|
||||
Response::ResponseCode cmdForgotPasswordChallenge(const Command_ForgotPasswordChallenge &cmd,
|
||||
ResponseContainer &rc);
|
||||
Response::ResponseCode processExtendedSessionCommand(int cmdType, const SessionCommand &cmd, ResponseContainer &rc);
|
||||
Response::ResponseCode processExtendedModeratorCommand(int cmdType, const ModeratorCommand &cmd, ResponseContainer &rc);
|
||||
Response::ResponseCode
|
||||
processExtendedModeratorCommand(int cmdType, const ModeratorCommand &cmd, ResponseContainer &rc);
|
||||
Response::ResponseCode processExtendedAdminCommand(int cmdType, const AdminCommand &cmd, ResponseContainer &rc);
|
||||
|
||||
Response::ResponseCode cmdAccountEdit(const Command_AccountEdit &cmd, ResponseContainer &rc);
|
||||
Response::ResponseCode cmdAccountImage(const Command_AccountImage &cmd, ResponseContainer &rc);
|
||||
Response::ResponseCode cmdAccountPassword(const Command_AccountPassword &cmd, ResponseContainer &rc);
|
||||
|
||||
public:
|
||||
AbstractServerSocketInterface(Servatrice *_server, Servatrice_DatabaseInterface *_databaseInterface, QObject *parent = 0);
|
||||
~AbstractServerSocketInterface() { };
|
||||
AbstractServerSocketInterface(Servatrice *_server,
|
||||
Servatrice_DatabaseInterface *_databaseInterface,
|
||||
QObject *parent = 0);
|
||||
~AbstractServerSocketInterface(){};
|
||||
bool initSession();
|
||||
|
||||
virtual QHostAddress getPeerAddress() const = 0;
|
||||
|
|
@ -131,21 +138,40 @@ class TcpServerSocketInterface : public AbstractServerSocketInterface
|
|||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
TcpServerSocketInterface(Servatrice *_server, Servatrice_DatabaseInterface *_databaseInterface, QObject *parent = 0);
|
||||
TcpServerSocketInterface(Servatrice *_server,
|
||||
Servatrice_DatabaseInterface *_databaseInterface,
|
||||
QObject *parent = 0);
|
||||
~TcpServerSocketInterface();
|
||||
|
||||
QHostAddress getPeerAddress() const { return socket->peerAddress(); }
|
||||
QString getAddress() const { return socket->peerAddress().toString(); }
|
||||
QString getConnectionType() const { return "tcp"; };
|
||||
QHostAddress getPeerAddress() const
|
||||
{
|
||||
return socket->peerAddress();
|
||||
}
|
||||
QString getAddress() const
|
||||
{
|
||||
return socket->peerAddress().toString();
|
||||
}
|
||||
QString getConnectionType() const
|
||||
{
|
||||
return "tcp";
|
||||
};
|
||||
|
||||
private:
|
||||
QTcpSocket *socket;
|
||||
QByteArray inputBuffer;
|
||||
bool messageInProgress;
|
||||
bool handshakeStarted;
|
||||
int messageLength;
|
||||
|
||||
protected:
|
||||
void writeToSocket(QByteArray & data) { socket->write(data); };
|
||||
void flushSocket() { socket->flush(); };
|
||||
void writeToSocket(QByteArray &data)
|
||||
{
|
||||
socket->write(data);
|
||||
};
|
||||
void flushSocket()
|
||||
{
|
||||
socket->flush();
|
||||
};
|
||||
void initSessionDeprecated();
|
||||
bool initTcpSession();
|
||||
protected slots:
|
||||
|
|
@ -160,23 +186,42 @@ class WebsocketServerSocketInterface : public AbstractServerSocketInterface
|
|||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
WebsocketServerSocketInterface(Servatrice *_server, Servatrice_DatabaseInterface *_databaseInterface, QObject *parent = 0);
|
||||
WebsocketServerSocketInterface(Servatrice *_server,
|
||||
Servatrice_DatabaseInterface *_databaseInterface,
|
||||
QObject *parent = 0);
|
||||
~WebsocketServerSocketInterface();
|
||||
|
||||
QHostAddress getPeerAddress() const { return socket->peerAddress(); }
|
||||
QString getAddress() const { return socket->peerAddress().toString(); }
|
||||
QString getConnectionType() const { return "websocket"; };
|
||||
QHostAddress getPeerAddress() const
|
||||
{
|
||||
return socket->peerAddress();
|
||||
}
|
||||
QString getAddress() const
|
||||
{
|
||||
return socket->peerAddress().toString();
|
||||
}
|
||||
QString getConnectionType() const
|
||||
{
|
||||
return "websocket";
|
||||
};
|
||||
|
||||
private:
|
||||
QWebSocket *socket;
|
||||
|
||||
protected:
|
||||
void writeToSocket(QByteArray & data) { socket->sendBinaryMessage(data); };
|
||||
void flushSocket() { socket->flush(); };
|
||||
void writeToSocket(QByteArray &data)
|
||||
{
|
||||
socket->sendBinaryMessage(data);
|
||||
};
|
||||
void flushSocket()
|
||||
{
|
||||
socket->flush();
|
||||
};
|
||||
bool initWebsocketSession();
|
||||
protected slots:
|
||||
void binaryMessageReceived(const QByteArray & message);
|
||||
void binaryMessageReceived(const QByteArray &message);
|
||||
void flushOutputQueue();
|
||||
public slots:
|
||||
void initConnection(void * _socket);
|
||||
void initConnection(void *_socket);
|
||||
};
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -1,45 +1,45 @@
|
|||
#include "settingscache.h"
|
||||
#include <QCoreApplication>
|
||||
#include <QDebug>
|
||||
#include <QFile>
|
||||
#include <QStandardPaths>
|
||||
#include <QDebug>
|
||||
|
||||
SettingsCache::SettingsCache(const QString & fileName, QSettings::Format format, QObject * parent)
|
||||
:QSettings(fileName, format, parent)
|
||||
SettingsCache::SettingsCache(const QString &fileName, QSettings::Format format, QObject *parent)
|
||||
: QSettings(fileName, format, parent)
|
||||
{
|
||||
// first, figure out if we are running in portable mode
|
||||
isPortableBuild = QFile::exists(qApp->applicationDirPath() + "/portable.dat");
|
||||
|
||||
QStringList disallowedRegExpStr = value("users/disallowedregexp", "").toString().split(",", QString::SkipEmptyParts);
|
||||
QStringList disallowedRegExpStr =
|
||||
value("users/disallowedregexp", "").toString().split(",", QString::SkipEmptyParts);
|
||||
disallowedRegExpStr.removeDuplicates();
|
||||
for (const QString ®ExpStr : disallowedRegExpStr) {
|
||||
disallowedRegExp.append(QRegExp(regExpStr));
|
||||
}
|
||||
}
|
||||
|
||||
QString SettingsCache::guessConfigurationPath(QString & specificPath)
|
||||
QString SettingsCache::guessConfigurationPath(QString &specificPath)
|
||||
{
|
||||
const QString fileName="servatrice.ini";
|
||||
if(QFile::exists(qApp->applicationDirPath() + "/portable.dat"))
|
||||
{
|
||||
const QString fileName = "servatrice.ini";
|
||||
if (QFile::exists(qApp->applicationDirPath() + "/portable.dat")) {
|
||||
qDebug() << "Portable mode enabled";
|
||||
return fileName;
|
||||
}
|
||||
|
||||
QString guessFileName;
|
||||
// specific path
|
||||
if(!specificPath.isEmpty() && QFile::exists(specificPath))
|
||||
if (!specificPath.isEmpty() && QFile::exists(specificPath))
|
||||
return specificPath;
|
||||
|
||||
// application directory path
|
||||
guessFileName = QCoreApplication::applicationDirPath() + "/" + fileName;
|
||||
if(QFile::exists(guessFileName))
|
||||
if (QFile::exists(guessFileName))
|
||||
return guessFileName;
|
||||
|
||||
#ifdef Q_OS_UNIX
|
||||
// /etc
|
||||
guessFileName = "/etc/servatrice/" + fileName;
|
||||
if(QFile::exists(guessFileName))
|
||||
if (QFile::exists(guessFileName))
|
||||
return guessFileName;
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -1,21 +1,28 @@
|
|||
#ifndef SERVATRICE_SETTINGSCACHE_H
|
||||
#define SERVATRICE_SETTINGSCACHE_H
|
||||
|
||||
#include <QSettings>
|
||||
#include <QString>
|
||||
#include <QList>
|
||||
#include <QRegExp>
|
||||
#include <QSettings>
|
||||
#include <QString>
|
||||
|
||||
class SettingsCache : public QSettings {
|
||||
class SettingsCache : public QSettings
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
QSettings *settings;
|
||||
bool isPortableBuild;
|
||||
|
||||
public:
|
||||
SettingsCache(const QString & fileName="servatrice.ini", QSettings::Format format=QSettings::IniFormat, QObject * parent = 0);
|
||||
static QString guessConfigurationPath(QString & specificPath);
|
||||
SettingsCache(const QString &fileName = "servatrice.ini",
|
||||
QSettings::Format format = QSettings::IniFormat,
|
||||
QObject *parent = 0);
|
||||
static QString guessConfigurationPath(QString &specificPath);
|
||||
QList<QRegExp> disallowedRegExp;
|
||||
bool getIsPortableBuild() const { return isPortableBuild; }
|
||||
bool getIsPortableBuild() const
|
||||
{
|
||||
return isPortableBuild;
|
||||
}
|
||||
};
|
||||
|
||||
extern SettingsCache *settingsCache;
|
||||
|
|
|
|||
|
|
@ -1,26 +1,25 @@
|
|||
#include <QSocketNotifier>
|
||||
|
||||
#include "signalhandler.h"
|
||||
#include "main.h"
|
||||
#include "server_logger.h"
|
||||
#include "settingscache.h"
|
||||
#include "main.h"
|
||||
#include "signalhandler.h"
|
||||
|
||||
#ifdef Q_OS_UNIX
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <cstdio>
|
||||
#include <execinfo.h>
|
||||
#include <iostream>
|
||||
#include <cstdio>
|
||||
#include <signal.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#define SIGSEGV_TRACE_LINES 40
|
||||
|
||||
int SignalHandler::sigHupFD[2];
|
||||
|
||||
SignalHandler::SignalHandler(QObject *parent)
|
||||
: QObject(parent)
|
||||
SignalHandler::SignalHandler(QObject *parent) : QObject(parent)
|
||||
{
|
||||
#ifdef Q_OS_UNIX
|
||||
::socketpair(AF_UNIX, SOCK_STREAM, 0, sigHupFD);
|
||||
|
|
@ -34,14 +33,14 @@ SignalHandler::SignalHandler(QObject *parent)
|
|||
hup.sa_flags = 0;
|
||||
hup.sa_flags |= SA_RESTART;
|
||||
sigaction(SIGHUP, &hup, 0);
|
||||
|
||||
|
||||
struct sigaction segv;
|
||||
segv.sa_handler = SignalHandler::sigSegvHandler;
|
||||
segv.sa_flags = SA_RESETHAND;
|
||||
sigemptyset(&segv.sa_mask);
|
||||
sigaction(SIGSEGV, &segv, 0);
|
||||
sigaction(SIGABRT, &segv, 0);
|
||||
|
||||
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
#endif
|
||||
}
|
||||
|
|
@ -69,7 +68,7 @@ void SignalHandler::internalSigHupHandler()
|
|||
logger->rotateLogs();
|
||||
|
||||
settingsCache->sync();
|
||||
|
||||
|
||||
snHup->setEnabled(true);
|
||||
}
|
||||
|
||||
|
|
@ -90,12 +89,11 @@ void SignalHandler::sigSegvHandler(int sig)
|
|||
logger->logMessage("CRASH: SIGSEGV");
|
||||
else if (sig == SIGABRT)
|
||||
logger->logMessage("CRASH: SIGABRT");
|
||||
|
||||
|
||||
logger->deleteLater();
|
||||
loggerThread->wait();
|
||||
delete loggerThread;
|
||||
|
||||
|
||||
raise(sig);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,20 +5,20 @@
|
|||
|
||||
class QSocketNotifier;
|
||||
|
||||
class SignalHandler: public QObject
|
||||
class SignalHandler : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public:
|
||||
SignalHandler(QObject *parent = 0);
|
||||
~SignalHandler() { };
|
||||
static void sigHupHandler(int /* sig */);
|
||||
static void sigSegvHandler(int sig);
|
||||
private:
|
||||
static int sigHupFD[2];
|
||||
QSocketNotifier *snHup;
|
||||
private slots:
|
||||
void internalSigHupHandler();
|
||||
SignalHandler(QObject *parent = 0);
|
||||
~SignalHandler(){};
|
||||
static void sigHupHandler(int /* sig */);
|
||||
static void sigSegvHandler(int sig);
|
||||
|
||||
private:
|
||||
static int sigHupFD[2];
|
||||
QSocketNotifier *snHup;
|
||||
private slots:
|
||||
void internalSigHupHandler();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -2,36 +2,37 @@
|
|||
#include "settingscache.h"
|
||||
#include "smtp/qxtsmtp.h"
|
||||
|
||||
#include <QTcpSocket>
|
||||
#include <QSslSocket>
|
||||
#include <QTcpSocket>
|
||||
|
||||
SmtpClient::SmtpClient(QObject *parent)
|
||||
: QObject(parent)
|
||||
SmtpClient::SmtpClient(QObject *parent) : QObject(parent)
|
||||
{
|
||||
smtp = new QxtSmtp(this);
|
||||
|
||||
connect(smtp, SIGNAL(authenticated()), this, SLOT(authenticated()));
|
||||
connect(smtp, SIGNAL(authenticationFailed(const QByteArray &)), this, SLOT(authenticationFailed(const QByteArray &)));
|
||||
connect(smtp, SIGNAL(authenticationFailed(const QByteArray &)), this,
|
||||
SLOT(authenticationFailed(const QByteArray &)));
|
||||
connect(smtp, SIGNAL(connected()), this, SLOT(connected()));
|
||||
connect(smtp, SIGNAL(connectionFailed(const QByteArray &)), this, SLOT(connectionFailed(const QByteArray &)));
|
||||
connect(smtp, SIGNAL(disconnected()), this, SLOT(disconnected()));
|
||||
connect(smtp, SIGNAL(encrypted()), this, SLOT(encrypted()));
|
||||
connect(smtp, SIGNAL(encryptionFailed(const QByteArray &)), this, SLOT(encryptionFailed(const QByteArray &)));
|
||||
connect(smtp, SIGNAL(finished()), this, SLOT(finished()));
|
||||
connect(smtp, SIGNAL(mailFailed(int, int, const QByteArray &)), this, SLOT(mailFailed(int, int, const QByteArray &)));
|
||||
connect(smtp, SIGNAL(mailFailed(int, int, const QByteArray &)), this,
|
||||
SLOT(mailFailed(int, int, const QByteArray &)));
|
||||
connect(smtp, SIGNAL(mailSent(int)), this, SLOT(mailSent(int)));
|
||||
connect(smtp, SIGNAL(recipientRejected(int, const QString &, const QByteArray &)), this, SLOT(recipientRejected(int, const QString &, const QByteArray &)));
|
||||
connect(smtp, SIGNAL(senderRejected(int, const QString &, const QByteArray &)), this, SLOT(senderRejected(int, const QString &, const QByteArray &)));
|
||||
connect(smtp, SIGNAL(recipientRejected(int, const QString &, const QByteArray &)), this,
|
||||
SLOT(recipientRejected(int, const QString &, const QByteArray &)));
|
||||
connect(smtp, SIGNAL(senderRejected(int, const QString &, const QByteArray &)), this,
|
||||
SLOT(senderRejected(int, const QString &, const QByteArray &)));
|
||||
}
|
||||
|
||||
SmtpClient::~SmtpClient()
|
||||
{
|
||||
if(smtp)
|
||||
{
|
||||
if (smtp) {
|
||||
delete smtp;
|
||||
smtp = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool SmtpClient::enqueueActivationTokenMail(const QString &nickname, const QString &recipient, const QString &token)
|
||||
|
|
@ -41,32 +42,27 @@ bool SmtpClient::enqueueActivationTokenMail(const QString &nickname, const QStri
|
|||
QString subject = settingsCache->value("smtp/subject", "").toString();
|
||||
QString body = settingsCache->value("smtp/body", "").toString();
|
||||
|
||||
if(email.isEmpty())
|
||||
{
|
||||
if (email.isEmpty()) {
|
||||
qDebug() << "[MAIL] Missing sender email in configuration";
|
||||
return false;
|
||||
}
|
||||
|
||||
if(subject.isEmpty())
|
||||
{
|
||||
if (subject.isEmpty()) {
|
||||
qDebug() << "[MAIL] Missing subject field in configuration";
|
||||
return false;
|
||||
}
|
||||
|
||||
if(body.isEmpty())
|
||||
{
|
||||
if (body.isEmpty()) {
|
||||
qDebug() << "[MAIL] Missing body field in configuration";
|
||||
return false;
|
||||
}
|
||||
|
||||
if(recipient.isEmpty())
|
||||
{
|
||||
if (recipient.isEmpty()) {
|
||||
qDebug() << "[MAIL] Missing recipient field for user " << nickname;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(token.isEmpty())
|
||||
{
|
||||
if (token.isEmpty()) {
|
||||
qDebug() << "[MAIL] Missing token field for user " << nickname;
|
||||
return false;
|
||||
}
|
||||
|
|
@ -89,32 +85,27 @@ bool SmtpClient::enqueueForgotPasswordTokenMail(const QString &nickname, const Q
|
|||
QString subject = settingsCache->value("forgotpassword/subject", "").toString();
|
||||
QString body = settingsCache->value("forgotpassword/body", "").toString();
|
||||
|
||||
if (email.isEmpty())
|
||||
{
|
||||
if (email.isEmpty()) {
|
||||
qDebug() << "[MAIL] Missing sender email in configuration";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (subject.isEmpty())
|
||||
{
|
||||
if (subject.isEmpty()) {
|
||||
qDebug() << "[MAIL] Missing subject field in configuration";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (body.isEmpty())
|
||||
{
|
||||
if (body.isEmpty()) {
|
||||
qDebug() << "[MAIL] Missing body field in configuration";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (recipient.isEmpty())
|
||||
{
|
||||
if (recipient.isEmpty()) {
|
||||
qDebug() << "[MAIL] Missing recipient field for user " << nickname;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (token.isEmpty())
|
||||
{
|
||||
if (token.isEmpty()) {
|
||||
qDebug() << "[MAIL] Missing token field for user " << nickname;
|
||||
return false;
|
||||
}
|
||||
|
|
@ -133,10 +124,10 @@ bool SmtpClient::enqueueForgotPasswordTokenMail(const QString &nickname, const Q
|
|||
void SmtpClient::sendAllEmails()
|
||||
{
|
||||
// still connected from the previous round
|
||||
if(smtp->socket()->state() == QAbstractSocket::ConnectedState)
|
||||
if (smtp->socket()->state() == QAbstractSocket::ConnectedState)
|
||||
return;
|
||||
|
||||
if(smtp->pendingMessages() == 0)
|
||||
if (smtp->pendingMessages() == 0)
|
||||
return;
|
||||
|
||||
QString connectionType = settingsCache->value("smtp/connection", "tcp").toString();
|
||||
|
|
@ -150,9 +141,8 @@ void SmtpClient::sendAllEmails()
|
|||
smtp->setPassword(password);
|
||||
|
||||
// Connect
|
||||
if(connectionType == "ssl")
|
||||
{
|
||||
if(acceptAllCerts)
|
||||
if (connectionType == "ssl") {
|
||||
if (acceptAllCerts)
|
||||
smtp->sslSocket()->setPeerVerifyMode(QSslSocket::QueryPeer);
|
||||
smtp->connectToSecureHost(host, port);
|
||||
} else {
|
||||
|
|
@ -165,7 +155,7 @@ void SmtpClient::authenticated()
|
|||
qDebug() << "[MAIL] authenticated";
|
||||
}
|
||||
|
||||
void SmtpClient::authenticationFailed(const QByteArray & msg)
|
||||
void SmtpClient::authenticationFailed(const QByteArray &msg)
|
||||
{
|
||||
qDebug() << "[MAIL] authenticationFailed" << QString(msg);
|
||||
}
|
||||
|
|
@ -175,7 +165,7 @@ void SmtpClient::connected()
|
|||
qDebug() << "[MAIL] connected";
|
||||
}
|
||||
|
||||
void SmtpClient::connectionFailed(const QByteArray & msg)
|
||||
void SmtpClient::connectionFailed(const QByteArray &msg)
|
||||
{
|
||||
qDebug() << "[MAIL] connectionFailed" << QString(msg);
|
||||
}
|
||||
|
|
@ -190,7 +180,7 @@ void SmtpClient::encrypted()
|
|||
qDebug() << "[MAIL] encrypted";
|
||||
}
|
||||
|
||||
void SmtpClient::encryptionFailed(const QByteArray & msg)
|
||||
void SmtpClient::encryptionFailed(const QByteArray &msg)
|
||||
{
|
||||
qDebug() << "[MAIL] encryptionFailed" << QString(msg);
|
||||
qDebug() << "[MAIL] Try enabling the \"acceptallcerts\" option in servatrice.ini";
|
||||
|
|
@ -202,7 +192,7 @@ void SmtpClient::finished()
|
|||
smtp->disconnectFromHost();
|
||||
}
|
||||
|
||||
void SmtpClient::mailFailed(int mailID, int errorCode, const QByteArray & msg)
|
||||
void SmtpClient::mailFailed(int mailID, int errorCode, const QByteArray &msg)
|
||||
{
|
||||
qDebug() << "[MAIL] mailFailed id=" << mailID << " errorCode=" << errorCode << "msg=" << QString(msg);
|
||||
}
|
||||
|
|
@ -212,12 +202,12 @@ void SmtpClient::mailSent(int mailID)
|
|||
qDebug() << "[MAIL] mailSent" << mailID;
|
||||
}
|
||||
|
||||
void SmtpClient::recipientRejected(int mailID, const QString & address, const QByteArray & msg)
|
||||
void SmtpClient::recipientRejected(int mailID, const QString &address, const QByteArray &msg)
|
||||
{
|
||||
qDebug() << "[MAIL] recipientRejected id=" << mailID << " address=" << address << "msg=" << QString(msg);
|
||||
}
|
||||
|
||||
void SmtpClient::senderRejected(int mailID, const QString & address, const QByteArray & msg)
|
||||
void SmtpClient::senderRejected(int mailID, const QString &address, const QByteArray &msg)
|
||||
{
|
||||
qDebug() << "[MAIL] senderRejected id=" << mailID << " address=" << address << "msg=" << QString(msg);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,11 +6,13 @@
|
|||
class QxtSmtp;
|
||||
class QxtMailMessage;
|
||||
|
||||
class SmtpClient : public QObject {
|
||||
class SmtpClient : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
SmtpClient(QObject *parent = 0);
|
||||
~SmtpClient();
|
||||
|
||||
protected:
|
||||
QxtSmtp *smtp;
|
||||
public slots:
|
||||
|
|
@ -19,17 +21,17 @@ public slots:
|
|||
void sendAllEmails();
|
||||
protected slots:
|
||||
void authenticated();
|
||||
void authenticationFailed(const QByteArray & msg);
|
||||
void authenticationFailed(const QByteArray &msg);
|
||||
void connected();
|
||||
void connectionFailed(const QByteArray & msg);
|
||||
void connectionFailed(const QByteArray &msg);
|
||||
void disconnected();
|
||||
void encrypted();
|
||||
void encryptionFailed(const QByteArray & msg);
|
||||
void encryptionFailed(const QByteArray &msg);
|
||||
void finished();
|
||||
void mailFailed(int mailID, int errorCode, const QByteArray & msg);
|
||||
void mailFailed(int mailID, int errorCode, const QByteArray &msg);
|
||||
void mailSent(int mailID);
|
||||
void recipientRejected(int mailID, const QString & address, const QByteArray & msg);
|
||||
void senderRejected(int mailID, const QString & address, const QByteArray & msg);
|
||||
void recipientRejected(int mailID, const QString &address, const QByteArray &msg);
|
||||
void senderRejected(int mailID, const QString &address, const QByteArray &msg);
|
||||
};
|
||||
|
||||
#endif
|
||||
Loading…
Add table
Add a link
Reference in a new issue