improved logging, improved server multithreading

This commit is contained in:
Max-Wilhelm Bruker 2011-03-22 17:55:20 +01:00
parent 8edc5b0635
commit fd7593edc1
11 changed files with 128 additions and 31 deletions

View file

@ -353,6 +353,7 @@ ResponseCode Server_ProtocolHandler::cmdJoinRoom(Command_JoinRoom *cmd, CommandC
return RespNameNotFound; return RespNameNotFound;
r->addClient(this); r->addClient(this);
connect(r, SIGNAL(gameCreated(Server_Game *)), this, SLOT(gameCreated(Server_Game *)));
rooms.insert(r->getId(), r); rooms.insert(r->getId(), r);
enqueueProtocolItem(new Event_RoomSay(r->getId(), QString(), r->getJoinMessage())); enqueueProtocolItem(new Event_RoomSay(r->getId(), QString(), r->getJoinMessage()));
@ -420,13 +421,17 @@ ResponseCode Server_ProtocolHandler::cmdCreateGame(Command_CreateGame *cmd, Comm
for (int i = 0; i < gameTypeList.size(); ++i) for (int i = 0; i < gameTypeList.size(); ++i)
gameTypes.append(gameTypeList[i]->getData()); gameTypes.append(gameTypeList[i]->getData());
Server_Game *game = room->createGame(cmd->getDescription(), cmd->getPassword(), cmd->getMaxPlayers(), gameTypes, cmd->getOnlyBuddies(), cmd->getOnlyRegistered(), cmd->getSpectatorsAllowed(), cmd->getSpectatorsNeedPassword(), cmd->getSpectatorsCanTalk(), cmd->getSpectatorsSeeEverything(), this); room->createGame(cmd->getDescription(), cmd->getPassword(), cmd->getMaxPlayers(), gameTypes, cmd->getOnlyBuddies(), cmd->getOnlyRegistered(), cmd->getSpectatorsAllowed(), cmd->getSpectatorsNeedPassword(), cmd->getSpectatorsCanTalk(), cmd->getSpectatorsSeeEverything(), this);
return RespOk;
}
void Server_ProtocolHandler::gameCreated(Server_Game *game)
{
Server_Player *creator = game->getPlayers().values().first(); Server_Player *creator = game->getPlayers().values().first();
games.insert(game->getGameId(), QPair<Server_Game *, Server_Player *>(game, creator)); games.insert(game->getGameId(), QPair<Server_Game *, Server_Player *>(game, creator));
enqueueProtocolItem(new Event_GameJoined(game->getGameId(), game->getDescription(), creator->getPlayerId(), false, game->getSpectatorsCanTalk(), game->getSpectatorsSeeEverything(), false)); sendProtocolItem(new Event_GameJoined(game->getGameId(), game->getDescription(), creator->getPlayerId(), false, game->getSpectatorsCanTalk(), game->getSpectatorsSeeEverything(), false));
enqueueProtocolItem(GameEventContainer::makeNew(new Event_GameStateChanged(game->getGameStarted(), game->getActivePlayer(), game->getActivePhase(), game->getGameState(creator)), game->getGameId())); sendProtocolItem(GameEventContainer::makeNew(new Event_GameStateChanged(game->getGameStarted(), game->getActivePlayer(), game->getActivePhase(), game->getGameState(creator)), game->getGameId()));
return RespOk;
} }
ResponseCode Server_ProtocolHandler::cmdJoinGame(Command_JoinGame *cmd, CommandContainer * /*cont*/, Server_Room *room) ResponseCode Server_ProtocolHandler::cmdJoinGame(Command_JoinGame *cmd, CommandContainer * /*cont*/, Server_Room *room)

View file

@ -91,6 +91,7 @@ private:
ResponseCode processCommandHelper(Command *command, CommandContainer *cont); ResponseCode processCommandHelper(Command *command, CommandContainer *cont);
private slots: private slots:
void pingClockTimeout(); void pingClockTimeout();
void gameCreated(Server_Game *game);
public: public:
Server_ProtocolHandler(Server *_server, QObject *parent = 0); Server_ProtocolHandler(Server *_server, QObject *parent = 0);
~Server_ProtocolHandler(); ~Server_ProtocolHandler();

View file

@ -6,6 +6,7 @@
Server_Room::Server_Room(int _id, const QString &_name, const QString &_description, bool _autoJoin, const QString &_joinMessage, const QStringList &_gameTypes, Server *parent) Server_Room::Server_Room(int _id, const QString &_name, const QString &_description, bool _autoJoin, const QString &_joinMessage, const QStringList &_gameTypes, Server *parent)
: QObject(parent), id(_id), name(_name), description(_description), autoJoin(_autoJoin), joinMessage(_joinMessage), gameTypes(_gameTypes) : QObject(parent), id(_id), name(_name), description(_description), autoJoin(_autoJoin), joinMessage(_joinMessage), gameTypes(_gameTypes)
{ {
connect(this, SIGNAL(sigCreateGame(const QString &, const QString &, int, const QList<int> &, bool, bool, bool, bool, bool, bool, Server_ProtocolHandler *)), this, SLOT(doCreateGame(const QString &, const QString &, int, const QList<int> &, bool, bool, bool, bool, bool, bool, Server_ProtocolHandler *)));
} }
Server *Server_Room::getServer() const Server *Server_Room::getServer() const
@ -68,7 +69,7 @@ void Server_Room::broadcastGameListUpdate(Server_Game *game)
delete event; delete event;
} }
Server_Game *Server_Room::createGame(const QString &description, const QString &password, int maxPlayers, const QList<int> &gameTypes, bool onlyBuddies, bool onlyRegistered, bool spectatorsAllowed, bool spectatorsNeedPassword, bool spectatorsCanTalk, bool spectatorsSeeEverything, Server_ProtocolHandler *creator) void Server_Room::doCreateGame(const QString &description, const QString &password, int maxPlayers, const QList<int> &gameTypes, bool onlyBuddies, bool onlyRegistered, bool spectatorsAllowed, bool spectatorsNeedPassword, bool spectatorsCanTalk, bool spectatorsSeeEverything, Server_ProtocolHandler *creator)
{ {
Server_Game *newGame = new Server_Game(creator, static_cast<Server *>(parent())->getNextGameId(), description, password, maxPlayers, gameTypes, onlyBuddies, onlyRegistered, spectatorsAllowed, spectatorsNeedPassword, spectatorsCanTalk, spectatorsSeeEverything, this); Server_Game *newGame = new Server_Game(creator, static_cast<Server *>(parent())->getNextGameId(), description, password, maxPlayers, gameTypes, onlyBuddies, onlyRegistered, spectatorsAllowed, spectatorsNeedPassword, spectatorsCanTalk, spectatorsSeeEverything, this);
games.insert(newGame->getGameId(), newGame); games.insert(newGame->getGameId(), newGame);
@ -78,8 +79,11 @@ Server_Game *Server_Room::createGame(const QString &description, const QString &
emit gameCreated(newGame); emit gameCreated(newGame);
emit roomInfoChanged(); emit roomInfoChanged();
}
return newGame; void Server_Room::createGame(const QString &description, const QString &password, int maxPlayers, const QList<int> &gameTypes, bool onlyBuddies, bool onlyRegistered, bool spectatorsAllowed, bool spectatorsNeedPassword, bool spectatorsCanTalk, bool spectatorsSeeEverything, Server_ProtocolHandler *creator)
{
emit sigCreateGame(description, password, maxPlayers, gameTypes, onlyBuddies, onlyRegistered, spectatorsAllowed, spectatorsNeedPassword, spectatorsCanTalk, spectatorsSeeEverything, creator);
} }
void Server_Room::removeGame() void Server_Room::removeGame()

View file

@ -19,6 +19,8 @@ signals:
void roomInfoChanged(); void roomInfoChanged();
void gameCreated(Server_Game *game); void gameCreated(Server_Game *game);
void gameClosing(int gameId); void gameClosing(int gameId);
void sigCreateGame(const QString &description, const QString &password, int maxPlayers, const QList<int> &_gameTypes, bool onlyBuddies, bool onlyRegistered, bool spectatorsAllowed, bool spectatorsNeedPassword, bool spectatorsCanTalk, bool spectatorsSeeEverything, Server_ProtocolHandler *creator);
private: private:
int id; int id;
QString name; QString name;
@ -28,6 +30,7 @@ private:
QStringList gameTypes; QStringList gameTypes;
QMap<int, Server_Game *> games; QMap<int, Server_Game *> games;
private slots: private slots:
void doCreateGame(const QString &description, const QString &password, int maxPlayers, const QList<int> &_gameTypes, bool onlyBuddies, bool onlyRegistered, bool spectatorsAllowed, bool spectatorsNeedPassword, bool spectatorsCanTalk, bool spectatorsSeeEverything, Server_ProtocolHandler *creator);
void removeGame(); void removeGame();
public: public:
Server_Room(int _id, const QString &_name, const QString &_description, bool _autoJoin, const QString &_joinMessage, const QStringList &_gameTypes, Server *parent); Server_Room(int _id, const QString &_name, const QString &_description, bool _autoJoin, const QString &_joinMessage, const QStringList &_gameTypes, Server *parent);
@ -44,7 +47,7 @@ public:
void removeClient(Server_ProtocolHandler *client); void removeClient(Server_ProtocolHandler *client);
void say(Server_ProtocolHandler *client, const QString &s); void say(Server_ProtocolHandler *client, const QString &s);
void broadcastGameListUpdate(Server_Game *game); void broadcastGameListUpdate(Server_Game *game);
Server_Game *createGame(const QString &description, const QString &password, int maxPlayers, const QList<int> &_gameTypes, bool onlyBuddies, bool onlyRegistered, bool spectatorsAllowed, bool spectatorsNeedPassword, bool spectatorsCanTalk, bool spectatorsSeeEverything, Server_ProtocolHandler *creator); void createGame(const QString &description, const QString &password, int maxPlayers, const QList<int> &_gameTypes, bool onlyBuddies, bool onlyRegistered, bool spectatorsAllowed, bool spectatorsNeedPassword, bool spectatorsCanTalk, bool spectatorsSeeEverything, Server_ProtocolHandler *creator);
void sendRoomEvent(RoomEvent *event); void sendRoomEvent(RoomEvent *event);
}; };

View file

@ -17,6 +17,7 @@ HEADERS += src/main.h \
src/servatrice.h \ src/servatrice.h \
src/serversocketinterface.h \ src/serversocketinterface.h \
src/server_logger.h \ src/server_logger.h \
src/serversocketthread.h \
../common/color.h \ ../common/color.h \
../common/serializable_item.h \ ../common/serializable_item.h \
../common/decklist.h \ ../common/decklist.h \
@ -40,6 +41,7 @@ SOURCES += src/main.cpp \
src/servatrice.cpp \ src/servatrice.cpp \
src/serversocketinterface.cpp \ src/serversocketinterface.cpp \
src/server_logger.cpp \ src/server_logger.cpp \
src/serversocketthread.cpp \
../common/serializable_item.cpp \ ../common/serializable_item.cpp \
../common/decklist.cpp \ ../common/decklist.cpp \
../common/protocol.cpp \ ../common/protocol.cpp \

View file

@ -21,6 +21,8 @@
#include <QCoreApplication> #include <QCoreApplication>
#include <QTextCodec> #include <QTextCodec>
#include <iostream> #include <iostream>
#include <QMetaType>
#include <QSettings>
#include "servatrice.h" #include "servatrice.h"
#include "server_logger.h" #include "server_logger.h"
#include "rng_sfmt.h" #include "rng_sfmt.h"
@ -65,14 +67,27 @@ void testRNG()
std::cerr << std::endl << std::endl; std::cerr << std::endl << std::endl;
} }
void myMessageOutput(QtMsgType /*type*/, const char *msg)
{
logger->logMessage(msg);
}
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
QCoreApplication app(argc, argv); QCoreApplication app(argc, argv);
app.setOrganizationName("Cockatrice"); app.setOrganizationName("Cockatrice");
app.setApplicationName("Servatrice"); app.setApplicationName("Servatrice");
QStringList args = app.arguments();
bool testRandom = args.contains("--test-random");
qRegisterMetaType<QList<int> >("QList<int>");
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8")); QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
logger = new ServerLogger;
QSettings *settings = new QSettings("servatrice.ini", QSettings::IniFormat);
logger = new ServerLogger(settings->value("server/logfile").toString());
qInstallMsgHandler(myMessageOutput);
#ifdef Q_OS_UNIX #ifdef Q_OS_UNIX
struct sigaction hup; struct sigaction hup;
hup.sa_handler = ServerLogger::hupSignalHandler; hup.sa_handler = ServerLogger::hupSignalHandler;
@ -86,9 +101,10 @@ int main(int argc, char *argv[])
std::cerr << "Servatrice " << Servatrice::versionString.toStdString() << " starting." << std::endl; std::cerr << "Servatrice " << Servatrice::versionString.toStdString() << " starting." << std::endl;
std::cerr << "-------------------------" << std::endl; std::cerr << "-------------------------" << std::endl;
testRNG(); if (testRandom)
testRNG();
Servatrice server; Servatrice server(settings);
std::cerr << "-------------------------" << std::endl; std::cerr << "-------------------------" << std::endl;
std::cerr << "Server initialized." << std::endl; std::cerr << "Server initialized." << std::endl;
@ -96,6 +112,7 @@ int main(int argc, char *argv[])
int retval = app.exec(); int retval = app.exec();
delete rng; delete rng;
delete settings;
return retval; return retval;
} }

View file

@ -24,10 +24,18 @@
#include "servatrice.h" #include "servatrice.h"
#include "server_room.h" #include "server_room.h"
#include "serversocketinterface.h" #include "serversocketinterface.h"
#include "serversocketthread.h"
#include "protocol.h" #include "protocol.h"
Servatrice::Servatrice(QObject *parent) void Servatrice_TcpServer::incomingConnection(int socketDescriptor)
: Server(parent), uptime(0) {
ServerSocketThread *sst = new ServerSocketThread(socketDescriptor, server, this);
connect(sst, SIGNAL(clientAdded(ServerSocketInterface *)), this, SIGNAL(clientAdded(ServerSocketInterface *)));
sst->start();
}
Servatrice::Servatrice(QSettings *_settings, QObject *parent)
: Server(parent), dbMutex(QMutex::Recursive), settings(_settings), uptime(0)
{ {
pingClock = new QTimer(this); pingClock = new QTimer(this);
connect(pingClock, SIGNAL(timeout()), this, SIGNAL(pingClockTimeout())); connect(pingClock, SIGNAL(timeout()), this, SIGNAL(pingClockTimeout()));
@ -38,7 +46,6 @@ Servatrice::Servatrice(QObject *parent)
banTimeoutClock->start(60000); banTimeoutClock->start(60000);
ProtocolItem::initializeHash(); ProtocolItem::initializeHash();
settings = new QSettings("servatrice.ini", QSettings::IniFormat, this);
int statusUpdateTime = settings->value("server/statusupdate").toInt(); int statusUpdateTime = settings->value("server/statusupdate").toInt();
statusUpdateClock = new QTimer(this); statusUpdateClock = new QTimer(this);
@ -48,8 +55,8 @@ Servatrice::Servatrice(QObject *parent)
statusUpdateClock->start(statusUpdateTime); statusUpdateClock->start(statusUpdateTime);
} }
tcpServer = new QTcpServer(this); tcpServer = new Servatrice_TcpServer(this);
connect(tcpServer, SIGNAL(newConnection()), this, SLOT(newConnection())); connect(tcpServer, SIGNAL(clientAdded(ServerSocketInterface *)), this, SLOT(newConnection(ServerSocketInterface *)));
int port = settings->value("server/port", 4747).toInt(); int port = settings->value("server/port", 4747).toInt();
qDebug() << "Starting server on port" << port; qDebug() << "Starting server on port" << port;
tcpServer->listen(QHostAddress::Any, port); tcpServer->listen(QHostAddress::Any, port);
@ -133,6 +140,7 @@ bool Servatrice::openDatabase()
void Servatrice::checkSql() void Servatrice::checkSql()
{ {
QMutexLocker locker(&dbMutex);
if (!QSqlDatabase::database().exec("select 1").isActive()) if (!QSqlDatabase::database().exec("select 1").isActive())
openDatabase(); openDatabase();
} }
@ -145,15 +153,14 @@ bool Servatrice::execSqlQuery(QSqlQuery &query)
return false; return false;
} }
void Servatrice::newConnection() void Servatrice::newConnection(ServerSocketInterface *client)
{ {
QTcpSocket *socket = tcpServer->nextPendingConnection(); addClient(client);
ServerSocketInterface *ssi = new ServerSocketInterface(this, socket);
addClient(ssi);
} }
AuthenticationResult Servatrice::checkUserPassword(const QString &user, const QString &password) AuthenticationResult Servatrice::checkUserPassword(const QString &user, const QString &password)
{ {
QMutexLocker locker(&dbMutex);
const QString method = settings->value("authentication/method").toString(); const QString method = settings->value("authentication/method").toString();
if (method == "none") if (method == "none")
return UnknownUser; return UnknownUser;
@ -181,6 +188,7 @@ AuthenticationResult Servatrice::checkUserPassword(const QString &user, const QS
bool Servatrice::userExists(const QString &user) bool Servatrice::userExists(const QString &user)
{ {
QMutexLocker locker(&dbMutex);
const QString method = settings->value("authentication/method").toString(); const QString method = settings->value("authentication/method").toString();
if (method == "sql") { if (method == "sql") {
checkSql(); checkSql();
@ -219,6 +227,7 @@ ServerInfo_User *Servatrice::evalUserQueryResult(const QSqlQuery &query, bool co
ServerInfo_User *Servatrice::getUserData(const QString &name) ServerInfo_User *Servatrice::getUserData(const QString &name)
{ {
QMutexLocker locker(&dbMutex);
const QString method = settings->value("authentication/method").toString(); const QString method = settings->value("authentication/method").toString();
if (method == "sql") { if (method == "sql") {
checkSql(); checkSql();
@ -248,6 +257,7 @@ int Servatrice::getUsersWithAddress(const QHostAddress &address) const
QMap<QString, ServerInfo_User *> Servatrice::getBuddyList(const QString &name) QMap<QString, ServerInfo_User *> Servatrice::getBuddyList(const QString &name)
{ {
QMutexLocker locker(&dbMutex);
QMap<QString, ServerInfo_User *> result; QMap<QString, ServerInfo_User *> result;
const QString method = settings->value("authentication/method").toString(); const QString method = settings->value("authentication/method").toString();
@ -270,6 +280,7 @@ QMap<QString, ServerInfo_User *> Servatrice::getBuddyList(const QString &name)
QMap<QString, ServerInfo_User *> Servatrice::getIgnoreList(const QString &name) QMap<QString, ServerInfo_User *> Servatrice::getIgnoreList(const QString &name)
{ {
QMutexLocker locker(&dbMutex);
QMap<QString, ServerInfo_User *> result; QMap<QString, ServerInfo_User *> result;
const QString method = settings->value("authentication/method").toString(); const QString method = settings->value("authentication/method").toString();
@ -318,6 +329,7 @@ void Servatrice::updateBanTimer()
void Servatrice::updateLoginMessage() void Servatrice::updateLoginMessage()
{ {
QMutexLocker locker(&dbMutex);
checkSql(); checkSql();
QSqlQuery query; QSqlQuery query;
query.prepare("select message from " + dbPrefix + "_servermessages order by timest desc limit 1"); query.prepare("select message from " + dbPrefix + "_servermessages order by timest desc limit 1");
@ -336,6 +348,7 @@ void Servatrice::updateLoginMessage()
void Servatrice::statusUpdate() void Servatrice::statusUpdate()
{ {
QMutexLocker locker(&dbMutex);
uptime += statusUpdateClock->interval() / 1000; uptime += statusUpdateClock->interval() / 1000;
checkSql(); checkSql();

View file

@ -21,6 +21,7 @@
#define SERVATRICE_H #define SERVATRICE_H
#include <QTcpServer> #include <QTcpServer>
#include <QMutex>
#include "server.h" #include "server.h"
class QSqlDatabase; class QSqlDatabase;
@ -28,16 +29,33 @@ class QSettings;
class QSqlQuery; class QSqlQuery;
class QTimer; class QTimer;
class Servatrice;
class ServerSocketInterface;
class Servatrice_TcpServer : public QTcpServer {
Q_OBJECT
private:
Servatrice *server;
public:
Servatrice_TcpServer(Servatrice *_server, QObject *parent = 0)
: QTcpServer(parent), server(_server) { }
protected:
void incomingConnection(int socketDescriptor);
signals:
void clientAdded(ServerSocketInterface *client);
};
class Servatrice : public Server class Servatrice : public Server
{ {
Q_OBJECT Q_OBJECT
private slots: private slots:
void newConnection(); void newConnection(ServerSocketInterface *client);
void statusUpdate(); void statusUpdate();
void updateBanTimer(); void updateBanTimer();
public: public:
QMutex dbMutex;
static const QString versionString; static const QString versionString;
Servatrice(QObject *parent = 0); Servatrice(QSettings *_settings, QObject *parent = 0);
~Servatrice(); ~Servatrice();
bool openDatabase(); bool openDatabase();
void checkSql(); void checkSql();

View file

@ -2,19 +2,27 @@
#include <QSocketNotifier> #include <QSocketNotifier>
#include <QFile> #include <QFile>
#include <QTextStream> #include <QTextStream>
#include <QMutex>
#include <QDateTime>
#include <QThread>
#ifdef Q_OS_UNIX
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <sys/socket.h>
#endif
ServerLogger::ServerLogger(QObject *parent) ServerLogger::ServerLogger(const QString &logFileName, QObject *parent)
: QObject(parent) : QObject(parent)
{ {
logFile = new QFile("server.log", this); if (!logFileName.isEmpty()) {
logFile->open(QIODevice::Append); logFile = new QFile(logFileName, this);
logFile->open(QIODevice::Append);
#ifdef Q_OS_UNIX #ifdef Q_OS_UNIX
::socketpair(AF_UNIX, SOCK_STREAM, 0, sigHupFD); ::socketpair(AF_UNIX, SOCK_STREAM, 0, sigHupFD);
#endif #endif
snHup = new QSocketNotifier(sigHupFD[1], QSocketNotifier::Read, this); snHup = new QSocketNotifier(sigHupFD[1], QSocketNotifier::Read, this);
connect(snHup, SIGNAL(activated(int)), this, SLOT(handleSigHup())); connect(snHup, SIGNAL(activated(int)), this, SLOT(handleSigHup()));
} else
logFile = 0;
} }
ServerLogger::~ServerLogger() ServerLogger::~ServerLogger()
@ -23,18 +31,30 @@ ServerLogger::~ServerLogger()
void ServerLogger::logMessage(QString message) void ServerLogger::logMessage(QString message)
{ {
if (!logFile)
return;
static QMutex mutex;
mutex.lock();
QTextStream stream(logFile); QTextStream stream(logFile);
stream << message << "\n"; stream << QDateTime::currentDateTime().toString() << " " << ((void *) QThread::currentThread()) << " " << message << "\n";
mutex.unlock();
} }
void ServerLogger::hupSignalHandler(int /*unused*/) void ServerLogger::hupSignalHandler(int /*unused*/)
{ {
if (!logFile)
return;
char a = 1; char a = 1;
::write(sigHupFD[0], &a, sizeof(a)); ::write(sigHupFD[0], &a, sizeof(a));
} }
void ServerLogger::handleSigHup() void ServerLogger::handleSigHup()
{ {
if (!logFile)
return;
snHup->setEnabled(false); snHup->setEnabled(false);
char tmp; char tmp;
::read(sigHupFD[1], &tmp, sizeof(tmp)); ::read(sigHupFD[1], &tmp, sizeof(tmp));

View file

@ -9,7 +9,7 @@ class QFile;
class ServerLogger : public QObject { class ServerLogger : public QObject {
Q_OBJECT Q_OBJECT
public: public:
ServerLogger(QObject *parent = 0); ServerLogger(const QString &logFileName, QObject *parent = 0);
~ServerLogger(); ~ServerLogger();
static void hupSignalHandler(int unused); static void hupSignalHandler(int unused);
public slots: public slots:

View file

@ -101,14 +101,18 @@ void ServerSocketInterface::catchSocketError(QAbstractSocket::SocketError socket
void ServerSocketInterface::sendProtocolItem(ProtocolItem *item, bool deleteItem) void ServerSocketInterface::sendProtocolItem(ProtocolItem *item, bool deleteItem)
{ {
static QMutex mutex;
mutex.lock();
item->write(xmlWriter); item->write(xmlWriter);
socket->flush(); socket->flush();
mutex.unlock();
if (deleteItem) if (deleteItem)
delete item; delete item;
} }
int ServerSocketInterface::getUserIdInDB(const QString &name) const int ServerSocketInterface::getUserIdInDB(const QString &name) const
{ {
QMutexLocker locker(&servatrice->dbMutex);
QSqlQuery query; QSqlQuery query;
query.prepare("select id from " + servatrice->getDbPrefix() + "_users where name = :name"); query.prepare("select id from " + servatrice->getDbPrefix() + "_users where name = :name");
query.bindValue(":name", name); query.bindValue(":name", name);
@ -142,6 +146,7 @@ ResponseCode ServerSocketInterface::cmdAddToList(Command_AddToList *cmd, Command
if (id1 == id2) if (id1 == id2)
return RespContextError; return RespContextError;
QMutexLocker locker(&servatrice->dbMutex);
QSqlQuery query; QSqlQuery query;
query.prepare("insert into " + servatrice->getDbPrefix() + "_" + list + "list (id_user1, id_user2) values(:id1, :id2)"); query.prepare("insert into " + servatrice->getDbPrefix() + "_" + list + "list (id_user1, id_user2) values(:id1, :id2)");
query.bindValue(":id1", id1); query.bindValue(":id1", id1);
@ -180,6 +185,7 @@ ResponseCode ServerSocketInterface::cmdRemoveFromList(Command_RemoveFromList *cm
if (id2 < 0) if (id2 < 0)
return RespNameNotFound; return RespNameNotFound;
QMutexLocker locker(&servatrice->dbMutex);
QSqlQuery query; QSqlQuery query;
query.prepare("delete from " + servatrice->getDbPrefix() + "_" + list + "list where id_user1 = :id1 and id_user2 = :id2"); query.prepare("delete from " + servatrice->getDbPrefix() + "_" + list + "list where id_user1 = :id1 and id_user2 = :id2");
query.bindValue(":id1", id1); query.bindValue(":id1", id1);
@ -206,6 +212,7 @@ int ServerSocketInterface::getDeckPathId(int basePathId, QStringList path)
if (path[0].isEmpty()) if (path[0].isEmpty())
return 0; return 0;
QMutexLocker locker(&servatrice->dbMutex);
QSqlQuery query; QSqlQuery query;
query.prepare("select id from " + servatrice->getDbPrefix() + "_decklist_folders where id_parent = :id_parent and name = :name and user = :user"); query.prepare("select id from " + servatrice->getDbPrefix() + "_decklist_folders where id_parent = :id_parent and name = :name and user = :user");
query.bindValue(":id_parent", basePathId); query.bindValue(":id_parent", basePathId);
@ -229,6 +236,7 @@ int ServerSocketInterface::getDeckPathId(const QString &path)
bool ServerSocketInterface::deckListHelper(DeckList_Directory *folder) bool ServerSocketInterface::deckListHelper(DeckList_Directory *folder)
{ {
QMutexLocker locker(&servatrice->dbMutex);
QSqlQuery query; QSqlQuery query;
query.prepare("select id, name from " + servatrice->getDbPrefix() + "_decklist_folders where id_parent = :id_parent and user = :user"); query.prepare("select id, name from " + servatrice->getDbPrefix() + "_decklist_folders where id_parent = :id_parent and user = :user");
query.bindValue(":id_parent", folder->getId()); query.bindValue(":id_parent", folder->getId());
@ -288,6 +296,7 @@ ResponseCode ServerSocketInterface::cmdDeckNewDir(Command_DeckNewDir *cmd, Comma
if (folderId == -1) if (folderId == -1)
return RespNameNotFound; return RespNameNotFound;
QMutexLocker locker(&servatrice->dbMutex);
QSqlQuery query; QSqlQuery query;
query.prepare("insert into " + servatrice->getDbPrefix() + "_decklist_folders (id_parent, user, name) values(:id_parent, :user, :name)"); query.prepare("insert into " + servatrice->getDbPrefix() + "_decklist_folders (id_parent, user, name) values(:id_parent, :user, :name)");
query.bindValue(":id_parent", folderId); query.bindValue(":id_parent", folderId);
@ -302,6 +311,7 @@ void ServerSocketInterface::deckDelDirHelper(int basePathId)
{ {
servatrice->checkSql(); servatrice->checkSql();
QMutexLocker locker(&servatrice->dbMutex);
QSqlQuery query; QSqlQuery query;
query.prepare("select id from " + servatrice->getDbPrefix() + "_decklist_folders where id_parent = :id_parent"); query.prepare("select id from " + servatrice->getDbPrefix() + "_decklist_folders where id_parent = :id_parent");
@ -340,6 +350,7 @@ ResponseCode ServerSocketInterface::cmdDeckDel(Command_DeckDel *cmd, CommandCont
servatrice->checkSql(); servatrice->checkSql();
QMutexLocker locker(&servatrice->dbMutex);
QSqlQuery query; QSqlQuery query;
query.prepare("select id from " + servatrice->getDbPrefix() + "_decklist_files where id = :id and user = :user"); query.prepare("select id from " + servatrice->getDbPrefix() + "_decklist_files where id = :id and user = :user");
@ -379,6 +390,7 @@ ResponseCode ServerSocketInterface::cmdDeckUpload(Command_DeckUpload *cmd, Comma
if (deckName.isEmpty()) if (deckName.isEmpty())
deckName = "Unnamed deck"; deckName = "Unnamed deck";
QMutexLocker locker(&servatrice->dbMutex);
QSqlQuery query; QSqlQuery query;
query.prepare("insert into " + servatrice->getDbPrefix() + "_decklist_files (id_folder, user, name, upload_time, content) values(:id_folder, :user, :name, NOW(), :content)"); query.prepare("insert into " + servatrice->getDbPrefix() + "_decklist_files (id_folder, user, name, upload_time, content) values(:id_folder, :user, :name, NOW(), :content)");
query.bindValue(":id_folder", folderId); query.bindValue(":id_folder", folderId);
@ -395,6 +407,7 @@ DeckList *ServerSocketInterface::getDeckFromDatabase(int deckId)
{ {
servatrice->checkSql(); servatrice->checkSql();
QMutexLocker locker(&servatrice->dbMutex);
QSqlQuery query; QSqlQuery query;
query.prepare("select content from " + servatrice->getDbPrefix() + "_decklist_files where id = :id and user = :user"); query.prepare("select content from " + servatrice->getDbPrefix() + "_decklist_files where id = :id and user = :user");
@ -447,6 +460,7 @@ ResponseCode ServerSocketInterface::cmdBanFromServer(Command_BanFromServer *cmd,
if (user->getUserInfo()->getUserLevel() & ServerInfo_User::IsRegistered) { if (user->getUserInfo()->getUserLevel() & ServerInfo_User::IsRegistered) {
// Registered users can be banned by name. // Registered users can be banned by name.
if (minutes == 0) { if (minutes == 0) {
QMutexLocker locker(&servatrice->dbMutex);
QSqlQuery query; QSqlQuery query;
query.prepare("update " + servatrice->getDbPrefix() + "_users set banned=1 where name = :name"); query.prepare("update " + servatrice->getDbPrefix() + "_users set banned=1 where name = :name");
query.bindValue(":name", userName); query.bindValue(":name", userName);