From 648a6a388495a8ecaf427976b5fa5f1c57bcca3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mark=20Morschh=C3=A4user?= Date: Fri, 20 Jun 2014 16:53:45 +0200 Subject: [PATCH 01/51] Qt5: QUrl addQueryItem moved to QUrlQuery --- cockatrice/src/deckstats_interface.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/cockatrice/src/deckstats_interface.cpp b/cockatrice/src/deckstats_interface.cpp index eae4caae..d5cb4ba0 100644 --- a/cockatrice/src/deckstats_interface.cpp +++ b/cockatrice/src/deckstats_interface.cpp @@ -7,6 +7,10 @@ #include #include +#if QT_VERSION >= 0x050000 +#include +#endif + DeckStatsInterface::DeckStatsInterface(QObject *parent) : QObject(parent) { @@ -42,7 +46,13 @@ void DeckStatsInterface::queryFinished(QNetworkReply *reply) void DeckStatsInterface::analyzeDeck(DeckList *deck) { QUrl params; +#if QT_VERSION < 0x050000 params.addQueryItem("deck", deck->writeToString_Plain()); +#else + QUrlQuery urlQuery; + urlQuery.addQueryItem("deck", deck->writeToString_Plain()); + params.setUrlQuery(urlQuery); +#endif QByteArray data; data.append(params.encodedQuery()); From a903c231f266a87fa6ef5b49600a9e6dc8df62b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mark=20Morschh=C3=A4user?= Date: Fri, 20 Jun 2014 16:54:46 +0200 Subject: [PATCH 02/51] Qt5: QDesktopServices::storageLocation deprecated --- cockatrice/src/main.cpp | 4 ++++ oracle/src/window_main.cpp | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/cockatrice/src/main.cpp b/cockatrice/src/main.cpp index ef57655a..2de76f9e 100644 --- a/cockatrice/src/main.cpp +++ b/cockatrice/src/main.cpp @@ -120,7 +120,11 @@ int main(int argc, char *argv[]) qsrand(QDateTime::currentDateTime().toTime_t()); bool startMainProgram = true; +#if QT_VERSION < 0x050000 const QString dataDir = QDesktopServices::storageLocation(QDesktopServices::DataLocation); +#else + const QString dataDir = QStandardPaths::standardLocations(QStandardPaths::DataLocation)).toString(); +#endif if (!db->getLoadSuccess()) if (db->loadCardDatabase(dataDir + "/cards.xml")) settingsCache->setCardDatabasePath(dataDir + "/cards.xml"); diff --git a/oracle/src/window_main.cpp b/oracle/src/window_main.cpp index 0283bded..6d4a1be9 100644 --- a/oracle/src/window_main.cpp +++ b/oracle/src/window_main.cpp @@ -24,7 +24,11 @@ const QString WindowMain::defaultSetsUrl = QString("http://www.woogerworks.com/f WindowMain::WindowMain(QWidget *parent) : QMainWindow(parent) { +#if QT_VERSION < 0x050000 importer = new OracleImporter(QDesktopServices::storageLocation(QDesktopServices::DataLocation), this); +#else + importer = new OracleImporter(QStandardPaths::standardLocations(QStandardPaths::DataLocation)).toString(), this); +#endif nam = new QNetworkAccessManager(this); checkBoxLayout = new QVBoxLayout; @@ -176,7 +180,11 @@ void WindowMain::updateTotalProgress(int cardsImported, int setIndex, const QStr if (nextSetName.isEmpty()) { QMessageBox::information(this, tr("Oracle importer"), tr("Import finished: %1 cards.").arg(importer->getCardList().size())); bool ok = false; +#if QT_VERSION < 0x050000 const QString dataDir = QDesktopServices::storageLocation(QDesktopServices::DataLocation); +#else + const QString dataDir = QStandardPaths::standardLocations(QStandardPaths::DataLocation)).toString(); +#endif QDir dir(dataDir); if (!dir.exists()) dir.mkpath(dataDir); From 6fa94dd475a951b393052179ca096ba285e943e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mark=20Morschh=C3=A4user?= Date: Fri, 20 Jun 2014 16:55:26 +0200 Subject: [PATCH 03/51] Qt5: toAscii() and fromAscii() Methods are deprecated --- cockatrice/src/qt-json/json.cpp | 2 +- servatrice/src/passwordhasher.cpp | 2 +- servatrice/src/servatrice.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cockatrice/src/qt-json/json.cpp b/cockatrice/src/qt-json/json.cpp index 1cda4453..faf6601b 100644 --- a/cockatrice/src/qt-json/json.cpp +++ b/cockatrice/src/qt-json/json.cpp @@ -553,7 +553,7 @@ int Json::nextToken(const QString &json, int &index) QChar c = json[index]; index++; - switch(c.toAscii()) + switch(c.toLatin1()) { case '{': return JsonTokenCurlyOpen; case '}': return JsonTokenCurlyClose; diff --git a/servatrice/src/passwordhasher.cpp b/servatrice/src/passwordhasher.cpp index 1cc8528c..073cd9b9 100644 --- a/servatrice/src/passwordhasher.cpp +++ b/servatrice/src/passwordhasher.cpp @@ -16,7 +16,7 @@ QString PasswordHasher::computeHash(const QString &password, const QString &salt const int algo = GCRY_MD_SHA512; const int rounds = 1000; - QByteArray passwordBuffer = (salt + password).toAscii(); + QByteArray passwordBuffer = (salt + password).toLatin1(); int hashLen = gcry_md_get_algo_dlen(algo); char hash[hashLen], tmp[hashLen]; gcry_md_hash_buffer(algo, hash, passwordBuffer.data(), passwordBuffer.size()); diff --git a/servatrice/src/servatrice.cpp b/servatrice/src/servatrice.cpp index ee513339..c4a31205 100644 --- a/servatrice/src/servatrice.cpp +++ b/servatrice/src/servatrice.cpp @@ -319,7 +319,7 @@ void Servatrice::updateServerList() query.prepare("select id, ssl_cert, hostname, address, game_port, control_port from " + dbPrefix + "_servers order by id asc"); servatriceDatabaseInterface->execSqlQuery(query); while (query.next()) { - ServerProperties prop(query.value(0).toInt(), QSslCertificate(query.value(1).toString().toAscii()), 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().toLatin1()), 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); } From 0721f5b41656757e56a0a4a343412c942f63306f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mark=20Morschh=C3=A4user?= Date: Fri, 20 Jun 2014 16:56:15 +0200 Subject: [PATCH 04/51] Qt5: QtWidgets as a Separate Module --- oracle/src/oracleimporter.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/oracle/src/oracleimporter.cpp b/oracle/src/oracleimporter.cpp index c244e56a..f4463455 100644 --- a/oracle/src/oracleimporter.cpp +++ b/oracle/src/oracleimporter.cpp @@ -1,5 +1,10 @@ #include "oracleimporter.h" +#if QT_VERSION < 0x050000 #include +#else +#include +#endif + #include #include #include From 05f46011eb35efff2c90ee4d7fa57c53f4ca2d53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mark=20Morschh=C3=A4user?= Date: Fri, 20 Jun 2014 18:16:46 +0200 Subject: [PATCH 05/51] Fix toLatin1() changes from 6fa94dd to toUtf8(). --- servatrice/src/passwordhasher.cpp | 2 +- servatrice/src/servatrice.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/servatrice/src/passwordhasher.cpp b/servatrice/src/passwordhasher.cpp index 073cd9b9..785034b4 100644 --- a/servatrice/src/passwordhasher.cpp +++ b/servatrice/src/passwordhasher.cpp @@ -16,7 +16,7 @@ QString PasswordHasher::computeHash(const QString &password, const QString &salt const int algo = GCRY_MD_SHA512; const int rounds = 1000; - QByteArray passwordBuffer = (salt + password).toLatin1(); + QByteArray passwordBuffer = (salt + password).toUtf8(); int hashLen = gcry_md_get_algo_dlen(algo); char hash[hashLen], tmp[hashLen]; gcry_md_hash_buffer(algo, hash, passwordBuffer.data(), passwordBuffer.size()); diff --git a/servatrice/src/servatrice.cpp b/servatrice/src/servatrice.cpp index c4a31205..6e0dbeb1 100644 --- a/servatrice/src/servatrice.cpp +++ b/servatrice/src/servatrice.cpp @@ -319,7 +319,7 @@ void Servatrice::updateServerList() query.prepare("select id, ssl_cert, hostname, address, game_port, control_port from " + dbPrefix + "_servers order by id asc"); servatriceDatabaseInterface->execSqlQuery(query); while (query.next()) { - ServerProperties prop(query.value(0).toInt(), QSslCertificate(query.value(1).toString().toLatin1()), 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); } From d7a962c055a49a85d491dc4562b6805dd9340cb6 Mon Sep 17 00:00:00 2001 From: Fabio Bas Date: Sat, 21 Jun 2014 14:12:55 +0200 Subject: [PATCH 06/51] CMake: support fir linking against qt5 --- CMakeLists.txt | 14 +++++- cockatrice/CMakeLists.txt | 97 ++++++++++++++++++++++++++++++++------- common/CMakeLists.txt | 15 +++++- oracle/CMakeLists.txt | 54 +++++++++++++++++++--- servatrice/CMakeLists.txt | 49 ++++++++++++++++++-- 5 files changed, 199 insertions(+), 30 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c8756e90..e60540e0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -71,8 +71,18 @@ IF(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") ADD_DEFINITIONS("-DSFMT_MEXP=19937") ENDIF() -#Find Qt4 and enable the needed features -FIND_PACKAGE(Qt4 REQUIRED) +#Find Qt and enable the needed features +FIND_PACKAGE(Qt5Widgets) +IF(Qt5Widgets_FOUND) + MESSAGE(STATUS "Found Qt ${Qt5Widgets_VERSION_STRING}") +ELSE() + FIND_PACKAGE(Qt4 REQUIRED) + IF(Qt4_FOUND) + MESSAGE(STATUS "Found Qt ${QT_VERSION_MAJOR}.${QT_VERSION_MINOR}.${QT_VERSION_PATCH}") + ELSE() + MESSAGE(FATAL_ERROR "No Qt4 or Qt5 found!") + ENDIF() +ENDIF() set(CMAKE_AUTOMOC TRUE) diff --git a/cockatrice/CMakeLists.txt b/cockatrice/CMakeLists.txt index 499836dd..8edbf602 100644 --- a/cockatrice/CMakeLists.txt +++ b/cockatrice/CMakeLists.txt @@ -125,36 +125,101 @@ if(APPLE) set(cockatrice_SOURCES ${cockatrice_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/resources/appicon.icns) ENDIF(APPLE) -if (NOT QT_QTMULTIMEDIA_FOUND) - FIND_PACKAGE(QtMobility REQUIRED) -endif (NOT QT_QTMULTIMEDIA_FOUND) +set(COCKATRICE_LIBS) -SET(QT_USE_QTNETWORK TRUE) -SET(QT_USE_QTMULTIMEDIA TRUE) -SET(QT_USE_QTXML TRUE) -SET(QT_USE_QTSVG TRUE) +# Qt4 stuff +if(Qt4_FOUND) + if (NOT QT_QTMULTIMEDIA_FOUND) + FIND_PACKAGE(QtMobility REQUIRED) + endif (NOT QT_QTMULTIMEDIA_FOUND) + + SET(QT_USE_QTNETWORK TRUE) + SET(QT_USE_QTMULTIMEDIA TRUE) + SET(QT_USE_QTXML TRUE) + SET(QT_USE_QTSVG TRUE) + + # Include directories + INCLUDE(${QT_USE_FILE}) + INCLUDE_DIRECTORIES(${QT_INCLUDES}) + INCLUDE_DIRECTORIES(${QT_MOBILITY_INCLUDE_DIR}) + INCLUDE_DIRECTORIES(${QT_MOBILITY_MULTIMEDIAKIT_INCLUDE_DIR}) + LIST(APPEND COCKATRICE_LIBS ${QT_LIBRARIES}) + LIST(APPEND COCKATRICE_LIBS ${QT_QTMAIN_LIBRARY}) + LIST(APPEND COCKATRICE_LIBS ${QT_MOBILITY_MULTIMEDIAKIT_LIBRARY}) + + # Let cmake chew Qt4's translations and resource files + # Note: header files are MOC-ed automatically by cmake + QT4_ADD_TRANSLATION(cockatrice_QM ${cockatrice_TS}) + QT4_ADD_RESOURCES(cockatrice_RESOURCES_RCC ${cockatrice_RESOURCES}) +endif() + +# qt5 stuff +if(Qt5Widgets_FOUND) + include_directories(${Qt5Widgets_INCLUDE_DIRS}) + list(APPEND COCKATRICE_LIBS Widgets) + + # QtNetwork + find_package(Qt5Network) + if(Qt5Network_FOUND) + include_directories(${Qt5Network_INCLUDE_DIRS}) + list(APPEND COCKATRICE_LIBS Network) + endif() + + # QtMultimedia + find_package(Qt5Multimedia) + if(Qt5Multimedia_FOUND) + include_directories(${Qt5Multimedia_INCLUDE_DIRS}) + list(APPEND COCKATRICE_LIBS Multimedia) + endif() + + # QtXml + find_package(Qt5Xml) + if(Qt5Xml_FOUND) + include_directories(${Qt5Xml_INCLUDE_DIRS}) + list(APPEND COCKATRICE_LIBS Xml) + endif() + + # QtSvg + find_package(Qt5Svg) + if(Qt5Svg_FOUND) + include_directories(${Qt5Svg_INCLUDE_DIRS}) + list(APPEND COCKATRICE_LIBS Svg) + endif() + + # Qt5LinguistTools + find_package(Qt5LinguistTools) + if(Qt5LinguistTools_FOUND) + include_directories(${Qt5LinguistTools_INCLUDE_DIRS}) + list(APPEND COCKATRICE_LIBS LinguistTools) + endif() + + # Let cmake chew Qt4's translations and resource files + # Note: header files are MOC-ed automatically by cmake + QT5_ADD_TRANSLATION(cockatrice_QM ${cockatrice_TS}) + QT5_ADD_RESOURCES(cockatrice_RESOURCES_RCC ${cockatrice_RESOURCES}) +endif() # Declare path variables set(ICONDIR share/icons CACHE STRING "icon dir") set(DESKTOPDIR share/applications CACHE STRING "desktop file destination") -# Let cmake chew Qt4's translations and resource files -# Note: header files are MOC-ed automatically by cmake -QT4_ADD_TRANSLATION(cockatrice_QM ${cockatrice_TS}) -QT4_ADD_RESOURCES(cockatrice_RESOURCES_RCC ${cockatrice_RESOURCES}) - # Include directories -INCLUDE(${QT_USE_FILE}) INCLUDE_DIRECTORIES(../common) INCLUDE_DIRECTORIES(${PROTOBUF_INCLUDE_DIR}) INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR}/common) INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}) -INCLUDE_DIRECTORIES(${QT_MOBILITY_INCLUDE_DIR}) -INCLUDE_DIRECTORIES(${QT_MOBILITY_MULTIMEDIAKIT_INCLUDE_DIR}) # Build cockatrice binary and link it ADD_EXECUTABLE(cockatrice WIN32 MACOSX_BUNDLE ${cockatrice_SOURCES} ${cockatrice_QM} ${cockatrice_RESOURCES_RCC} ${cockatrice_MOC_SRCS}) -TARGET_LINK_LIBRARIES(cockatrice cockatrice_common ${QT_QTMAIN_LIBRARY} ${QT_LIBRARIES} ${QT_MOBILITY_MULTIMEDIAKIT_LIBRARY}) + +if(Qt4_FOUND) + TARGET_LINK_LIBRARIES(cockatrice cockatrice_common ${COCKATRICE_LIBS}) +endif() +if(Qt5Widgets_FOUND) + TARGET_LINK_LIBRARIES(cockatrice cockatrice_common) + qt5_use_modules(cockatrice ${COCKATRICE_LIBS}) +endif() + if(MSVC) set_target_properties(cockatrice PROPERTIES LINK_FLAGS "/SUBSYSTEM:WINDOWS") diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 3f0d8c6c..47dab1f5 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -28,7 +28,20 @@ SET(common_SOURCES sfmt/SFMT.c ) -INCLUDE(${QT_USE_FILE}) +set(ORACLE_LIBS) + +# Qt4 stuff +if(Qt4_FOUND) + # Include directories + INCLUDE(${QT_USE_FILE}) + include_directories(${QT_INCLUDES}) +endif() + +# qt5 stuff +if(Qt5Widgets_FOUND) + include_directories(${Qt5Widgets_INCLUDE_DIRS}) +endif() + INCLUDE_DIRECTORIES(pb) INCLUDE_DIRECTORIES(sfmt) INCLUDE_DIRECTORIES(${PROTOBUF_INCLUDE_DIR}) diff --git a/oracle/CMakeLists.txt b/oracle/CMakeLists.txt index 624d9e96..dd544a1c 100644 --- a/oracle/CMakeLists.txt +++ b/oracle/CMakeLists.txt @@ -15,17 +15,59 @@ SET(oracle_SOURCES ../cockatrice/src/settingscache.cpp ) -SET(QT_USE_QTNETWORK TRUE) -SET(QT_USE_QTXML TRUE) -SET(QT_USE_QTSVG TRUE) +set(ORACLE_LIBS) + +# Qt4 stuff +if(Qt4_FOUND) + SET(QT_USE_QTNETWORK TRUE) + SET(QT_USE_QTXML TRUE) + SET(QT_USE_QTSVG TRUE) + + # Include directories + INCLUDE(${QT_USE_FILE}) + include_directories(${QT_INCLUDES}) + LIST(APPEND ORACLE_LIBS ${QT_QTMAIN_LIBRARY}) + LIST(APPEND ORACLE_LIBS ${QT_LIBRARIES}) +endif() + +# qt5 stuff +if(Qt5Widgets_FOUND) + include_directories(${Qt5Widgets_INCLUDE_DIRS}) + list(APPEND ORACLE_LIBS Widgets) + + # QtNetwork + find_package(Qt5Network) + if(Qt5Network_FOUND) + include_directories(${Qt5Network_INCLUDE_DIRS}) + list(APPEND ORACLE_LIBS Network) + endif() + + # QtXml + find_package(Qt5Xml) + if(Qt5Xml_FOUND) + include_directories(${Qt5Xml_INCLUDE_DIRS}) + list(APPEND ORACLE_LIBS Xml) + endif() + + # QtSvg + find_package(Qt5Svg) + if(Qt5Svg_FOUND) + include_directories(${Qt5Svg_INCLUDE_DIRS}) + list(APPEND ORACLE_LIBS Svg) + endif() +endif() -# Include directories -INCLUDE(${QT_USE_FILE}) INCLUDE_DIRECTORIES(../cockatrice/src) # Build oracle binary and link it ADD_EXECUTABLE(oracle WIN32 MACOSX_BUNDLE ${oracle_SOURCES} ${oracle_MOC_SRCS}) -TARGET_LINK_LIBRARIES(oracle ${QT_QTMAIN_LIBRARY} ${QT_LIBRARIES}) + +if(Qt4_FOUND) + TARGET_LINK_LIBRARIES(oracle ${ORACLE_LIBS}) +endif() +if(Qt5Widgets_FOUND) + qt5_use_modules(oracle ${ORACLE_LIBS}) +endif() if(MSVC) set_target_properties(oracle PROPERTIES LINK_FLAGS "/SUBSYSTEM:WINDOWS") diff --git a/servatrice/CMakeLists.txt b/servatrice/CMakeLists.txt index 799cecbd..ff403e23 100644 --- a/servatrice/CMakeLists.txt +++ b/servatrice/CMakeLists.txt @@ -20,12 +20,42 @@ SET(servatrice_SOURCES ${CMAKE_CURRENT_BINARY_DIR}/version_string.cpp ) -SET(QT_DONTUSE_QTGUI) -SET(QT_USE_QTNETWORK TRUE) -SET(QT_USE_QTSQL TRUE) +set(SERVATRICE_LIBS) + +# Qt4 stuff +if(Qt4_FOUND) + SET(QT_USE_QTNETWORK TRUE) + SET(QT_USE_QTSQL TRUE) + + # Include directories + INCLUDE(${QT_USE_FILE}) + include_directories(${QT_INCLUDES}) + LIST(APPEND SERVATRICE_LIBS ${QT_LIBRARIES}) +endif() + +# qt5 stuff +if(Qt5Widgets_FOUND) + include_directories(${Qt5Widgets_INCLUDE_DIRS}) + list(APPEND SERVATRICE_LIBS Widgets) + + # QtNetwork + find_package(Qt5Network) + if(Qt5Network_FOUND) + include_directories(${Qt5Network_INCLUDE_DIRS}) + list(APPEND SERVATRICE_LIBS Network) + endif() + + # QtSql + find_package(Qt5Sql) + if(Qt5Sql_FOUND) + include_directories(${Qt5Sql_INCLUDE_DIRS}) + list(APPEND SERVATRICE_LIBS Sql) + endif() +endif() + +SET(QT_DONT_USE_QTGUI TRUE) # Include directories -INCLUDE(${QT_USE_FILE}) INCLUDE_DIRECTORIES(../common) INCLUDE_DIRECTORIES(${LIBGCRYPT_INCLUDE_DIR}) INCLUDE_DIRECTORIES(${PROTOBUF_INCLUDE_DIR}) @@ -34,7 +64,16 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}) # Build servatrice binary and link it ADD_EXECUTABLE(servatrice MACOSX_BUNDLE ${servatrice_SOURCES} ${servatrice_MOC_SRCS}) -TARGET_LINK_LIBRARIES(servatrice cockatrice_common ${QT_LIBRARIES} ${LIBGCRYPT_LIBRARY} ${CMAKE_THREAD_LIBS_INIT}) + +if(Qt4_FOUND) + TARGET_LINK_LIBRARIES(servatrice cockatrice_common ${SERVATRICE_LIBS} ${LIBGCRYPT_LIBRARY} ${CMAKE_THREAD_LIBS_INIT}) +endif() +if(Qt5Widgets_FOUND) + TARGET_LINK_LIBRARIES(servatrice cockatrice_common ${LIBGCRYPT_LIBRARY} ${CMAKE_THREAD_LIBS_INIT}) + qt5_use_modules(servatrice ${SERVATRICE_LIBS}) +endif() + + #add_custom_target(versionheader ALL DEPENDS version_header) add_custom_command( From 80f68306b5210d83e7b130b49a82488020606d78 Mon Sep 17 00:00:00 2001 From: Fabio Bas Date: Tue, 24 Jun 2014 18:28:09 +0200 Subject: [PATCH 07/51] Ported oracle to Qt5 --- common/server_response_containers.h | 1 + oracle/CMakeLists.txt | 7 ++++++ oracle/src/main.cpp | 7 ++++-- oracle/src/oraclewizard.cpp | 35 ++++++++++++++++++++++++++--- 4 files changed, 45 insertions(+), 5 deletions(-) diff --git a/common/server_response_containers.h b/common/server_response_containers.h index 9220cdac..afad1a1e 100644 --- a/common/server_response_containers.h +++ b/common/server_response_containers.h @@ -2,6 +2,7 @@ #define SERVER_RESPONSE_CONTAINERS_H #include +#include #include "pb/server_message.pb.h" namespace google { namespace protobuf { class Message; } } diff --git a/oracle/CMakeLists.txt b/oracle/CMakeLists.txt index fddfe774..12dc6406 100644 --- a/oracle/CMakeLists.txt +++ b/oracle/CMakeLists.txt @@ -36,6 +36,13 @@ if(Qt5Widgets_FOUND) include_directories(${Qt5Widgets_INCLUDE_DIRS}) list(APPEND ORACLE_LIBS Widgets) + # QtConcurrent + find_package(Qt5Concurrent) + if(Qt5Concurrent_FOUND) + include_directories(${Qt5Concurrent_INCLUDE_DIRS}) + list(APPEND ORACLE_LIBS Concurrent) + endif() + # QtNetwork find_package(Qt5Network) if(Qt5Network_FOUND) diff --git a/oracle/src/main.cpp b/oracle/src/main.cpp index 44b900f3..d2fb708d 100644 --- a/oracle/src/main.cpp +++ b/oracle/src/main.cpp @@ -8,9 +8,12 @@ SettingsCache *settingsCache; int main(int argc, char *argv[]) { QApplication app(argc, argv); - + +#if QT_VERSION < 0x050000 + // gone in Qt5, all source files _MUST_ be utf8-encoded QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8")); - +#endif + QCoreApplication::setOrganizationName("Cockatrice"); QCoreApplication::setOrganizationDomain("cockatrice"); // this can't be changed, as it influences the default savepath for cards.xml diff --git a/oracle/src/oraclewizard.cpp b/oracle/src/oraclewizard.cpp index 75381b1d..4f0e102a 100644 --- a/oracle/src/oraclewizard.cpp +++ b/oracle/src/oraclewizard.cpp @@ -1,8 +1,25 @@ #include +#if QT_VERSION < 0x050000 + #include +#else + #include +#endif +#include +#include +#include +#include #include -#include +#include +#include +#include #include #include +#include +#include +#include +#include +#include +#include #include "oraclewizard.h" #include "oracleimporter.h" @@ -13,7 +30,14 @@ OracleWizard::OracleWizard(QWidget *parent) : QWizard(parent) { settings = new QSettings(this); - importer = new OracleImporter(QDesktopServices::storageLocation(QDesktopServices::DataLocation), this); + + importer = new OracleImporter( +#if QT_VERSION < 0x050000 + QDesktopServices::storageLocation(QDesktopServices::DataLocation) +#else + QStandardPaths::standardLocations(QStandardPaths::DataLocation).first() +#endif + , this); addPage(new IntroPage); addPage(new LoadSetsPage); @@ -372,7 +396,12 @@ void SaveSetsPage::updateTotalProgress(int cardsImported, int setIndex, const QS bool SaveSetsPage::validatePage() { bool ok = false; - const QString dataDir = QDesktopServices::storageLocation(QDesktopServices::DataLocation); + const QString dataDir = +#if QT_VERSION < 0x050000 + QDesktopServices::storageLocation(QDesktopServices::DataLocation); +#else + QStandardPaths::standardLocations(QStandardPaths::DataLocation).first(); +#endif QDir dir(dataDir); if (!dir.exists()) dir.mkpath(dataDir); From 2953c6ba2a6895cf429db0d3d3a0157db3bf8550 Mon Sep 17 00:00:00 2001 From: Fabio Bas Date: Tue, 24 Jun 2014 18:42:46 +0200 Subject: [PATCH 08/51] Ported servatrice --- servatrice/src/main.cpp | 34 ++++++++++++++++++++++++++++++---- servatrice/src/servatrice.cpp | 8 ++++++++ 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/servatrice/src/main.cpp b/servatrice/src/main.cpp index 0f7f0112..a37f3bd6 100644 --- a/servatrice/src/main.cpp +++ b/servatrice/src/main.cpp @@ -93,6 +93,17 @@ void myMessageOutput2(QtMsgType /*type*/, const char *msg) std::cerr << msg << std::endl; } +void myMessageOutputQt5(QtMsgType /*type*/, const QMessageLogContext &, const QString &msg) +{ + logger->logMessage(msg); +} + +void myMessageOutput2Qt5(QtMsgType /*type*/, const QMessageLogContext &, const QString &msg) +{ + logger->logMessage(msg); + std::cerr << msg.toStdString() << std::endl; +} + #ifdef Q_OS_UNIX void sigSegvHandler(int sig) { @@ -121,9 +132,12 @@ int main(int argc, char *argv[]) bool logToConsole = args.contains("--log-to-console"); qRegisterMetaType >("QList"); - + +#if QT_VERSION < 0x050000 + // gone in Qt5, all source files _MUST_ be utf8-encoded QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8")); - +#endif + QSettings *settings = new QSettings("servatrice.ini", QSettings::IniFormat); loggerThread = new QThread; @@ -133,11 +147,19 @@ int main(int argc, char *argv[]) loggerThread->start(); QMetaObject::invokeMethod(logger, "startLog", Qt::BlockingQueuedConnection, Q_ARG(QString, settings->value("server/logfile").toString())); - + +#if QT_VERSION < 0x050000 if (logToConsole) qInstallMsgHandler(myMessageOutput); else qInstallMsgHandler(myMessageOutput2); +#else + if (logToConsole) + qInstallMessageHandler(myMessageOutputQt5); + else + qInstallMessageHandler(myMessageOutput2Qt5); +#endif + #ifdef Q_OS_UNIX struct sigaction hup; hup.sa_handler = ServerLogger::hupSignalHandler; @@ -173,8 +195,12 @@ int main(int argc, char *argv[]) if (server->initServer()) { std::cerr << "-------------------------" << std::endl; std::cerr << "Server initialized." << std::endl; - + +#if QT_VERSION < 0x050000 qInstallMsgHandler(myMessageOutput); +#else + qInstallMessageHandler(myMessageOutputQt5); +#endif retval = app.exec(); std::cerr << "Server quit." << std::endl; diff --git a/servatrice/src/servatrice.cpp b/servatrice/src/servatrice.cpp index 6e0dbeb1..87eada78 100644 --- a/servatrice/src/servatrice.cpp +++ b/servatrice/src/servatrice.cpp @@ -234,8 +234,16 @@ bool Servatrice::initServer() if (!certFile.open(QIODevice::ReadOnly)) throw QString("Error opening certificate file: %1").arg(certFileName); QSslCertificate cert(&certFile); +#if QT_VERSION < 0x050000 if (!cert.isValid()) throw(QString("Invalid certificate.")); +#else + const QDateTime currentTime = QDateTime::currentDateTime(); + if(currentTime < cert.effectiveDate() || + currentTime > cert.expiryDate() || + cert.isBlacklisted()) + throw(QString("Invalid certificate.")); +#endif qDebug() << "Loading private key..."; QFile keyFile(keyFileName); if (!keyFile.open(QIODevice::ReadOnly)) From bab340f7b708aeb197d51c874f915c0545c61c0d Mon Sep 17 00:00:00 2001 From: Fabio Bas Date: Tue, 24 Jun 2014 18:52:04 +0200 Subject: [PATCH 09/51] Reworked a bit message handling from previous commit --- servatrice/src/main.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/servatrice/src/main.cpp b/servatrice/src/main.cpp index a37f3bd6..37b750f4 100644 --- a/servatrice/src/main.cpp +++ b/servatrice/src/main.cpp @@ -82,6 +82,7 @@ void testHash() std::cerr << startTime.secsTo(endTime) << "secs" << std::endl; } +#if QT_VERSION < 0x050000 void myMessageOutput(QtMsgType /*type*/, const char *msg) { logger->logMessage(msg); @@ -92,17 +93,18 @@ void myMessageOutput2(QtMsgType /*type*/, const char *msg) logger->logMessage(msg); std::cerr << msg << std::endl; } - -void myMessageOutputQt5(QtMsgType /*type*/, const QMessageLogContext &, const QString &msg) +#else +void myMessageOutput(QtMsgType /*type*/, const QMessageLogContext &, const QString &msg) { logger->logMessage(msg); } -void myMessageOutput2Qt5(QtMsgType /*type*/, const QMessageLogContext &, const QString &msg) +void myMessageOutput2(QtMsgType /*type*/, const QMessageLogContext &, const QString &msg) { logger->logMessage(msg); std::cerr << msg.toStdString() << std::endl; } +#endif #ifdef Q_OS_UNIX void sigSegvHandler(int sig) @@ -155,9 +157,9 @@ int main(int argc, char *argv[]) qInstallMsgHandler(myMessageOutput2); #else if (logToConsole) - qInstallMessageHandler(myMessageOutputQt5); + qInstallMessageHandler(myMessageOutput); else - qInstallMessageHandler(myMessageOutput2Qt5); + qInstallMessageHandler(myMessageOutput2); #endif #ifdef Q_OS_UNIX @@ -199,7 +201,7 @@ int main(int argc, char *argv[]) #if QT_VERSION < 0x050000 qInstallMsgHandler(myMessageOutput); #else - qInstallMessageHandler(myMessageOutputQt5); + qInstallMessageHandler(myMessageOutput); #endif retval = app.exec(); From 6dbdaafb332aa1cde577ece46bb554cb0ac28c6b Mon Sep 17 00:00:00 2001 From: Fabio Bas Date: Tue, 24 Jun 2014 19:13:47 +0200 Subject: [PATCH 10/51] Ported cockatrice --- cockatrice/CMakeLists.txt | 7 +++ cockatrice/src/abstractcounter.cpp | 14 ++++- cockatrice/src/carddatabasemodel.cpp | 8 +++ cockatrice/src/decklistmodel.cpp | 8 +++ cockatrice/src/deckstats_interface.cpp | 8 +-- cockatrice/src/deckview.cpp | 4 ++ cockatrice/src/dlg_create_token.cpp | 5 ++ cockatrice/src/dlg_edit_tokens.cpp | 5 ++ cockatrice/src/gameselector.cpp | 5 +- cockatrice/src/main.cpp | 23 +++++++- cockatrice/src/pilezone.cpp | 4 ++ cockatrice/src/player.cpp | 52 ++++++++++++++++--- cockatrice/src/playerlistwidget.cpp | 4 ++ cockatrice/src/remotedecklist_treewidget.cpp | 13 +++++ .../src/remotereplaylist_treewidget.cpp | 4 ++ cockatrice/src/soundengine.cpp | 5 ++ cockatrice/src/tab_deck_editor.cpp | 4 ++ cockatrice/src/tab_deck_storage.cpp | 4 ++ cockatrice/src/tab_replays.cpp | 4 ++ cockatrice/src/tab_server.cpp | 8 ++- cockatrice/src/tablezone.cpp | 4 ++ cockatrice/src/userlist.cpp | 4 ++ 22 files changed, 181 insertions(+), 16 deletions(-) diff --git a/cockatrice/CMakeLists.txt b/cockatrice/CMakeLists.txt index 8edbf602..e02f9e2c 100644 --- a/cockatrice/CMakeLists.txt +++ b/cockatrice/CMakeLists.txt @@ -172,6 +172,13 @@ if(Qt5Widgets_FOUND) list(APPEND COCKATRICE_LIBS Multimedia) endif() + # QtPrinter + find_package(Qt5PrintSupport) + if(Qt5PrintSupport_FOUND) + include_directories(${Qt5PrintSupport_INCLUDE_DIRS}) + list(APPEND COCKATRICE_LIBS PrintSupport) + endif() + # QtXml find_package(Qt5Xml) if(Qt5Xml_FOUND) diff --git a/cockatrice/src/abstractcounter.cpp b/cockatrice/src/abstractcounter.cpp index 73fc9466..b9debae4 100644 --- a/cockatrice/src/abstractcounter.cpp +++ b/cockatrice/src/abstractcounter.cpp @@ -11,8 +11,12 @@ AbstractCounter::AbstractCounter(Player *_player, int _id, const QString &_name, bool _shownInCounterArea, int _value, QGraphicsItem *parent) : QGraphicsItem(parent), player(_player), id(_id), name(_name), value(_value), hovered(false), aDec(0), aInc(0), dialogSemaphore(false), deleteAfterDialog(false), shownInCounterArea(_shownInCounterArea) { +#if QT_VERSION < 0x050000 setAcceptsHoverEvents(true); - +#else + setAcceptHoverEvents(true); +#endif + if (player->getLocal()) { menu = new QMenu(name); aSet = new QAction(this); @@ -129,7 +133,13 @@ void AbstractCounter::setCounter() { bool ok; dialogSemaphore = true; - int newValue = QInputDialog::getInteger(0, tr("Set counter"), tr("New value for counter '%1':").arg(name), value, -2000000000, 2000000000, 1, &ok); + int newValue = +#if QT_VERSION < 0x050000 + QInputDialog::getInteger( +#else + QInputDialog::getInt( +#endif + 0, tr("Set counter"), tr("New value for counter '%1':").arg(name), value, -2000000000, 2000000000, 1, &ok); if (deleteAfterDialog) { deleteLater(); return; diff --git a/cockatrice/src/carddatabasemodel.cpp b/cockatrice/src/carddatabasemodel.cpp index e62664be..65b08d49 100644 --- a/cockatrice/src/carddatabasemodel.cpp +++ b/cockatrice/src/carddatabasemodel.cpp @@ -68,6 +68,10 @@ QVariant CardDatabaseModel::headerData(int section, Qt::Orientation orientation, void CardDatabaseModel::updateCardList() { +#if QT_VERSION >= 0x050000 + beginResetModel(); +#endif + for (int i = 0; i < cardList.size(); ++i) disconnect(cardList[i], 0, this, 0); @@ -75,7 +79,11 @@ void CardDatabaseModel::updateCardList() for (int i = 0; i < cardList.size(); ++i) connect(cardList[i], SIGNAL(cardInfoChanged(CardInfo *)), this, SLOT(cardInfoChanged(CardInfo *))); +#if QT_VERSION < 0x050000 reset(); +#else + endResetModel(); +#endif } void CardDatabaseModel::cardInfoChanged(CardInfo *card) diff --git a/cockatrice/src/decklistmodel.cpp b/cockatrice/src/decklistmodel.cpp index 00d92fae..8a1065f0 100644 --- a/cockatrice/src/decklistmodel.cpp +++ b/cockatrice/src/decklistmodel.cpp @@ -30,6 +30,10 @@ DeckListModel::~DeckListModel() void DeckListModel::rebuildTree() { +#if QT_VERSION >= 0x050000 + beginResetModel(); +#endif + root->clearTree(); InnerDecklistNode *listRoot = deckList->getRoot(); for (int i = 0; i < listRoot->size(); i++) { @@ -55,7 +59,11 @@ void DeckListModel::rebuildTree() } } +#if QT_VERSION < 0x050000 reset(); +#else + endResetModel(); +#endif } int DeckListModel::rowCount(const QModelIndex &parent) const diff --git a/cockatrice/src/deckstats_interface.cpp b/cockatrice/src/deckstats_interface.cpp index d5cb4ba0..4eb62d20 100644 --- a/cockatrice/src/deckstats_interface.cpp +++ b/cockatrice/src/deckstats_interface.cpp @@ -48,13 +48,15 @@ void DeckStatsInterface::analyzeDeck(DeckList *deck) QUrl params; #if QT_VERSION < 0x050000 params.addQueryItem("deck", deck->writeToString_Plain()); + QByteArray data; + data.append(params.encodedQuery()); #else QUrlQuery urlQuery; urlQuery.addQueryItem("deck", deck->writeToString_Plain()); - params.setUrlQuery(urlQuery); -#endif + params.setQuery(urlQuery); QByteArray data; - data.append(params.encodedQuery()); + data.append(params.query(QUrl::EncodeReserved)); +#endif QNetworkRequest request(QUrl("http://deckstats.net/index.php")); request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded"); diff --git a/cockatrice/src/deckview.cpp b/cockatrice/src/deckview.cpp index 1746c58b..5a14ec3f 100644 --- a/cockatrice/src/deckview.cpp +++ b/cockatrice/src/deckview.cpp @@ -64,7 +64,11 @@ void DeckViewCardDragItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) DeckViewCard::DeckViewCard(const QString &_name, const QString &_originZone, QGraphicsItem *parent) : AbstractCardItem(_name, 0, -1, parent), originZone(_originZone), dragItem(0) { +#if QT_VERSION < 0x050000 setAcceptsHoverEvents(true); +#else + setAcceptHoverEvents(true); +#endif } DeckViewCard::~DeckViewCard() diff --git a/cockatrice/src/dlg_create_token.cpp b/cockatrice/src/dlg_create_token.cpp index 942fdda6..9775ed0c 100644 --- a/cockatrice/src/dlg_create_token.cpp +++ b/cockatrice/src/dlg_create_token.cpp @@ -79,8 +79,13 @@ DlgCreateToken::DlgCreateToken(const QStringList &_predefinedTokens, QWidget *pa chooseTokenView->header()->setStretchLastSection(false); chooseTokenView->header()->hideSection(1); chooseTokenView->header()->hideSection(2); +#if QT_VERSION < 0x050000 chooseTokenView->header()->setResizeMode(3, QHeaderView::ResizeToContents); chooseTokenView->header()->setResizeMode(4, QHeaderView::ResizeToContents); +#else + chooseTokenView->header()->setSectionResizeMode(3, QHeaderView::ResizeToContents); + chooseTokenView->header()->setSectionResizeMode(4, QHeaderView::ResizeToContents); +#endif connect(chooseTokenView->selectionModel(), SIGNAL(currentRowChanged(QModelIndex, QModelIndex)), this, SLOT(tokenSelectionChanged(QModelIndex, QModelIndex))); if (predefinedTokens.isEmpty()) diff --git a/cockatrice/src/dlg_edit_tokens.cpp b/cockatrice/src/dlg_edit_tokens.cpp index 038b1a4a..28fefa7d 100644 --- a/cockatrice/src/dlg_edit_tokens.cpp +++ b/cockatrice/src/dlg_edit_tokens.cpp @@ -73,8 +73,13 @@ DlgEditTokens::DlgEditTokens(CardDatabaseModel *_cardDatabaseModel, QWidget *par chooseTokenView->header()->setStretchLastSection(false); chooseTokenView->header()->hideSection(1); chooseTokenView->header()->hideSection(2); +#if QT_VERSION < 0x050000 chooseTokenView->header()->setResizeMode(3, QHeaderView::ResizeToContents); chooseTokenView->header()->setResizeMode(4, QHeaderView::ResizeToContents); +#else + chooseTokenView->header()->setSectionResizeMode(3, QHeaderView::ResizeToContents); + chooseTokenView->header()->setSectionResizeMode(4, QHeaderView::ResizeToContents); +#endif connect(chooseTokenView->selectionModel(), SIGNAL(currentRowChanged(QModelIndex, QModelIndex)), this, SLOT(tokenSelectionChanged(QModelIndex, QModelIndex))); QAction *aAddToken = new QAction(tr("Add token"), this); diff --git a/cockatrice/src/gameselector.cpp b/cockatrice/src/gameselector.cpp index 6a05d905..02fb323e 100644 --- a/cockatrice/src/gameselector.cpp +++ b/cockatrice/src/gameselector.cpp @@ -33,8 +33,11 @@ GameSelector::GameSelector(AbstractClient *_client, const TabSupervisor *_tabSup gameListView->header()->hideSection(1); else gameListProxyModel->setUnavailableGamesVisible(true); +#if QT_VERSION < 0x050000 gameListView->header()->setResizeMode(1, QHeaderView::ResizeToContents); - +#else + gameListView->header()->setSectionResizeMode(1, QHeaderView::ResizeToContents); +#endif filterButton = new QPushButton; filterButton->setIcon(QIcon(":/resources/icon_search.svg")); connect(filterButton, SIGNAL(clicked()), this, SLOT(actSetFilter())); diff --git a/cockatrice/src/main.cpp b/cockatrice/src/main.cpp index 23ca8c7a..c47eb7bc 100644 --- a/cockatrice/src/main.cpp +++ b/cockatrice/src/main.cpp @@ -55,6 +55,7 @@ QString translationPath = TRANSLATION_PATH; QString translationPath = QString(); #endif +#if QT_VERSION < 0x050000 void myMessageOutput(QtMsgType /*type*/, const char *msg) { QFile file("qdebug.txt"); @@ -63,6 +64,16 @@ void myMessageOutput(QtMsgType /*type*/, const char *msg) out << msg << endl; file.close(); } +#else +void myMessageOutput(QtMsgType /*type*/, const QMessageLogContext &, const QString &msg) +{ + QFile file("qdebug.txt"); + file.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text); + QTextStream out(&file); + out << msg << endl; + file.close(); +} +#endif void installNewTranslator() { @@ -87,7 +98,13 @@ int main(int argc, char *argv[]) QApplication app(argc, argv); if (app.arguments().contains("--debug-output")) + { +#if QT_VERSION < 0x050000 qInstallMsgHandler(myMessageOutput); +#else + qInstallMessageHandler(myMessageOutput); +#endif + } #ifdef Q_OS_MAC QDir baseDir(app.applicationDirPath()); baseDir.cdUp(); @@ -100,7 +117,11 @@ int main(int argc, char *argv[]) #ifdef Q_OS_WIN app.addLibraryPath(app.applicationDirPath() + "/plugins"); #endif + +#if QT_VERSION < 0x050000 + // gone in Qt5, all source files _MUST_ be utf8-encoded QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8")); +#endif QCoreApplication::setOrganizationName("Cockatrice"); QCoreApplication::setOrganizationDomain("cockatrice.de"); @@ -131,7 +152,7 @@ int main(int argc, char *argv[]) #if QT_VERSION < 0x050000 const QString dataDir = QDesktopServices::storageLocation(QDesktopServices::DataLocation); #else - const QString dataDir = QStandardPaths::standardLocations(QStandardPaths::DataLocation)).toString(); + const QString dataDir = QStandardPaths::standardLocations(QStandardPaths::DataLocation).first(); #endif if (!db->getLoadSuccess()) if (db->loadCardDatabase(dataDir + "/cards.xml")) diff --git a/cockatrice/src/pilezone.cpp b/cockatrice/src/pilezone.cpp index 0dbdd566..ed9daa88 100644 --- a/cockatrice/src/pilezone.cpp +++ b/cockatrice/src/pilezone.cpp @@ -13,7 +13,11 @@ PileZone::PileZone(Player *_p, const QString &_name, bool _isShufflable, bool _c : CardZone(_p, _name, false, _isShufflable, _contentsKnown, parent) { setCacheMode(DeviceCoordinateCache); // Do not move this line to the parent constructor! +#if QT_VERSION < 0x050000 setAcceptsHoverEvents(true); +#else + setAcceptHoverEvents(true); +#endif setCursor(Qt::OpenHandCursor); setTransform(QTransform().translate((float) CARD_WIDTH / 2, (float) CARD_HEIGHT / 2).rotate(90).translate((float) -CARD_WIDTH / 2, (float) -CARD_HEIGHT / 2)); diff --git a/cockatrice/src/player.cpp b/cockatrice/src/player.cpp index 762b4387..d260cbea 100644 --- a/cockatrice/src/player.cpp +++ b/cockatrice/src/player.cpp @@ -774,7 +774,13 @@ void Player::actViewLibrary() void Player::actViewTopCards() { bool ok; - int number = QInputDialog::getInteger(0, tr("View top cards of library"), tr("Number of cards:"), defaultNumberTopCards, 1, 2000000000, 1, &ok); + int number = +#if QT_VERSION < 0x050000 + QInputDialog::getInteger( +#else + QInputDialog::getInt( +#endif + 0, tr("View top cards of library"), tr("Number of cards:"), defaultNumberTopCards, 1, 2000000000, 1, &ok); if (ok) { defaultNumberTopCards = number; static_cast(scene())->toggleZoneView(this, "deck", number); @@ -829,7 +835,13 @@ void Player::actMulligan() void Player::actDrawCards() { - int number = QInputDialog::getInteger(0, tr("Draw cards"), tr("Number:")); + int number = +#if QT_VERSION < 0x050000 + QInputDialog::getInteger( +#else + QInputDialog::getInt( +#endif + 0, tr("Draw cards"), tr("Number:")); if (number) { Command_DrawCards cmd; cmd.set_number(number); @@ -844,8 +856,14 @@ void Player::actUndoDraw() void Player::actMoveTopCardsToGrave() { - int number = QInputDialog::getInteger(0, tr("Move top cards to grave"), tr("Number:")); - if (!number) + int number = +#if QT_VERSION < 0x050000 + QInputDialog::getInteger( +#else + QInputDialog::getInt( +#endif + 0, tr("Move top cards to grave"), tr("Number:")); + if (!number) return; const int maxCards = zones.value("deck")->getCards().size(); @@ -867,8 +885,14 @@ void Player::actMoveTopCardsToGrave() void Player::actMoveTopCardsToExile() { - int number = QInputDialog::getInteger(0, tr("Move top cards to exile"), tr("Number:")); - if (!number) + int number = +#if QT_VERSION < 0x050000 + QInputDialog::getInteger( +#else + QInputDialog::getInt( +#endif + 0, tr("Move top cards to exile"), tr("Number:")); + if (!number) return; const int maxCards = zones.value("deck")->getCards().size(); @@ -914,7 +938,13 @@ void Player::actUntapAll() void Player::actRollDie() { bool ok; - int sides = QInputDialog::getInteger(0, tr("Roll die"), tr("Number of sides:"), 20, 2, 1000, 1, &ok); + int sides = +#if QT_VERSION < 0x050000 + QInputDialog::getInteger( +#else + QInputDialog::getInt( +#endif + 0, tr("Roll die"), tr("Number of sides:"), 20, 2, 1000, 1, &ok); if (ok) { Command_RollDie cmd; cmd.set_sides(sides); @@ -2022,7 +2052,13 @@ void Player::actCardCounterTrigger() case 11: { bool ok; dialogSemaphore = true; - int number = QInputDialog::getInteger(0, tr("Set counters"), tr("Number:"), 0, 0, MAX_COUNTERS_ON_CARD, 1, &ok); + int number = +#if QT_VERSION < 0x050000 + QInputDialog::getInteger( +#else + QInputDialog::getInt( +#endif + 0, tr("Set counters"), tr("Number:"), 0, 0, MAX_COUNTERS_ON_CARD, 1, &ok); dialogSemaphore = false; if (clearCardsToDelete()) return; diff --git a/cockatrice/src/playerlistwidget.cpp b/cockatrice/src/playerlistwidget.cpp index f299cda9..ee088203 100644 --- a/cockatrice/src/playerlistwidget.cpp +++ b/cockatrice/src/playerlistwidget.cpp @@ -72,7 +72,11 @@ PlayerListWidget::PlayerListWidget(TabSupervisor *_tabSupervisor, AbstractClient setColumnCount(6); setHeaderHidden(true); setRootIsDecorated(false); +#if QT_VERSION < 0x050000 header()->setResizeMode(QHeaderView::ResizeToContents); +#else + header()->setSectionResizeMode(QHeaderView::ResizeToContents); +#endif retranslateUi(); } diff --git a/cockatrice/src/remotedecklist_treewidget.cpp b/cockatrice/src/remotedecklist_treewidget.cpp index b72df671..809f3fe8 100644 --- a/cockatrice/src/remotedecklist_treewidget.cpp +++ b/cockatrice/src/remotedecklist_treewidget.cpp @@ -258,8 +258,17 @@ void RemoteDeckList_TreeModel::deckListFinished(const Response &r) { const Response_DeckList &resp = r.GetExtension(Response_DeckList::ext); +#if QT_VERSION >= 0x050000 + beginResetModel(); +#endif + root->clearTree(); + +#if QT_VERSION < 0x050000 reset(); +#else + endResetModel(); +#endif ServerInfo_DeckStorage_TreeItem tempRoot; tempRoot.set_id(0); @@ -280,7 +289,11 @@ RemoteDeckList_TreeWidget::RemoteDeckList_TreeWidget(AbstractClient *_client, QW setModel(proxyModel); connect(treeModel, SIGNAL(treeRefreshed()), this, SLOT(expandAll())); +#if QT_VERSION < 0x050000 header()->setResizeMode(QHeaderView::ResizeToContents); +#else + header()->setSectionResizeMode(QHeaderView::ResizeToContents); +#endif setUniformRowHeights(true); setSortingEnabled(true); proxyModel->sort(0, Qt::AscendingOrder); diff --git a/cockatrice/src/remotereplaylist_treewidget.cpp b/cockatrice/src/remotereplaylist_treewidget.cpp index 6184049e..5357596f 100644 --- a/cockatrice/src/remotereplaylist_treewidget.cpp +++ b/cockatrice/src/remotereplaylist_treewidget.cpp @@ -278,7 +278,11 @@ RemoteReplayList_TreeWidget::RemoteReplayList_TreeWidget(AbstractClient *_client proxyModel->setSortCaseSensitivity(Qt::CaseInsensitive); setModel(proxyModel); +#if QT_VERSION < 0x050000 header()->setResizeMode(QHeaderView::ResizeToContents); +#else + header()->setSectionResizeMode(QHeaderView::ResizeToContents); +#endif header()->setStretchLastSection(false); setUniformRowHeights(true); setSortingEnabled(true); diff --git a/cockatrice/src/soundengine.cpp b/cockatrice/src/soundengine.cpp index 5847c9ae..89820f9d 100644 --- a/cockatrice/src/soundengine.cpp +++ b/cockatrice/src/soundengine.cpp @@ -33,8 +33,13 @@ void SoundEngine::soundEnabledChanged() if (settingsCache->getSoundEnabled()) { qDebug("SoundEngine: enabling sound"); QAudioFormat format; +#if QT_VERSION < 0x050000 format.setFrequency(44100); format.setChannels(1); +#else + format.setSampleRate(44100); + format.setChannelCount(1); +#endif format.setSampleSize(16); format.setCodec("audio/pcm"); format.setByteOrder(QAudioFormat::LittleEndian); diff --git a/cockatrice/src/tab_deck_editor.cpp b/cockatrice/src/tab_deck_editor.cpp index 0c1d44e1..0b27dcbf 100644 --- a/cockatrice/src/tab_deck_editor.cpp +++ b/cockatrice/src/tab_deck_editor.cpp @@ -134,7 +134,11 @@ TabDeckEditor::TabDeckEditor(TabSupervisor *_tabSupervisor, QWidget *parent) deckView->setUniformRowHeights(true); deckView->setSortingEnabled(true); deckView->sortByColumn(1, Qt::AscendingOrder); +#if QT_VERSION < 0x050000 deckView->header()->setResizeMode(QHeaderView::ResizeToContents); +#else + deckView->header()->setSectionResizeMode(QHeaderView::ResizeToContents); +#endif deckView->installEventFilter(&deckViewKeySignals); connect(deckView->selectionModel(), SIGNAL(currentRowChanged(const QModelIndex &, const QModelIndex &)), this, SLOT(updateCardInfoRight(const QModelIndex &, const QModelIndex &))); connect(&deckViewKeySignals, SIGNAL(onEnter()), this, SLOT(actIncrement())); diff --git a/cockatrice/src/tab_deck_storage.cpp b/cockatrice/src/tab_deck_storage.cpp index 7e7d30ed..9898c9ee 100644 --- a/cockatrice/src/tab_deck_storage.cpp +++ b/cockatrice/src/tab_deck_storage.cpp @@ -38,7 +38,11 @@ TabDeckStorage::TabDeckStorage(TabSupervisor *_tabSupervisor, AbstractClient *_c localDirView->setColumnHidden(1, true); localDirView->setRootIndex(localDirModel->index(localDirModel->rootPath(), 0)); localDirView->setSortingEnabled(true); +#if QT_VERSION < 0x050000 localDirView->header()->setResizeMode(QHeaderView::ResizeToContents); +#else + localDirView->header()->setSectionResizeMode(QHeaderView::ResizeToContents); +#endif localDirView->header()->setSortIndicator(0, Qt::AscendingOrder); leftToolBar = new QToolBar; diff --git a/cockatrice/src/tab_replays.cpp b/cockatrice/src/tab_replays.cpp index 92b0be08..6b3a6210 100644 --- a/cockatrice/src/tab_replays.cpp +++ b/cockatrice/src/tab_replays.cpp @@ -36,7 +36,11 @@ TabReplays::TabReplays(TabSupervisor *_tabSupervisor, AbstractClient *_client) localDirView->setColumnHidden(1, true); localDirView->setRootIndex(localDirModel->index(localDirModel->rootPath(), 0)); localDirView->setSortingEnabled(true); +#if QT_VERSION < 0x050000 localDirView->header()->setResizeMode(QHeaderView::ResizeToContents); +#else + localDirView->header()->setSectionResizeMode(QHeaderView::ResizeToContents); +#endif localDirView->header()->setSortIndicator(0, Qt::AscendingOrder); leftToolBar = new QToolBar; diff --git a/cockatrice/src/tab_server.cpp b/cockatrice/src/tab_server.cpp index a8e89af5..b82248a3 100644 --- a/cockatrice/src/tab_server.cpp +++ b/cockatrice/src/tab_server.cpp @@ -28,11 +28,17 @@ RoomSelector::RoomSelector(AbstractClient *_client, QWidget *parent) roomList->setRootIsDecorated(false); roomList->setColumnCount(4); roomList->header()->setStretchLastSection(false); +#if QT_VERSION < 0x050000 roomList->header()->setResizeMode(0, QHeaderView::ResizeToContents); roomList->header()->setResizeMode(1, QHeaderView::Stretch); roomList->header()->setResizeMode(2, QHeaderView::ResizeToContents); roomList->header()->setResizeMode(3, QHeaderView::ResizeToContents); - +#else + roomList->header()->setSectionResizeMode(0, QHeaderView::ResizeToContents); + roomList->header()->setSectionResizeMode(1, QHeaderView::Stretch); + roomList->header()->setSectionResizeMode(2, QHeaderView::ResizeToContents); + roomList->header()->setSectionResizeMode(3, QHeaderView::ResizeToContents); +#endif joinButton = new QPushButton; connect(joinButton, SIGNAL(clicked()), this, SLOT(joinClicked())); QHBoxLayout *buttonLayout = new QHBoxLayout; diff --git a/cockatrice/src/tablezone.cpp b/cockatrice/src/tablezone.cpp index d7fa4218..f716cfbc 100644 --- a/cockatrice/src/tablezone.cpp +++ b/cockatrice/src/tablezone.cpp @@ -28,7 +28,11 @@ TableZone::TableZone(Player *_p, QGraphicsItem *parent) currentMinimumWidth = minWidth; setCacheMode(DeviceCoordinateCache); +#if QT_VERSION < 0x050000 setAcceptsHoverEvents(true); +#else + setAcceptHoverEvents(true); +#endif } void TableZone::updateBgPixmap() diff --git a/cockatrice/src/userlist.cpp b/cockatrice/src/userlist.cpp index 562d395b..29d13781 100644 --- a/cockatrice/src/userlist.cpp +++ b/cockatrice/src/userlist.cpp @@ -216,7 +216,11 @@ UserList::UserList(TabSupervisor *_tabSupervisor, AbstractClient *_client, UserL userTree = new QTreeWidget; userTree->setColumnCount(3); +#if QT_VERSION < 0x050000 userTree->header()->setResizeMode(QHeaderView::ResizeToContents); +#else + userTree->header()->setSectionResizeMode(QHeaderView::ResizeToContents); +#endif userTree->setHeaderHidden(true); userTree->setRootIsDecorated(false); userTree->setIconSize(QSize(20, 12)); From 7035150351c3b9f013a55af9db00097b8f8bd77c Mon Sep 17 00:00:00 2001 From: Fabio Bas Date: Wed, 25 Jun 2014 09:07:02 +0200 Subject: [PATCH 11/51] Deckstats: move QUrl handling into its own function; better separation of qt4/qt5 code --- cockatrice/src/deckstats_interface.cpp | 21 +++++++++++++++------ cockatrice/src/deckstats_interface.h | 2 ++ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/cockatrice/src/deckstats_interface.cpp b/cockatrice/src/deckstats_interface.cpp index 4eb62d20..245e04c2 100644 --- a/cockatrice/src/deckstats_interface.cpp +++ b/cockatrice/src/deckstats_interface.cpp @@ -43,20 +43,29 @@ void DeckStatsInterface::queryFinished(QNetworkReply *reply) deleteLater(); } -void DeckStatsInterface::analyzeDeck(DeckList *deck) +#if QT_VERSION < 0x050000 +void DeckStatsInterface::getAnalyzeRequestData(DeckList *deck, QByteArray *data) { QUrl params; -#if QT_VERSION < 0x050000 params.addQueryItem("deck", deck->writeToString_Plain()); - QByteArray data; - data.append(params.encodedQuery()); + data->append(params.encodedQuery()); +} #else +void DeckStatsInterface::getAnalyzeRequestData(DeckList *deck, QByteArray *data) +{ + QUrl params; QUrlQuery urlQuery; urlQuery.addQueryItem("deck", deck->writeToString_Plain()); params.setQuery(urlQuery); - QByteArray data; - data.append(params.query(QUrl::EncodeReserved)); + data->append(params.query(QUrl::EncodeReserved)); +} #endif + + +void DeckStatsInterface::analyzeDeck(DeckList *deck) +{ + QByteArray data; + getAnalyzeRequestData(deck, &data); QNetworkRequest request(QUrl("http://deckstats.net/index.php")); request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded"); diff --git a/cockatrice/src/deckstats_interface.h b/cockatrice/src/deckstats_interface.h index e8454dd5..756f917d 100644 --- a/cockatrice/src/deckstats_interface.h +++ b/cockatrice/src/deckstats_interface.h @@ -3,6 +3,7 @@ #include +class QByteArray; class QNetworkAccessManager; class QNetworkReply; class DeckList; @@ -13,6 +14,7 @@ private: QNetworkAccessManager *manager; private slots: void queryFinished(QNetworkReply *reply); + void getAnalyzeRequestData(DeckList *deck, QByteArray *data); public: DeckStatsInterface(QObject *parent = 0); void analyzeDeck(DeckList *deck); From c4458b16b2004aa9fbe6c353c58c81134fb4304b Mon Sep 17 00:00:00 2001 From: Fabio Bas Date: Wed, 25 Jun 2014 15:53:25 +0200 Subject: [PATCH 12/51] Qt5: fix plugin installation --- cockatrice/CMakeLists.txt | 5 ++++- oracle/CMakeLists.txt | 3 +++ servatrice/CMakeLists.txt | 3 +++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/cockatrice/CMakeLists.txt b/cockatrice/CMakeLists.txt index 92586891..be347188 100644 --- a/cockatrice/CMakeLists.txt +++ b/cockatrice/CMakeLists.txt @@ -201,10 +201,13 @@ if(Qt5Widgets_FOUND) list(APPEND COCKATRICE_LIBS LinguistTools) endif() - # Let cmake chew Qt4's translations and resource files + # Let cmake chew Qt5's translations and resource files # Note: header files are MOC-ed automatically by cmake QT5_ADD_TRANSLATION(cockatrice_QM ${cockatrice_TS}) QT5_ADD_RESOURCES(cockatrice_RESOURCES_RCC ${cockatrice_RESOURCES}) + + # guess plugins directory + set(QT_PLUGINS_DIR "${Qt5Widgets_DIR}/../../../plugins") endif() # Declare path variables diff --git a/oracle/CMakeLists.txt b/oracle/CMakeLists.txt index 99abc4d1..b6db8eb4 100644 --- a/oracle/CMakeLists.txt +++ b/oracle/CMakeLists.txt @@ -63,6 +63,9 @@ if(Qt5Widgets_FOUND) include_directories(${Qt5Svg_INCLUDE_DIRS}) list(APPEND ORACLE_LIBS Svg) endif() + + # guess plugins directory + set(QT_PLUGINS_DIR "${Qt5Widgets_DIR}/../../../plugins") endif() INCLUDE_DIRECTORIES(../cockatrice/src) diff --git a/servatrice/CMakeLists.txt b/servatrice/CMakeLists.txt index b1fc00c8..a5743f8e 100644 --- a/servatrice/CMakeLists.txt +++ b/servatrice/CMakeLists.txt @@ -51,6 +51,9 @@ if(Qt5Widgets_FOUND) include_directories(${Qt5Sql_INCLUDE_DIRS}) list(APPEND SERVATRICE_LIBS Sql) endif() + + # guess plugins directory + set(QT_PLUGINS_DIR "${Qt5Widgets_DIR}/../../../plugins") endif() SET(QT_DONT_USE_QTGUI TRUE) From 2354ed6909f18f228152869a7bb34af7a379f700 Mon Sep 17 00:00:00 2001 From: Fabio Bas Date: Wed, 25 Jun 2014 16:00:48 +0200 Subject: [PATCH 13/51] Require Qt4 >=4.8.0; remove some ifdefs on qt version --- CMakeLists.txt | 2 +- cockatrice/src/carddatabasemodel.cpp | 6 ------ cockatrice/src/decklistmodel.cpp | 6 ------ cockatrice/src/remotedecklist_treewidget.cpp | 6 ------ 4 files changed, 1 insertion(+), 19 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 16e2f0ee..9c74b40e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -76,7 +76,7 @@ FIND_PACKAGE(Qt5Widgets) IF(Qt5Widgets_FOUND) MESSAGE(STATUS "Found Qt ${Qt5Widgets_VERSION_STRING}") ELSE() - FIND_PACKAGE(Qt4 REQUIRED) + FIND_PACKAGE(Qt4 4.8.0 REQUIRED) IF(Qt4_FOUND) MESSAGE(STATUS "Found Qt ${QT_VERSION_MAJOR}.${QT_VERSION_MINOR}.${QT_VERSION_PATCH}") ELSE() diff --git a/cockatrice/src/carddatabasemodel.cpp b/cockatrice/src/carddatabasemodel.cpp index 65b08d49..a77bbd12 100644 --- a/cockatrice/src/carddatabasemodel.cpp +++ b/cockatrice/src/carddatabasemodel.cpp @@ -68,9 +68,7 @@ QVariant CardDatabaseModel::headerData(int section, Qt::Orientation orientation, void CardDatabaseModel::updateCardList() { -#if QT_VERSION >= 0x050000 beginResetModel(); -#endif for (int i = 0; i < cardList.size(); ++i) disconnect(cardList[i], 0, this, 0); @@ -79,11 +77,7 @@ void CardDatabaseModel::updateCardList() for (int i = 0; i < cardList.size(); ++i) connect(cardList[i], SIGNAL(cardInfoChanged(CardInfo *)), this, SLOT(cardInfoChanged(CardInfo *))); -#if QT_VERSION < 0x050000 - reset(); -#else endResetModel(); -#endif } void CardDatabaseModel::cardInfoChanged(CardInfo *card) diff --git a/cockatrice/src/decklistmodel.cpp b/cockatrice/src/decklistmodel.cpp index 8a1065f0..de18a9c5 100644 --- a/cockatrice/src/decklistmodel.cpp +++ b/cockatrice/src/decklistmodel.cpp @@ -30,9 +30,7 @@ DeckListModel::~DeckListModel() void DeckListModel::rebuildTree() { -#if QT_VERSION >= 0x050000 beginResetModel(); -#endif root->clearTree(); InnerDecklistNode *listRoot = deckList->getRoot(); @@ -59,11 +57,7 @@ void DeckListModel::rebuildTree() } } -#if QT_VERSION < 0x050000 - reset(); -#else endResetModel(); -#endif } int DeckListModel::rowCount(const QModelIndex &parent) const diff --git a/cockatrice/src/remotedecklist_treewidget.cpp b/cockatrice/src/remotedecklist_treewidget.cpp index 809f3fe8..cb96ef7f 100644 --- a/cockatrice/src/remotedecklist_treewidget.cpp +++ b/cockatrice/src/remotedecklist_treewidget.cpp @@ -258,17 +258,11 @@ void RemoteDeckList_TreeModel::deckListFinished(const Response &r) { const Response_DeckList &resp = r.GetExtension(Response_DeckList::ext); -#if QT_VERSION >= 0x050000 beginResetModel(); -#endif root->clearTree(); -#if QT_VERSION < 0x050000 - reset(); -#else endResetModel(); -#endif ServerInfo_DeckStorage_TreeItem tempRoot; tempRoot.set_id(0); From 4e4401a9e2e2d6366e0c3fb8c1da4abf4034a053 Mon Sep 17 00:00:00 2001 From: Fabio Bas Date: Wed, 25 Jun 2014 18:39:26 +0200 Subject: [PATCH 14/51] maybe fix travis build for ubuntu --- travis-dependencies.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/travis-dependencies.sh b/travis-dependencies.sh index 533a213b..e9317d2a 100755 --- a/travis-dependencies.sh +++ b/travis-dependencies.sh @@ -5,5 +5,5 @@ if [[ $TRAVIS_OS_NAME == "osx" ]] ; then brew install qt cmake protobuf else sudo apt-get update -qq - sudo apt-get install -y qtmobility-dev libprotobuf-dev protobuf-compiler libqt4-dev + sudo apt-get install -y qtmobility-dev libprotobuf-dev protobuf-compiler libqt4-dev qt4-dev-tools fi From 382a382c70b78a0c582ca52217c4e84addf24d68 Mon Sep 17 00:00:00 2001 From: Fabio Bas Date: Wed, 25 Jun 2014 18:50:58 +0200 Subject: [PATCH 15/51] Maybe workaround buggy cmake module --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9c74b40e..65448a1c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -77,7 +77,7 @@ IF(Qt5Widgets_FOUND) MESSAGE(STATUS "Found Qt ${Qt5Widgets_VERSION_STRING}") ELSE() FIND_PACKAGE(Qt4 4.8.0 REQUIRED) - IF(Qt4_FOUND) + IF(Qt4_FOUND OR QT4_FOUND) MESSAGE(STATUS "Found Qt ${QT_VERSION_MAJOR}.${QT_VERSION_MINOR}.${QT_VERSION_PATCH}") ELSE() MESSAGE(FATAL_ERROR "No Qt4 or Qt5 found!") From 07ed519a2529c51aa73a899aecfd9a3149538d70 Mon Sep 17 00:00:00 2001 From: Fabio Bas Date: Wed, 25 Jun 2014 19:12:38 +0200 Subject: [PATCH 16/51] Apply the patch in the previous commit globally --- CMakeLists.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 65448a1c..ed69a67a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -77,7 +77,11 @@ IF(Qt5Widgets_FOUND) MESSAGE(STATUS "Found Qt ${Qt5Widgets_VERSION_STRING}") ELSE() FIND_PACKAGE(Qt4 4.8.0 REQUIRED) - IF(Qt4_FOUND OR QT4_FOUND) + IF(QT4_FOUND) + # Old FindQt4.cmake modules used the same flag with different case + SET(Qt4_FOUND TRUE) + ENDIF() + IF(Qt4_FOUND) MESSAGE(STATUS "Found Qt ${QT_VERSION_MAJOR}.${QT_VERSION_MINOR}.${QT_VERSION_PATCH}") ELSE() MESSAGE(FATAL_ERROR "No Qt4 or Qt5 found!") From 4e56ceb623e935f049bf6b255ec263814402f47d Mon Sep 17 00:00:00 2001 From: Fabio Bas Date: Wed, 25 Jun 2014 19:13:11 +0200 Subject: [PATCH 17/51] revert changes in .travis.yml --- travis-dependencies.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/travis-dependencies.sh b/travis-dependencies.sh index e9317d2a..533a213b 100755 --- a/travis-dependencies.sh +++ b/travis-dependencies.sh @@ -5,5 +5,5 @@ if [[ $TRAVIS_OS_NAME == "osx" ]] ; then brew install qt cmake protobuf else sudo apt-get update -qq - sudo apt-get install -y qtmobility-dev libprotobuf-dev protobuf-compiler libqt4-dev qt4-dev-tools + sudo apt-get install -y qtmobility-dev libprotobuf-dev protobuf-compiler libqt4-dev fi From 62ca6130d16f1c4be26d18c9e15289a4b7d39f5a Mon Sep 17 00:00:00 2001 From: Fabio Bas Date: Wed, 25 Jun 2014 19:28:03 +0200 Subject: [PATCH 18/51] #include only for qt5, qt4 has this in QtCore --- oracle/src/oraclewizard.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/oracle/src/oraclewizard.cpp b/oracle/src/oraclewizard.cpp index 4f0e102a..96b78145 100644 --- a/oracle/src/oraclewizard.cpp +++ b/oracle/src/oraclewizard.cpp @@ -3,9 +3,9 @@ #include #else #include + #include #endif #include -#include #include #include #include From 634dd91b665cfd0a544a0525863b11ff2fde6c89 Mon Sep 17 00:00:00 2001 From: Fabio Bas Date: Thu, 26 Jun 2014 20:19:47 +0200 Subject: [PATCH 19/51] Set some cmake policies to mute cmake warnings --- CMakeLists.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index ed69a67a..b2439806 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,6 +7,14 @@ cmake_minimum_required(VERSION 2.6) +if(POLICY CMP0043) + cmake_policy(SET CMP0043 OLD) +endif() + +if(POLICY CMP0048) + cmake_policy(SET CMP0048 OLD) +endif() + set(PROJECT_NAME "Cockatrice") set(PROJECT_VERSION_MAJOR 0) set(PROJECT_VERSION_MINOR 0) From 34772cccab9d4db03c681b0a8542220d46cb7d50 Mon Sep 17 00:00:00 2001 From: Fabio Bas Date: Fri, 27 Jun 2014 17:09:09 +0200 Subject: [PATCH 20/51] Compilation fix for MSVC+Qt5 --- cockatrice/CMakeLists.txt | 14 ++++++++------ oracle/CMakeLists.txt | 10 ++++++---- servatrice/CMakeLists.txt | 11 ++++++++--- 3 files changed, 22 insertions(+), 13 deletions(-) diff --git a/cockatrice/CMakeLists.txt b/cockatrice/CMakeLists.txt index be347188..08714b07 100644 --- a/cockatrice/CMakeLists.txt +++ b/cockatrice/CMakeLists.txt @@ -224,18 +224,20 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}) ADD_EXECUTABLE(cockatrice WIN32 MACOSX_BUNDLE ${cockatrice_SOURCES} ${cockatrice_QM} ${cockatrice_RESOURCES_RCC} ${cockatrice_MOC_SRCS}) if(Qt4_FOUND) + if(MSVC) + set(QT_USE_QTMAIN true) + endif() TARGET_LINK_LIBRARIES(cockatrice cockatrice_common ${COCKATRICE_LIBS}) endif() if(Qt5Widgets_FOUND) - TARGET_LINK_LIBRARIES(cockatrice cockatrice_common) + if(MSVC) + TARGET_LINK_LIBRARIES(cockatrice cockatrice_common Qt5::WinMain) + else() + TARGET_LINK_LIBRARIES(cockatrice cockatrice_common) + endif() qt5_use_modules(cockatrice ${COCKATRICE_LIBS}) endif() - -if(MSVC) - set_target_properties(cockatrice PROPERTIES LINK_FLAGS "/SUBSYSTEM:WINDOWS") -endif(MSVC) - if(UNIX) if(APPLE) INSTALL(TARGETS cockatrice BUNDLE DESTINATION ./) diff --git a/oracle/CMakeLists.txt b/oracle/CMakeLists.txt index b6db8eb4..9f713889 100644 --- a/oracle/CMakeLists.txt +++ b/oracle/CMakeLists.txt @@ -74,16 +74,18 @@ INCLUDE_DIRECTORIES(../cockatrice/src) ADD_EXECUTABLE(oracle WIN32 MACOSX_BUNDLE ${oracle_SOURCES} ${oracle_MOC_SRCS}) if(Qt4_FOUND) + if(MSVC) + set(QT_USE_QTMAIN true) + endif() TARGET_LINK_LIBRARIES(oracle ${ORACLE_LIBS}) endif() if(Qt5Widgets_FOUND) + if(MSVC) + TARGET_LINK_LIBRARIES(oracle Qt5::WinMain) + endif() qt5_use_modules(oracle ${ORACLE_LIBS}) endif() -if(MSVC) - set_target_properties(oracle PROPERTIES LINK_FLAGS "/SUBSYSTEM:WINDOWS") -endif(MSVC) - if(UNIX) if(APPLE) INSTALL(TARGETS oracle BUNDLE DESTINATION ./) diff --git a/servatrice/CMakeLists.txt b/servatrice/CMakeLists.txt index a5743f8e..1f548038 100644 --- a/servatrice/CMakeLists.txt +++ b/servatrice/CMakeLists.txt @@ -69,15 +69,20 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}) ADD_EXECUTABLE(servatrice MACOSX_BUNDLE ${servatrice_SOURCES} ${servatrice_MOC_SRCS}) if(Qt4_FOUND) + if(MSVC) + set(QT_USE_QTMAIN true) + endif() TARGET_LINK_LIBRARIES(servatrice cockatrice_common ${SERVATRICE_LIBS} ${LIBGCRYPT_LIBRARY} ${CMAKE_THREAD_LIBS_INIT}) endif() if(Qt5Widgets_FOUND) - TARGET_LINK_LIBRARIES(servatrice cockatrice_common ${LIBGCRYPT_LIBRARY} ${CMAKE_THREAD_LIBS_INIT}) + if(MSVC) + TARGET_LINK_LIBRARIES(servatrice cockatrice_common ${LIBGCRYPT_LIBRARY} ${CMAKE_THREAD_LIBS_INIT} Qt5::WinMain) + else() + TARGET_LINK_LIBRARIES(servatrice cockatrice_common ${LIBGCRYPT_LIBRARY} ${CMAKE_THREAD_LIBS_INIT}) + endif() qt5_use_modules(servatrice ${SERVATRICE_LIBS}) endif() - - #add_custom_target(versionheader ALL DEPENDS version_header) add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/version_string.h ${CMAKE_CURRENT_BINARY_DIR}/version_string.cpp From fc8c55ae9761c037f63344bb6783c06923d3e395 Mon Sep 17 00:00:00 2001 From: Fabio Bas Date: Fri, 27 Jun 2014 17:24:25 +0200 Subject: [PATCH 21/51] Added cmake policy specific for win32 compilation --- CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index b2439806..1317c483 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,6 +7,10 @@ cmake_minimum_required(VERSION 2.6) +if(POLICY CMP0020) + cmake_policy(SET CMP0020 OLD) +endif() + if(POLICY CMP0043) cmake_policy(SET CMP0043 OLD) endif() From 096f200eb9f8058a432baf7e54779f0391e0560a Mon Sep 17 00:00:00 2001 From: Fabio Bas Date: Fri, 27 Jun 2014 17:40:29 +0200 Subject: [PATCH 22/51] Install libraries and plugins automatically under windows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit You won’t have to copy manually all the dlls in the release directory anymore --- cockatrice/CMakeLists.txt | 37 ++++++++++++++++++++++++++++++++++++- oracle/CMakeLists.txt | 36 +++++++++++++++++++++++++++++++++++- servatrice/CMakeLists.txt | 36 +++++++++++++++++++++++++++++++++++- 3 files changed, 106 insertions(+), 3 deletions(-) diff --git a/cockatrice/CMakeLists.txt b/cockatrice/CMakeLists.txt index 08714b07..53313151 100644 --- a/cockatrice/CMakeLists.txt +++ b/cockatrice/CMakeLists.txt @@ -206,8 +206,10 @@ if(Qt5Widgets_FOUND) QT5_ADD_TRANSLATION(cockatrice_QM ${cockatrice_TS}) QT5_ADD_RESOURCES(cockatrice_RESOURCES_RCC ${cockatrice_RESOURCES}) - # guess plugins directory + # guess plugins and libraries directory set(QT_PLUGINS_DIR "${Qt5Widgets_DIR}/../../../plugins") + get_target_property(QT_LIBRARY_DIR Qt5::Core LOCATION) + get_filename_component(QT_LIBRARY_DIR ${QT_LIBRARY_DIR} PATH) endif() # Declare path variables @@ -292,3 +294,36 @@ Data = Resources\") fixup_bundle(\"\${CMAKE_INSTALL_PREFIX}/cockatrice.app\" \"\${QTPLUGINS}\" \"${QT_LIBRARY_DIR}\") " COMPONENT Runtime) endif() + +if(WIN32) + # these needs to be relative to CMAKE_INSTALL_PREFIX + set(plugin_dest_dir Plugins) + set(qtconf_dest_dir .) + + # note: no codecs in qt5 + # note: phonon_backend => mediaservice + # note: needs platform on osx + + if (CMAKE_BUILD_TYPE STREQUAL "Debug") + install(DIRECTORY "${QT_PLUGINS_DIR}/" DESTINATION ${plugin_dest_dir} COMPONENT Runtime + FILES_MATCHING REGEX "(codecs|iconengines|imageformats|mediaservice|phonon_backend|platforms)/.*d\\.dll") + else() + install(DIRECTORY "${QT_PLUGINS_DIR}/" DESTINATION ${plugin_dest_dir} COMPONENT Runtime + FILES_MATCHING REGEX "(codecs|iconengines|imageformats|mediaservice|phonon_backend|platforms)/.*[^d]\\.dll") + endif() + + install(CODE " + file(WRITE \"\${CMAKE_INSTALL_PREFIX}/${qtconf_dest_dir}/qt.conf\" \"[Paths] +Plugins = Plugins +Translations = Resources/translations +Data = Resources\") + " COMPONENT Runtime) + + install(CODE " + file(GLOB_RECURSE QTPLUGINS + \"\${CMAKE_INSTALL_PREFIX}/${plugin_dest_dir}/*.dll\") + set(BU_CHMOD_BUNDLE_ITEMS ON) + include(BundleUtilities) + fixup_bundle(\"\${CMAKE_INSTALL_PREFIX}/cockatrice.exe\" \"\${QTPLUGINS}\" \"${QT_LIBRARY_DIR}\") + " COMPONENT Runtime) +endif() \ No newline at end of file diff --git a/oracle/CMakeLists.txt b/oracle/CMakeLists.txt index 9f713889..c3431571 100644 --- a/oracle/CMakeLists.txt +++ b/oracle/CMakeLists.txt @@ -64,8 +64,10 @@ if(Qt5Widgets_FOUND) list(APPEND ORACLE_LIBS Svg) endif() - # guess plugins directory + # guess plugins and libraries directory set(QT_PLUGINS_DIR "${Qt5Widgets_DIR}/../../../plugins") + get_target_property(QT_LIBRARY_DIR Qt5::Core LOCATION) + get_filename_component(QT_LIBRARY_DIR ${QT_LIBRARY_DIR} PATH) endif() INCLUDE_DIRECTORIES(../cockatrice/src) @@ -132,3 +134,35 @@ Translations = Resources/translations\") fixup_bundle(\"\${CMAKE_INSTALL_PREFIX}/oracle.app\" \"\${QTPLUGINS}\" \"${QT_LIBRARY_DIR}\") " COMPONENT Runtime) endif() + +IF(WIN32) + # these needs to be relative to CMAKE_INSTALL_PREFIX + set(plugin_dest_dir Plugins) + set(qtconf_dest_dir .) + + # note: no codecs in qt5 + # note: phonon_backend => mediaservice + # note: needs platform on osx + + if (CMAKE_BUILD_TYPE STREQUAL "Debug") + install(DIRECTORY "${QT_PLUGINS_DIR}/" DESTINATION ${plugin_dest_dir} COMPONENT Runtime + FILES_MATCHING REGEX "(codecs|iconengines|imageformats|mediaservice|phonon_backend|platforms)/.*d\\.dll") + else() + install(DIRECTORY "${QT_PLUGINS_DIR}/" DESTINATION ${plugin_dest_dir} COMPONENT Runtime + FILES_MATCHING REGEX "(codecs|iconengines|imageformats|mediaservice|phonon_backend|platforms)/.*[^d]\\.dll") + endif() + + install(CODE " + file(WRITE \"\${CMAKE_INSTALL_PREFIX}/${qtconf_dest_dir}/qt.conf\" \"[Paths] +Plugins = Plugins +Translations = Resources/translations\") + " COMPONENT Runtime) + + install(CODE " + file(GLOB_RECURSE QTPLUGINS + \"\${CMAKE_INSTALL_PREFIX}/${plugin_dest_dir}/*.dll\") + set(BU_CHMOD_BUNDLE_ITEMS ON) + include(BundleUtilities) + fixup_bundle(\"\${CMAKE_INSTALL_PREFIX}/oracle.exe\" \"\${QTPLUGINS}\" \"${QT_LIBRARY_DIR}\") + " COMPONENT Runtime) +endif() \ No newline at end of file diff --git a/servatrice/CMakeLists.txt b/servatrice/CMakeLists.txt index 1f548038..1f5383b4 100644 --- a/servatrice/CMakeLists.txt +++ b/servatrice/CMakeLists.txt @@ -52,8 +52,10 @@ if(Qt5Widgets_FOUND) list(APPEND SERVATRICE_LIBS Sql) endif() - # guess plugins directory + # guess plugins and libraries directory set(QT_PLUGINS_DIR "${Qt5Widgets_DIR}/../../../plugins") + get_target_property(QT_LIBRARY_DIR Qt5::Core LOCATION) + get_filename_component(QT_LIBRARY_DIR ${QT_LIBRARY_DIR} PATH) endif() SET(QT_DONT_USE_QTGUI TRUE) @@ -132,3 +134,35 @@ Translations = Resources/translations\") fixup_bundle(\"\${CMAKE_INSTALL_PREFIX}/servatrice.app\" \"\${QTPLUGINS}\" \"${QT_LIBRARY_DIR}\") " COMPONENT Runtime) endif() + +if(WIN32) + # these needs to be relative to CMAKE_INSTALL_PREFIX + set(plugin_dest_dir Plugins) + set(qtconf_dest_dir .) + + # note: no codecs in qt5 + # note: phonon_backend => mediaservice + # note: needs platform on osx + + if (CMAKE_BUILD_TYPE STREQUAL "Debug") + install(DIRECTORY "${QT_PLUGINS_DIR}/" DESTINATION ${plugin_dest_dir} COMPONENT Runtime + FILES_MATCHING REGEX "(codecs|iconengines|imageformats|mediaservice|phonon_backend|platforms)/.*d\\.dll") + else() + install(DIRECTORY "${QT_PLUGINS_DIR}/" DESTINATION ${plugin_dest_dir} COMPONENT Runtime + FILES_MATCHING REGEX "(codecs|iconengines|imageformats|mediaservice|phonon_backend|platforms)/.*[^d]\\.dll") + endif() + + install(CODE " + file(WRITE \"\${CMAKE_INSTALL_PREFIX}/${qtconf_dest_dir}/qt.conf\" \"[Paths] +Plugins = Plugins +Translations = Resources/translations\") + " COMPONENT Runtime) + + install(CODE " + file(GLOB_RECURSE QTPLUGINS + \"\${CMAKE_INSTALL_PREFIX}/${plugin_dest_dir}/*.dll\") + set(BU_CHMOD_BUNDLE_ITEMS ON) + include(BundleUtilities) + fixup_bundle(\"\${CMAKE_INSTALL_PREFIX}/servatrice.exe\" \"\${QTPLUGINS}\" \"${QT_LIBRARY_DIR}\") + " COMPONENT Runtime) +endif() \ No newline at end of file From d19340a117e165472dfaed1db96ffc98e3aac696 Mon Sep 17 00:00:00 2001 From: Fabio Bas Date: Fri, 27 Jun 2014 20:21:26 +0200 Subject: [PATCH 23/51] Windows: create nsis package using cake --- CMakeLists.txt | 2 +- nsis/NSIS.template.in | 95 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 nsis/NSIS.template.in diff --git a/CMakeLists.txt b/CMakeLists.txt index 1317c483..8542836a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -139,7 +139,7 @@ elseif(WIN32) set(CPACK_NSIS_HELP_LINK "https://github.com/Daenyth/Cockatrice") set(CPACK_NSIS_URL_INFO_ABOUT "https://github.com/Daenyth/Cockatrice") set(CPACK_NSIS_CONTACT "Daenyth+github@gmail.com") - set(CPACK_NSIS_MODIFY_PATH ON) + set(CPACK_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/nsis") endif() include(CPack) diff --git a/nsis/NSIS.template.in b/nsis/NSIS.template.in new file mode 100644 index 00000000..dde353e9 --- /dev/null +++ b/nsis/NSIS.template.in @@ -0,0 +1,95 @@ +!include "MUI2.nsh" +!include "FileFunc.nsh" + +!define /date TIMESTAMP "%Y%m%d" +!searchparse /file ../../../cockatrice/version_string.cpp '= "' VERSION '";' + +Name "Cockatrice" +OutFile "cockatrice_win32_${TIMESTAMP}_git-${VERSION}.exe" +SetCompressor /SOLID lzma +InstallDir "$PROGRAMFILES\Cockatrice" + +!define MUI_ABORTWARNING +!define MUI_WELCOMEFINISHPAGE_BITMAP "..\..\..\..\nsis\leftimage.bmp" +!define MUI_UNWELCOMEFINISHPAGE_BITMAP "..\..\..\..\nsis\leftimage.bmp" +!define MUI_HEADERIMAGE +!define MUI_HEADERIMAGE_BITMAP "..\..\..\..\nsis\headerimage.bmp" +!define MUI_HEADERIMAGE_UNBITMAP "..\..\..\..\nsis\headerimage.bmp" +!define MUI_WELCOMEPAGE_TEXT "This wizard will guide you through the installation of Cockatrice.$\r$\n$\r$\nClick Next to continue." +!define MUI_FINISHPAGE_RUN "$INSTDIR/oracle.exe" +!define MUI_FINISHPAGE_RUN_TEXT "Run card database downloader now" +!define MUI_FINISHPAGE_RUN_PARAMETERS "-dlsets" + +!insertmacro MUI_PAGE_WELCOME +!insertmacro MUI_PAGE_LICENSE "..\..\..\..\COPYING" +!insertmacro MUI_PAGE_COMPONENTS +!insertmacro MUI_PAGE_DIRECTORY +!insertmacro MUI_PAGE_INSTFILES +!insertmacro MUI_PAGE_FINISH + +!insertmacro MUI_UNPAGE_CONFIRM +!insertmacro MUI_UNPAGE_INSTFILES +!insertmacro MUI_UNPAGE_FINISH + +!insertmacro MUI_LANGUAGE "English" + +Section "Application" SecApplication + SetShellVarContext all + SetOutPath "$INSTDIR" + + File /r ..\..\..\Release\*.* + + WriteUninstaller "$INSTDIR\uninstall.exe" + ${GetSize} "$INSTDIR" "/S=0K" $0 $1 $2 + IntFmt $0 "0x%08X" $0 + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Cockatrice" "DisplayName" "Cockatrice" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Cockatrice" "UninstallString" "$\"$INSTDIR\uninstall.exe$\"" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Cockatrice" "QuietUninstallString" "$\"$INSTDIR\uninstall.exe$\" /S" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Cockatrice" "InstallLocation" "$INSTDIR" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Cockatrice" "DisplayIcon" "$INSTDIR\cockatrice.exe" + WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Cockatrice" "EstimatedSize" "$0" +SectionEnd + +Section "Update configuration" SecUpdateConfig + WriteRegStr HKCU "Software\Cockatrice\Cockatrice\paths" "carddatabase" "$APPDATA\Cockatrice\cards.xml" + WriteRegStr HKCU "Software\Cockatrice\Cockatrice\paths" "decks" "$APPDATA\Cockatrice\decks" + WriteRegStr HKCU "Software\Cockatrice\Cockatrice\paths" "pics" "$APPDATA\Cockatrice\pics" + WriteRegStr HKCU "Software\Cockatrice\Cockatrice\sound" "path" "$APPDATA\Cockatrice\sounds" +SectionEnd + +Section "Start menu item" SecStartMenu + createDirectory "$SMPROGRAMS\Cockatrice" + createShortCut "$SMPROGRAMS\Cockatrice\Cockatrice.lnk" "$INSTDIR\cockatrice.exe" '--debug-output' + createShortCut "$SMPROGRAMS\Cockatrice\Oracle.lnk" "$INSTDIR\oracle.exe" + createShortCut "$SMPROGRAMS\Cockatrice\Usermanual.lnk" "$INSTDIR\Usermanual.pdf" +SectionEnd + +Section Uninstall +SetShellVarContext all + RMDir /r "$INSTDIR\zonebg" + RMDir /r "$INSTDIR\plugins" + RMDir /r "$INSTDIR\sounds" + RMDir /r "$INSTDIR\translations" + Delete "$INSTDIR\uninstall.exe" + Delete "$INSTDIR\cockatrice.exe" + Delete "$INSTDIR\oracle.exe" + Delete "$INSTDIR\Usermanual.pdf" + Delete "$INSTDIR\libprotobuf.lib" + Delete "$INSTDIR\Qt*.dll" + RMDir "$INSTDIR" + + RMDir "$SMPROGRAMS\Cockatrice" + + DeleteRegKey HKCU "Software\Cockatrice" + DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Cockatrice" +SectionEnd + +LangString DESC_SecApplication ${LANG_ENGLISH} "Cockatrice program files" +LangString DESC_SecUpdateConfig ${LANG_ENGLISH} "Update the paths in the application settings according to the installation paths." +LangString DESC_SecStartMenu ${LANG_ENGLISH} "Create start menu items for Cockatrice and Oracle." +!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN + !insertmacro MUI_DESCRIPTION_TEXT ${SecApplication} $(DESC_SecApplication) + !insertmacro MUI_DESCRIPTION_TEXT ${SecUpdateConfig} $(DESC_SecUpdateConfig) + !insertmacro MUI_DESCRIPTION_TEXT ${SecStartMenu} $(DESC_SecStartMenu) +!insertmacro MUI_FUNCTION_DESCRIPTION_END + From 803fd7c95d784059014ea687a7855eb460d3e8e7 Mon Sep 17 00:00:00 2001 From: Fabio Bas Date: Sat, 28 Jun 2014 18:43:18 +0200 Subject: [PATCH 24/51] Windows: Generate an nsis package on the fly with "make package" --- CMakeLists.txt | 6 ++++++ nsis/NSIS.definitions.nsh.in | 3 +++ nsis/NSIS.template.in | 17 +++++++++-------- 3 files changed, 18 insertions(+), 8 deletions(-) create mode 100644 nsis/NSIS.definitions.nsh.in diff --git a/CMakeLists.txt b/CMakeLists.txt index 6f19f769..b8bba102 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -140,6 +140,12 @@ elseif(WIN32) set(CPACK_NSIS_URL_INFO_ABOUT "https://github.com/Daenyth/Cockatrice") set(CPACK_NSIS_CONTACT "Daenyth+github@gmail.com") set(CPACK_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/nsis") + + # Configure file with custom definitions for NSIS. + configure_file( + ${PROJECT_SOURCE_DIR}/nsis/NSIS.definitions.nsh.in + ${PROJECT_BINARY_DIR}/NSIS.definitions.nsh + ) endif() include(CPack) diff --git a/nsis/NSIS.definitions.nsh.in b/nsis/NSIS.definitions.nsh.in new file mode 100644 index 00000000..0d98b666 --- /dev/null +++ b/nsis/NSIS.definitions.nsh.in @@ -0,0 +1,3 @@ +!define NSIS_PROJECT_NAME "@PROJECT_NAME@" +!define NSIS_SOURCE_PATH "@PROJECT_SOURCE_DIR@" +!define NSIS_BINARY_PATH "@PROJECT_BINARY_DIR@" \ No newline at end of file diff --git a/nsis/NSIS.template.in b/nsis/NSIS.template.in index dde353e9..8deb40ea 100644 --- a/nsis/NSIS.template.in +++ b/nsis/NSIS.template.in @@ -1,27 +1,28 @@ +!include ..\..\..\NSIS.definitions.nsh !include "MUI2.nsh" !include "FileFunc.nsh" !define /date TIMESTAMP "%Y%m%d" !searchparse /file ../../../cockatrice/version_string.cpp '= "' VERSION '";' -Name "Cockatrice" -OutFile "cockatrice_win32_${TIMESTAMP}_git-${VERSION}.exe" +Name "${NSIS_PROJECT_NAME}" +OutFile "@CPACK_TOPLEVEL_DIRECTORY@/@CPACK_OUTPUT_FILE_NAME@" SetCompressor /SOLID lzma InstallDir "$PROGRAMFILES\Cockatrice" !define MUI_ABORTWARNING -!define MUI_WELCOMEFINISHPAGE_BITMAP "..\..\..\..\nsis\leftimage.bmp" -!define MUI_UNWELCOMEFINISHPAGE_BITMAP "..\..\..\..\nsis\leftimage.bmp" +!define MUI_WELCOMEFINISHPAGE_BITMAP "${NSIS_SOURCE_PATH}\nsis\leftimage.bmp" +!define MUI_UNWELCOMEFINISHPAGE_BITMAP "${NSIS_SOURCE_PATH}\nsis\leftimage.bmp" !define MUI_HEADERIMAGE -!define MUI_HEADERIMAGE_BITMAP "..\..\..\..\nsis\headerimage.bmp" -!define MUI_HEADERIMAGE_UNBITMAP "..\..\..\..\nsis\headerimage.bmp" +!define MUI_HEADERIMAGE_BITMAP "${NSIS_SOURCE_PATH}\nsis\headerimage.bmp" +!define MUI_HEADERIMAGE_UNBITMAP "${NSIS_SOURCE_PATH}\nsis\headerimage.bmp" !define MUI_WELCOMEPAGE_TEXT "This wizard will guide you through the installation of Cockatrice.$\r$\n$\r$\nClick Next to continue." !define MUI_FINISHPAGE_RUN "$INSTDIR/oracle.exe" !define MUI_FINISHPAGE_RUN_TEXT "Run card database downloader now" !define MUI_FINISHPAGE_RUN_PARAMETERS "-dlsets" !insertmacro MUI_PAGE_WELCOME -!insertmacro MUI_PAGE_LICENSE "..\..\..\..\COPYING" +!insertmacro MUI_PAGE_LICENSE "${NSIS_SOURCE_PATH}\COPYING" !insertmacro MUI_PAGE_COMPONENTS !insertmacro MUI_PAGE_DIRECTORY !insertmacro MUI_PAGE_INSTFILES @@ -37,7 +38,7 @@ Section "Application" SecApplication SetShellVarContext all SetOutPath "$INSTDIR" - File /r ..\..\..\Release\*.* + File /r "${NSIS_BINARY_PATH}\Release\*.*" WriteUninstaller "$INSTDIR\uninstall.exe" ${GetSize} "$INSTDIR" "/S=0K" $0 $1 $2 From e997b1d2bc121f6cec880971e1579788a9938a8f Mon Sep 17 00:00:00 2001 From: Fabio Bas Date: Sat, 28 Jun 2014 18:44:19 +0200 Subject: [PATCH 25/51] Windows: drop the old nsis script cpack generates it on the fly from a template --- nsis/cockatrice.nsi | 132 -------------------------------------------- 1 file changed, 132 deletions(-) delete mode 100644 nsis/cockatrice.nsi diff --git a/nsis/cockatrice.nsi b/nsis/cockatrice.nsi deleted file mode 100644 index 27f55ce3..00000000 --- a/nsis/cockatrice.nsi +++ /dev/null @@ -1,132 +0,0 @@ -!include "MUI2.nsh" -!include "FileFunc.nsh" - -!define /date TIMESTAMP "%Y%m%d" -!searchparse /file ../build/cockatrice/version_string.cpp '= "' VERSION '";' - -Name "Cockatrice" -OutFile "cockatrice_win32_${TIMESTAMP}_git-${VERSION}.exe" -SetCompressor /SOLID lzma -InstallDir "$PROGRAMFILES\Cockatrice" - -; set the Qt install dir here (and make sure you use the latest 4.8 version for packaging) -!define QTDIR "C:\Qt\4.8.6" - -!define MUI_ABORTWARNING -!define MUI_WELCOMEFINISHPAGE_BITMAP "leftimage.bmp" -!define MUI_UNWELCOMEFINISHPAGE_BITMAP "leftimage.bmp" -!define MUI_HEADERIMAGE -!define MUI_HEADERIMAGE_BITMAP "headerimage.bmp" -!define MUI_HEADERIMAGE_UNBITMAP "headerimage.bmp" -!define MUI_WELCOMEPAGE_TEXT "This wizard will guide you through the installation of Cockatrice.$\r$\n$\r$\nClick Next to continue." -!define MUI_FINISHPAGE_RUN "$INSTDIR/oracle.exe" -!define MUI_FINISHPAGE_RUN_TEXT "Run card database downloader now" -!define MUI_FINISHPAGE_RUN_PARAMETERS "-dlsets" - -!insertmacro MUI_PAGE_WELCOME -!insertmacro MUI_PAGE_LICENSE "..\COPYING" -!insertmacro MUI_PAGE_COMPONENTS -!insertmacro MUI_PAGE_DIRECTORY -!insertmacro MUI_PAGE_INSTFILES -!insertmacro MUI_PAGE_FINISH - -!insertmacro MUI_UNPAGE_CONFIRM -!insertmacro MUI_UNPAGE_INSTFILES -!insertmacro MUI_UNPAGE_FINISH - -!insertmacro MUI_LANGUAGE "English" - -Section "Application" SecApplication - SetShellVarContext all - SetOutPath "$INSTDIR" - File ..\build\cockatrice\Release\cockatrice.exe - File ..\build\oracle\Release\oracle.exe - File ..\doc\usermanual\Usermanual.pdf - File ..\build\protobuf-2.5.0\protobuf-2.5.0\vsprojects\Release\libprotobuf.lib - File "${QTDIR}\bin\QtCore4.dll" - File "${QTDIR}\bin\QtGui4.dll" - File "${QTDIR}\bin\QtNetwork4.dll" - File "${QTDIR}\bin\QtSvg4.dll" - File "${QTDIR}\bin\QtXml4.dll" - File "${QTDIR}\bin\QtMultimedia4.dll" - - SetOutPath "$INSTDIR\zonebg" - File /r ..\zonebg\*.* - - SetOutPath "$INSTDIR\plugins" - SetOutPath "$INSTDIR\plugins\codecs" - File "${QTDIR}\plugins\codecs\qcncodecs4.dll" - File "${QTDIR}\plugins\codecs\qjpcodecs4.dll" - File "${QTDIR}\plugins\codecs\qkrcodecs4.dll" - File "${QTDIR}\plugins\codecs\qtwcodecs4.dll" - SetOutPath "$INSTDIR\plugins\iconengines" - File "${QTDIR}\plugins\iconengines\qsvgicon4.dll" - SetOutPath "$INSTDIR\plugins\imageformats" - File "${QTDIR}\plugins\imageformats\qjpeg4.dll" - File "${QTDIR}\plugins\imageformats\qsvg4.dll" - - SetOutPath "$INSTDIR\sounds" - File /r ..\sounds\*.* - - SetOutPath "$INSTDIR\translations" - File /r ..\build\cockatrice\*.qm - - WriteUninstaller "$INSTDIR\uninstall.exe" - ${GetSize} "$INSTDIR" "/S=0K" $0 $1 $2 - IntFmt $0 "0x%08X" $0 - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Cockatrice" "DisplayName" "Cockatrice" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Cockatrice" "UninstallString" "$\"$INSTDIR\uninstall.exe$\"" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Cockatrice" "QuietUninstallString" "$\"$INSTDIR\uninstall.exe$\" /S" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Cockatrice" "InstallLocation" "$INSTDIR" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Cockatrice" "DisplayIcon" "$INSTDIR\cockatrice.exe" - WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Cockatrice" "EstimatedSize" "$0" -SectionEnd - -Section "Update configuration" SecUpdateConfig - WriteRegStr HKCU "Software\Cockatrice\Cockatrice\paths" "carddatabase" "$APPDATA\Cockatrice\cards.xml" - WriteRegStr HKCU "Software\Cockatrice\Cockatrice\paths" "decks" "$APPDATA\Cockatrice\decks" - WriteRegStr HKCU "Software\Cockatrice\Cockatrice\paths" "pics" "$APPDATA\Cockatrice\pics" - WriteRegStr HKCU "Software\Cockatrice\Cockatrice\sound" "path" "$APPDATA\Cockatrice\sounds" -SectionEnd - -Section "Start menu item" SecStartMenu - createDirectory "$SMPROGRAMS\Cockatrice" - createShortCut "$SMPROGRAMS\Cockatrice\Cockatrice.lnk" "$INSTDIR\cockatrice.exe" '--debug-output' - createShortCut "$SMPROGRAMS\Cockatrice\Oracle.lnk" "$INSTDIR\oracle.exe" - createShortCut "$SMPROGRAMS\Cockatrice\Usermanual.lnk" "$INSTDIR\Usermanual.pdf" -SectionEnd - -Section Uninstall -SetShellVarContext all - RMDir /r "$INSTDIR\zonebg" - RMDir /r "$INSTDIR\plugins" - RMDir /r "$INSTDIR\sounds" - RMDir /r "$INSTDIR\translations" - Delete "$INSTDIR\uninstall.exe" - Delete "$INSTDIR\cockatrice.exe" - Delete "$INSTDIR\oracle.exe" - Delete "$INSTDIR\Usermanual.pdf" - Delete "$INSTDIR\libprotobuf.lib" - Delete "$INSTDIR\QtCore4.dll" - Delete "$INSTDIR\QtGui4.dll" - Delete "$INSTDIR\QtNetwork4.dll" - Delete "$INSTDIR\QtSvg4.dll" - Delete "$INSTDIR\QtXml4.dll" - Delete "$INSTDIR\QtMultimedia4.dll" - RMDir "$INSTDIR" - - RMDir "$SMPROGRAMS\Cockatrice" - - DeleteRegKey HKCU "Software\Cockatrice" - DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Cockatrice" -SectionEnd - -LangString DESC_SecApplication ${LANG_ENGLISH} "Cockatrice program files" -LangString DESC_SecUpdateConfig ${LANG_ENGLISH} "Update the paths in the application settings according to the installation paths." -LangString DESC_SecStartMenu ${LANG_ENGLISH} "Create start menu items for Cockatrice and Oracle." -!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN - !insertmacro MUI_DESCRIPTION_TEXT ${SecApplication} $(DESC_SecApplication) - !insertmacro MUI_DESCRIPTION_TEXT ${SecUpdateConfig} $(DESC_SecUpdateConfig) - !insertmacro MUI_DESCRIPTION_TEXT ${SecStartMenu} $(DESC_SecStartMenu) -!insertmacro MUI_FUNCTION_DESCRIPTION_END - From fc24ffdec2123e5069debf023d0f215775464f36 Mon Sep 17 00:00:00 2001 From: Fabio Bas Date: Sat, 28 Jun 2014 19:39:26 +0200 Subject: [PATCH 26/51] Cmake reorganization MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Move all cmake-related files in a new “cmake” folder * move nsis files in there, too, since they are templates parsed by cake * retrieve git version once when cmake is run, and use it for both creating version_string.h/cpp and for package naming --- CMakeLists.txt | 29 ++++++++++----------- {servatrice => cmake}/FindLibgcrypt.cmake | 0 {cockatrice => cmake}/FindQtMobility.cmake | 0 {nsis => cmake}/NSIS.definitions.nsh.in | 0 {nsis => cmake}/NSIS.template.in | 8 +++--- cmake/createversionfile.cmake | 17 ++++++++++++ {common => cmake}/getversion.cmake | 14 ++-------- {nsis => cmake}/headerimage.bmp | Bin {nsis => cmake}/leftimage.bmp | Bin cockatrice/CMakeLists.txt | 10 ++----- servatrice/CMakeLists.txt | 10 +------ 11 files changed, 40 insertions(+), 48 deletions(-) rename {servatrice => cmake}/FindLibgcrypt.cmake (100%) rename {cockatrice => cmake}/FindQtMobility.cmake (100%) rename {nsis => cmake}/NSIS.definitions.nsh.in (100%) rename {nsis => cmake}/NSIS.template.in (92%) create mode 100644 cmake/createversionfile.cmake rename {common => cmake}/getversion.cmake (52%) rename {nsis => cmake}/headerimage.bmp (100%) rename {nsis => cmake}/leftimage.bmp (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index b8bba102..4f95201a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,12 +20,8 @@ if(POLICY CMP0048) endif() set(PROJECT_NAME "Cockatrice") -set(PROJECT_VERSION_MAJOR 0) -set(PROJECT_VERSION_MINOR 0) -set(PROJECT_VERSION_PATCH 1) -set(PROJECT_VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH} ) -# Defualt to "Release" build type +# Default to "Release" build type # User-provided value for CMAKE_BUILD_TYPE must be checked before the PROJECT() call IF(DEFINED CMAKE_BUILD_TYPE) SET(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "Type of build") @@ -36,9 +32,19 @@ ENDIF() # A project name is needed for CPack PROJECT("${PROJECT_NAME}") + # Set conventional loops set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true) +# Search path for cmake modules +SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) + +# Retrieve git version hash +include(getversion) + +# Create a header and a cpp file containing the version hash +include(createversionfile) + # Define a proper install path if(UNIX) if(APPLE) @@ -109,8 +115,8 @@ FIND_PACKAGE(Protobuf REQUIRED) set(CPACK_PACKAGE_CONTACT "Daenyth+github@gmail.com") set(CPACK_PACKAGE_DESCRIPTION_SUMMARY ${PROJECT_NAME}) set(CPACK_PACKAGE_VENDOR "Cockatrice Development Team") -set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README.md") -set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/COPYING") +set(CPACK_PACKAGE_DESCRIPTION_FILE "${PROJECT_SOURCE_DIR}/README.md") +set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/COPYING") set(CPACK_PACKAGE_VERSION_MAJOR "${PROJECT_VERSION_MAJOR}") set(CPACK_PACKAGE_VERSION_MINOR "${PROJECT_VERSION_MINOR}") set(CPACK_PACKAGE_VERSION_PATCH "${PROJECT_VERSION_PATCH}") @@ -133,17 +139,10 @@ if(UNIX) endif() elseif(WIN32) set(CPACK_GENERATOR NSIS ${CPACK_GENERATOR}) - set(CPACK_PACKAGE_INSTALL_DIRECTORY "${PROJECT_NAME}\\\\${PROJECT_VERSION}") - set(CPACK_NSIS_INSTALLED_ICON_NAME "bin\\\\${PROJECT_NAME}.exe") - set(CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY} ${PROJECT_NAME}") - set(CPACK_NSIS_HELP_LINK "https://github.com/Daenyth/Cockatrice") - set(CPACK_NSIS_URL_INFO_ABOUT "https://github.com/Daenyth/Cockatrice") - set(CPACK_NSIS_CONTACT "Daenyth+github@gmail.com") - set(CPACK_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/nsis") # Configure file with custom definitions for NSIS. configure_file( - ${PROJECT_SOURCE_DIR}/nsis/NSIS.definitions.nsh.in + ${CMAKE_MODULE_PATH}/NSIS.definitions.nsh.in ${PROJECT_BINARY_DIR}/NSIS.definitions.nsh ) endif() diff --git a/servatrice/FindLibgcrypt.cmake b/cmake/FindLibgcrypt.cmake similarity index 100% rename from servatrice/FindLibgcrypt.cmake rename to cmake/FindLibgcrypt.cmake diff --git a/cockatrice/FindQtMobility.cmake b/cmake/FindQtMobility.cmake similarity index 100% rename from cockatrice/FindQtMobility.cmake rename to cmake/FindQtMobility.cmake diff --git a/nsis/NSIS.definitions.nsh.in b/cmake/NSIS.definitions.nsh.in similarity index 100% rename from nsis/NSIS.definitions.nsh.in rename to cmake/NSIS.definitions.nsh.in diff --git a/nsis/NSIS.template.in b/cmake/NSIS.template.in similarity index 92% rename from nsis/NSIS.template.in rename to cmake/NSIS.template.in index 8deb40ea..ed28a165 100644 --- a/nsis/NSIS.template.in +++ b/cmake/NSIS.template.in @@ -11,11 +11,11 @@ SetCompressor /SOLID lzma InstallDir "$PROGRAMFILES\Cockatrice" !define MUI_ABORTWARNING -!define MUI_WELCOMEFINISHPAGE_BITMAP "${NSIS_SOURCE_PATH}\nsis\leftimage.bmp" -!define MUI_UNWELCOMEFINISHPAGE_BITMAP "${NSIS_SOURCE_PATH}\nsis\leftimage.bmp" +!define MUI_WELCOMEFINISHPAGE_BITMAP "${NSIS_SOURCE_PATH}\cmake\leftimage.bmp" +!define MUI_UNWELCOMEFINISHPAGE_BITMAP "${NSIS_SOURCE_PATH}\cmake\leftimage.bmp" !define MUI_HEADERIMAGE -!define MUI_HEADERIMAGE_BITMAP "${NSIS_SOURCE_PATH}\nsis\headerimage.bmp" -!define MUI_HEADERIMAGE_UNBITMAP "${NSIS_SOURCE_PATH}\nsis\headerimage.bmp" +!define MUI_HEADERIMAGE_BITMAP "${NSIS_SOURCE_PATH}\cmake\headerimage.bmp" +!define MUI_HEADERIMAGE_UNBITMAP "${NSIS_SOURCE_PATH}\cmake\headerimage.bmp" !define MUI_WELCOMEPAGE_TEXT "This wizard will guide you through the installation of Cockatrice.$\r$\n$\r$\nClick Next to continue." !define MUI_FINISHPAGE_RUN "$INSTDIR/oracle.exe" !define MUI_FINISHPAGE_RUN_TEXT "Run card database downloader now" diff --git a/cmake/createversionfile.cmake b/cmake/createversionfile.cmake new file mode 100644 index 00000000..b71aa8ad --- /dev/null +++ b/cmake/createversionfile.cmake @@ -0,0 +1,17 @@ +set(VERSION_STRING_CPP "${PROJECT_BINARY_DIR}/version_string.cpp") +set(VERSION_STRING_H "${PROJECT_BINARY_DIR}/version_string.h") +INCLUDE_DIRECTORIES(${PROJECT_BINARY_DIR}) + +set( hstring "extern const char *VERSION_STRING\;\n" ) +set( cppstring "const char * VERSION_STRING = \"${PROJECT_VERSION}\"\;\n") + +file(WRITE ${PROJECT_BINARY_DIR}/version_string.cpp.txt ${cppstring} ) +file(WRITE ${PROJECT_BINARY_DIR}/version_string.h.txt ${hstring} ) + +execute_process( + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${PROJECT_BINARY_DIR}/version_string.h.txt ${VERSION_STRING_H} +) +execute_process( + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${PROJECT_BINARY_DIR}/version_string.cpp.txt ${VERSION_STRING_CPP} +) + diff --git a/common/getversion.cmake b/cmake/getversion.cmake similarity index 52% rename from common/getversion.cmake rename to cmake/getversion.cmake index ec5fe753..9db61040 100644 --- a/common/getversion.cmake +++ b/cmake/getversion.cmake @@ -15,15 +15,5 @@ else() message( WARNING "Git not found. Build will not contain git revision info." ) endif() -set( hstring "extern const char *VERSION_STRING\;\n" ) -set( cppstring "const char * VERSION_STRING = \"${GIT_COMMIT_ID}\"\;\n") - -file(WRITE version_string.cpp.txt ${cppstring} ) -file(WRITE version_string.h.txt ${hstring} ) - -execute_process( - COMMAND ${CMAKE_COMMAND} -E copy_if_different version_string.h.txt ${CMAKE_CURRENT_BINARY_DIR}/version_string.h -) -execute_process( - COMMAND ${CMAKE_COMMAND} -E copy_if_different version_string.cpp.txt ${CMAKE_CURRENT_BINARY_DIR}/version_string.cpp -) +set(PROJECT_VERSION_MAJOR ${GIT_COMMIT_ID}) +set(PROJECT_VERSION ${GIT_COMMIT_ID} ) \ No newline at end of file diff --git a/nsis/headerimage.bmp b/cmake/headerimage.bmp similarity index 100% rename from nsis/headerimage.bmp rename to cmake/headerimage.bmp diff --git a/nsis/leftimage.bmp b/cmake/leftimage.bmp similarity index 100% rename from nsis/leftimage.bmp rename to cmake/leftimage.bmp diff --git a/cockatrice/CMakeLists.txt b/cockatrice/CMakeLists.txt index 53313151..f785b1fd 100644 --- a/cockatrice/CMakeLists.txt +++ b/cockatrice/CMakeLists.txt @@ -90,7 +90,7 @@ SET(cockatrice_SOURCES src/qt-json/json.cpp src/soundengine.cpp src/pending_command.cpp - ${CMAKE_CURRENT_BINARY_DIR}/version_string.cpp + ${VERSION_STRING_CPP} ) if (UNIX AND NOT APPLE) @@ -130,9 +130,8 @@ set(COCKATRICE_LIBS) # Qt4 stuff if(Qt4_FOUND) if (NOT QT_QTMULTIMEDIA_FOUND) - SET(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}) FIND_PACKAGE(QtMobility REQUIRED) - endif (NOT QT_QTMULTIMEDIA_FOUND) + endif() SET(QT_USE_QTNETWORK TRUE) SET(QT_USE_QTMULTIMEDIA TRUE) @@ -257,11 +256,6 @@ elseif(WIN32) INSTALL(FILES ${cockatrice_QM} DESTINATION ./translations) endif() -add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/version_string.cpp ${CMAKE_CURRENT_BINARY_DIR}/version_string.h - COMMAND ${CMAKE_COMMAND} -DSOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR} -P ${CMAKE_CURRENT_SOURCE_DIR}/../common/getversion.cmake -) - if(APPLE) # these needs to be relative to CMAKE_INSTALL_PREFIX set(plugin_dest_dir cockatrice.app/Contents/Plugins) diff --git a/servatrice/CMakeLists.txt b/servatrice/CMakeLists.txt index 1f5383b4..42e2bb74 100644 --- a/servatrice/CMakeLists.txt +++ b/servatrice/CMakeLists.txt @@ -4,8 +4,6 @@ PROJECT(servatrice) -# cmake module for libgcrypt is included in current directory -SET(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}) FIND_PACKAGE(Libgcrypt REQUIRED) SET(servatrice_SOURCES @@ -17,7 +15,7 @@ SET(servatrice_SOURCES src/server_logger.cpp src/serversocketinterface.cpp src/isl_interface.cpp - ${CMAKE_CURRENT_BINARY_DIR}/version_string.cpp + ${VERSION_STRING_CPP} ) set(SERVATRICE_LIBS) @@ -85,12 +83,6 @@ if(Qt5Widgets_FOUND) qt5_use_modules(servatrice ${SERVATRICE_LIBS}) endif() -#add_custom_target(versionheader ALL DEPENDS version_header) -add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/version_string.h ${CMAKE_CURRENT_BINARY_DIR}/version_string.cpp - COMMAND ${CMAKE_COMMAND} -DSOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR} -P ${CMAKE_CURRENT_SOURCE_DIR}/../common/getversion.cmake -) - # install rules if(UNIX) if(APPLE) From fc5a193e0dc707562d1fefe88b684cd921f95152 Mon Sep 17 00:00:00 2001 From: Fabio Bas Date: Sat, 28 Jun 2014 19:39:47 +0200 Subject: [PATCH 27/51] NSIS: remove additional files on uninstall --- cmake/NSIS.template.in | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cmake/NSIS.template.in b/cmake/NSIS.template.in index ed28a165..e9607466 100644 --- a/cmake/NSIS.template.in +++ b/cmake/NSIS.template.in @@ -77,6 +77,9 @@ SetShellVarContext all Delete "$INSTDIR\Usermanual.pdf" Delete "$INSTDIR\libprotobuf.lib" Delete "$INSTDIR\Qt*.dll" + Delete "$INSTDIR\icu*.dll" + Delete "$INSTDIR\qt.conf" + Delete "$INSTDIR\qdebug.txt" RMDir "$INSTDIR" RMDir "$SMPROGRAMS\Cockatrice" From 3509df76b769eef4c35e6d27e19842ae5f3ace34 Mon Sep 17 00:00:00 2001 From: Fabio Bas Date: Sat, 28 Jun 2014 19:48:51 +0200 Subject: [PATCH 28/51] Remove old version parsing from nsis script --- cmake/NSIS.template.in | 3 --- 1 file changed, 3 deletions(-) diff --git a/cmake/NSIS.template.in b/cmake/NSIS.template.in index e9607466..b2c60d11 100644 --- a/cmake/NSIS.template.in +++ b/cmake/NSIS.template.in @@ -2,9 +2,6 @@ !include "MUI2.nsh" !include "FileFunc.nsh" -!define /date TIMESTAMP "%Y%m%d" -!searchparse /file ../../../cockatrice/version_string.cpp '= "' VERSION '";' - Name "${NSIS_PROJECT_NAME}" OutFile "@CPACK_TOPLEVEL_DIRECTORY@/@CPACK_OUTPUT_FILE_NAME@" SetCompressor /SOLID lzma From c0981a174324e693eb986c0bb1bd29bd185631bd Mon Sep 17 00:00:00 2001 From: Fabio Bas Date: Sat, 28 Jun 2014 19:53:15 +0200 Subject: [PATCH 29/51] Prettier package name --- CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4f95201a..8101be12 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -128,7 +128,7 @@ if(UNIX) set(CPACK_DMG_FORMAT "UDBZ") set(CPACK_DMG_VOLUME_NAME "${PROJECT_NAME}") set(CPACK_SYSTEM_NAME "OSX") - set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${PROJECT_VERSION}") + set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-osx_git-${PROJECT_VERSION}") set(CPACK_PACKAGE_ICON "${CMAKE_CURRENT_SOURCE_DIR}/cockatrice/resources/appicon.icns") else() # linux @@ -139,6 +139,7 @@ if(UNIX) endif() elseif(WIN32) set(CPACK_GENERATOR NSIS ${CPACK_GENERATOR}) + set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}_win32_git-${PROJECT_VERSION}") # Configure file with custom definitions for NSIS. configure_file( From 27bd00bec835988b3f5631bf8cf9e97048aad026 Mon Sep 17 00:00:00 2001 From: Fabio Bas Date: Sun, 29 Jun 2014 18:06:39 +0200 Subject: [PATCH 30/51] Direct chat: ensure focus is on the input line; fixes #113 --- cockatrice/src/tab_message.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cockatrice/src/tab_message.cpp b/cockatrice/src/tab_message.cpp index 80a56154..eec46bb9 100644 --- a/cockatrice/src/tab_message.cpp +++ b/cockatrice/src/tab_message.cpp @@ -34,6 +34,10 @@ TabMessage::TabMessage(TabSupervisor *_tabSupervisor, AbstractClient *_client, c retranslateUi(); setLayout(vbox); + + setFocusProxy(sayEdit); + chatView->setFocusProxy(sayEdit); + sayEdit->setFocus(); } TabMessage::~TabMessage() From d86fa410df8cdcca08fb00c5a48efecfbe616391 Mon Sep 17 00:00:00 2001 From: Fabio Bas Date: Sun, 29 Jun 2014 19:16:31 +0200 Subject: [PATCH 31/51] Chat room: ensure focus on the input line --- cockatrice/src/tab_room.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cockatrice/src/tab_room.cpp b/cockatrice/src/tab_room.cpp index 79673e0f..2af3dd1e 100644 --- a/cockatrice/src/tab_room.cpp +++ b/cockatrice/src/tab_room.cpp @@ -97,6 +97,10 @@ TabRoom::TabRoom(TabSupervisor *_tabSupervisor, AbstractClient *_client, ServerI const int gameListSize = info.game_list_size(); for (int i = 0; i < gameListSize; ++i) gameSelector->processGameInfo(info.game_list(i)); + + setFocusProxy(sayEdit); + chatView->setFocusProxy(sayEdit); + sayEdit->setFocus(); } TabRoom::~TabRoom() From 523483bccc504bae63e1c120895cc1bf1e59293f Mon Sep 17 00:00:00 2001 From: Fabio Bas Date: Mon, 30 Jun 2014 22:10:29 +0200 Subject: [PATCH 32/51] Add a WITH_QT4 cmake option to force the use of Qt4 --- CMakeLists.txt | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2eb5fac1..7cb17317 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -89,8 +89,14 @@ IF(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") ADD_DEFINITIONS("-DSFMT_MEXP=19937") ENDIF() -#Find Qt and enable the needed features -FIND_PACKAGE(Qt5Widgets) +# Find Qt and enable the needed features +# Default is Qt5 unless WITH_QT4 option is enabled +option(WITH_QT4 "Force thr use of Qt4 libraries" OFF) + +IF(NOT WITH_QT4) + FIND_PACKAGE(Qt5Widgets) +ENDIF() + IF(Qt5Widgets_FOUND) MESSAGE(STATUS "Found Qt ${Qt5Widgets_VERSION_STRING}") ELSE() From f730dca14c84d9f764f66c825418d973058c1f7a Mon Sep 17 00:00:00 2001 From: arxanas Date: Tue, 1 Jul 2014 02:29:25 -0400 Subject: [PATCH 33/51] Fix #155: Vanguard card names no longer conflict with regular card names. --- oracle/src/oracleimporter.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/oracle/src/oracleimporter.cpp b/oracle/src/oracleimporter.cpp index 70972d92..241924e3 100644 --- a/oracle/src/oracleimporter.cpp +++ b/oracle/src/oracleimporter.cpp @@ -197,6 +197,11 @@ int OracleImporter::importTextSpoiler(CardSet *set, const QVariant &data) cardText = map.contains("text") ? map.value("text").toString() : QString(""); cardId = map.contains("multiverseid") ? map.value("multiverseid").toInt() : 0; cardLoyalty = map.contains("loyalty") ? map.value("loyalty").toInt() : 0; + + // Distinguish Vanguard cards from regular cards of the same name. + if (map.value("layout") == "vanguard") { + cardName += " Avatar"; + } } CardInfo *card = addCard(set->getShortName(), cardName, false, cardId, cardCost, cardType, cardPT, cardLoyalty, cardText.split("\n")); From fb4a7b327478056aba254e71e25baa908139a4b0 Mon Sep 17 00:00:00 2001 From: Gavin Bisesi Date: Tue, 1 Jul 2014 12:04:33 -0400 Subject: [PATCH 34/51] Give more friendly login error message --- cockatrice/src/window_main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cockatrice/src/window_main.cpp b/cockatrice/src/window_main.cpp index f5dc2684..7890d63a 100644 --- a/cockatrice/src/window_main.cpp +++ b/cockatrice/src/window_main.cpp @@ -241,7 +241,7 @@ void MainWindow::loginError(Response::ResponseCode r, QString reasonStr, quint32 { switch (r) { case Response::RespWrongPassword: - QMessageBox::critical(this, tr("Error"), tr("Invalid login data.")); + QMessageBox::critical(this, tr("Error"), tr("Incorrect username or password. Please check your authentication information and try again.")); break; case Response::RespWouldOverwriteOldSession: QMessageBox::critical(this, tr("Error"), tr("There is already an active session using this user name.\nPlease close that session first and re-login.")); From 2b55170110ea9162dcf3695b50cd9d1128a24a99 Mon Sep 17 00:00:00 2001 From: woogerboy21 Date: Tue, 1 Jul 2014 13:11:52 -0400 Subject: [PATCH 35/51] DB Maint Scripts External shell script to help maintain the cockatrice database tables. --- servatrice/scripts/maint_replays | 6 ++++++ servatrice/scripts/maint_sessions | 7 +++++++ servatrice/scripts/mysql.cnf | 3 +++ 3 files changed, 16 insertions(+) create mode 100644 servatrice/scripts/maint_replays create mode 100644 servatrice/scripts/maint_sessions create mode 100644 servatrice/scripts/mysql.cnf diff --git a/servatrice/scripts/maint_replays b/servatrice/scripts/maint_replays new file mode 100644 index 00000000..b1326d9b --- /dev/null +++ b/servatrice/scripts/maint_replays @@ -0,0 +1,6 @@ +#!/bin/bash +#RUN THIS SCRIPT TO REMOVE ALL COCKATRICE REPLAYS FROM THE DATABASE +#--CAN BE SCHEDULED WITH CRONTAB + +mysql --defaults-file=./mysql.cnf -h localhost -e 'truncate table servatrice.cockatrice_replays' +mysql --defaults-file=./mysql.cnf -h localhost -e 'truncate table servatrice.cockatrice_replays_access' diff --git a/servatrice/scripts/maint_sessions b/servatrice/scripts/maint_sessions new file mode 100644 index 00000000..1fabd68f --- /dev/null +++ b/servatrice/scripts/maint_sessions @@ -0,0 +1,7 @@ +#!/bin/bash +#REPLACE THE --date="1 month ago" WITH THE TIME FRAME TO CLEAR UP +#EX: --date="1 day ago" (FOR SINGLE DAY) +#--CAN BE SCHEDULED WITH CRONTAB + +DATE=$(date +%Y-%m --date="1 month ago") +mysql --defaults-file=./mysql.cnf -h localhost -e "delete from servatrice.cockatrice_sessions where start_time like \"${DATE}%\"" diff --git a/servatrice/scripts/mysql.cnf b/servatrice/scripts/mysql.cnf new file mode 100644 index 00000000..e5d901be --- /dev/null +++ b/servatrice/scripts/mysql.cnf @@ -0,0 +1,3 @@ +[client] +user={db_username} +password={db_password} From b27873667b87e55a4df1dc27aa7cf71cafbbc820 Mon Sep 17 00:00:00 2001 From: woogerboy21 Date: Wed, 2 Jul 2014 11:11:17 -0400 Subject: [PATCH 36/51] Optimization Updates for performance improvements per request --- servatrice/scripts/maint_replays | 7 ++----- servatrice/scripts/maint_sessions | 8 ++------ 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/servatrice/scripts/maint_replays b/servatrice/scripts/maint_replays index b1326d9b..1ce1b400 100644 --- a/servatrice/scripts/maint_replays +++ b/servatrice/scripts/maint_replays @@ -1,6 +1,3 @@ #!/bin/bash -#RUN THIS SCRIPT TO REMOVE ALL COCKATRICE REPLAYS FROM THE DATABASE -#--CAN BE SCHEDULED WITH CRONTAB - -mysql --defaults-file=./mysql.cnf -h localhost -e 'truncate table servatrice.cockatrice_replays' -mysql --defaults-file=./mysql.cnf -h localhost -e 'truncate table servatrice.cockatrice_replays_access' +# SCHEDULE WITH CRONTAB BASED ON TIME PERIOD REPLAYS SHOULD BE SAVED UNTIL (EX: SCHEDULE ONCE A WEEK TO KEEP A WEEKS WORTH OF REPLAYS IN THE DB) +mysql --defaults-file=./mysql.cnf -h localhost -e 'truncate table servatrice.cockatrice_replays;truncate table servatrice.cockatrice_replays_access' diff --git a/servatrice/scripts/maint_sessions b/servatrice/scripts/maint_sessions index 1fabd68f..2c41da6d 100644 --- a/servatrice/scripts/maint_sessions +++ b/servatrice/scripts/maint_sessions @@ -1,7 +1,3 @@ #!/bin/bash -#REPLACE THE --date="1 month ago" WITH THE TIME FRAME TO CLEAR UP -#EX: --date="1 day ago" (FOR SINGLE DAY) -#--CAN BE SCHEDULED WITH CRONTAB - -DATE=$(date +%Y-%m --date="1 month ago") -mysql --defaults-file=./mysql.cnf -h localhost -e "delete from servatrice.cockatrice_sessions where start_time like \"${DATE}%\"" +# SCHEDULE WITH CRONTAB TO RUN ONCE A MONTH +mysql --defaults-file=./mysql.cnf -h localhost -e "delete from servatrice.cockatrice_sessions where start_time < DATE_SUB(now(), INTERVAL 1 MONTH)" From 9ba74fee5c16b0e1d625947066bd4a64c31afa2c Mon Sep 17 00:00:00 2001 From: woogerboy21 Date: Wed, 2 Jul 2014 13:23:50 -0400 Subject: [PATCH 37/51] Example Update Renamed mysql configuration file to include example extension and set git to ignore mysql.cnf per request. --- .gitignore | 1 + servatrice/scripts/{mysql.cnf => mysql.cnf.example} | 0 2 files changed, 1 insertion(+) rename servatrice/scripts/{mysql.cnf => mysql.cnf.example} (100%) diff --git a/.gitignore b/.gitignore index 1753f78c..df1a5c9f 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ tags build* *.qm .directory +mysql.cnf diff --git a/servatrice/scripts/mysql.cnf b/servatrice/scripts/mysql.cnf.example similarity index 100% rename from servatrice/scripts/mysql.cnf rename to servatrice/scripts/mysql.cnf.example From 6f18e3692dbddb2f4efca9f02374a76e3a51fa6b Mon Sep 17 00:00:00 2001 From: Fabio Bas Date: Thu, 3 Jul 2014 15:45:13 +0200 Subject: [PATCH 38/51] Chat room: ensure the line input has focus when the window gets created --- cockatrice/src/tab_room.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cockatrice/src/tab_room.cpp b/cockatrice/src/tab_room.cpp index 2af3dd1e..a7514e79 100644 --- a/cockatrice/src/tab_room.cpp +++ b/cockatrice/src/tab_room.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include "tab_supervisor.h" #include "tab_room.h" #include "tab_userlists.h" @@ -100,7 +101,7 @@ TabRoom::TabRoom(TabSupervisor *_tabSupervisor, AbstractClient *_client, ServerI setFocusProxy(sayEdit); chatView->setFocusProxy(sayEdit); - sayEdit->setFocus(); + QTimer::singleShot(0, sayEdit, SLOT(setFocus())); } TabRoom::~TabRoom() From aead0843af9207a170282cd21a84df9c9870e6a6 Mon Sep 17 00:00:00 2001 From: Fabio Bas Date: Sun, 6 Jul 2014 14:27:35 +0200 Subject: [PATCH 39/51] Room and Message tabs: focus input line when convenient; Fix #180 As suggest by Daenyth in #185 --- cockatrice/src/tab.h | 1 + cockatrice/src/tab_message.cpp | 10 ++++++---- cockatrice/src/tab_message.h | 1 + cockatrice/src/tab_room.cpp | 11 ++++++----- cockatrice/src/tab_room.h | 1 + cockatrice/src/tab_supervisor.cpp | 1 + 6 files changed, 16 insertions(+), 9 deletions(-) diff --git a/cockatrice/src/tab.h b/cockatrice/src/tab.h index 65473121..1b8b7704 100644 --- a/cockatrice/src/tab.h +++ b/cockatrice/src/tab.h @@ -31,6 +31,7 @@ public: virtual QString getTabText() const = 0; virtual void retranslateUi() = 0; virtual void closeRequest() { } + virtual void tabActivated() { } }; #endif diff --git a/cockatrice/src/tab_message.cpp b/cockatrice/src/tab_message.cpp index eec46bb9..6369f2a6 100644 --- a/cockatrice/src/tab_message.cpp +++ b/cockatrice/src/tab_message.cpp @@ -34,10 +34,6 @@ TabMessage::TabMessage(TabSupervisor *_tabSupervisor, AbstractClient *_client, c retranslateUi(); setLayout(vbox); - - setFocusProxy(sayEdit); - chatView->setFocusProxy(sayEdit); - sayEdit->setFocus(); } TabMessage::~TabMessage() @@ -53,6 +49,12 @@ void TabMessage::retranslateUi() aLeave->setText(tr("&Leave")); } +void TabMessage::tabActivated() +{ + if(!sayEdit->hasFocus()) + sayEdit->setFocus(); +} + QString TabMessage::getUserName() const { return QString::fromStdString(otherUserInfo->name()); diff --git a/cockatrice/src/tab_message.h b/cockatrice/src/tab_message.h index b8f98959..80263975 100644 --- a/cockatrice/src/tab_message.h +++ b/cockatrice/src/tab_message.h @@ -34,6 +34,7 @@ public: ~TabMessage(); void retranslateUi(); void closeRequest(); + void tabActivated(); QString getUserName() const; QString getTabText() const; diff --git a/cockatrice/src/tab_room.cpp b/cockatrice/src/tab_room.cpp index a7514e79..a4bb9ce0 100644 --- a/cockatrice/src/tab_room.cpp +++ b/cockatrice/src/tab_room.cpp @@ -9,7 +9,6 @@ #include #include #include -#include #include "tab_supervisor.h" #include "tab_room.h" #include "tab_userlists.h" @@ -98,10 +97,6 @@ TabRoom::TabRoom(TabSupervisor *_tabSupervisor, AbstractClient *_client, ServerI const int gameListSize = info.game_list_size(); for (int i = 0; i < gameListSize; ++i) gameSelector->processGameInfo(info.game_list(i)); - - setFocusProxy(sayEdit); - chatView->setFocusProxy(sayEdit); - QTimer::singleShot(0, sayEdit, SLOT(setFocus())); } TabRoom::~TabRoom() @@ -126,6 +121,12 @@ void TabRoom::closeRequest() actLeaveRoom(); } +void TabRoom::tabActivated() +{ + if(!sayEdit->hasFocus()) + sayEdit->setFocus(); +} + QString TabRoom::sanitizeHtml(QString dirty) const { return dirty diff --git a/cockatrice/src/tab_room.h b/cockatrice/src/tab_room.h index ada3aca8..857f37a2 100644 --- a/cockatrice/src/tab_room.h +++ b/cockatrice/src/tab_room.h @@ -64,6 +64,7 @@ public: ~TabRoom(); void retranslateUi(); void closeRequest(); + void tabActivated(); void processRoomEvent(const RoomEvent &event); int getRoomId() const { return roomId; } const QMap &getGameTypes() const { return gameTypes; } diff --git a/cockatrice/src/tab_supervisor.cpp b/cockatrice/src/tab_supervisor.cpp index e85efc6a..dda918a0 100644 --- a/cockatrice/src/tab_supervisor.cpp +++ b/cockatrice/src/tab_supervisor.cpp @@ -479,6 +479,7 @@ void TabSupervisor::updateCurrent(int index) tab->setContentsChanged(false); } emit setMenu(static_cast(widget(index))->getTabMenus()); + tab->tabActivated(); } else emit setMenu(); } From 04ad73fcdc5f52e523743c95145f4b0bf03e9609 Mon Sep 17 00:00:00 2001 From: Fabio Bas Date: Sun, 6 Jul 2014 23:25:44 +0200 Subject: [PATCH 40/51] Workaround for qt5 version compiled with -reduce-relocations --- CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7cb17317..825ed5cb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -99,6 +99,11 @@ ENDIF() IF(Qt5Widgets_FOUND) MESSAGE(STATUS "Found Qt ${Qt5Widgets_VERSION_STRING}") + + if(UNIX AND NOT APPLE AND "${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64") + # FIX: Qt was built with -reduce-relocations + add_definitions(-fPIC) + endif() ELSE() FIND_PACKAGE(Qt4 4.8.0 REQUIRED) IF(QT4_FOUND) From 8141901679fe8c66d8ea079f441546c0a81693ef Mon Sep 17 00:00:00 2001 From: arxanas Date: Mon, 7 Jul 2014 17:31:42 -0400 Subject: [PATCH 41/51] Fix #137: Game filter preferences are saved. --- cockatrice/src/dlg_filter_games.cpp | 76 ++++++++++++++++++++++++++--- cockatrice/src/dlg_filter_games.h | 4 ++ cockatrice/src/gameselector.cpp | 6 --- 3 files changed, 73 insertions(+), 13 deletions(-) diff --git a/cockatrice/src/dlg_filter_games.cpp b/cockatrice/src/dlg_filter_games.cpp index 5e402294..b4ce11c8 100644 --- a/cockatrice/src/dlg_filter_games.cpp +++ b/cockatrice/src/dlg_filter_games.cpp @@ -9,26 +9,52 @@ #include #include #include +#include -DlgFilterGames::DlgFilterGames(const QMap &allGameTypes, QWidget *parent) - : QDialog(parent) +DlgFilterGames::DlgFilterGames(const QMap &_allGameTypes, QWidget *parent) + : QDialog(parent), + allGameTypes(_allGameTypes) { + QSettings settings; + settings.beginGroup("filter_games"); + unavailableGamesVisibleCheckBox = new QCheckBox(tr("Show &unavailable games")); + unavailableGamesVisibleCheckBox->setChecked( + settings.value("unavailable_games_visible", false).toBool() + ); + passwordProtectedGamesVisibleCheckBox = new QCheckBox(tr("Show &password protected games")); + passwordProtectedGamesVisibleCheckBox->setChecked( + settings.value("password_protected_games_visible", false).toBool() + ); - QLabel *gameNameFilterLabel = new QLabel(tr("Game &description:")); gameNameFilterEdit = new QLineEdit; + gameNameFilterEdit->setText( + settings.value("game_name_filter", "").toString() + ); + QLabel *gameNameFilterLabel = new QLabel(tr("Game &description:")); gameNameFilterLabel->setBuddy(gameNameFilterEdit); - QLabel *creatorNameFilterLabel = new QLabel(tr("&Creator name:")); creatorNameFilterEdit = new QLineEdit; + creatorNameFilterEdit->setText( + settings.value("creator_name_filter", "").toString() + ); + QLabel *creatorNameFilterLabel = new QLabel(tr("&Creator name:")); creatorNameFilterLabel->setBuddy(creatorNameFilterEdit); QVBoxLayout *gameTypeFilterLayout = new QVBoxLayout; QMapIterator gameTypesIterator(allGameTypes); while (gameTypesIterator.hasNext()) { gameTypesIterator.next(); + QCheckBox *temp = new QCheckBox(gameTypesIterator.value()); + temp->setChecked( + settings.value( + "game_type/" + gameTypesIterator.value(), + false + ).toBool() + ); + gameTypeFilterCheckBoxes.insert(gameTypesIterator.key(), temp); gameTypeFilterLayout->addWidget(temp); } @@ -43,14 +69,18 @@ DlgFilterGames::DlgFilterGames(const QMap &allGameTypes, QWidget * maxPlayersFilterMinSpinBox = new QSpinBox; maxPlayersFilterMinSpinBox->setMinimum(1); maxPlayersFilterMinSpinBox->setMaximum(99); - maxPlayersFilterMinSpinBox->setValue(1); + maxPlayersFilterMinSpinBox->setValue( + settings.value("min_players", 1).toInt() + ); maxPlayersFilterMinLabel->setBuddy(maxPlayersFilterMinSpinBox); QLabel *maxPlayersFilterMaxLabel = new QLabel(tr("at &most:")); maxPlayersFilterMaxSpinBox = new QSpinBox; maxPlayersFilterMaxSpinBox->setMinimum(1); maxPlayersFilterMaxSpinBox->setMaximum(99); - maxPlayersFilterMaxSpinBox->setValue(99); + maxPlayersFilterMaxSpinBox->setValue( + settings.value("max_players", 99).toInt() + ); maxPlayersFilterMaxLabel->setBuddy(maxPlayersFilterMaxSpinBox); QGridLayout *maxPlayersFilterLayout = new QGridLayout; @@ -83,7 +113,7 @@ DlgFilterGames::DlgFilterGames(const QMap &allGameTypes, QWidget * hbox->addLayout(rightColumn); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept())); + connect(buttonBox, SIGNAL(accepted()), this, SLOT(actOk())); connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); QVBoxLayout *mainLayout = new QVBoxLayout; @@ -94,6 +124,38 @@ DlgFilterGames::DlgFilterGames(const QMap &allGameTypes, QWidget * setWindowTitle(tr("Filter games")); } +void DlgFilterGames::actOk() { + QSettings settings; + settings.beginGroup("filter_games"); + settings.setValue( + "unavailable_games_visible", + unavailableGamesVisibleCheckBox->isChecked() + ); + settings.setValue( + "password_protected_games_visible", + passwordProtectedGamesVisibleCheckBox->isChecked() + ); + settings.setValue("game_name_filter", gameNameFilterEdit->text()); + settings.setValue("creator_name_filter", creatorNameFilterEdit->text()); + + QMapIterator gameTypeIterator(allGameTypes); + QMapIterator checkboxIterator(gameTypeFilterCheckBoxes); + while (gameTypeIterator.hasNext()) { + gameTypeIterator.next(); + checkboxIterator.next(); + + settings.setValue( + "game_type/" + gameTypeIterator.value(), + checkboxIterator.value()->isChecked() + ); + } + + settings.setValue("min_players", maxPlayersFilterMinSpinBox->value()); + settings.setValue("max_players", maxPlayersFilterMaxSpinBox->value()); + + accept(); +} + bool DlgFilterGames::getUnavailableGamesVisible() const { return unavailableGamesVisibleCheckBox->isChecked(); diff --git a/cockatrice/src/dlg_filter_games.h b/cockatrice/src/dlg_filter_games.h index 8059da45..ac727d19 100644 --- a/cockatrice/src/dlg_filter_games.h +++ b/cockatrice/src/dlg_filter_games.h @@ -19,6 +19,10 @@ private: QMap gameTypeFilterCheckBoxes; QSpinBox *maxPlayersFilterMinSpinBox; QSpinBox *maxPlayersFilterMaxSpinBox; + + const QMap &allGameTypes; +private slots: + void actOk(); public: DlgFilterGames(const QMap &allGameTypes, QWidget *parent = 0); diff --git a/cockatrice/src/gameselector.cpp b/cockatrice/src/gameselector.cpp index 6a05d905..f5ef9ec8 100644 --- a/cockatrice/src/gameselector.cpp +++ b/cockatrice/src/gameselector.cpp @@ -81,12 +81,6 @@ void GameSelector::actSetFilter() if (room) gameTypeMap = gameListModel->getGameTypes().value(room->getRoomId()); DlgFilterGames dlg(gameTypeMap, this); - dlg.setUnavailableGamesVisible(gameListProxyModel->getUnavailableGamesVisible()); - dlg.setPasswordProtectedGamesVisible(gameListProxyModel->getPasswordProtectedGamesVisible()); - dlg.setGameNameFilter(gameListProxyModel->getGameNameFilter()); - dlg.setCreatorNameFilter(gameListProxyModel->getCreatorNameFilter()); - dlg.setGameTypeFilter(gameListProxyModel->getGameTypeFilter()); - dlg.setMaxPlayersFilter(gameListProxyModel->getMaxPlayersFilterMin(), gameListProxyModel->getMaxPlayersFilterMax()); if (!dlg.exec()) return; From 1217689ed63f5721f5ab6310f0f31cb933790a1a Mon Sep 17 00:00:00 2001 From: arxanas Date: Mon, 7 Jul 2014 19:04:01 -0400 Subject: [PATCH 42/51] Hash the game type. --- cockatrice/src/dlg_filter_games.cpp | 9 +++++++-- cockatrice/src/dlg_filter_games.h | 6 ++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/cockatrice/src/dlg_filter_games.cpp b/cockatrice/src/dlg_filter_games.cpp index b4ce11c8..eb2e8f78 100644 --- a/cockatrice/src/dlg_filter_games.cpp +++ b/cockatrice/src/dlg_filter_games.cpp @@ -10,6 +10,7 @@ #include #include #include +#include DlgFilterGames::DlgFilterGames(const QMap &_allGameTypes, QWidget *parent) : QDialog(parent), @@ -50,7 +51,7 @@ DlgFilterGames::DlgFilterGames(const QMap &_allGameTypes, QWidget QCheckBox *temp = new QCheckBox(gameTypesIterator.value()); temp->setChecked( settings.value( - "game_type/" + gameTypesIterator.value(), + "game_type/" + hashGameType(gameTypesIterator.value()), false ).toBool() ); @@ -145,7 +146,7 @@ void DlgFilterGames::actOk() { checkboxIterator.next(); settings.setValue( - "game_type/" + gameTypeIterator.value(), + "game_type/" + hashGameType(gameTypeIterator.value()), checkboxIterator.value()->isChecked() ); } @@ -156,6 +157,10 @@ void DlgFilterGames::actOk() { accept(); } +QString DlgFilterGames::hashGameType(const QString &gameType) const { + return QCryptographicHash::hash(gameType.toUtf8(), QCryptographicHash::Md5).toHex(); +} + bool DlgFilterGames::getUnavailableGamesVisible() const { return unavailableGamesVisibleCheckBox->isChecked(); diff --git a/cockatrice/src/dlg_filter_games.h b/cockatrice/src/dlg_filter_games.h index ac727d19..2480e642 100644 --- a/cockatrice/src/dlg_filter_games.h +++ b/cockatrice/src/dlg_filter_games.h @@ -21,6 +21,12 @@ private: QSpinBox *maxPlayersFilterMaxSpinBox; const QMap &allGameTypes; + + /* + * The game type might contain special characters, so to use it in + * QSettings we just hash it. + */ + QString hashGameType(const QString &gameType) const; private slots: void actOk(); public: From d894c5326566d5ba56925cfed0358c8cd787da3c Mon Sep 17 00:00:00 2001 From: Fabio Bas Date: Tue, 8 Jul 2014 22:05:06 +0200 Subject: [PATCH 43/51] Servatrice: fix handling of incoming connections on qt5 --- servatrice/src/servatrice.cpp | 4 ++++ servatrice/src/servatrice.h | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/servatrice/src/servatrice.cpp b/servatrice/src/servatrice.cpp index 87eada78..30c88cfd 100644 --- a/servatrice/src/servatrice.cpp +++ b/servatrice/src/servatrice.cpp @@ -78,7 +78,11 @@ Servatrice_GameServer::~Servatrice_GameServer() } } +#if QT_VERSION < 0x050000 void Servatrice_GameServer::incomingConnection(int socketDescriptor) +#else +void Servatrice_GameServer::incomingConnection(qintptr socketDescriptor) +#endif { // Determine connection pool with smallest client count int minClientCount = -1; diff --git a/servatrice/src/servatrice.h b/servatrice/src/servatrice.h index fbfac035..2b991512 100644 --- a/servatrice/src/servatrice.h +++ b/servatrice/src/servatrice.h @@ -52,7 +52,11 @@ public: Servatrice_GameServer(Servatrice *_server, int _numberPools, const QSqlDatabase &_sqlDatabase, QObject *parent = 0); ~Servatrice_GameServer(); protected: +#if QT_VERSION < 0x050000 void incomingConnection(int socketDescriptor); +#else + void incomingConnection(qintptr socketDescriptor); +#endif }; class Servatrice_IslServer : public QTcpServer { From 4e8ba699d2a003db734b134a51049fce3baecd39 Mon Sep 17 00:00:00 2001 From: arxanas Date: Tue, 8 Jul 2014 22:53:02 -0400 Subject: [PATCH 44/51] Tabs to spaces. --- common/color.h | 22 +- common/decklist.cpp | 870 +++---- common/decklist.h | 196 +- common/get_pb_extension.cpp | 12 +- common/get_pb_extension.h | 6 +- common/rng_abstract.cpp | 38 +- common/rng_abstract.h | 10 +- common/rng_sfmt.cpp | 74 +- common/rng_sfmt.h | 14 +- common/server.cpp | 842 +++---- common/server.h | 152 +- common/server_abstractuserinterface.cpp | 116 +- common/server_abstractuserinterface.h | 46 +- common/server_arrow.cpp | 24 +- common/server_arrow.h | 22 +- common/server_arrowtarget.cpp | 2 +- common/server_arrowtarget.h | 2 +- common/server_card.cpp | 200 +- common/server_card.h | 118 +- common/server_cardzone.h | 80 +- common/server_counter.cpp | 10 +- common/server_counter.h | 30 +- common/server_database_interface.h | 46 +- common/server_game.cpp | 1124 ++++----- common/server_game.h | 150 +- common/server_player.cpp | 2782 +++++++++++------------ common/server_player.h | 188 +- common/server_player_reference.h | 16 +- common/server_protocolhandler.cpp | 900 ++++---- common/server_protocolhandler.h | 102 +- common/server_remoteuserinterface.cpp | 8 +- common/server_remoteuserinterface.h | 16 +- common/server_response_containers.cpp | 76 +- common/server_response_containers.h | 70 +- common/server_room.cpp | 500 ++-- common/server_room.h | 96 +- common/serverinfo_user_container.cpp | 42 +- common/serverinfo_user_container.h | 18 +- 38 files changed, 4510 insertions(+), 4510 deletions(-) diff --git a/common/color.h b/common/color.h index c96eda07..1ea3e33d 100644 --- a/common/color.h +++ b/common/color.h @@ -10,26 +10,26 @@ #ifdef QT_GUI_LIB inline QColor convertColorToQColor(const color &c) { - return QColor(c.r(), c.g(), c.b()); + return QColor(c.r(), c.g(), c.b()); } inline color convertQColorToColor(const QColor &c) { - color result; - result.set_r(c.red()); - result.set_g(c.green()); - result.set_b(c.blue()); - return result; + color result; + result.set_r(c.red()); + result.set_g(c.green()); + result.set_b(c.blue()); + return result; } #endif inline color makeColor(int r, int g, int b) { - color result; - result.set_r(r); - result.set_g(g); - result.set_b(b); - return result; + color result; + result.set_r(r); + result.set_g(g); + result.set_b(b); + return result; } #endif diff --git a/common/decklist.cpp b/common/decklist.cpp index 90b5cb7e..8e877ba9 100644 --- a/common/decklist.cpp +++ b/common/decklist.cpp @@ -6,155 +6,155 @@ #include "decklist.h" SideboardPlan::SideboardPlan(const QString &_name, const QList &_moveList) - : name(_name), moveList(_moveList) + : name(_name), moveList(_moveList) { } void SideboardPlan::setMoveList(const QList &_moveList) { - moveList = _moveList; + moveList = _moveList; } bool SideboardPlan::readElement(QXmlStreamReader *xml) { - while (!xml->atEnd()) { - xml->readNext(); - const QString childName = xml->name().toString(); - if (xml->isStartElement()) { - if (childName == "name") - name = xml->readElementText(); - else if (childName == "move_card_to_zone") { - MoveCard_ToZone m; - while (!xml->atEnd()) { - xml->readNext(); - const QString childName2 = xml->name().toString(); - if (xml->isStartElement()) { - if (childName2 == "card_name") - m.set_card_name(xml->readElementText().toStdString()); - else if (childName2 == "start_zone") - m.set_start_zone(xml->readElementText().toStdString()); - else if (childName2 == "target_zone") - m.set_target_zone(xml->readElementText().toStdString()); - } else if (xml->isEndElement() && (childName2 == "move_card_to_zone")) { - moveList.append(m); - break; - } - } - } - } else if (xml->isEndElement() && (childName == "sideboard_plan")) - return true; - } - return false; + while (!xml->atEnd()) { + xml->readNext(); + const QString childName = xml->name().toString(); + if (xml->isStartElement()) { + if (childName == "name") + name = xml->readElementText(); + else if (childName == "move_card_to_zone") { + MoveCard_ToZone m; + while (!xml->atEnd()) { + xml->readNext(); + const QString childName2 = xml->name().toString(); + if (xml->isStartElement()) { + if (childName2 == "card_name") + m.set_card_name(xml->readElementText().toStdString()); + else if (childName2 == "start_zone") + m.set_start_zone(xml->readElementText().toStdString()); + else if (childName2 == "target_zone") + m.set_target_zone(xml->readElementText().toStdString()); + } else if (xml->isEndElement() && (childName2 == "move_card_to_zone")) { + moveList.append(m); + break; + } + } + } + } else if (xml->isEndElement() && (childName == "sideboard_plan")) + return true; + } + return false; } void SideboardPlan::write(QXmlStreamWriter *xml) { - xml->writeStartElement("sideboard_plan"); - xml->writeTextElement("name", name); - for (int i = 0; i < moveList.size(); ++i) { - xml->writeStartElement("move_card_to_zone"); - xml->writeTextElement("card_name", QString::fromStdString(moveList[i].card_name())); - xml->writeTextElement("start_zone", QString::fromStdString(moveList[i].start_zone())); - xml->writeTextElement("target_zone", QString::fromStdString(moveList[i].target_zone())); - xml->writeEndElement(); - } - xml->writeEndElement(); + xml->writeStartElement("sideboard_plan"); + xml->writeTextElement("name", name); + for (int i = 0; i < moveList.size(); ++i) { + xml->writeStartElement("move_card_to_zone"); + xml->writeTextElement("card_name", QString::fromStdString(moveList[i].card_name())); + xml->writeTextElement("start_zone", QString::fromStdString(moveList[i].start_zone())); + xml->writeTextElement("target_zone", QString::fromStdString(moveList[i].target_zone())); + xml->writeEndElement(); + } + xml->writeEndElement(); } AbstractDecklistNode::AbstractDecklistNode(InnerDecklistNode *_parent) - : parent(_parent) + : parent(_parent) { - if (parent) - parent->append(this); + if (parent) + parent->append(this); } int AbstractDecklistNode::depth() const { - if (parent) - return parent->depth() + 1; - else - return 0; + if (parent) + return parent->depth() + 1; + else + return 0; } InnerDecklistNode::InnerDecklistNode(InnerDecklistNode *other, InnerDecklistNode *_parent) - : AbstractDecklistNode(_parent), name(other->getName()) + : AbstractDecklistNode(_parent), name(other->getName()) { - for (int i = 0; i < other->size(); ++i) { - InnerDecklistNode *inner = dynamic_cast(other->at(i)); - if (inner) - new InnerDecklistNode(inner, this); - else - new DecklistCardNode(dynamic_cast(other->at(i)), this); - } + for (int i = 0; i < other->size(); ++i) { + InnerDecklistNode *inner = dynamic_cast(other->at(i)); + if (inner) + new InnerDecklistNode(inner, this); + else + new DecklistCardNode(dynamic_cast(other->at(i)), this); + } } InnerDecklistNode::~InnerDecklistNode() { - clearTree(); + clearTree(); } QString InnerDecklistNode::visibleNameFromName(const QString &_name) { - if (_name == "main") - return QObject::tr("Maindeck"); - else if (_name == "side") - return QObject::tr("Sideboard"); - else if (_name == "tokens") - return QObject::tr("Tokens"); - else - return _name; + if (_name == "main") + return QObject::tr("Maindeck"); + else if (_name == "side") + return QObject::tr("Sideboard"); + else if (_name == "tokens") + return QObject::tr("Tokens"); + else + return _name; } void InnerDecklistNode::setSortMethod(DeckSortMethod method) { - sortMethod = method; - for (int i = 0; i < size(); i++) - at(i)->setSortMethod(method); + sortMethod = method; + for (int i = 0; i < size(); i++) + at(i)->setSortMethod(method); } QString InnerDecklistNode::getVisibleName() const { - return visibleNameFromName(name); + return visibleNameFromName(name); } void InnerDecklistNode::clearTree() { - for (int i = 0; i < size(); i++) - delete at(i); - clear(); + for (int i = 0; i < size(); i++) + delete at(i); + clear(); } DecklistCardNode::DecklistCardNode(DecklistCardNode *other, InnerDecklistNode *_parent) - : AbstractDecklistCardNode(_parent), name(other->getName()), number(other->getNumber()), price(other->getPrice()) + : AbstractDecklistCardNode(_parent), name(other->getName()), number(other->getNumber()), price(other->getPrice()) { } AbstractDecklistNode *InnerDecklistNode::findChild(const QString &name) { - for (int i = 0; i < size(); i++) - if (at(i)->getName() == name) - return at(i); - return 0; + for (int i = 0; i < size(); i++) + if (at(i)->getName() == name) + return at(i); + return 0; } int InnerDecklistNode::height() const { - return at(0)->height() + 1; + return at(0)->height() + 1; } int InnerDecklistNode::recursiveCount(bool countTotalCards) const { - int result = 0; - for (int i = 0; i < size(); i++) { - InnerDecklistNode *node = dynamic_cast(at(i)); - if (node) - result += node->recursiveCount(countTotalCards); - else if (countTotalCards) - result += dynamic_cast(at(i))->getNumber(); - else - result += 1; - } - return result; + int result = 0; + for (int i = 0; i < size(); i++) { + InnerDecklistNode *node = dynamic_cast(at(i)); + if (node) + result += node->recursiveCount(countTotalCards); + else if (countTotalCards) + result += dynamic_cast(at(i))->getNumber(); + else + result += 1; + } + return result; } float InnerDecklistNode::recursivePrice(bool countTotalCards) const @@ -172,275 +172,275 @@ float InnerDecklistNode::recursivePrice(bool countTotalCards) const bool InnerDecklistNode::compare(AbstractDecklistNode *other) const { - switch (sortMethod) { - case 0: - return compareNumber(other); - case 1: - return compareName(other); - case 2: - return comparePrice(other); - } + switch (sortMethod) { + case 0: + return compareNumber(other); + case 1: + return compareName(other); + case 2: + return comparePrice(other); + } return 0; } bool InnerDecklistNode::compareNumber(AbstractDecklistNode *other) const { - InnerDecklistNode *other2 = dynamic_cast(other); - if (other2) { - int n1 = recursiveCount(true); - int n2 = other2->recursiveCount(true); - return (n1 != n2) ? (n1 > n2) : compareName(other); - } else { - return false; - } + InnerDecklistNode *other2 = dynamic_cast(other); + if (other2) { + int n1 = recursiveCount(true); + int n2 = other2->recursiveCount(true); + return (n1 != n2) ? (n1 > n2) : compareName(other); + } else { + return false; + } } bool InnerDecklistNode::compareName(AbstractDecklistNode *other) const { - InnerDecklistNode *other2 = dynamic_cast(other); - if (other2) { - return (getName() > other2->getName()); - } else { - return false; - } + InnerDecklistNode *other2 = dynamic_cast(other); + if (other2) { + return (getName() > other2->getName()); + } else { + return false; + } } bool InnerDecklistNode::comparePrice(AbstractDecklistNode *other) const { - InnerDecklistNode *other2 = dynamic_cast(other); - if (other2) { - int p1 = 100*recursivePrice(true); - int p2 = 100*other2->recursivePrice(true); - return (p1 != p2) ? (p1 > p2) : compareName(other); - } else { - return false; - } + InnerDecklistNode *other2 = dynamic_cast(other); + if (other2) { + int p1 = 100*recursivePrice(true); + int p2 = 100*other2->recursivePrice(true); + return (p1 != p2) ? (p1 > p2) : compareName(other); + } else { + return false; + } } bool AbstractDecklistCardNode::compare(AbstractDecklistNode *other) const { - switch (sortMethod) { - case ByNumber: - return compareNumber(other); - case ByName: - return compareName(other); - case ByPrice: - return compareTotalPrice(other); - } + switch (sortMethod) { + case ByNumber: + return compareNumber(other); + case ByName: + return compareName(other); + case ByPrice: + return compareTotalPrice(other); + } return 0; } bool AbstractDecklistCardNode::compareNumber(AbstractDecklistNode *other) const { - AbstractDecklistCardNode *other2 = dynamic_cast(other); - if (other2) { - int n1 = getNumber(); - int n2 = other2->getNumber(); - return (n1 != n2) ? (n1 > n2) : compareName(other); - } else { - return true; - } + AbstractDecklistCardNode *other2 = dynamic_cast(other); + if (other2) { + int n1 = getNumber(); + int n2 = other2->getNumber(); + return (n1 != n2) ? (n1 > n2) : compareName(other); + } else { + return true; + } } bool AbstractDecklistCardNode::compareName(AbstractDecklistNode *other) const { - AbstractDecklistCardNode *other2 = dynamic_cast(other); - if (other2) { - return (getName() > other2->getName()); - } else { - return true; - } + AbstractDecklistCardNode *other2 = dynamic_cast(other); + if (other2) { + return (getName() > other2->getName()); + } else { + return true; + } } bool AbstractDecklistCardNode::compareTotalPrice(AbstractDecklistNode *other) const { - AbstractDecklistCardNode *other2 = dynamic_cast(other); - if (other2) { - int p1 = 100*getTotalPrice(); - int p2 = 100*other2->getTotalPrice(); - return (p1 != p2) ? (p1 > p2) : compareName(other); - } else { - return true; - } + AbstractDecklistCardNode *other2 = dynamic_cast(other); + if (other2) { + int p1 = 100*getTotalPrice(); + int p2 = 100*other2->getTotalPrice(); + return (p1 != p2) ? (p1 > p2) : compareName(other); + } else { + return true; + } } class InnerDecklistNode::compareFunctor { private: - Qt::SortOrder order; + Qt::SortOrder order; public: - compareFunctor(Qt::SortOrder _order) : order(_order) { } - inline bool operator()(QPair a, QPair b) const - { - return (order == Qt::AscendingOrder) ^ (a.second->compare(b.second)); - } + compareFunctor(Qt::SortOrder _order) : order(_order) { } + inline bool operator()(QPair a, QPair b) const + { + return (order == Qt::AscendingOrder) ^ (a.second->compare(b.second)); + } }; bool InnerDecklistNode::readElement(QXmlStreamReader *xml) { - while (!xml->atEnd()) { - xml->readNext(); - const QString childName = xml->name().toString(); - if (xml->isStartElement()) { - if (childName == "zone") { - InnerDecklistNode *newZone = new InnerDecklistNode(xml->attributes().value("name").toString(), this); - newZone->readElement(xml); - } else if (childName == "card") { - float price = (xml->attributes().value("price") != NULL) ? xml->attributes().value("price").toString().toFloat() : 0; - DecklistCardNode *newCard = new DecklistCardNode(xml->attributes().value("name").toString(), xml->attributes().value("number").toString().toInt(), price, this); - newCard->readElement(xml); - } - } else if (xml->isEndElement() && (childName == "zone")) - return false; - } - return true; + while (!xml->atEnd()) { + xml->readNext(); + const QString childName = xml->name().toString(); + if (xml->isStartElement()) { + if (childName == "zone") { + InnerDecklistNode *newZone = new InnerDecklistNode(xml->attributes().value("name").toString(), this); + newZone->readElement(xml); + } else if (childName == "card") { + float price = (xml->attributes().value("price") != NULL) ? xml->attributes().value("price").toString().toFloat() : 0; + DecklistCardNode *newCard = new DecklistCardNode(xml->attributes().value("name").toString(), xml->attributes().value("number").toString().toInt(), price, this); + newCard->readElement(xml); + } + } else if (xml->isEndElement() && (childName == "zone")) + return false; + } + return true; } void InnerDecklistNode::writeElement(QXmlStreamWriter *xml) { - xml->writeStartElement("zone"); - xml->writeAttribute("name", name); - for (int i = 0; i < size(); i++) - at(i)->writeElement(xml); - xml->writeEndElement(); // zone + xml->writeStartElement("zone"); + xml->writeAttribute("name", name); + for (int i = 0; i < size(); i++) + at(i)->writeElement(xml); + xml->writeEndElement(); // zone } bool AbstractDecklistCardNode::readElement(QXmlStreamReader *xml) { - while (!xml->atEnd()) { - xml->readNext(); - if (xml->isEndElement() && xml->name() == "card") - return false; - } - return true; + while (!xml->atEnd()) { + xml->readNext(); + if (xml->isEndElement() && xml->name() == "card") + return false; + } + return true; } void AbstractDecklistCardNode::writeElement(QXmlStreamWriter *xml) { - xml->writeEmptyElement("card"); - xml->writeAttribute("number", QString::number(getNumber())); + xml->writeEmptyElement("card"); + xml->writeAttribute("number", QString::number(getNumber())); xml->writeAttribute("price", QString::number(getPrice())); - xml->writeAttribute("name", getName()); + xml->writeAttribute("name", getName()); } QVector > InnerDecklistNode::sort(Qt::SortOrder order) { - QVector > result(size()); - - // Initialize temporary list with contents of current list - QVector > tempList(size()); - for (int i = size() - 1; i >= 0; --i) { - tempList[i].first = i; - tempList[i].second = at(i); - } - - // Sort temporary list - compareFunctor cmp(order); - qSort(tempList.begin(), tempList.end(), cmp); - - // Map old indexes to new indexes and - // copy temporary list to the current one - for (int i = size() - 1; i >= 0; --i) { - result[i].first = tempList[i].first; - result[i].second = i; - replace(i, tempList[i].second); - } + QVector > result(size()); + + // Initialize temporary list with contents of current list + QVector > tempList(size()); + for (int i = size() - 1; i >= 0; --i) { + tempList[i].first = i; + tempList[i].second = at(i); + } + + // Sort temporary list + compareFunctor cmp(order); + qSort(tempList.begin(), tempList.end(), cmp); + + // Map old indexes to new indexes and + // copy temporary list to the current one + for (int i = size() - 1; i >= 0; --i) { + result[i].first = tempList[i].first; + result[i].second = i; + replace(i, tempList[i].second); + } - return result; + return result; } DeckList::DeckList() { - root = new InnerDecklistNode; + root = new InnerDecklistNode; } // TODO: http://qt-project.org/doc/qt-4.8/qobject.html#no-copy-constructor-or-assignment-operator DeckList::DeckList(const DeckList &other) - : name(other.name), - comments(other.comments), - deckHash(other.deckHash) + : name(other.name), + comments(other.comments), + deckHash(other.deckHash) { - root = new InnerDecklistNode(other.getRoot()); - - QMapIterator spIterator(other.getSideboardPlans()); - while (spIterator.hasNext()) { - spIterator.next(); - sideboardPlans.insert(spIterator.key(), new SideboardPlan(spIterator.key(), spIterator.value()->getMoveList())); - } - updateDeckHash(); + root = new InnerDecklistNode(other.getRoot()); + + QMapIterator spIterator(other.getSideboardPlans()); + while (spIterator.hasNext()) { + spIterator.next(); + sideboardPlans.insert(spIterator.key(), new SideboardPlan(spIterator.key(), spIterator.value()->getMoveList())); + } + updateDeckHash(); } DeckList::DeckList(const QString &nativeString) { - root = new InnerDecklistNode; - loadFromString_Native(nativeString); + root = new InnerDecklistNode; + loadFromString_Native(nativeString); } DeckList::~DeckList() { - delete root; - - QMapIterator i(sideboardPlans); - while (i.hasNext()) - delete i.next().value(); + delete root; + + QMapIterator i(sideboardPlans); + while (i.hasNext()) + delete i.next().value(); } QList DeckList::getCurrentSideboardPlan() { - SideboardPlan *current = sideboardPlans.value(QString(), 0); - if (!current) - return QList(); - else - return current->getMoveList(); + SideboardPlan *current = sideboardPlans.value(QString(), 0); + if (!current) + return QList(); + else + return current->getMoveList(); } void DeckList::setCurrentSideboardPlan(const QList &plan) { - SideboardPlan *current = sideboardPlans.value(QString(), 0); - if (!current) { - current = new SideboardPlan; - sideboardPlans.insert(QString(), current); - } - - current->setMoveList(plan); + SideboardPlan *current = sideboardPlans.value(QString(), 0); + if (!current) { + current = new SideboardPlan; + sideboardPlans.insert(QString(), current); + } + + current->setMoveList(plan); } bool DeckList::readElement(QXmlStreamReader *xml) { - const QString childName = xml->name().toString(); - if (xml->isStartElement()) { - if (childName == "deckname") - name = xml->readElementText(); - else if (childName == "comments") - comments = xml->readElementText(); - else if (childName == "zone") { - InnerDecklistNode *newZone = new InnerDecklistNode(xml->attributes().value("name").toString(), root); - newZone->readElement(xml); - } else if (childName == "sideboard_plan") { - SideboardPlan *newSideboardPlan = new SideboardPlan; - if (newSideboardPlan->readElement(xml)) - sideboardPlans.insert(newSideboardPlan->getName(), newSideboardPlan); - else - delete newSideboardPlan; - } - } else if (xml->isEndElement() && (childName == "cockatrice_deck")) - return false; - return true; + const QString childName = xml->name().toString(); + if (xml->isStartElement()) { + if (childName == "deckname") + name = xml->readElementText(); + else if (childName == "comments") + comments = xml->readElementText(); + else if (childName == "zone") { + InnerDecklistNode *newZone = new InnerDecklistNode(xml->attributes().value("name").toString(), root); + newZone->readElement(xml); + } else if (childName == "sideboard_plan") { + SideboardPlan *newSideboardPlan = new SideboardPlan; + if (newSideboardPlan->readElement(xml)) + sideboardPlans.insert(newSideboardPlan->getName(), newSideboardPlan); + else + delete newSideboardPlan; + } + } else if (xml->isEndElement() && (childName == "cockatrice_deck")) + return false; + return true; } void DeckList::write(QXmlStreamWriter *xml) { - xml->writeStartElement("cockatrice_deck"); - xml->writeAttribute("version", "1"); - xml->writeTextElement("deckname", name); - xml->writeTextElement("comments", comments); + xml->writeStartElement("cockatrice_deck"); + xml->writeAttribute("version", "1"); + xml->writeTextElement("deckname", name); + xml->writeTextElement("comments", comments); - for (int i = 0; i < root->size(); i++) - root->at(i)->writeElement(xml); - - QMapIterator i(sideboardPlans); - while (i.hasNext()) - i.next().value()->write(xml); - xml->writeEndElement(); + for (int i = 0; i < root->size(); i++) + root->at(i)->writeElement(xml); + + QMapIterator i(sideboardPlans); + while (i.hasNext()) + i.next().value()->write(xml); + xml->writeEndElement(); } bool DeckList::loadFromXml(QXmlStreamReader *xml) @@ -450,187 +450,187 @@ bool DeckList::loadFromXml(QXmlStreamReader *xml) return false; } - cleanList(); - while (!xml->atEnd()) { - xml->readNext(); - if (xml->isStartElement()) { - if (xml->name() != "cockatrice_deck") - return false; - while (!xml->atEnd()) { - xml->readNext(); - if (!readElement(xml)) - break; - } - } - } - updateDeckHash(); + cleanList(); + while (!xml->atEnd()) { + xml->readNext(); + if (xml->isStartElement()) { + if (xml->name() != "cockatrice_deck") + return false; + while (!xml->atEnd()) { + xml->readNext(); + if (!readElement(xml)) + break; + } + } + } + updateDeckHash(); if (xml->error()) { qDebug() << "Error loading deck from xml: " << xml->errorString(); return false; } - return true; + return true; } bool DeckList::loadFromString_Native(const QString &nativeString) { - QXmlStreamReader xml(nativeString); - return loadFromXml(&xml); + QXmlStreamReader xml(nativeString); + return loadFromXml(&xml); } QString DeckList::writeToString_Native() { - QString result; - QXmlStreamWriter xml(&result); - xml.writeStartDocument(); - write(&xml); - xml.writeEndDocument(); - return result; + QString result; + QXmlStreamWriter xml(&result); + xml.writeStartDocument(); + write(&xml); + xml.writeEndDocument(); + return result; } bool DeckList::loadFromFile_Native(QIODevice *device) { - QXmlStreamReader xml(device); - return loadFromXml(&xml); + QXmlStreamReader xml(device); + return loadFromXml(&xml); } bool DeckList::saveToFile_Native(QIODevice *device) { - QXmlStreamWriter xml(device); - xml.setAutoFormatting(true); - xml.writeStartDocument(); + QXmlStreamWriter xml(device); + xml.setAutoFormatting(true); + xml.writeStartDocument(); - write(&xml); + write(&xml); - xml.writeEndDocument(); - return true; + xml.writeEndDocument(); + return true; } bool DeckList::loadFromStream_Plain(QTextStream &in) { - cleanList(); + cleanList(); - InnerDecklistNode *main = 0, *side = 0; - bool inSideboard = false; + InnerDecklistNode *main = 0, *side = 0; + bool inSideboard = false; - int okRows = 0; - while (!in.atEnd()) { - QString line = in.readLine().simplified(); - if (line.startsWith("//")) - continue; + int okRows = 0; + while (!in.atEnd()) { + QString line = in.readLine().simplified(); + if (line.startsWith("//")) + continue; - InnerDecklistNode *zone; - if (line.startsWith("Sideboard", Qt::CaseInsensitive)) { - inSideboard = true; - continue; - } else if (line.startsWith("SB:", Qt::CaseInsensitive)) { - line = line.mid(3).trimmed(); - if (!side) - side = new InnerDecklistNode("side", root); - zone = side; - } else if (inSideboard) { - if (!side) - side = new InnerDecklistNode("side", root); - zone = side; - } else { - if (!main) - main = new InnerDecklistNode("main", root); - zone = main; - } + InnerDecklistNode *zone; + if (line.startsWith("Sideboard", Qt::CaseInsensitive)) { + inSideboard = true; + continue; + } else if (line.startsWith("SB:", Qt::CaseInsensitive)) { + line = line.mid(3).trimmed(); + if (!side) + side = new InnerDecklistNode("side", root); + zone = side; + } else if (inSideboard) { + if (!side) + side = new InnerDecklistNode("side", root); + zone = side; + } else { + if (!main) + main = new InnerDecklistNode("main", root); + zone = main; + } - // Filter out MWS edition symbols and basic land extras - QRegExp rx("\\[.*\\]"); - line.remove(rx); - rx.setPattern("\\(.*\\)"); - line.remove(rx); - //Filter out post card name editions - rx.setPattern("\\|.*$"); - line.remove(rx); - line = line.simplified(); + // Filter out MWS edition symbols and basic land extras + QRegExp rx("\\[.*\\]"); + line.remove(rx); + rx.setPattern("\\(.*\\)"); + line.remove(rx); + //Filter out post card name editions + rx.setPattern("\\|.*$"); + line.remove(rx); + line = line.simplified(); - int i = line.indexOf(' '); - bool ok; - int number = line.left(i).toInt(&ok); - if (!ok) - continue; + int i = line.indexOf(' '); + bool ok; + int number = line.left(i).toInt(&ok); + if (!ok) + continue; - QString cardName = line.mid(i + 1); + QString cardName = line.mid(i + 1); // Common differences between cockatrice's card names // and what's commonly used in decklists - rx.setPattern("’"); + rx.setPattern("’"); cardName.replace(rx, "'"); - rx.setPattern("Æ"); - cardName.replace(rx, "AE"); - rx.setPattern("^Aether"); - cardName.replace(rx, "AEther"); - rx.setPattern("\\s*[&|/]{1,2}\\s*"); - cardName.replace(rx, " // "); + rx.setPattern("Æ"); + cardName.replace(rx, "AE"); + rx.setPattern("^Aether"); + cardName.replace(rx, "AEther"); + rx.setPattern("\\s*[&|/]{1,2}\\s*"); + cardName.replace(rx, " // "); - ++okRows; - new DecklistCardNode(cardName, number, zone); - } - updateDeckHash(); - return (okRows > 0); + ++okRows; + new DecklistCardNode(cardName, number, zone); + } + updateDeckHash(); + return (okRows > 0); } bool DeckList::loadFromFile_Plain(QIODevice *device) { - QTextStream in(device); - return loadFromStream_Plain(in); + QTextStream in(device); + return loadFromStream_Plain(in); } bool DeckList::saveToStream_Plain(QTextStream &out) { - // Support for this is only possible if the internal structure doesn't get more complicated. - for (int i = 0; i < root->size(); i++) { - InnerDecklistNode *node = dynamic_cast(root->at(i)); - for (int j = 0; j < node->size(); j++) { - DecklistCardNode *card = dynamic_cast(node->at(j)); - out << QString("%1%2 %3\n").arg(node->getName() == "side" ? "SB: " : "").arg(card->getNumber()).arg(card->getName()); - } - } - return true; + // Support for this is only possible if the internal structure doesn't get more complicated. + for (int i = 0; i < root->size(); i++) { + InnerDecklistNode *node = dynamic_cast(root->at(i)); + for (int j = 0; j < node->size(); j++) { + DecklistCardNode *card = dynamic_cast(node->at(j)); + out << QString("%1%2 %3\n").arg(node->getName() == "side" ? "SB: " : "").arg(card->getNumber()).arg(card->getName()); + } + } + return true; } bool DeckList::saveToFile_Plain(QIODevice *device) { - QTextStream out(device); - return saveToStream_Plain(out); + QTextStream out(device); + return saveToStream_Plain(out); } QString DeckList::writeToString_Plain() { - QString result; - QTextStream out(&result); - saveToStream_Plain(out); - return result; + QString result; + QTextStream out(&result); + saveToStream_Plain(out); + return result; } void DeckList::cleanList() { - root->clearTree(); - setName(); - setComments(); - deckHash = QString(); - emit deckHashChanged(); + root->clearTree(); + setName(); + setComments(); + deckHash = QString(); + emit deckHashChanged(); } void DeckList::getCardListHelper(InnerDecklistNode *item, QSet &result) const { - for (int i = 0; i < item->size(); ++i) { - DecklistCardNode *node = dynamic_cast(item->at(i)); - if (node) - result.insert(node->getName()); - else - getCardListHelper(dynamic_cast(item->at(i)), result); - } + for (int i = 0; i < item->size(); ++i) { + DecklistCardNode *node = dynamic_cast(item->at(i)); + if (node) + result.insert(node->getName()); + else + getCardListHelper(dynamic_cast(item->at(i)), result); + } } QStringList DeckList::getCardList() const { - QSet result; - getCardListHelper(root, result); - return result.toList(); + QSet result; + getCardListHelper(root, result); + return result.toList(); } int DeckList::getSideboardSize() const @@ -640,7 +640,7 @@ int DeckList::getSideboardSize() const InnerDecklistNode *node = dynamic_cast(root->at(i)); if (node->getName() != "side") continue; - for (int j = 0; j < node->size(); j++) { + for (int j = 0; j < node->size(); j++) { DecklistCardNode *card = dynamic_cast(node->at(j)); size += card->getNumber(); } @@ -650,65 +650,65 @@ int DeckList::getSideboardSize() const DecklistCardNode *DeckList::addCard(const QString &cardName, const QString &zoneName) { - InnerDecklistNode *zoneNode = dynamic_cast(root->findChild(zoneName)); - if (!zoneNode) - zoneNode = new InnerDecklistNode(zoneName, root); + InnerDecklistNode *zoneNode = dynamic_cast(root->findChild(zoneName)); + if (!zoneNode) + zoneNode = new InnerDecklistNode(zoneName, root); - DecklistCardNode *node = new DecklistCardNode(cardName, 1, zoneNode); - updateDeckHash(); - return node; + DecklistCardNode *node = new DecklistCardNode(cardName, 1, zoneNode); + updateDeckHash(); + return node; } bool DeckList::deleteNode(AbstractDecklistNode *node, InnerDecklistNode *rootNode) { - if (node == root) - return true; - bool updateHash = false; - if (!rootNode) { - rootNode = root; - updateHash = true; - } - - int index = rootNode->indexOf(node); - if (index != -1) { - delete rootNode->takeAt(index); - if (!rootNode->size()) - deleteNode(rootNode, rootNode->getParent()); - if (updateHash) - updateDeckHash(); - return true; - } - for (int i = 0; i < rootNode->size(); i++) { - InnerDecklistNode *inner = dynamic_cast(rootNode->at(i)); - if (inner) - if (deleteNode(node, inner)) { - if (updateHash) - updateDeckHash(); - return true; - } - } - return false; + if (node == root) + return true; + bool updateHash = false; + if (!rootNode) { + rootNode = root; + updateHash = true; + } + + int index = rootNode->indexOf(node); + if (index != -1) { + delete rootNode->takeAt(index); + if (!rootNode->size()) + deleteNode(rootNode, rootNode->getParent()); + if (updateHash) + updateDeckHash(); + return true; + } + for (int i = 0; i < rootNode->size(); i++) { + InnerDecklistNode *inner = dynamic_cast(rootNode->at(i)); + if (inner) + if (deleteNode(node, inner)) { + if (updateHash) + updateDeckHash(); + return true; + } + } + return false; } void DeckList::updateDeckHash() { - QStringList cardList; - for (int i = 0; i < root->size(); i++) { - InnerDecklistNode *node = dynamic_cast(root->at(i)); - for (int j = 0; j < node->size(); j++) { - DecklistCardNode *card = dynamic_cast(node->at(j)); - for (int k = 0; k < card->getNumber(); ++k) - cardList.append((node->getName() == "side" ? "SB:" : "") + card->getName().toLower()); - } - } - cardList.sort(); - QByteArray deckHashArray = QCryptographicHash::hash(cardList.join(";").toUtf8(), QCryptographicHash::Sha1); - quint64 number = (((quint64) (unsigned char) deckHashArray[0]) << 32) - + (((quint64) (unsigned char) deckHashArray[1]) << 24) - + (((quint64) (unsigned char) deckHashArray[2] << 16)) - + (((quint64) (unsigned char) deckHashArray[3]) << 8) - + (quint64) (unsigned char) deckHashArray[4]; - deckHash = QString::number(number, 32).rightJustified(8, '0'); - - emit deckHashChanged(); + QStringList cardList; + for (int i = 0; i < root->size(); i++) { + InnerDecklistNode *node = dynamic_cast(root->at(i)); + for (int j = 0; j < node->size(); j++) { + DecklistCardNode *card = dynamic_cast(node->at(j)); + for (int k = 0; k < card->getNumber(); ++k) + cardList.append((node->getName() == "side" ? "SB:" : "") + card->getName().toLower()); + } + } + cardList.sort(); + QByteArray deckHashArray = QCryptographicHash::hash(cardList.join(";").toUtf8(), QCryptographicHash::Sha1); + quint64 number = (((quint64) (unsigned char) deckHashArray[0]) << 32) + + (((quint64) (unsigned char) deckHashArray[1]) << 24) + + (((quint64) (unsigned char) deckHashArray[2] << 16)) + + (((quint64) (unsigned char) deckHashArray[3]) << 8) + + (quint64) (unsigned char) deckHashArray[4]; + deckHash = QString::number(number, 32).rightJustified(8, '0'); + + emit deckHashChanged(); } diff --git a/common/decklist.h b/common/decklist.h index 2eed52fc..8b71a4b7 100644 --- a/common/decklist.h +++ b/common/decklist.h @@ -23,152 +23,152 @@ class InnerDecklistNode; class SideboardPlan { private: - QString name; - QList moveList; + QString name; + QList moveList; public: - SideboardPlan(const QString &_name = QString(), const QList &_moveList = QList()); - bool readElement(QXmlStreamReader *xml); - void write(QXmlStreamWriter *xml); + SideboardPlan(const QString &_name = QString(), const QList &_moveList = QList()); + bool readElement(QXmlStreamReader *xml); + void write(QXmlStreamWriter *xml); - QString getName() const { return name; } - const QList &getMoveList() const { return moveList; } - void setMoveList(const QList &_moveList); + QString getName() const { return name; } + const QList &getMoveList() const { return moveList; } + void setMoveList(const QList &_moveList); }; enum DeckSortMethod { ByNumber, ByName, ByPrice }; class AbstractDecklistNode { protected: - InnerDecklistNode *parent; - DeckSortMethod sortMethod; + InnerDecklistNode *parent; + DeckSortMethod sortMethod; public: - AbstractDecklistNode(InnerDecklistNode *_parent = 0); - virtual ~AbstractDecklistNode() { } - virtual void setSortMethod(DeckSortMethod method) { sortMethod = method; } - virtual QString getName() const = 0; - InnerDecklistNode *getParent() const { return parent; } - int depth() const; - virtual int height() const = 0; - virtual bool compare(AbstractDecklistNode *other) const = 0; + AbstractDecklistNode(InnerDecklistNode *_parent = 0); + virtual ~AbstractDecklistNode() { } + virtual void setSortMethod(DeckSortMethod method) { sortMethod = method; } + virtual QString getName() const = 0; + InnerDecklistNode *getParent() const { return parent; } + int depth() const; + virtual int height() const = 0; + virtual bool compare(AbstractDecklistNode *other) const = 0; - virtual bool readElement(QXmlStreamReader *xml) = 0; - virtual void writeElement(QXmlStreamWriter *xml) = 0; + virtual bool readElement(QXmlStreamReader *xml) = 0; + virtual void writeElement(QXmlStreamWriter *xml) = 0; }; class InnerDecklistNode : public AbstractDecklistNode, public QList { private: - QString name; - class compareFunctor; + QString name; + class compareFunctor; public: - InnerDecklistNode(const QString &_name = QString(), InnerDecklistNode *_parent = 0) : AbstractDecklistNode(_parent), name(_name) { } - InnerDecklistNode(InnerDecklistNode *other, InnerDecklistNode *_parent = 0); - virtual ~InnerDecklistNode(); - void setSortMethod(DeckSortMethod method); - QString getName() const { return name; } - void setName(const QString &_name) { name = _name; } - static QString visibleNameFromName(const QString &_name); - virtual QString getVisibleName() const; - void clearTree(); - AbstractDecklistNode *findChild(const QString &name); - int height() const; - int recursiveCount(bool countTotalCards = false) const; + InnerDecklistNode(const QString &_name = QString(), InnerDecklistNode *_parent = 0) : AbstractDecklistNode(_parent), name(_name) { } + InnerDecklistNode(InnerDecklistNode *other, InnerDecklistNode *_parent = 0); + virtual ~InnerDecklistNode(); + void setSortMethod(DeckSortMethod method); + QString getName() const { return name; } + void setName(const QString &_name) { name = _name; } + static QString visibleNameFromName(const QString &_name); + virtual QString getVisibleName() const; + void clearTree(); + AbstractDecklistNode *findChild(const QString &name); + int height() const; + int recursiveCount(bool countTotalCards = false) const; float recursivePrice(bool countTotalCards = false) const; - bool compare(AbstractDecklistNode *other) const; - bool compareNumber(AbstractDecklistNode *other) const; - bool compareName(AbstractDecklistNode *other) const; - bool comparePrice(AbstractDecklistNode *other) const; - QVector > sort(Qt::SortOrder order = Qt::AscendingOrder); + bool compare(AbstractDecklistNode *other) const; + bool compareNumber(AbstractDecklistNode *other) const; + bool compareName(AbstractDecklistNode *other) const; + bool comparePrice(AbstractDecklistNode *other) const; + QVector > sort(Qt::SortOrder order = Qt::AscendingOrder); - bool readElement(QXmlStreamReader *xml); - void writeElement(QXmlStreamWriter *xml); + bool readElement(QXmlStreamReader *xml); + void writeElement(QXmlStreamWriter *xml); }; class AbstractDecklistCardNode : public AbstractDecklistNode { public: - AbstractDecklistCardNode(InnerDecklistNode *_parent = 0) : AbstractDecklistNode(_parent) { } - virtual int getNumber() const = 0; - virtual void setNumber(int _number) = 0; - virtual QString getName() const = 0; - virtual void setName(const QString &_name) = 0; + AbstractDecklistCardNode(InnerDecklistNode *_parent = 0) : AbstractDecklistNode(_parent) { } + virtual int getNumber() const = 0; + virtual void setNumber(int _number) = 0; + virtual QString getName() const = 0; + virtual void setName(const QString &_name) = 0; virtual float getPrice() const = 0; virtual void setPrice(const float _price) = 0; float getTotalPrice() const { return getNumber() * getPrice(); } - int height() const { return 0; } - bool compare(AbstractDecklistNode *other) const; - bool compareNumber(AbstractDecklistNode *other) const; - bool compareName(AbstractDecklistNode *other) const; - bool compareTotalPrice(AbstractDecklistNode *other) const; + int height() const { return 0; } + bool compare(AbstractDecklistNode *other) const; + bool compareNumber(AbstractDecklistNode *other) const; + bool compareName(AbstractDecklistNode *other) const; + bool compareTotalPrice(AbstractDecklistNode *other) const; - bool readElement(QXmlStreamReader *xml); - void writeElement(QXmlStreamWriter *xml); + bool readElement(QXmlStreamReader *xml); + void writeElement(QXmlStreamWriter *xml); }; class DecklistCardNode : public AbstractDecklistCardNode { private: - QString name; - int number; + QString name; + int number; float price; public: DecklistCardNode(const QString &_name = QString(), int _number = 1, float _price = 0, InnerDecklistNode *_parent = 0) : AbstractDecklistCardNode(_parent), name(_name), number(_number), price(_price) { } DecklistCardNode(const QString &_name = QString(), int _number = 1, InnerDecklistNode *_parent = 0) : AbstractDecklistCardNode(_parent), name(_name), number(_number), price(0) { } - DecklistCardNode(DecklistCardNode *other, InnerDecklistNode *_parent); - int getNumber() const { return number; } - void setNumber(int _number) { number = _number; } - QString getName() const { return name; } - void setName(const QString &_name) { name = _name; } + DecklistCardNode(DecklistCardNode *other, InnerDecklistNode *_parent); + int getNumber() const { return number; } + void setNumber(int _number) { number = _number; } + QString getName() const { return name; } + void setName(const QString &_name) { name = _name; } float getPrice() const { return price; } void setPrice(const float _price) { price = _price; } }; class DeckList : public QObject { - Q_OBJECT + Q_OBJECT private: - QString name, comments; - QString deckHash; - QMap sideboardPlans; - InnerDecklistNode *root; - void getCardListHelper(InnerDecklistNode *node, QSet &result) const; + QString name, comments; + QString deckHash; + QMap sideboardPlans; + InnerDecklistNode *root; + void getCardListHelper(InnerDecklistNode *node, QSet &result) const; signals: - void deckHashChanged(); + void deckHashChanged(); public slots: - void setName(const QString &_name = QString()) { name = _name; } - void setComments(const QString &_comments = QString()) { comments = _comments; } + void setName(const QString &_name = QString()) { name = _name; } + void setComments(const QString &_comments = QString()) { comments = _comments; } public: - DeckList(); - DeckList(const DeckList &other); - DeckList(const QString &nativeString); - ~DeckList(); - QString getName() const { return name; } - QString getComments() const { return comments; } - QList getCurrentSideboardPlan(); - void setCurrentSideboardPlan(const QList &plan); - const QMap &getSideboardPlans() const { return sideboardPlans; } + DeckList(); + DeckList(const DeckList &other); + DeckList(const QString &nativeString); + ~DeckList(); + QString getName() const { return name; } + QString getComments() const { return comments; } + QList getCurrentSideboardPlan(); + void setCurrentSideboardPlan(const QList &plan); + const QMap &getSideboardPlans() const { return sideboardPlans; } - bool readElement(QXmlStreamReader *xml); - void write(QXmlStreamWriter *xml); - bool loadFromXml(QXmlStreamReader *xml); - bool loadFromString_Native(const QString &nativeString); - QString writeToString_Native(); - bool loadFromFile_Native(QIODevice *device); - bool saveToFile_Native(QIODevice *device); - bool loadFromStream_Plain(QTextStream &stream); - bool loadFromFile_Plain(QIODevice *device); - bool saveToStream_Plain(QTextStream &stream); - bool saveToFile_Plain(QIODevice *device); - QString writeToString_Plain(); + bool readElement(QXmlStreamReader *xml); + void write(QXmlStreamWriter *xml); + bool loadFromXml(QXmlStreamReader *xml); + bool loadFromString_Native(const QString &nativeString); + QString writeToString_Native(); + bool loadFromFile_Native(QIODevice *device); + bool saveToFile_Native(QIODevice *device); + bool loadFromStream_Plain(QTextStream &stream); + bool loadFromFile_Plain(QIODevice *device); + bool saveToStream_Plain(QTextStream &stream); + bool saveToFile_Plain(QIODevice *device); + QString writeToString_Plain(); - void cleanList(); - bool isEmpty() const { return root->isEmpty() && name.isEmpty() && comments.isEmpty() && sideboardPlans.isEmpty(); } - QStringList getCardList() const; + void cleanList(); + bool isEmpty() const { return root->isEmpty() && name.isEmpty() && comments.isEmpty() && sideboardPlans.isEmpty(); } + QStringList getCardList() const; int getSideboardSize() const; - QString getDeckHash() const { return deckHash; } - void updateDeckHash(); + QString getDeckHash() const { return deckHash; } + void updateDeckHash(); - InnerDecklistNode *getRoot() const { return root; } - DecklistCardNode *addCard(const QString &cardName, const QString &zoneName); - bool deleteNode(AbstractDecklistNode *node, InnerDecklistNode *rootNode = 0); + InnerDecklistNode *getRoot() const { return root; } + DecklistCardNode *addCard(const QString &cardName, const QString &zoneName); + bool deleteNode(AbstractDecklistNode *node, InnerDecklistNode *rootNode = 0); }; #endif diff --git a/common/get_pb_extension.cpp b/common/get_pb_extension.cpp index d561f0c8..1e980f4b 100644 --- a/common/get_pb_extension.cpp +++ b/common/get_pb_extension.cpp @@ -4,10 +4,10 @@ int getPbExtension(const ::google::protobuf::Message &message) { - std::vector< const ::google::protobuf::FieldDescriptor * > fieldList; - message.GetReflection()->ListFields(message, &fieldList); - for (unsigned int j = 0; j < fieldList.size(); ++j) - if (fieldList[j]->is_extension()) - return fieldList[j]->number(); - return -1; + std::vector< const ::google::protobuf::FieldDescriptor * > fieldList; + message.GetReflection()->ListFields(message, &fieldList); + for (unsigned int j = 0; j < fieldList.size(); ++j) + if (fieldList[j]->is_extension()) + return fieldList[j]->number(); + return -1; } diff --git a/common/get_pb_extension.h b/common/get_pb_extension.h index c55aa937..bebef39e 100644 --- a/common/get_pb_extension.h +++ b/common/get_pb_extension.h @@ -2,9 +2,9 @@ #define GET_PB_EXTENSION_H namespace google { - namespace protobuf { - class Message; - } + namespace protobuf { + class Message; + } } int getPbExtension(const ::google::protobuf::Message &message); diff --git a/common/rng_abstract.cpp b/common/rng_abstract.cpp index 4c51143a..79054908 100644 --- a/common/rng_abstract.cpp +++ b/common/rng_abstract.cpp @@ -4,27 +4,27 @@ QVector RNG_Abstract::makeNumbersVector(int n, int min, int max) { - const int bins = max - min + 1; - QVector result(bins); - for (int i = 0; i < n; ++i) { - int number = rand(min, max); - if ((number < min) || (number > max)) - qDebug() << "rand(" << min << "," << max << ") returned " << number; - else - result[number - min]++; - } - return result; + const int bins = max - min + 1; + QVector result(bins); + for (int i = 0; i < n; ++i) { + int number = rand(min, max); + if ((number < min) || (number > max)) + qDebug() << "rand(" << min << "," << max << ") returned " << number; + else + result[number - min]++; + } + return result; } double RNG_Abstract::testRandom(const QVector &numbers) const { - int n = 0; - for (int i = 0; i < numbers.size(); ++i) - n += numbers[i]; - double expected = (double) n / (double) numbers.size(); - double chisq = 0; - for (int i = 0; i < numbers.size(); ++i) - chisq += ((double) numbers[i] - expected) * ((double) numbers[i] - expected) / expected; - - return chisq; + int n = 0; + for (int i = 0; i < numbers.size(); ++i) + n += numbers[i]; + double expected = (double) n / (double) numbers.size(); + double chisq = 0; + for (int i = 0; i < numbers.size(); ++i) + chisq += ((double) numbers[i] - expected) * ((double) numbers[i] - expected) / expected; + + return chisq; } diff --git a/common/rng_abstract.h b/common/rng_abstract.h index f2017819..0423930c 100644 --- a/common/rng_abstract.h +++ b/common/rng_abstract.h @@ -5,12 +5,12 @@ #include class RNG_Abstract : public QObject { - Q_OBJECT + Q_OBJECT public: - RNG_Abstract(QObject *parent = 0) : QObject(parent) { } - virtual unsigned int rand(int min, int max) = 0; - QVector makeNumbersVector(int n, int min, int max); - double testRandom(const QVector &numbers) const; + RNG_Abstract(QObject *parent = 0) : QObject(parent) { } + virtual unsigned int rand(int min, int max) = 0; + QVector makeNumbersVector(int n, int min, int max); + double testRandom(const QVector &numbers) const; }; extern RNG_Abstract *rng; diff --git a/common/rng_sfmt.cpp b/common/rng_sfmt.cpp index d3d55d1c..783594a0 100644 --- a/common/rng_sfmt.cpp +++ b/common/rng_sfmt.cpp @@ -11,10 +11,10 @@ #endif RNG_SFMT::RNG_SFMT(QObject *parent) - : RNG_Abstract(parent) + : RNG_Abstract(parent) { - // initialize the random number generator with a 32bit integer seed (timestamp) - sfmt_init_gen_rand(&sfmt, QDateTime::currentDateTime().toTime_t()); + // initialize the random number generator with a 32bit integer seed (timestamp) + sfmt_init_gen_rand(&sfmt, QDateTime::currentDateTime().toTime_t()); } /** @@ -32,11 +32,11 @@ unsigned int RNG_SFMT::rand(int min, int max) { * There has been no use for negative random numbers with rand() though, so it's treated as error. */ if(min < 0) { - throw std::invalid_argument( - QString("Invalid bounds for RNG: Got min " + - QString::number(min) + " < 0!\n").toStdString()); - // at this point, the method exits. No return value is needed, because - // basically the exception itself is returned. + throw std::invalid_argument( + QString("Invalid bounds for RNG: Got min " + + QString::number(min) + " < 0!\n").toStdString()); + // at this point, the method exits. No return value is needed, because + // basically the exception itself is returned. } // For complete fairness and equal timing, this should be a roll, but let's skip it anyway @@ -99,38 +99,38 @@ unsigned int RNG_SFMT::rand(int min, int max) { */ unsigned int RNG_SFMT::cdf(unsigned int min, unsigned int max) { - // This all makes no sense if min > max, which should never happen. - if(min > max) { - throw std::invalid_argument( - QString("Invalid bounds for RNG: min > max! Values were: min = " + - QString::number(min) + ", max = " + - QString::number(max)).toStdString()); - // at this point, the method exits. No return value is needed, because - // basically the exception itself is returned. - } + // This all makes no sense if min > max, which should never happen. + if(min > max) { + throw std::invalid_argument( + QString("Invalid bounds for RNG: min > max! Values were: min = " + + QString::number(min) + ", max = " + + QString::number(max)).toStdString()); + // at this point, the method exits. No return value is needed, because + // basically the exception itself is returned. + } - // First compute the diameter (aka size, length) of the [min, max] interval - const unsigned int diameter = max - min + 1; + // First compute the diameter (aka size, length) of the [min, max] interval + const unsigned int diameter = max - min + 1; - // Compute how many buckets (each in size of the diameter) will fit into the - // universe. - // If the division has a remainder, the result is floored automatically. - const uint64_t buckets = UINT64_MAX / diameter; + // Compute how many buckets (each in size of the diameter) will fit into the + // universe. + // If the division has a remainder, the result is floored automatically. + const uint64_t buckets = UINT64_MAX / diameter; - // Compute the last valid random number. All numbers beyond have to be ignored. - // If there was no remainder in the previous step, limit is equal to UINT64_MAX. - const uint64_t limit = diameter * buckets; + // Compute the last valid random number. All numbers beyond have to be ignored. + // If there was no remainder in the previous step, limit is equal to UINT64_MAX. + const uint64_t limit = diameter * buckets; - uint64_t rand; - // To make the random number generation thread-safe, a mutex is created around - // the generation. Outside of the loop of course, to avoid lock/unlock overhead. - mutex.lock(); - do { - rand = sfmt_genrand_uint64(&sfmt); - } while (rand >= limit); - mutex.unlock(); + uint64_t rand; + // To make the random number generation thread-safe, a mutex is created around + // the generation. Outside of the loop of course, to avoid lock/unlock overhead. + mutex.lock(); + do { + rand = sfmt_genrand_uint64(&sfmt); + } while (rand >= limit); + mutex.unlock(); - // Now determine the bucket containing the SFMT() random number and after adding - // the lower bound, a random number from [min, max] can be returned. - return (unsigned int) (rand / buckets + min); + // Now determine the bucket containing the SFMT() random number and after adding + // the lower bound, a random number from [min, max] can be returned. + return (unsigned int) (rand / buckets + min); } diff --git a/common/rng_sfmt.h b/common/rng_sfmt.h index d35ce97d..ec7a75c9 100644 --- a/common/rng_sfmt.h +++ b/common/rng_sfmt.h @@ -26,15 +26,15 @@ */ class RNG_SFMT : public RNG_Abstract { - Q_OBJECT + Q_OBJECT private: - QMutex mutex; - sfmt_t sfmt; - // The discrete cumulative distribution function for the RNG - unsigned int cdf(unsigned int min, unsigned int max); + QMutex mutex; + sfmt_t sfmt; + // The discrete cumulative distribution function for the RNG + unsigned int cdf(unsigned int min, unsigned int max); public: - RNG_SFMT(QObject *parent = 0); - unsigned int rand(int min, int max); + RNG_SFMT(QObject *parent = 0); + unsigned int rand(int min, int max); }; #endif diff --git a/common/server.cpp b/common/server.cpp index f0530497..132cba94 100644 --- a/common/server.cpp +++ b/common/server.cpp @@ -36,18 +36,18 @@ #include Server::Server(bool _threaded, QObject *parent) - : QObject(parent), threaded(_threaded), nextLocalGameId(0) + : QObject(parent), threaded(_threaded), nextLocalGameId(0) { - qRegisterMetaType("ServerInfo_Game"); - qRegisterMetaType("ServerInfo_Room"); - qRegisterMetaType("ServerInfo_User"); - qRegisterMetaType("CommandContainer"); - qRegisterMetaType("Response"); - qRegisterMetaType("GameEventContainer"); - qRegisterMetaType("IslMessage"); - qRegisterMetaType("Command_JoinGame"); - - connect(this, SIGNAL(sigSendIslMessage(IslMessage, int)), this, SLOT(doSendIslMessage(IslMessage, int)), Qt::QueuedConnection); + qRegisterMetaType("ServerInfo_Game"); + qRegisterMetaType("ServerInfo_Room"); + qRegisterMetaType("ServerInfo_User"); + qRegisterMetaType("CommandContainer"); + qRegisterMetaType("Response"); + qRegisterMetaType("GameEventContainer"); + qRegisterMetaType("IslMessage"); + qRegisterMetaType("Command_JoinGame"); + + connect(this, SIGNAL(sigSendIslMessage(IslMessage, int)), this, SLOT(doSendIslMessage(IslMessage, int)), Qt::QueuedConnection); } Server::~Server() @@ -56,532 +56,532 @@ Server::~Server() void Server::prepareDestroy() { - // dirty :( - if (threaded) { - clientsLock.lockForRead(); - for (int i = 0; i < clients.size(); ++i) - QMetaObject::invokeMethod(clients.at(i), "prepareDestroy", Qt::QueuedConnection); - clientsLock.unlock(); - - bool done = false; - - class SleeperThread : public QThread - { - public: - static void msleep(unsigned long msecs) { QThread::usleep(msecs); } - }; + // dirty :( + if (threaded) { + clientsLock.lockForRead(); + for (int i = 0; i < clients.size(); ++i) + QMetaObject::invokeMethod(clients.at(i), "prepareDestroy", Qt::QueuedConnection); + clientsLock.unlock(); + + bool done = false; + + class SleeperThread : public QThread + { + public: + static void msleep(unsigned long msecs) { QThread::usleep(msecs); } + }; - do { - SleeperThread::msleep(10); - clientsLock.lockForRead(); - if (clients.isEmpty()) - done = true; - clientsLock.unlock(); - } while (!done); - } else { - // no locking is needed in unthreaded mode - while (!clients.isEmpty()) - clients.first()->prepareDestroy(); - } - - roomsLock.lockForWrite(); - QMapIterator roomIterator(rooms); - while (roomIterator.hasNext()) - delete roomIterator.next().value(); - rooms.clear(); - roomsLock.unlock(); + do { + SleeperThread::msleep(10); + clientsLock.lockForRead(); + if (clients.isEmpty()) + done = true; + clientsLock.unlock(); + } while (!done); + } else { + // no locking is needed in unthreaded mode + while (!clients.isEmpty()) + clients.first()->prepareDestroy(); + } + + roomsLock.lockForWrite(); + QMapIterator roomIterator(rooms); + while (roomIterator.hasNext()) + delete roomIterator.next().value(); + rooms.clear(); + roomsLock.unlock(); } void Server::setDatabaseInterface(Server_DatabaseInterface *_databaseInterface) { - connect(this, SIGNAL(endSession(qint64)), _databaseInterface, SLOT(endSession(qint64))); - databaseInterfaces.insert(QThread::currentThread(), _databaseInterface); + connect(this, SIGNAL(endSession(qint64)), _databaseInterface, SLOT(endSession(qint64))); + databaseInterfaces.insert(QThread::currentThread(), _databaseInterface); } Server_DatabaseInterface *Server::getDatabaseInterface() const { - return databaseInterfaces.value(QThread::currentThread()); + return databaseInterfaces.value(QThread::currentThread()); } AuthenticationResult Server::loginUser(Server_ProtocolHandler *session, QString &name, const QString &password, QString &reasonStr, int &secondsLeft) { - if (name.size() > 35) - name = name.left(35); - - Server_DatabaseInterface *databaseInterface = getDatabaseInterface(); - - QWriteLocker locker(&clientsLock); - - AuthenticationResult authState = databaseInterface->checkUserPassword(session, name, password, reasonStr, secondsLeft); - if ((authState == NotLoggedIn) || (authState == UserIsBanned || authState == UsernameInvalid)) - return authState; - - ServerInfo_User data = databaseInterface->getUserData(name, true); - data.set_address(session->getAddress().toStdString()); - name = QString::fromStdString(data.name()); // Compensate for case indifference - - databaseInterface->lockSessionTables(); - - if (authState == PasswordRight) { - if (users.contains(name) || databaseInterface->userSessionExists(name)) { - qDebug("Login denied: would overwrite old session"); - databaseInterface->unlockSessionTables(); - return WouldOverwriteOldSession; - } - } else if (authState == UnknownUser) { - // Change user name so that no two users have the same names, - // don't interfere with registered user names though. - QString tempName = name; - int i = 0; - while (users.contains(tempName) || databaseInterface->userExists(tempName) || databaseInterface->userSessionExists(tempName)) - tempName = name + "_" + QString::number(++i); - name = tempName; - data.set_name(name.toStdString()); - } - - users.insert(name, session); - qDebug() << "Server::loginUser:" << session << "name=" << name; - - data.set_session_id(databaseInterface->startSession(name, session->getAddress())); - databaseInterface->unlockSessionTables(); - - usersBySessionId.insert(data.session_id(), session); - - qDebug() << "session id:" << data.session_id(); - session->setUserInfo(data); - - Event_UserJoined event; - event.mutable_user_info()->CopyFrom(session->copyUserInfo(false)); - SessionEvent *se = Server_ProtocolHandler::prepareSessionEvent(event); - for (int i = 0; i < clients.size(); ++i) - if (clients[i]->getAcceptsUserListChanges()) - clients[i]->sendProtocolItem(*se); - delete se; - - event.mutable_user_info()->CopyFrom(session->copyUserInfo(true, true, true)); - locker.unlock(); - - se = Server_ProtocolHandler::prepareSessionEvent(event); - sendIsl_SessionEvent(*se); - delete se; - - return authState; + if (name.size() > 35) + name = name.left(35); + + Server_DatabaseInterface *databaseInterface = getDatabaseInterface(); + + QWriteLocker locker(&clientsLock); + + AuthenticationResult authState = databaseInterface->checkUserPassword(session, name, password, reasonStr, secondsLeft); + if ((authState == NotLoggedIn) || (authState == UserIsBanned || authState == UsernameInvalid)) + return authState; + + ServerInfo_User data = databaseInterface->getUserData(name, true); + data.set_address(session->getAddress().toStdString()); + name = QString::fromStdString(data.name()); // Compensate for case indifference + + databaseInterface->lockSessionTables(); + + if (authState == PasswordRight) { + if (users.contains(name) || databaseInterface->userSessionExists(name)) { + qDebug("Login denied: would overwrite old session"); + databaseInterface->unlockSessionTables(); + return WouldOverwriteOldSession; + } + } else if (authState == UnknownUser) { + // Change user name so that no two users have the same names, + // don't interfere with registered user names though. + QString tempName = name; + int i = 0; + while (users.contains(tempName) || databaseInterface->userExists(tempName) || databaseInterface->userSessionExists(tempName)) + tempName = name + "_" + QString::number(++i); + name = tempName; + data.set_name(name.toStdString()); + } + + users.insert(name, session); + qDebug() << "Server::loginUser:" << session << "name=" << name; + + data.set_session_id(databaseInterface->startSession(name, session->getAddress())); + databaseInterface->unlockSessionTables(); + + usersBySessionId.insert(data.session_id(), session); + + qDebug() << "session id:" << data.session_id(); + session->setUserInfo(data); + + Event_UserJoined event; + event.mutable_user_info()->CopyFrom(session->copyUserInfo(false)); + SessionEvent *se = Server_ProtocolHandler::prepareSessionEvent(event); + for (int i = 0; i < clients.size(); ++i) + if (clients[i]->getAcceptsUserListChanges()) + clients[i]->sendProtocolItem(*se); + delete se; + + event.mutable_user_info()->CopyFrom(session->copyUserInfo(true, true, true)); + locker.unlock(); + + se = Server_ProtocolHandler::prepareSessionEvent(event); + sendIsl_SessionEvent(*se); + delete se; + + return authState; } void Server::addPersistentPlayer(const QString &userName, int roomId, int gameId, int playerId) { - QWriteLocker locker(&persistentPlayersLock); - persistentPlayers.insert(userName, PlayerReference(roomId, gameId, playerId)); + QWriteLocker locker(&persistentPlayersLock); + persistentPlayers.insert(userName, PlayerReference(roomId, gameId, playerId)); } void Server::removePersistentPlayer(const QString &userName, int roomId, int gameId, int playerId) { - QWriteLocker locker(&persistentPlayersLock); - persistentPlayers.remove(userName, PlayerReference(roomId, gameId, playerId)); + QWriteLocker locker(&persistentPlayersLock); + persistentPlayers.remove(userName, PlayerReference(roomId, gameId, playerId)); } QList Server::getPersistentPlayerReferences(const QString &userName) const { - QReadLocker locker(&persistentPlayersLock); - return persistentPlayers.values(userName); + QReadLocker locker(&persistentPlayersLock); + return persistentPlayers.values(userName); } Server_AbstractUserInterface *Server::findUser(const QString &userName) const { - // Call this only with clientsLock set. - - Server_AbstractUserInterface *userHandler = users.value(userName); - if (userHandler) - return userHandler; - else - return externalUsers.value(userName); + // Call this only with clientsLock set. + + Server_AbstractUserInterface *userHandler = users.value(userName); + if (userHandler) + return userHandler; + else + return externalUsers.value(userName); } void Server::addClient(Server_ProtocolHandler *client) { - QWriteLocker locker(&clientsLock); - clients << client; + QWriteLocker locker(&clientsLock); + clients << client; } void Server::removeClient(Server_ProtocolHandler *client) { - QWriteLocker locker(&clientsLock); - clients.removeAt(clients.indexOf(client)); - ServerInfo_User *data = client->getUserInfo(); - if (data) { - Event_UserLeft event; - event.set_name(data->name()); - SessionEvent *se = Server_ProtocolHandler::prepareSessionEvent(event); - for (int i = 0; i < clients.size(); ++i) - if (clients[i]->getAcceptsUserListChanges()) - clients[i]->sendProtocolItem(*se); - sendIsl_SessionEvent(*se); - delete se; - - users.remove(QString::fromStdString(data->name())); - qDebug() << "Server::removeClient: name=" << QString::fromStdString(data->name()); - - if (data->has_session_id()) { - const qint64 sessionId = data->session_id(); - usersBySessionId.remove(sessionId); - emit endSession(sessionId); - qDebug() << "closed session id:" << sessionId; - } - } - qDebug() << "Server::removeClient: removed" << (void *) client << ";" << clients.size() << "clients; " << users.size() << "users left"; + QWriteLocker locker(&clientsLock); + clients.removeAt(clients.indexOf(client)); + ServerInfo_User *data = client->getUserInfo(); + if (data) { + Event_UserLeft event; + event.set_name(data->name()); + SessionEvent *se = Server_ProtocolHandler::prepareSessionEvent(event); + for (int i = 0; i < clients.size(); ++i) + if (clients[i]->getAcceptsUserListChanges()) + clients[i]->sendProtocolItem(*se); + sendIsl_SessionEvent(*se); + delete se; + + users.remove(QString::fromStdString(data->name())); + qDebug() << "Server::removeClient: name=" << QString::fromStdString(data->name()); + + if (data->has_session_id()) { + const qint64 sessionId = data->session_id(); + usersBySessionId.remove(sessionId); + emit endSession(sessionId); + qDebug() << "closed session id:" << sessionId; + } + } + qDebug() << "Server::removeClient: removed" << (void *) client << ";" << clients.size() << "clients; " << users.size() << "users left"; } void Server::externalUserJoined(const ServerInfo_User &userInfo) { - // This function is always called from the main thread via signal/slot. - clientsLock.lockForWrite(); - - Server_RemoteUserInterface *newUser = new Server_RemoteUserInterface(this, ServerInfo_User_Container(userInfo)); - externalUsers.insert(QString::fromStdString(userInfo.name()), newUser); - externalUsersBySessionId.insert(userInfo.session_id(), newUser); - - Event_UserJoined event; - event.mutable_user_info()->CopyFrom(userInfo); - - SessionEvent *se = Server_ProtocolHandler::prepareSessionEvent(event); - for (int i = 0; i < clients.size(); ++i) - if (clients[i]->getAcceptsUserListChanges()) - clients[i]->sendProtocolItem(*se); - delete se; - clientsLock.unlock(); - - ResponseContainer rc(-1); - newUser->joinPersistentGames(rc); - newUser->sendResponseContainer(rc, Response::RespNothing); + // This function is always called from the main thread via signal/slot. + clientsLock.lockForWrite(); + + Server_RemoteUserInterface *newUser = new Server_RemoteUserInterface(this, ServerInfo_User_Container(userInfo)); + externalUsers.insert(QString::fromStdString(userInfo.name()), newUser); + externalUsersBySessionId.insert(userInfo.session_id(), newUser); + + Event_UserJoined event; + event.mutable_user_info()->CopyFrom(userInfo); + + SessionEvent *se = Server_ProtocolHandler::prepareSessionEvent(event); + for (int i = 0; i < clients.size(); ++i) + if (clients[i]->getAcceptsUserListChanges()) + clients[i]->sendProtocolItem(*se); + delete se; + clientsLock.unlock(); + + ResponseContainer rc(-1); + newUser->joinPersistentGames(rc); + newUser->sendResponseContainer(rc, Response::RespNothing); } void Server::externalUserLeft(const QString &userName) { - // This function is always called from the main thread via signal/slot. - - clientsLock.lockForWrite(); - Server_AbstractUserInterface *user = externalUsers.take(userName); - externalUsersBySessionId.remove(user->getUserInfo()->session_id()); - clientsLock.unlock(); - - QMap > userGames(user->getGames()); - QMapIterator > userGamesIterator(userGames); - roomsLock.lockForRead(); - while (userGamesIterator.hasNext()) { - userGamesIterator.next(); - Server_Room *room = rooms.value(userGamesIterator.value().first); - if (!room) - continue; - - QReadLocker roomGamesLocker(&room->gamesLock); - Server_Game *game = room->getGames().value(userGamesIterator.key()); - if (!game) - continue; - - QMutexLocker gameLocker(&game->gameMutex); - Server_Player *player = game->getPlayers().value(userGamesIterator.value().second); - if (!player) - continue; - - player->disconnectClient(); - } - roomsLock.unlock(); - - delete user; - - Event_UserLeft event; - event.set_name(userName.toStdString()); - - SessionEvent *se = Server_ProtocolHandler::prepareSessionEvent(event); - clientsLock.lockForRead(); - for (int i = 0; i < clients.size(); ++i) - if (clients[i]->getAcceptsUserListChanges()) - clients[i]->sendProtocolItem(*se); - clientsLock.unlock(); - delete se; + // This function is always called from the main thread via signal/slot. + + clientsLock.lockForWrite(); + Server_AbstractUserInterface *user = externalUsers.take(userName); + externalUsersBySessionId.remove(user->getUserInfo()->session_id()); + clientsLock.unlock(); + + QMap > userGames(user->getGames()); + QMapIterator > userGamesIterator(userGames); + roomsLock.lockForRead(); + while (userGamesIterator.hasNext()) { + userGamesIterator.next(); + Server_Room *room = rooms.value(userGamesIterator.value().first); + if (!room) + continue; + + QReadLocker roomGamesLocker(&room->gamesLock); + Server_Game *game = room->getGames().value(userGamesIterator.key()); + if (!game) + continue; + + QMutexLocker gameLocker(&game->gameMutex); + Server_Player *player = game->getPlayers().value(userGamesIterator.value().second); + if (!player) + continue; + + player->disconnectClient(); + } + roomsLock.unlock(); + + delete user; + + Event_UserLeft event; + event.set_name(userName.toStdString()); + + SessionEvent *se = Server_ProtocolHandler::prepareSessionEvent(event); + clientsLock.lockForRead(); + for (int i = 0; i < clients.size(); ++i) + if (clients[i]->getAcceptsUserListChanges()) + clients[i]->sendProtocolItem(*se); + clientsLock.unlock(); + delete se; } void Server::externalRoomUserJoined(int roomId, const ServerInfo_User &userInfo) { - // This function is always called from the main thread via signal/slot. - QReadLocker locker(&roomsLock); - - Server_Room *room = rooms.value(roomId); - if (!room) { - qDebug() << "externalRoomUserJoined: room id=" << roomId << "not found"; - return; - } - room->addExternalUser(userInfo); + // This function is always called from the main thread via signal/slot. + QReadLocker locker(&roomsLock); + + Server_Room *room = rooms.value(roomId); + if (!room) { + qDebug() << "externalRoomUserJoined: room id=" << roomId << "not found"; + return; + } + room->addExternalUser(userInfo); } void Server::externalRoomUserLeft(int roomId, const QString &userName) { - // This function is always called from the main thread via signal/slot. - QReadLocker locker(&roomsLock); - - Server_Room *room = rooms.value(roomId); - if (!room) { - qDebug() << "externalRoomUserLeft: room id=" << roomId << "not found"; - return; - } - room->removeExternalUser(userName); + // This function is always called from the main thread via signal/slot. + QReadLocker locker(&roomsLock); + + Server_Room *room = rooms.value(roomId); + if (!room) { + qDebug() << "externalRoomUserLeft: room id=" << roomId << "not found"; + return; + } + room->removeExternalUser(userName); } void Server::externalRoomSay(int roomId, const QString &userName, const QString &message) { - // This function is always called from the main thread via signal/slot. - QReadLocker locker(&roomsLock); - - Server_Room *room = rooms.value(roomId); - if (!room) { - qDebug() << "externalRoomSay: room id=" << roomId << "not found"; - return; - } - room->say(userName, message, false); + // This function is always called from the main thread via signal/slot. + QReadLocker locker(&roomsLock); + + Server_Room *room = rooms.value(roomId); + if (!room) { + qDebug() << "externalRoomSay: room id=" << roomId << "not found"; + return; + } + room->say(userName, message, false); } void Server::externalRoomGameListChanged(int roomId, const ServerInfo_Game &gameInfo) { - // This function is always called from the main thread via signal/slot. - QReadLocker locker(&roomsLock); - - Server_Room *room = rooms.value(roomId); - if (!room) { - qDebug() << "externalRoomGameListChanged: room id=" << roomId << "not found"; - return; - } - room->updateExternalGameList(gameInfo); + // This function is always called from the main thread via signal/slot. + QReadLocker locker(&roomsLock); + + Server_Room *room = rooms.value(roomId); + if (!room) { + qDebug() << "externalRoomGameListChanged: room id=" << roomId << "not found"; + return; + } + room->updateExternalGameList(gameInfo); } void Server::externalJoinGameCommandReceived(const Command_JoinGame &cmd, int cmdId, int roomId, int serverId, qint64 sessionId) { - // This function is always called from the main thread via signal/slot. - - try { - QReadLocker roomsLocker(&roomsLock); - QReadLocker clientsLocker(&clientsLock); - - Server_Room *room = rooms.value(roomId); - if (!room) { - qDebug() << "externalJoinGameCommandReceived: room id=" << roomId << "not found"; - throw Response::RespNotInRoom; - } - Server_AbstractUserInterface *userInterface = externalUsersBySessionId.value(sessionId); - if (!userInterface) { - qDebug() << "externalJoinGameCommandReceived: session id=" << sessionId << "not found"; - throw Response::RespNotInRoom; - } - - ResponseContainer responseContainer(cmdId); - Response::ResponseCode responseCode = room->processJoinGameCommand(cmd, responseContainer, userInterface); - userInterface->sendResponseContainer(responseContainer, responseCode); - } catch (Response::ResponseCode code) { - Response response; - response.set_cmd_id(cmdId); - response.set_response_code(code); - - sendIsl_Response(response, serverId, sessionId); - } + // This function is always called from the main thread via signal/slot. + + try { + QReadLocker roomsLocker(&roomsLock); + QReadLocker clientsLocker(&clientsLock); + + Server_Room *room = rooms.value(roomId); + if (!room) { + qDebug() << "externalJoinGameCommandReceived: room id=" << roomId << "not found"; + throw Response::RespNotInRoom; + } + Server_AbstractUserInterface *userInterface = externalUsersBySessionId.value(sessionId); + if (!userInterface) { + qDebug() << "externalJoinGameCommandReceived: session id=" << sessionId << "not found"; + throw Response::RespNotInRoom; + } + + ResponseContainer responseContainer(cmdId); + Response::ResponseCode responseCode = room->processJoinGameCommand(cmd, responseContainer, userInterface); + userInterface->sendResponseContainer(responseContainer, responseCode); + } catch (Response::ResponseCode code) { + Response response; + response.set_cmd_id(cmdId); + response.set_response_code(code); + + sendIsl_Response(response, serverId, sessionId); + } } void Server::externalGameCommandContainerReceived(const CommandContainer &cont, int playerId, int serverId, qint64 sessionId) { - // This function is always called from the main thread via signal/slot. - - try { - ResponseContainer responseContainer(cont.cmd_id()); - Response::ResponseCode finalResponseCode = Response::RespOk; - - QReadLocker roomsLocker(&roomsLock); - Server_Room *room = rooms.value(cont.room_id()); - if (!room) { - qDebug() << "externalGameCommandContainerReceived: room id=" << cont.room_id() << "not found"; - throw Response::RespNotInRoom; - } - - QReadLocker roomGamesLocker(&room->gamesLock); - Server_Game *game = room->getGames().value(cont.game_id()); - if (!game) { - qDebug() << "externalGameCommandContainerReceived: game id=" << cont.game_id() << "not found"; - throw Response::RespNotInRoom; - } - - QMutexLocker gameLocker(&game->gameMutex); - Server_Player *player = game->getPlayers().value(playerId); - if (!player) { - qDebug() << "externalGameCommandContainerReceived: player id=" << playerId << "not found"; - throw Response::RespNotInRoom; - } - - GameEventStorage ges; - for (int i = cont.game_command_size() - 1; i >= 0; --i) { - const GameCommand &sc = cont.game_command(i); - qDebug() << "[ISL]" << QString::fromStdString(sc.ShortDebugString()); - - Response::ResponseCode resp = player->processGameCommand(sc, responseContainer, ges); - - if (resp != Response::RespOk) - finalResponseCode = resp; - } - ges.sendToGame(game); - - if (finalResponseCode != Response::RespNothing) { - player->playerMutex.lock(); - player->getUserInterface()->sendResponseContainer(responseContainer, finalResponseCode); - player->playerMutex.unlock(); - } - } catch (Response::ResponseCode code) { - Response response; - response.set_cmd_id(cont.cmd_id()); - response.set_response_code(code); - - sendIsl_Response(response, serverId, sessionId); - } + // This function is always called from the main thread via signal/slot. + + try { + ResponseContainer responseContainer(cont.cmd_id()); + Response::ResponseCode finalResponseCode = Response::RespOk; + + QReadLocker roomsLocker(&roomsLock); + Server_Room *room = rooms.value(cont.room_id()); + if (!room) { + qDebug() << "externalGameCommandContainerReceived: room id=" << cont.room_id() << "not found"; + throw Response::RespNotInRoom; + } + + QReadLocker roomGamesLocker(&room->gamesLock); + Server_Game *game = room->getGames().value(cont.game_id()); + if (!game) { + qDebug() << "externalGameCommandContainerReceived: game id=" << cont.game_id() << "not found"; + throw Response::RespNotInRoom; + } + + QMutexLocker gameLocker(&game->gameMutex); + Server_Player *player = game->getPlayers().value(playerId); + if (!player) { + qDebug() << "externalGameCommandContainerReceived: player id=" << playerId << "not found"; + throw Response::RespNotInRoom; + } + + GameEventStorage ges; + for (int i = cont.game_command_size() - 1; i >= 0; --i) { + const GameCommand &sc = cont.game_command(i); + qDebug() << "[ISL]" << QString::fromStdString(sc.ShortDebugString()); + + Response::ResponseCode resp = player->processGameCommand(sc, responseContainer, ges); + + if (resp != Response::RespOk) + finalResponseCode = resp; + } + ges.sendToGame(game); + + if (finalResponseCode != Response::RespNothing) { + player->playerMutex.lock(); + player->getUserInterface()->sendResponseContainer(responseContainer, finalResponseCode); + player->playerMutex.unlock(); + } + } catch (Response::ResponseCode code) { + Response response; + response.set_cmd_id(cont.cmd_id()); + response.set_response_code(code); + + sendIsl_Response(response, serverId, sessionId); + } } void Server::externalGameEventContainerReceived(const GameEventContainer &cont, qint64 sessionId) { - // This function is always called from the main thread via signal/slot. - - QReadLocker usersLocker(&clientsLock); - - Server_ProtocolHandler *client = usersBySessionId.value(sessionId); - if (!client) { - qDebug() << "externalGameEventContainerReceived: session" << sessionId << "not found"; - return; - } - client->sendProtocolItem(cont); + // This function is always called from the main thread via signal/slot. + + QReadLocker usersLocker(&clientsLock); + + Server_ProtocolHandler *client = usersBySessionId.value(sessionId); + if (!client) { + qDebug() << "externalGameEventContainerReceived: session" << sessionId << "not found"; + return; + } + client->sendProtocolItem(cont); } void Server::externalResponseReceived(const Response &resp, qint64 sessionId) { - // This function is always called from the main thread via signal/slot. - - QReadLocker usersLocker(&clientsLock); - - Server_ProtocolHandler *client = usersBySessionId.value(sessionId); - if (!client) { - qDebug() << "externalResponseReceived: session" << sessionId << "not found"; - return; - } - client->sendProtocolItem(resp); + // This function is always called from the main thread via signal/slot. + + QReadLocker usersLocker(&clientsLock); + + Server_ProtocolHandler *client = usersBySessionId.value(sessionId); + if (!client) { + qDebug() << "externalResponseReceived: session" << sessionId << "not found"; + return; + } + client->sendProtocolItem(resp); } void Server::broadcastRoomUpdate(const ServerInfo_Room &roomInfo, bool sendToIsl) { - // This function is always called from the main thread via signal/slot. - - Event_ListRooms event; - event.add_room_list()->CopyFrom(roomInfo); - - SessionEvent *se = Server_ProtocolHandler::prepareSessionEvent(event); + // This function is always called from the main thread via signal/slot. + + Event_ListRooms event; + event.add_room_list()->CopyFrom(roomInfo); + + SessionEvent *se = Server_ProtocolHandler::prepareSessionEvent(event); - clientsLock.lockForRead(); - for (int i = 0; i < clients.size(); ++i) - if (clients[i]->getAcceptsRoomListChanges()) - clients[i]->sendProtocolItem(*se); - clientsLock.unlock(); - - if (sendToIsl) - sendIsl_SessionEvent(*se); - - delete se; + clientsLock.lockForRead(); + for (int i = 0; i < clients.size(); ++i) + if (clients[i]->getAcceptsRoomListChanges()) + clients[i]->sendProtocolItem(*se); + clientsLock.unlock(); + + if (sendToIsl) + sendIsl_SessionEvent(*se); + + delete se; } void Server::addRoom(Server_Room *newRoom) { - QWriteLocker locker(&roomsLock); - qDebug() << "Adding room: ID=" << newRoom->getId() << "name=" << newRoom->getName(); - rooms.insert(newRoom->getId(), newRoom); - connect(newRoom, SIGNAL(roomInfoChanged(ServerInfo_Room)), this, SLOT(broadcastRoomUpdate(const ServerInfo_Room &)), Qt::QueuedConnection); + QWriteLocker locker(&roomsLock); + qDebug() << "Adding room: ID=" << newRoom->getId() << "name=" << newRoom->getName(); + rooms.insert(newRoom->getId(), newRoom); + connect(newRoom, SIGNAL(roomInfoChanged(ServerInfo_Room)), this, SLOT(broadcastRoomUpdate(const ServerInfo_Room &)), Qt::QueuedConnection); } int Server::getUsersCount() const { - QReadLocker locker(&clientsLock); - return users.size(); + QReadLocker locker(&clientsLock); + return users.size(); } int Server::getGamesCount() const { - int result = 0; - QReadLocker locker(&roomsLock); - QMapIterator roomIterator(rooms); - while (roomIterator.hasNext()) { - Server_Room *room = roomIterator.next().value(); - QReadLocker roomLocker(&room->gamesLock); - result += room->getGames().size(); - } - return result; + int result = 0; + QReadLocker locker(&roomsLock); + QMapIterator roomIterator(rooms); + while (roomIterator.hasNext()) { + Server_Room *room = roomIterator.next().value(); + QReadLocker roomLocker(&room->gamesLock); + result += room->getGames().size(); + } + return result; } void Server::sendIsl_Response(const Response &item, int serverId, qint64 sessionId) { - IslMessage msg; - msg.set_message_type(IslMessage::RESPONSE); - if (sessionId != -1) - msg.set_session_id(sessionId); - msg.mutable_response()->CopyFrom(item); - - emit sigSendIslMessage(msg, serverId); + IslMessage msg; + msg.set_message_type(IslMessage::RESPONSE); + if (sessionId != -1) + msg.set_session_id(sessionId); + msg.mutable_response()->CopyFrom(item); + + emit sigSendIslMessage(msg, serverId); } void Server::sendIsl_SessionEvent(const SessionEvent &item, int serverId, qint64 sessionId) { - IslMessage msg; - msg.set_message_type(IslMessage::SESSION_EVENT); - if (sessionId != -1) - msg.set_session_id(sessionId); - msg.mutable_session_event()->CopyFrom(item); - - emit sigSendIslMessage(msg, serverId); + IslMessage msg; + msg.set_message_type(IslMessage::SESSION_EVENT); + if (sessionId != -1) + msg.set_session_id(sessionId); + msg.mutable_session_event()->CopyFrom(item); + + emit sigSendIslMessage(msg, serverId); } void Server::sendIsl_GameEventContainer(const GameEventContainer &item, int serverId, qint64 sessionId) { - IslMessage msg; - msg.set_message_type(IslMessage::GAME_EVENT_CONTAINER); - if (sessionId != -1) - msg.set_session_id(sessionId); - msg.mutable_game_event_container()->CopyFrom(item); - - emit sigSendIslMessage(msg, serverId); + IslMessage msg; + msg.set_message_type(IslMessage::GAME_EVENT_CONTAINER); + if (sessionId != -1) + msg.set_session_id(sessionId); + msg.mutable_game_event_container()->CopyFrom(item); + + emit sigSendIslMessage(msg, serverId); } void Server::sendIsl_RoomEvent(const RoomEvent &item, int serverId, qint64 sessionId) { - IslMessage msg; - msg.set_message_type(IslMessage::ROOM_EVENT); - if (sessionId != -1) - msg.set_session_id(sessionId); - msg.mutable_room_event()->CopyFrom(item); - - emit sigSendIslMessage(msg, serverId); + IslMessage msg; + msg.set_message_type(IslMessage::ROOM_EVENT); + if (sessionId != -1) + msg.set_session_id(sessionId); + msg.mutable_room_event()->CopyFrom(item); + + emit sigSendIslMessage(msg, serverId); } void Server::sendIsl_GameCommand(const CommandContainer &item, int serverId, qint64 sessionId, int roomId, int playerId) { - IslMessage msg; - msg.set_message_type(IslMessage::GAME_COMMAND_CONTAINER); - msg.set_session_id(sessionId); - msg.set_player_id(playerId); - - CommandContainer *cont = msg.mutable_game_command(); - cont->CopyFrom(item); - cont->set_room_id(roomId); - - emit sigSendIslMessage(msg, serverId); + IslMessage msg; + msg.set_message_type(IslMessage::GAME_COMMAND_CONTAINER); + msg.set_session_id(sessionId); + msg.set_player_id(playerId); + + CommandContainer *cont = msg.mutable_game_command(); + cont->CopyFrom(item); + cont->set_room_id(roomId); + + emit sigSendIslMessage(msg, serverId); } void Server::sendIsl_RoomCommand(const CommandContainer &item, int serverId, qint64 sessionId, int roomId) { - IslMessage msg; - msg.set_message_type(IslMessage::ROOM_COMMAND_CONTAINER); - msg.set_session_id(sessionId); - - CommandContainer *cont = msg.mutable_room_command(); - cont->CopyFrom(item); - cont->set_room_id(roomId); - - emit sigSendIslMessage(msg, serverId); + IslMessage msg; + msg.set_message_type(IslMessage::ROOM_COMMAND_CONTAINER); + msg.set_session_id(sessionId); + + CommandContainer *cont = msg.mutable_room_command(); + cont->CopyFrom(item); + cont->set_room_id(roomId); + + emit sigSendIslMessage(msg, serverId); } diff --git a/common/server.h b/common/server.h index 631d2d2e..6742f6e2 100644 --- a/common/server.h +++ b/common/server.h @@ -31,87 +31,87 @@ enum AuthenticationResult { NotLoggedIn = 0, PasswordRight = 1, UnknownUser = 2, class Server : public QObject { - Q_OBJECT + Q_OBJECT signals: - void pingClockTimeout(); - void sigSendIslMessage(const IslMessage &message, int serverId); - void endSession(qint64 sessionId); + void pingClockTimeout(); + void sigSendIslMessage(const IslMessage &message, int serverId); + void endSession(qint64 sessionId); private slots: - void broadcastRoomUpdate(const ServerInfo_Room &roomInfo, bool sendToIsl = false); + void broadcastRoomUpdate(const ServerInfo_Room &roomInfo, bool sendToIsl = false); public: - mutable QReadWriteLock clientsLock, roomsLock; // locking order: roomsLock before clientsLock - Server(bool _threaded, QObject *parent = 0); - ~Server(); - void setThreaded(bool _threaded) { threaded = _threaded; } - AuthenticationResult loginUser(Server_ProtocolHandler *session, QString &name, const QString &password, QString &reason, int &secondsLeft); - const QMap &getRooms() { return rooms; } - - Server_AbstractUserInterface *findUser(const QString &userName) const; - const QMap &getUsers() const { return users; } - const QMap &getUsersBySessionId() const { return usersBySessionId; } - void addClient(Server_ProtocolHandler *player); - void removeClient(Server_ProtocolHandler *player); - virtual QString getLoginMessage() const { return QString(); } - - virtual bool getGameShouldPing() const { return false; } - virtual int getMaxGameInactivityTime() const { return 9999999; } - virtual int getMaxPlayerInactivityTime() const { return 9999999; } - virtual int getMessageCountingInterval() const { return 0; } - virtual int getMaxMessageCountPerInterval() const { return 0; } - virtual int getMaxMessageSizePerInterval() const { return 0; } - virtual int getMaxGamesPerUser() const { return 0; } - virtual bool getThreaded() const { return false; } - - Server_DatabaseInterface *getDatabaseInterface() const; - int getNextLocalGameId() { QMutexLocker locker(&nextLocalGameIdMutex); return ++nextLocalGameId; } - - void sendIsl_Response(const Response &item, int serverId = -1, qint64 sessionId = -1); - void sendIsl_SessionEvent(const SessionEvent &item, int serverId = -1, qint64 sessionId = -1); - void sendIsl_GameEventContainer(const GameEventContainer &item, int serverId = -1, qint64 sessionId = -1); - void sendIsl_RoomEvent(const RoomEvent &item, int serverId = -1, qint64 sessionId = -1); - void sendIsl_GameCommand(const CommandContainer &item, int serverId, qint64 sessionId, int roomId, int playerId); - void sendIsl_RoomCommand(const CommandContainer &item, int serverId, qint64 sessionId, int roomId); - - void addExternalUser(const ServerInfo_User &userInfo); - void removeExternalUser(const QString &userName); - const QMap &getExternalUsers() const { return externalUsers; } - - void addPersistentPlayer(const QString &userName, int roomId, int gameId, int playerId); - void removePersistentPlayer(const QString &userName, int roomId, int gameId, int playerId); - QList getPersistentPlayerReferences(const QString &userName) const; + mutable QReadWriteLock clientsLock, roomsLock; // locking order: roomsLock before clientsLock + Server(bool _threaded, QObject *parent = 0); + ~Server(); + void setThreaded(bool _threaded) { threaded = _threaded; } + AuthenticationResult loginUser(Server_ProtocolHandler *session, QString &name, const QString &password, QString &reason, int &secondsLeft); + const QMap &getRooms() { return rooms; } + + Server_AbstractUserInterface *findUser(const QString &userName) const; + const QMap &getUsers() const { return users; } + const QMap &getUsersBySessionId() const { return usersBySessionId; } + void addClient(Server_ProtocolHandler *player); + void removeClient(Server_ProtocolHandler *player); + virtual QString getLoginMessage() const { return QString(); } + + virtual bool getGameShouldPing() const { return false; } + virtual int getMaxGameInactivityTime() const { return 9999999; } + virtual int getMaxPlayerInactivityTime() const { return 9999999; } + virtual int getMessageCountingInterval() const { return 0; } + virtual int getMaxMessageCountPerInterval() const { return 0; } + virtual int getMaxMessageSizePerInterval() const { return 0; } + virtual int getMaxGamesPerUser() const { return 0; } + virtual bool getThreaded() const { return false; } + + Server_DatabaseInterface *getDatabaseInterface() const; + int getNextLocalGameId() { QMutexLocker locker(&nextLocalGameIdMutex); return ++nextLocalGameId; } + + void sendIsl_Response(const Response &item, int serverId = -1, qint64 sessionId = -1); + void sendIsl_SessionEvent(const SessionEvent &item, int serverId = -1, qint64 sessionId = -1); + void sendIsl_GameEventContainer(const GameEventContainer &item, int serverId = -1, qint64 sessionId = -1); + void sendIsl_RoomEvent(const RoomEvent &item, int serverId = -1, qint64 sessionId = -1); + void sendIsl_GameCommand(const CommandContainer &item, int serverId, qint64 sessionId, int roomId, int playerId); + void sendIsl_RoomCommand(const CommandContainer &item, int serverId, qint64 sessionId, int roomId); + + void addExternalUser(const ServerInfo_User &userInfo); + void removeExternalUser(const QString &userName); + const QMap &getExternalUsers() const { return externalUsers; } + + void addPersistentPlayer(const QString &userName, int roomId, int gameId, int playerId); + void removePersistentPlayer(const QString &userName, int roomId, int gameId, int playerId); + QList getPersistentPlayerReferences(const QString &userName) const; private: - bool threaded; - QMultiMap persistentPlayers; - mutable QReadWriteLock persistentPlayersLock; - int nextLocalGameId; - QMutex nextLocalGameIdMutex; -protected slots: - void externalUserJoined(const ServerInfo_User &userInfo); - void externalUserLeft(const QString &userName); - void externalRoomUserJoined(int roomId, const ServerInfo_User &userInfo); - void externalRoomUserLeft(int roomId, const QString &userName); - void externalRoomSay(int roomId, const QString &userName, const QString &message); - void externalRoomGameListChanged(int roomId, const ServerInfo_Game &gameInfo); - void externalJoinGameCommandReceived(const Command_JoinGame &cmd, int cmdId, int roomId, int serverId, qint64 sessionId); - void externalGameCommandContainerReceived(const CommandContainer &cont, int playerId, int serverId, qint64 sessionId); - void externalGameEventContainerReceived(const GameEventContainer &cont, qint64 sessionId); - void externalResponseReceived(const Response &resp, qint64 sessionId); - - virtual void doSendIslMessage(const IslMessage &msg, int serverId) { } + bool threaded; + QMultiMap persistentPlayers; + mutable QReadWriteLock persistentPlayersLock; + int nextLocalGameId; + QMutex nextLocalGameIdMutex; +protected slots: + void externalUserJoined(const ServerInfo_User &userInfo); + void externalUserLeft(const QString &userName); + void externalRoomUserJoined(int roomId, const ServerInfo_User &userInfo); + void externalRoomUserLeft(int roomId, const QString &userName); + void externalRoomSay(int roomId, const QString &userName, const QString &message); + void externalRoomGameListChanged(int roomId, const ServerInfo_Game &gameInfo); + void externalJoinGameCommandReceived(const Command_JoinGame &cmd, int cmdId, int roomId, int serverId, qint64 sessionId); + void externalGameCommandContainerReceived(const CommandContainer &cont, int playerId, int serverId, qint64 sessionId); + void externalGameEventContainerReceived(const GameEventContainer &cont, qint64 sessionId); + void externalResponseReceived(const Response &resp, qint64 sessionId); + + virtual void doSendIslMessage(const IslMessage &msg, int serverId) { } protected: - void prepareDestroy(); - void setDatabaseInterface(Server_DatabaseInterface *_databaseInterface); - QList clients; - QMap usersBySessionId; - QMap users; - QMap externalUsersBySessionId; - QMap externalUsers; - QMap rooms; - QMap databaseInterfaces; - - int getUsersCount() const; - int getGamesCount() const; - void addRoom(Server_Room *newRoom); + void prepareDestroy(); + void setDatabaseInterface(Server_DatabaseInterface *_databaseInterface); + QList clients; + QMap usersBySessionId; + QMap users; + QMap externalUsersBySessionId; + QMap externalUsers; + QMap rooms; + QMap databaseInterfaces; + + int getUsersCount() const; + int getGamesCount() const; + void addRoom(Server_Room *newRoom); }; #endif diff --git a/common/server_abstractuserinterface.cpp b/common/server_abstractuserinterface.cpp index ea4b0f6b..d00c5034 100644 --- a/common/server_abstractuserinterface.cpp +++ b/common/server_abstractuserinterface.cpp @@ -15,82 +15,82 @@ void Server_AbstractUserInterface::sendProtocolItemByType(ServerMessage::MessageType type, const ::google::protobuf::Message &item) { - switch (type) { - case ServerMessage::RESPONSE: sendProtocolItem(static_cast(item)); break; - case ServerMessage::SESSION_EVENT: sendProtocolItem(static_cast(item)); break; - case ServerMessage::GAME_EVENT_CONTAINER: sendProtocolItem(static_cast(item)); break; - case ServerMessage::ROOM_EVENT: sendProtocolItem(static_cast(item)); break; - } + switch (type) { + case ServerMessage::RESPONSE: sendProtocolItem(static_cast(item)); break; + case ServerMessage::SESSION_EVENT: sendProtocolItem(static_cast(item)); break; + case ServerMessage::GAME_EVENT_CONTAINER: sendProtocolItem(static_cast(item)); break; + case ServerMessage::ROOM_EVENT: sendProtocolItem(static_cast(item)); break; + } } SessionEvent *Server_AbstractUserInterface::prepareSessionEvent(const ::google::protobuf::Message &sessionEvent) { - SessionEvent *event = new SessionEvent; - event->GetReflection()->MutableMessage(event, sessionEvent.GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(sessionEvent); - return event; + SessionEvent *event = new SessionEvent; + event->GetReflection()->MutableMessage(event, sessionEvent.GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(sessionEvent); + return event; } void Server_AbstractUserInterface::sendResponseContainer(const ResponseContainer &responseContainer, Response::ResponseCode responseCode) { - const QList > &preResponseQueue = responseContainer.getPreResponseQueue(); - for (int i = 0; i < preResponseQueue.size(); ++i) - sendProtocolItemByType(preResponseQueue[i].first, *preResponseQueue[i].second); - - if (responseCode != Response::RespNothing) { - Response response; - response.set_cmd_id(responseContainer.getCmdId()); - response.set_response_code(responseCode); - ::google::protobuf::Message *responseExtension = responseContainer.getResponseExtension(); - if (responseExtension) - response.GetReflection()->MutableMessage(&response, responseExtension->GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(*responseExtension); - sendProtocolItem(response); - } - - const QList > &postResponseQueue = responseContainer.getPostResponseQueue(); - for (int i = 0; i < postResponseQueue.size(); ++i) - sendProtocolItemByType(postResponseQueue[i].first, *postResponseQueue[i].second); + const QList > &preResponseQueue = responseContainer.getPreResponseQueue(); + for (int i = 0; i < preResponseQueue.size(); ++i) + sendProtocolItemByType(preResponseQueue[i].first, *preResponseQueue[i].second); + + if (responseCode != Response::RespNothing) { + Response response; + response.set_cmd_id(responseContainer.getCmdId()); + response.set_response_code(responseCode); + ::google::protobuf::Message *responseExtension = responseContainer.getResponseExtension(); + if (responseExtension) + response.GetReflection()->MutableMessage(&response, responseExtension->GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(*responseExtension); + sendProtocolItem(response); + } + + const QList > &postResponseQueue = responseContainer.getPostResponseQueue(); + for (int i = 0; i < postResponseQueue.size(); ++i) + sendProtocolItemByType(postResponseQueue[i].first, *postResponseQueue[i].second); } void Server_AbstractUserInterface::playerRemovedFromGame(Server_Game *game) { - qDebug() << "Server_AbstractUserInterface::playerRemovedFromGame(): gameId =" << game->getGameId(); - - QMutexLocker locker(&gameListMutex); - games.remove(game->getGameId()); + qDebug() << "Server_AbstractUserInterface::playerRemovedFromGame(): gameId =" << game->getGameId(); + + QMutexLocker locker(&gameListMutex); + games.remove(game->getGameId()); } void Server_AbstractUserInterface::playerAddedToGame(int gameId, int roomId, int playerId) { - qDebug() << "Server_AbstractUserInterface::playerAddedToGame(): gameId =" << gameId; - - QMutexLocker locker(&gameListMutex); - games.insert(gameId, QPair(roomId, playerId)); + qDebug() << "Server_AbstractUserInterface::playerAddedToGame(): gameId =" << gameId; + + QMutexLocker locker(&gameListMutex); + games.insert(gameId, QPair(roomId, playerId)); } void Server_AbstractUserInterface::joinPersistentGames(ResponseContainer &rc) { - QList gamesToJoin = server->getPersistentPlayerReferences(QString::fromStdString(userInfo->name())); - - server->roomsLock.lockForRead(); - for (int i = 0; i < gamesToJoin.size(); ++i) { - const PlayerReference &pr = gamesToJoin.at(i); - - Server_Room *room = server->getRooms().value(pr.getRoomId()); - if (!room) - continue; - QReadLocker roomGamesLocker(&room->gamesLock); - - Server_Game *game = room->getGames().value(pr.getGameId()); - if (!game) - continue; - QMutexLocker gameLocker(&game->gameMutex); - - Server_Player *player = game->getPlayers().value(pr.getPlayerId()); - - player->setUserInterface(this); - playerAddedToGame(game->getGameId(), room->getId(), player->getPlayerId()); - - game->createGameJoinedEvent(player, rc, true); - } - server->roomsLock.unlock(); + QList gamesToJoin = server->getPersistentPlayerReferences(QString::fromStdString(userInfo->name())); + + server->roomsLock.lockForRead(); + for (int i = 0; i < gamesToJoin.size(); ++i) { + const PlayerReference &pr = gamesToJoin.at(i); + + Server_Room *room = server->getRooms().value(pr.getRoomId()); + if (!room) + continue; + QReadLocker roomGamesLocker(&room->gamesLock); + + Server_Game *game = room->getGames().value(pr.getGameId()); + if (!game) + continue; + QMutexLocker gameLocker(&game->gameMutex); + + Server_Player *player = game->getPlayers().value(pr.getPlayerId()); + + player->setUserInterface(this); + playerAddedToGame(game->getGameId(), room->getId(), player->getPlayerId()); + + game->createGameJoinedEvent(player, rc, true); + } + server->roomsLock.unlock(); } diff --git a/common/server_abstractuserinterface.h b/common/server_abstractuserinterface.h index 485162e0..1253c0f4 100644 --- a/common/server_abstractuserinterface.h +++ b/common/server_abstractuserinterface.h @@ -18,31 +18,31 @@ class Server_Game; class Server_AbstractUserInterface : public ServerInfo_User_Container { private: - mutable QMutex gameListMutex; - QMap > games; // gameId -> (roomId, playerId) + mutable QMutex gameListMutex; + QMap > games; // gameId -> (roomId, playerId) protected: - Server *server; + Server *server; public: - Server_AbstractUserInterface(Server *_server) : server(_server) { } - Server_AbstractUserInterface(Server *_server, const ServerInfo_User_Container &other) : ServerInfo_User_Container(other), server(_server) { } - virtual ~Server_AbstractUserInterface() { } - - virtual int getLastCommandTime() const = 0; - - void playerRemovedFromGame(Server_Game *game); - void playerAddedToGame(int gameId, int roomId, int playerId); - void joinPersistentGames(ResponseContainer &rc); - - QMap > getGames() const { QMutexLocker locker(&gameListMutex); return games; } - - virtual void sendProtocolItem(const Response &item) = 0; - virtual void sendProtocolItem(const SessionEvent &item) = 0; - virtual void sendProtocolItem(const GameEventContainer &item) = 0; - virtual void sendProtocolItem(const RoomEvent &item) = 0; - void sendProtocolItemByType(ServerMessage::MessageType type, const ::google::protobuf::Message &item); - - static SessionEvent *prepareSessionEvent(const ::google::protobuf::Message &sessionEvent); - void sendResponseContainer(const ResponseContainer &responseContainer, Response::ResponseCode responseCode); + Server_AbstractUserInterface(Server *_server) : server(_server) { } + Server_AbstractUserInterface(Server *_server, const ServerInfo_User_Container &other) : ServerInfo_User_Container(other), server(_server) { } + virtual ~Server_AbstractUserInterface() { } + + virtual int getLastCommandTime() const = 0; + + void playerRemovedFromGame(Server_Game *game); + void playerAddedToGame(int gameId, int roomId, int playerId); + void joinPersistentGames(ResponseContainer &rc); + + QMap > getGames() const { QMutexLocker locker(&gameListMutex); return games; } + + virtual void sendProtocolItem(const Response &item) = 0; + virtual void sendProtocolItem(const SessionEvent &item) = 0; + virtual void sendProtocolItem(const GameEventContainer &item) = 0; + virtual void sendProtocolItem(const RoomEvent &item) = 0; + void sendProtocolItemByType(ServerMessage::MessageType type, const ::google::protobuf::Message &item); + + static SessionEvent *prepareSessionEvent(const ::google::protobuf::Message &sessionEvent); + void sendResponseContainer(const ResponseContainer &responseContainer, Response::ResponseCode responseCode); }; #endif diff --git a/common/server_arrow.cpp b/common/server_arrow.cpp index 9cbb2c38..a668cc25 100644 --- a/common/server_arrow.cpp +++ b/common/server_arrow.cpp @@ -14,17 +14,17 @@ Server_Arrow::Server_Arrow(int _id, Server_Card *_startCard, Server_ArrowTarget void Server_Arrow::getInfo(ServerInfo_Arrow *info) { - info->set_id(id); - info->set_start_player_id(startCard->getZone()->getPlayer()->getPlayerId()); - info->set_start_zone(startCard->getZone()->getName().toStdString()); - info->set_start_card_id(startCard->getId()); - info->mutable_arrow_color()->CopyFrom(arrowColor); + info->set_id(id); + info->set_start_player_id(startCard->getZone()->getPlayer()->getPlayerId()); + info->set_start_zone(startCard->getZone()->getName().toStdString()); + info->set_start_card_id(startCard->getId()); + info->mutable_arrow_color()->CopyFrom(arrowColor); - Server_Card *targetCard = qobject_cast(targetItem); - if (targetCard) { - info->set_target_player_id(targetCard->getZone()->getPlayer()->getPlayerId()); - info->set_target_zone(targetCard->getZone()->getName().toStdString()); - info->set_target_card_id(targetCard->getId()); - } else - info->set_target_player_id(static_cast(targetItem)->getPlayerId()); + Server_Card *targetCard = qobject_cast(targetItem); + if (targetCard) { + info->set_target_player_id(targetCard->getZone()->getPlayer()->getPlayerId()); + info->set_target_zone(targetCard->getZone()->getName().toStdString()); + info->set_target_card_id(targetCard->getId()); + } else + info->set_target_player_id(static_cast(targetItem)->getPlayerId()); } diff --git a/common/server_arrow.h b/common/server_arrow.h index 1d171ef3..01c472ef 100644 --- a/common/server_arrow.h +++ b/common/server_arrow.h @@ -9,18 +9,18 @@ class ServerInfo_Arrow; class Server_Arrow { private: - int id; - Server_Card *startCard; - Server_ArrowTarget *targetItem; - color arrowColor; + int id; + Server_Card *startCard; + Server_ArrowTarget *targetItem; + color arrowColor; public: - Server_Arrow(int _id, Server_Card *_startCard, Server_ArrowTarget *_targetItem, const color &_arrowColor); - int getId() const { return id; } - Server_Card *getStartCard() const { return startCard; } - Server_ArrowTarget *getTargetItem() const { return targetItem; } - const color &getColor() const { return arrowColor; } - - void getInfo(ServerInfo_Arrow *info); + Server_Arrow(int _id, Server_Card *_startCard, Server_ArrowTarget *_targetItem, const color &_arrowColor); + int getId() const { return id; } + Server_Card *getStartCard() const { return startCard; } + Server_ArrowTarget *getTargetItem() const { return targetItem; } + const color &getColor() const { return arrowColor; } + + void getInfo(ServerInfo_Arrow *info); }; #endif diff --git a/common/server_arrowtarget.cpp b/common/server_arrowtarget.cpp index aa7789dd..1b3385d5 100644 --- a/common/server_arrowtarget.cpp +++ b/common/server_arrowtarget.cpp @@ -1,2 +1,2 @@ -#include "server_arrowtarget.h" \ No newline at end of file +#include "server_arrowtarget.h" diff --git a/common/server_arrowtarget.h b/common/server_arrowtarget.h index f5783d5b..d94fc4b7 100644 --- a/common/server_arrowtarget.h +++ b/common/server_arrowtarget.h @@ -4,7 +4,7 @@ #include class Server_ArrowTarget : public QObject { - Q_OBJECT + Q_OBJECT }; #endif diff --git a/common/server_card.cpp b/common/server_card.cpp index 10c465b8..39e4aadc 100644 --- a/common/server_card.cpp +++ b/common/server_card.cpp @@ -23,138 +23,138 @@ #include "pb/serverinfo_card.pb.h" Server_Card::Server_Card(QString _name, int _id, int _coord_x, int _coord_y, Server_CardZone *_zone) - : zone(_zone), id(_id), coord_x(_coord_x), coord_y(_coord_y), name(_name), tapped(false), attacking(false), facedown(false), color(QString()), power(-1), toughness(-1), annotation(QString()), destroyOnZoneChange(false), doesntUntap(false), parentCard(0) + : zone(_zone), id(_id), coord_x(_coord_x), coord_y(_coord_y), name(_name), tapped(false), attacking(false), facedown(false), color(QString()), power(-1), toughness(-1), annotation(QString()), destroyOnZoneChange(false), doesntUntap(false), parentCard(0) { } Server_Card::~Server_Card() { - // setParentCard(0) leads to the item being removed from our list, so we can't iterate properly - while (!attachedCards.isEmpty()) - attachedCards.first()->setParentCard(0); - - if (parentCard) - parentCard->removeAttachedCard(this); + // setParentCard(0) leads to the item being removed from our list, so we can't iterate properly + while (!attachedCards.isEmpty()) + attachedCards.first()->setParentCard(0); + + if (parentCard) + parentCard->removeAttachedCard(this); } void Server_Card::resetState() { - counters.clear(); - setTapped(false); - setAttacking(false); - power = -1; - toughness = -1; - setAnnotation(QString()); - setDoesntUntap(false); + counters.clear(); + setTapped(false); + setAttacking(false); + power = -1; + toughness = -1; + setAnnotation(QString()); + setDoesntUntap(false); } QString Server_Card::setAttribute(CardAttribute attribute, const QString &avalue, bool allCards) { - switch (attribute) { - case AttrTapped: { - bool value = avalue == "1"; - if (!(!value && allCards && doesntUntap)) - setTapped(value); - break; - } - case AttrAttacking: setAttacking(avalue == "1"); break; - case AttrFaceDown: setFaceDown(avalue == "1"); break; - case AttrColor: setColor(avalue); break; - case AttrPT: setPT(avalue); return getPT(); - case AttrAnnotation: setAnnotation(avalue); break; - case AttrDoesntUntap: setDoesntUntap(avalue == "1"); break; - } - return avalue; + switch (attribute) { + case AttrTapped: { + bool value = avalue == "1"; + if (!(!value && allCards && doesntUntap)) + setTapped(value); + break; + } + case AttrAttacking: setAttacking(avalue == "1"); break; + case AttrFaceDown: setFaceDown(avalue == "1"); break; + case AttrColor: setColor(avalue); break; + case AttrPT: setPT(avalue); return getPT(); + case AttrAnnotation: setAnnotation(avalue); break; + case AttrDoesntUntap: setDoesntUntap(avalue == "1"); break; + } + return avalue; } void Server_Card::setCounter(int id, int value) { - if (value) - counters.insert(id, value); - else - counters.remove(id); + if (value) + counters.insert(id, value); + else + counters.remove(id); } void Server_Card::setPT(const QString &_pt) { - if (_pt.isEmpty()) { - power = 0; - toughness = -1; - } else { - int sep = _pt.indexOf('/'); - QString p1 = _pt.left(sep); - QString p2 = _pt.mid(sep + 1); - if (p1.isEmpty() || p2.isEmpty()) - return; - if ((p1[0] == '+') || (p2[0] == '+')) { - if (power < 0) - power = 0; - if (toughness < 0) - toughness = 0; - } - if (p1[0] == '+') - power += p1.mid(1).toInt(); - else - power = p1.toInt(); - if (p2[0] == '+') - toughness += p2.mid(1).toInt(); - else - toughness = p2.toInt(); - } + if (_pt.isEmpty()) { + power = 0; + toughness = -1; + } else { + int sep = _pt.indexOf('/'); + QString p1 = _pt.left(sep); + QString p2 = _pt.mid(sep + 1); + if (p1.isEmpty() || p2.isEmpty()) + return; + if ((p1[0] == '+') || (p2[0] == '+')) { + if (power < 0) + power = 0; + if (toughness < 0) + toughness = 0; + } + if (p1[0] == '+') + power += p1.mid(1).toInt(); + else + power = p1.toInt(); + if (p2[0] == '+') + toughness += p2.mid(1).toInt(); + else + toughness = p2.toInt(); + } } QString Server_Card::getPT() const { - if (toughness < 0) - return QString(""); - return QString::number(power) + "/" + QString::number(toughness); + if (toughness < 0) + return QString(""); + return QString::number(power) + "/" + QString::number(toughness); } void Server_Card::setParentCard(Server_Card *_parentCard) { - if (parentCard) - parentCard->removeAttachedCard(this); - parentCard = _parentCard; - if (parentCard) - parentCard->addAttachedCard(this); + if (parentCard) + parentCard->removeAttachedCard(this); + parentCard = _parentCard; + if (parentCard) + parentCard->addAttachedCard(this); } void Server_Card::getInfo(ServerInfo_Card *info) { - QString displayedName = facedown ? QString() : name; - - info->set_id(id); - info->set_name(displayedName.toStdString()); - info->set_x(coord_x); - info->set_y(coord_y); - if (facedown) - info->set_face_down(true); - info->set_tapped(tapped); - if (attacking) - info->set_attacking(true); - if (!color.isEmpty()) - info->set_color(color.toStdString()); - const QString ptStr = getPT(); - if (!ptStr.isEmpty()) - info->set_pt(ptStr.toStdString()); - if (!annotation.isEmpty()) - info->set_annotation(annotation.toStdString()); - if (destroyOnZoneChange) - info->set_destroy_on_zone_change(true); - if (doesntUntap) - info->set_doesnt_untap(true); - - QMapIterator cardCounterIterator(counters); - while (cardCounterIterator.hasNext()) { - cardCounterIterator.next(); - ServerInfo_CardCounter *counterInfo = info->add_counter_list(); - counterInfo->set_id(cardCounterIterator.key()); - counterInfo->set_value(cardCounterIterator.value()); - } + QString displayedName = facedown ? QString() : name; + + info->set_id(id); + info->set_name(displayedName.toStdString()); + info->set_x(coord_x); + info->set_y(coord_y); + if (facedown) + info->set_face_down(true); + info->set_tapped(tapped); + if (attacking) + info->set_attacking(true); + if (!color.isEmpty()) + info->set_color(color.toStdString()); + const QString ptStr = getPT(); + if (!ptStr.isEmpty()) + info->set_pt(ptStr.toStdString()); + if (!annotation.isEmpty()) + info->set_annotation(annotation.toStdString()); + if (destroyOnZoneChange) + info->set_destroy_on_zone_change(true); + if (doesntUntap) + info->set_doesnt_untap(true); + + QMapIterator cardCounterIterator(counters); + while (cardCounterIterator.hasNext()) { + cardCounterIterator.next(); + ServerInfo_CardCounter *counterInfo = info->add_counter_list(); + counterInfo->set_id(cardCounterIterator.key()); + counterInfo->set_value(cardCounterIterator.value()); + } - if (parentCard) { - info->set_attach_player_id(parentCard->getZone()->getPlayer()->getPlayerId()); - info->set_attach_zone(parentCard->getZone()->getName().toStdString()); - info->set_attach_card_id(parentCard->getId()); - } + if (parentCard) { + info->set_attach_player_id(parentCard->getZone()->getPlayer()->getPlayerId()); + info->set_attach_zone(parentCard->getZone()->getName().toStdString()); + info->set_attach_card_id(parentCard->getId()); + } } diff --git a/common/server_card.h b/common/server_card.h index 2af8aa6d..e3c76f05 100644 --- a/common/server_card.h +++ b/common/server_card.h @@ -29,68 +29,68 @@ class Server_CardZone; class ServerInfo_Card; class Server_Card : public Server_ArrowTarget { - Q_OBJECT + Q_OBJECT private: - Server_CardZone *zone; - int id; - int coord_x, coord_y; - QString name; - QMap counters; - bool tapped; - bool attacking; - bool facedown; - QString color; - int power, toughness; - QString annotation; - bool destroyOnZoneChange; - bool doesntUntap; - - Server_Card *parentCard; - QList attachedCards; + Server_CardZone *zone; + int id; + int coord_x, coord_y; + QString name; + QMap counters; + bool tapped; + bool attacking; + bool facedown; + QString color; + int power, toughness; + QString annotation; + bool destroyOnZoneChange; + bool doesntUntap; + + Server_Card *parentCard; + QList attachedCards; public: - Server_Card(QString _name, int _id, int _coord_x, int _coord_y, Server_CardZone *_zone = 0); - ~Server_Card(); - - Server_CardZone *getZone() const { return zone; } - void setZone(Server_CardZone *_zone) { zone = _zone; } - - int getId() const { return id; } - int getX() const { return coord_x; } - int getY() const { return coord_y; } - QString getName() const { return name; } - const QMap &getCounters() const { return counters; } - int getCounter(int id) const { return counters.value(id, 0); } - bool getTapped() const { return tapped; } - bool getAttacking() const { return attacking; } - bool getFaceDown() const { return facedown; } - QString getColor() const { return color; } - QString getPT() const; - QString getAnnotation() const { return annotation; } - bool getDoesntUntap() const { return doesntUntap; } - bool getDestroyOnZoneChange() const { return destroyOnZoneChange; } - Server_Card *getParentCard() const { return parentCard; } - const QList &getAttachedCards() const { return attachedCards; } + Server_Card(QString _name, int _id, int _coord_x, int _coord_y, Server_CardZone *_zone = 0); + ~Server_Card(); + + Server_CardZone *getZone() const { return zone; } + void setZone(Server_CardZone *_zone) { zone = _zone; } + + int getId() const { return id; } + int getX() const { return coord_x; } + int getY() const { return coord_y; } + QString getName() const { return name; } + const QMap &getCounters() const { return counters; } + int getCounter(int id) const { return counters.value(id, 0); } + bool getTapped() const { return tapped; } + bool getAttacking() const { return attacking; } + bool getFaceDown() const { return facedown; } + QString getColor() const { return color; } + QString getPT() const; + QString getAnnotation() const { return annotation; } + bool getDoesntUntap() const { return doesntUntap; } + bool getDestroyOnZoneChange() const { return destroyOnZoneChange; } + Server_Card *getParentCard() const { return parentCard; } + const QList &getAttachedCards() const { return attachedCards; } - void setId(int _id) { id = _id; } - void setCoords(int x, int y) { coord_x = x; coord_y = y; } - void setName(const QString &_name) { name = _name; } - void setCounter(int id, int value); - void setTapped(bool _tapped) { tapped = _tapped; } - void setAttacking(bool _attacking) { attacking = _attacking; } - void setFaceDown(bool _facedown) { facedown = _facedown; } - void setColor(const QString &_color) { color = _color; } - void setPT(const QString &_pt); - void setAnnotation(const QString &_annotation) { annotation = _annotation; } - void setDestroyOnZoneChange(bool _destroy) { destroyOnZoneChange = _destroy; } - void setDoesntUntap(bool _doesntUntap) { doesntUntap = _doesntUntap; } - void setParentCard(Server_Card *_parentCard); - void addAttachedCard(Server_Card *card) { attachedCards.append(card); } - void removeAttachedCard(Server_Card *card) { attachedCards.removeAt(attachedCards.indexOf(card)); } - - void resetState(); - QString setAttribute(CardAttribute attribute, const QString &avalue, bool allCards); - - void getInfo(ServerInfo_Card *info); + void setId(int _id) { id = _id; } + void setCoords(int x, int y) { coord_x = x; coord_y = y; } + void setName(const QString &_name) { name = _name; } + void setCounter(int id, int value); + void setTapped(bool _tapped) { tapped = _tapped; } + void setAttacking(bool _attacking) { attacking = _attacking; } + void setFaceDown(bool _facedown) { facedown = _facedown; } + void setColor(const QString &_color) { color = _color; } + void setPT(const QString &_pt); + void setAnnotation(const QString &_annotation) { annotation = _annotation; } + void setDestroyOnZoneChange(bool _destroy) { destroyOnZoneChange = _destroy; } + void setDoesntUntap(bool _doesntUntap) { doesntUntap = _doesntUntap; } + void setParentCard(Server_Card *_parentCard); + void addAttachedCard(Server_Card *card) { attachedCards.append(card); } + void removeAttachedCard(Server_Card *card) { attachedCards.removeAt(attachedCards.indexOf(card)); } + + void resetState(); + QString setAttribute(CardAttribute attribute, const QString &avalue, bool allCards); + + void getInfo(ServerInfo_Card *info); }; #endif diff --git a/common/server_cardzone.h b/common/server_cardzone.h index 1eeb9008..a00b367a 100644 --- a/common/server_cardzone.h +++ b/common/server_cardzone.h @@ -33,48 +33,48 @@ class GameEventStorage; class Server_CardZone { private: - Server_Player *player; - QString name; - bool has_coords; - ServerInfo_Zone::ZoneType type; - int cardsBeingLookedAt; - QSet playersWithWritePermission; - bool alwaysRevealTopCard; - QList cards; - QMap > coordinateMap; // y -> (x -> card) - QMap > freePilesMap; // y -> (cardName -> x) - QMap freeSpaceMap; // y -> x - void removeCardFromCoordMap(Server_Card *card, int oldX, int oldY); - void insertCardIntoCoordMap(Server_Card *card, int x, int y); + Server_Player *player; + QString name; + bool has_coords; + ServerInfo_Zone::ZoneType type; + int cardsBeingLookedAt; + QSet playersWithWritePermission; + bool alwaysRevealTopCard; + QList cards; + QMap > coordinateMap; // y -> (x -> card) + QMap > freePilesMap; // y -> (cardName -> x) + QMap freeSpaceMap; // y -> x + void removeCardFromCoordMap(Server_Card *card, int oldX, int oldY); + void insertCardIntoCoordMap(Server_Card *card, int x, int y); public: - Server_CardZone(Server_Player *_player, const QString &_name, bool _has_coords, ServerInfo_Zone::ZoneType _type); - ~Server_CardZone(); - - const QList &getCards() const { return cards; } - int removeCard(Server_Card *card); - Server_Card *getCard(int id, int *position = NULL, bool remove = false); + Server_CardZone(Server_Player *_player, const QString &_name, bool _has_coords, ServerInfo_Zone::ZoneType _type); + ~Server_CardZone(); + + const QList &getCards() const { return cards; } + int removeCard(Server_Card *card); + Server_Card *getCard(int id, int *position = NULL, bool remove = false); - int getCardsBeingLookedAt() const { return cardsBeingLookedAt; } - void setCardsBeingLookedAt(int _cardsBeingLookedAt) { cardsBeingLookedAt = _cardsBeingLookedAt; } - bool hasCoords() const { return has_coords; } - ServerInfo_Zone::ZoneType getType() const { return type; } - QString getName() const { return name; } - Server_Player *getPlayer() const { return player; } - void getInfo(ServerInfo_Zone *info, Server_Player *playerWhosAsking, bool omniscient); - - int getFreeGridColumn(int x, int y, const QString &cardName) const; - bool isColumnEmpty(int x, int y) const; - bool isColumnStacked(int x, int y) const; - void fixFreeSpaces(GameEventStorage &ges); - void moveCardInRow(GameEventStorage &ges, Server_Card *card, int x, int y); - void insertCard(Server_Card *card, int x, int y); - void updateCardCoordinates(Server_Card *card, int oldX, int oldY); - void shuffle(); - void clear(); - void addWritePermission(int playerId); - const QSet &getPlayersWithWritePermission() const { return playersWithWritePermission; } - bool getAlwaysRevealTopCard() const { return alwaysRevealTopCard; } - void setAlwaysRevealTopCard(bool _alwaysRevealTopCard) { alwaysRevealTopCard = _alwaysRevealTopCard; } + int getCardsBeingLookedAt() const { return cardsBeingLookedAt; } + void setCardsBeingLookedAt(int _cardsBeingLookedAt) { cardsBeingLookedAt = _cardsBeingLookedAt; } + bool hasCoords() const { return has_coords; } + ServerInfo_Zone::ZoneType getType() const { return type; } + QString getName() const { return name; } + Server_Player *getPlayer() const { return player; } + void getInfo(ServerInfo_Zone *info, Server_Player *playerWhosAsking, bool omniscient); + + int getFreeGridColumn(int x, int y, const QString &cardName) const; + bool isColumnEmpty(int x, int y) const; + bool isColumnStacked(int x, int y) const; + void fixFreeSpaces(GameEventStorage &ges); + void moveCardInRow(GameEventStorage &ges, Server_Card *card, int x, int y); + void insertCard(Server_Card *card, int x, int y); + void updateCardCoordinates(Server_Card *card, int oldX, int oldY); + void shuffle(); + void clear(); + void addWritePermission(int playerId); + const QSet &getPlayersWithWritePermission() const { return playersWithWritePermission; } + bool getAlwaysRevealTopCard() const { return alwaysRevealTopCard; } + void setAlwaysRevealTopCard(bool _alwaysRevealTopCard) { alwaysRevealTopCard = _alwaysRevealTopCard; } }; #endif diff --git a/common/server_counter.cpp b/common/server_counter.cpp index 2e0ffde8..df8dcd03 100644 --- a/common/server_counter.cpp +++ b/common/server_counter.cpp @@ -12,9 +12,9 @@ Server_Counter::Server_Counter(int _id, const QString &_name, const color &_coun void Server_Counter::getInfo(ServerInfo_Counter *info) { - info->set_id(id); - info->set_name(name.toStdString()); - info->mutable_counter_color()->CopyFrom(counterColor); - info->set_radius(radius); - info->set_count(count); + info->set_id(id); + info->set_name(name.toStdString()); + info->mutable_counter_color()->CopyFrom(counterColor); + info->set_radius(radius); + info->set_count(count); } diff --git a/common/server_counter.h b/common/server_counter.h index 42483b9d..60b70e69 100644 --- a/common/server_counter.h +++ b/common/server_counter.h @@ -27,22 +27,22 @@ class ServerInfo_Counter; class Server_Counter { protected: - int id; - QString name; - color counterColor; - int radius; - int count; + int id; + QString name; + color counterColor; + int radius; + int count; public: - Server_Counter(int _id, const QString &_name, const color &_counterColor, int _radius, int _count = 0); - ~Server_Counter() { } - int getId() const { return id; } - QString getName() const { return name; } - const color &getColor() const { return counterColor; } - int getRadius() const { return radius; } - int getCount() const { return count; } - void setCount(int _count) { count = _count; } - - void getInfo(ServerInfo_Counter *info); + Server_Counter(int _id, const QString &_name, const color &_counterColor, int _radius, int _count = 0); + ~Server_Counter() { } + int getId() const { return id; } + QString getName() const { return name; } + const color &getColor() const { return counterColor; } + int getRadius() const { return radius; } + int getCount() const { return count; } + void setCount(int _count) { count = _count; } + + void getInfo(ServerInfo_Counter *info); }; #endif diff --git a/common/server_database_interface.h b/common/server_database_interface.h index 10ce082a..df75cd63 100644 --- a/common/server_database_interface.h +++ b/common/server_database_interface.h @@ -6,32 +6,32 @@ #include "server.h" class Server_DatabaseInterface : public QObject { - Q_OBJECT + Q_OBJECT public: - Server_DatabaseInterface(QObject *parent = 0) - : QObject(parent) { } - - virtual AuthenticationResult checkUserPassword(Server_ProtocolHandler *handler, const QString &user, const QString &password, QString &reasonStr, int &secondsLeft) = 0; - virtual bool userExists(const QString &user) { return false; } - virtual QMap getBuddyList(const QString &name) { return QMap(); } - virtual QMap getIgnoreList(const QString &name) { return QMap(); } - virtual bool isInBuddyList(const QString &whoseList, const QString &who) { return false; } - virtual bool isInIgnoreList(const QString &whoseList, const QString &who) { return false; } - virtual ServerInfo_User getUserData(const QString &name, bool withId = false) = 0; - virtual void storeGameInformation(const QString &roomName, const QStringList &roomGameTypes, const ServerInfo_Game &gameInfo, const QSet &allPlayersEver, const QSet &allSpectatorsEver, const QList &replayList) { } - virtual DeckList *getDeckFromDatabase(int deckId, int userId) { return 0; } - - virtual qint64 startSession(const QString &userName, const QString &address) { return 0; } + Server_DatabaseInterface(QObject *parent = 0) + : QObject(parent) { } + + virtual AuthenticationResult checkUserPassword(Server_ProtocolHandler *handler, const QString &user, const QString &password, QString &reasonStr, int &secondsLeft) = 0; + virtual bool userExists(const QString &user) { return false; } + virtual QMap getBuddyList(const QString &name) { return QMap(); } + virtual QMap getIgnoreList(const QString &name) { return QMap(); } + virtual bool isInBuddyList(const QString &whoseList, const QString &who) { return false; } + virtual bool isInIgnoreList(const QString &whoseList, const QString &who) { return false; } + virtual ServerInfo_User getUserData(const QString &name, bool withId = false) = 0; + virtual void storeGameInformation(const QString &roomName, const QStringList &roomGameTypes, const ServerInfo_Game &gameInfo, const QSet &allPlayersEver, const QSet &allSpectatorsEver, const QList &replayList) { } + virtual DeckList *getDeckFromDatabase(int deckId, int userId) { return 0; } + + virtual qint64 startSession(const QString &userName, const QString &address) { return 0; } public slots: - virtual void endSession(qint64 sessionId) { } + virtual void endSession(qint64 sessionId) { } public: - virtual int getNextGameId() = 0; - virtual int getNextReplayId() = 0; - - virtual void clearSessionTables() { } - virtual void lockSessionTables() { } - virtual void unlockSessionTables() { } - virtual bool userSessionExists(const QString &userName) { return false; } + virtual int getNextGameId() = 0; + virtual int getNextReplayId() = 0; + + virtual void clearSessionTables() { } + virtual void lockSessionTables() { } + virtual void unlockSessionTables() { } + virtual bool userSessionExists(const QString &userName) { return false; } }; #endif diff --git a/common/server_game.cpp b/common/server_game.cpp index 94eb03ae..647aa22e 100644 --- a/common/server_game.cpp +++ b/common/server_game.cpp @@ -48,7 +48,7 @@ #include Server_Game::Server_Game(const ServerInfo_User &_creatorInfo, int _gameId, const QString &_description, const QString &_password, int _maxPlayers, const QList &_gameTypes, bool _onlyBuddies, bool _onlyRegistered, bool _spectatorsAllowed, bool _spectatorsNeedPassword, bool _spectatorsCanTalk, bool _spectatorsSeeEverything, Server_Room *_room) - : QObject(), + : QObject(), room(_room), nextPlayerId(0), hostId(0), @@ -75,667 +75,667 @@ Server_Game::Server_Game(const ServerInfo_User &_creatorInfo, int _gameId, const startTime(QDateTime::currentDateTime()), gameMutex(QMutex::Recursive) { - currentReplay = new GameReplay; - currentReplay->set_replay_id(room->getServer()->getDatabaseInterface()->getNextReplayId()); - - connect(this, SIGNAL(sigStartGameIfReady()), this, SLOT(doStartGameIfReady()), Qt::QueuedConnection); - - getInfo(*currentReplay->mutable_game_info()); + currentReplay = new GameReplay; + currentReplay->set_replay_id(room->getServer()->getDatabaseInterface()->getNextReplayId()); + + connect(this, SIGNAL(sigStartGameIfReady()), this, SLOT(doStartGameIfReady()), Qt::QueuedConnection); + + getInfo(*currentReplay->mutable_game_info()); - if (room->getServer()->getGameShouldPing()) { - pingClock = new QTimer(this); - connect(pingClock, SIGNAL(timeout()), this, SLOT(pingClockTimeout())); - pingClock->start(1000); - } + if (room->getServer()->getGameShouldPing()) { + pingClock = new QTimer(this); + connect(pingClock, SIGNAL(timeout()), this, SLOT(pingClockTimeout())); + pingClock->start(1000); + } } Server_Game::~Server_Game() { - room->gamesLock.lockForWrite(); - gameMutex.lock(); - - gameClosed = true; - sendGameEventContainer(prepareGameEvent(Event_GameClosed(), -1)); - - QMapIterator playerIterator(players); - while (playerIterator.hasNext()) - playerIterator.next().value()->prepareDestroy(); - players.clear(); - - room->removeGame(this); - delete creatorInfo; - creatorInfo = 0; - - gameMutex.unlock(); - room->gamesLock.unlock(); - - currentReplay->set_duration_seconds(secondsElapsed - startTimeOfThisGame); - replayList.append(currentReplay); - storeGameInformation(); - - for (int i = 0; i < replayList.size(); ++i) - delete replayList[i]; - - qDebug() << "Server_Game destructor: gameId=" << gameId; + room->gamesLock.lockForWrite(); + gameMutex.lock(); + + gameClosed = true; + sendGameEventContainer(prepareGameEvent(Event_GameClosed(), -1)); + + QMapIterator playerIterator(players); + while (playerIterator.hasNext()) + playerIterator.next().value()->prepareDestroy(); + players.clear(); + + room->removeGame(this); + delete creatorInfo; + creatorInfo = 0; + + gameMutex.unlock(); + room->gamesLock.unlock(); + + currentReplay->set_duration_seconds(secondsElapsed - startTimeOfThisGame); + replayList.append(currentReplay); + storeGameInformation(); + + for (int i = 0; i < replayList.size(); ++i) + delete replayList[i]; + + qDebug() << "Server_Game destructor: gameId=" << gameId; } void Server_Game::storeGameInformation() { - const ServerInfo_Game &gameInfo = replayList.first()->game_info(); - - Event_ReplayAdded replayEvent; - ServerInfo_ReplayMatch *replayMatchInfo = replayEvent.mutable_match_info(); - replayMatchInfo->set_game_id(gameInfo.game_id()); - replayMatchInfo->set_room_name(room->getName().toStdString()); - replayMatchInfo->set_time_started(QDateTime::currentDateTime().addSecs(-secondsElapsed).toTime_t()); - replayMatchInfo->set_length(secondsElapsed); - replayMatchInfo->set_game_name(gameInfo.description()); - - const QStringList &allGameTypes = room->getGameTypes(); - QStringList gameTypes; - for (int i = gameInfo.game_types_size() - 1; i >= 0; --i) - gameTypes.append(allGameTypes[gameInfo.game_types(i)]); - - QSetIterator playerIterator(allPlayersEver); - while (playerIterator.hasNext()) - replayMatchInfo->add_player_names(playerIterator.next().toStdString()); - - for (int i = 0; i < replayList.size(); ++i) { - ServerInfo_Replay *replayInfo = replayMatchInfo->add_replay_list(); - replayInfo->set_replay_id(replayList[i]->replay_id()); - replayInfo->set_replay_name(gameInfo.description()); - replayInfo->set_duration(replayList[i]->duration_seconds()); - } - - QSet allUsersInGame = allPlayersEver + allSpectatorsEver; - QSetIterator allUsersIterator(allUsersInGame); - - SessionEvent *sessionEvent = Server_ProtocolHandler::prepareSessionEvent(replayEvent); - Server *server = room->getServer(); - server->clientsLock.lockForRead(); - while (allUsersIterator.hasNext()) { - Server_AbstractUserInterface *userHandler = server->findUser(allUsersIterator.next()); - if (userHandler) - userHandler->sendProtocolItem(*sessionEvent); - } - server->clientsLock.unlock(); - delete sessionEvent; - - server->getDatabaseInterface()->storeGameInformation(room->getName(), gameTypes, gameInfo, allPlayersEver, allSpectatorsEver, replayList); + const ServerInfo_Game &gameInfo = replayList.first()->game_info(); + + Event_ReplayAdded replayEvent; + ServerInfo_ReplayMatch *replayMatchInfo = replayEvent.mutable_match_info(); + replayMatchInfo->set_game_id(gameInfo.game_id()); + replayMatchInfo->set_room_name(room->getName().toStdString()); + replayMatchInfo->set_time_started(QDateTime::currentDateTime().addSecs(-secondsElapsed).toTime_t()); + replayMatchInfo->set_length(secondsElapsed); + replayMatchInfo->set_game_name(gameInfo.description()); + + const QStringList &allGameTypes = room->getGameTypes(); + QStringList gameTypes; + for (int i = gameInfo.game_types_size() - 1; i >= 0; --i) + gameTypes.append(allGameTypes[gameInfo.game_types(i)]); + + QSetIterator playerIterator(allPlayersEver); + while (playerIterator.hasNext()) + replayMatchInfo->add_player_names(playerIterator.next().toStdString()); + + for (int i = 0; i < replayList.size(); ++i) { + ServerInfo_Replay *replayInfo = replayMatchInfo->add_replay_list(); + replayInfo->set_replay_id(replayList[i]->replay_id()); + replayInfo->set_replay_name(gameInfo.description()); + replayInfo->set_duration(replayList[i]->duration_seconds()); + } + + QSet allUsersInGame = allPlayersEver + allSpectatorsEver; + QSetIterator allUsersIterator(allUsersInGame); + + SessionEvent *sessionEvent = Server_ProtocolHandler::prepareSessionEvent(replayEvent); + Server *server = room->getServer(); + server->clientsLock.lockForRead(); + while (allUsersIterator.hasNext()) { + Server_AbstractUserInterface *userHandler = server->findUser(allUsersIterator.next()); + if (userHandler) + userHandler->sendProtocolItem(*sessionEvent); + } + server->clientsLock.unlock(); + delete sessionEvent; + + server->getDatabaseInterface()->storeGameInformation(room->getName(), gameTypes, gameInfo, allPlayersEver, allSpectatorsEver, replayList); } void Server_Game::pingClockTimeout() { - QMutexLocker locker(&gameMutex); - ++secondsElapsed; - - GameEventStorage ges; - ges.setGameEventContext(Context_PingChanged()); - - QList pingList; - QMapIterator playerIterator(players); - bool allPlayersInactive = true; - int playerCount = 0; - while (playerIterator.hasNext()) { - Server_Player *player = playerIterator.next().value(); - if (!player->getSpectator()) - ++playerCount; - - const int oldPingTime = player->getPingTime(); - player->playerMutex.lock(); - int newPingTime; - if (player->getUserInterface()) - newPingTime = player->getUserInterface()->getLastCommandTime(); - else - newPingTime = -1; - player->playerMutex.unlock(); - - if ((newPingTime != -1) && !player->getSpectator()) - allPlayersInactive = false; - - if ((abs(oldPingTime - newPingTime) > 1) || ((newPingTime == -1) && (oldPingTime != -1)) || ((newPingTime != -1) && (oldPingTime == -1))) { - player->setPingTime(newPingTime); - - Event_PlayerPropertiesChanged event; - event.mutable_player_properties()->set_ping_seconds(newPingTime); - ges.enqueueGameEvent(event, player->getPlayerId()); - } - } - ges.sendToGame(this); - - const int maxTime = room->getServer()->getMaxGameInactivityTime(); - if (allPlayersInactive) { - if (((++inactivityCounter >= maxTime) && (maxTime > 0)) || (playerCount < maxPlayers)) - deleteLater(); - } else - inactivityCounter = 0; + QMutexLocker locker(&gameMutex); + ++secondsElapsed; + + GameEventStorage ges; + ges.setGameEventContext(Context_PingChanged()); + + QList pingList; + QMapIterator playerIterator(players); + bool allPlayersInactive = true; + int playerCount = 0; + while (playerIterator.hasNext()) { + Server_Player *player = playerIterator.next().value(); + if (!player->getSpectator()) + ++playerCount; + + const int oldPingTime = player->getPingTime(); + player->playerMutex.lock(); + int newPingTime; + if (player->getUserInterface()) + newPingTime = player->getUserInterface()->getLastCommandTime(); + else + newPingTime = -1; + player->playerMutex.unlock(); + + if ((newPingTime != -1) && !player->getSpectator()) + allPlayersInactive = false; + + if ((abs(oldPingTime - newPingTime) > 1) || ((newPingTime == -1) && (oldPingTime != -1)) || ((newPingTime != -1) && (oldPingTime == -1))) { + player->setPingTime(newPingTime); + + Event_PlayerPropertiesChanged event; + event.mutable_player_properties()->set_ping_seconds(newPingTime); + ges.enqueueGameEvent(event, player->getPlayerId()); + } + } + ges.sendToGame(this); + + const int maxTime = room->getServer()->getMaxGameInactivityTime(); + if (allPlayersInactive) { + if (((++inactivityCounter >= maxTime) && (maxTime > 0)) || (playerCount < maxPlayers)) + deleteLater(); + } else + inactivityCounter = 0; } int Server_Game::getPlayerCount() const { - QMutexLocker locker(&gameMutex); - - QMapIterator playerIterator(players); - int result = 0; - while (playerIterator.hasNext()) - if (!playerIterator.next().value()->getSpectator()) - ++result; - return result; + QMutexLocker locker(&gameMutex); + + QMapIterator playerIterator(players); + int result = 0; + while (playerIterator.hasNext()) + if (!playerIterator.next().value()->getSpectator()) + ++result; + return result; } int Server_Game::getSpectatorCount() const { - QMutexLocker locker(&gameMutex); - - QMapIterator playerIterator(players); - int result = 0; - while (playerIterator.hasNext()) - if (playerIterator.next().value()->getSpectator()) - ++result; - return result; + QMutexLocker locker(&gameMutex); + + QMapIterator playerIterator(players); + int result = 0; + while (playerIterator.hasNext()) + if (playerIterator.next().value()->getSpectator()) + ++result; + return result; } void Server_Game::createGameStateChangedEvent(Event_GameStateChanged *event, Server_Player *playerWhosAsking, bool omniscient, bool withUserInfo) { - event->set_seconds_elapsed(secondsElapsed); - if (gameStarted) { - event->set_game_started(true); - event->set_active_player_id(0); - event->set_active_phase(0); - } else - event->set_game_started(false); - - QMapIterator playerIterator(players); - while (playerIterator.hasNext()) - playerIterator.next().value()->getInfo(event->add_player_list(), playerWhosAsking, omniscient, withUserInfo); + event->set_seconds_elapsed(secondsElapsed); + if (gameStarted) { + event->set_game_started(true); + event->set_active_player_id(0); + event->set_active_phase(0); + } else + event->set_game_started(false); + + QMapIterator playerIterator(players); + while (playerIterator.hasNext()) + playerIterator.next().value()->getInfo(event->add_player_list(), playerWhosAsking, omniscient, withUserInfo); } void Server_Game::sendGameStateToPlayers() { - // game state information for replay and omniscient spectators - Event_GameStateChanged omniscientEvent; - createGameStateChangedEvent(&omniscientEvent, 0, true, false); - - GameEventContainer *replayCont = prepareGameEvent(omniscientEvent, -1); - replayCont->set_seconds_elapsed(secondsElapsed - startTimeOfThisGame); - replayCont->clear_game_id(); - currentReplay->add_event_list()->CopyFrom(*replayCont); - delete replayCont; - - // If spectators are not omniscient, we need an additional createGameStateChangedEvent call, otherwise we can use the data we used for the replay. - // All spectators are equal, so we don't need to make a createGameStateChangedEvent call for each one. - Event_GameStateChanged spectatorEvent; - if (spectatorsSeeEverything) - spectatorEvent = omniscientEvent; - else - createGameStateChangedEvent(&spectatorEvent, 0, false, false); - - // send game state info to clients according to their role in the game - QMapIterator playerIterator(players); - while (playerIterator.hasNext()) { - Server_Player *player = playerIterator.next().value(); - GameEventContainer *gec; - if (player->getSpectator()) - gec = prepareGameEvent(spectatorEvent, -1); - else { - Event_GameStateChanged event; - createGameStateChangedEvent(&event, player, false, false); - - gec = prepareGameEvent(event, -1); - } - player->sendGameEvent(*gec); - delete gec; - } + // game state information for replay and omniscient spectators + Event_GameStateChanged omniscientEvent; + createGameStateChangedEvent(&omniscientEvent, 0, true, false); + + GameEventContainer *replayCont = prepareGameEvent(omniscientEvent, -1); + replayCont->set_seconds_elapsed(secondsElapsed - startTimeOfThisGame); + replayCont->clear_game_id(); + currentReplay->add_event_list()->CopyFrom(*replayCont); + delete replayCont; + + // If spectators are not omniscient, we need an additional createGameStateChangedEvent call, otherwise we can use the data we used for the replay. + // All spectators are equal, so we don't need to make a createGameStateChangedEvent call for each one. + Event_GameStateChanged spectatorEvent; + if (spectatorsSeeEverything) + spectatorEvent = omniscientEvent; + else + createGameStateChangedEvent(&spectatorEvent, 0, false, false); + + // send game state info to clients according to their role in the game + QMapIterator playerIterator(players); + while (playerIterator.hasNext()) { + Server_Player *player = playerIterator.next().value(); + GameEventContainer *gec; + if (player->getSpectator()) + gec = prepareGameEvent(spectatorEvent, -1); + else { + Event_GameStateChanged event; + createGameStateChangedEvent(&event, player, false, false); + + gec = prepareGameEvent(event, -1); + } + player->sendGameEvent(*gec); + delete gec; + } } void Server_Game::doStartGameIfReady() { - Server_DatabaseInterface *databaseInterface = room->getServer()->getDatabaseInterface(); - QMutexLocker locker(&gameMutex); - - if (getPlayerCount() < maxPlayers) - return; - QMapIterator playerIterator(players); - while (playerIterator.hasNext()) { - Server_Player *p = playerIterator.next().value(); - if (!p->getReadyStart() && !p->getSpectator()) - return; - } - playerIterator.toFront(); - while (playerIterator.hasNext()) { - Server_Player *p = playerIterator.next().value(); - if (!p->getSpectator()) - p->setupZones(); - } + Server_DatabaseInterface *databaseInterface = room->getServer()->getDatabaseInterface(); + QMutexLocker locker(&gameMutex); + + if (getPlayerCount() < maxPlayers) + return; + QMapIterator playerIterator(players); + while (playerIterator.hasNext()) { + Server_Player *p = playerIterator.next().value(); + if (!p->getReadyStart() && !p->getSpectator()) + return; + } + playerIterator.toFront(); + while (playerIterator.hasNext()) { + Server_Player *p = playerIterator.next().value(); + if (!p->getSpectator()) + p->setupZones(); + } - gameStarted = true; - playerIterator.toFront(); - while (playerIterator.hasNext()) { - Server_Player *player = playerIterator.next().value(); - player->setConceded(false); - player->setReadyStart(false); - } - - if (firstGameStarted) { - currentReplay->set_duration_seconds(secondsElapsed - startTimeOfThisGame); - replayList.append(currentReplay); - currentReplay = new GameReplay; - currentReplay->set_replay_id(databaseInterface->getNextReplayId()); - ServerInfo_Game *gameInfo = currentReplay->mutable_game_info(); - getInfo(*gameInfo); - gameInfo->set_started(false); - - Event_GameStateChanged omniscientEvent; - createGameStateChangedEvent(&omniscientEvent, 0, true, true); - - GameEventContainer *replayCont = prepareGameEvent(omniscientEvent, -1); - replayCont->set_seconds_elapsed(0); - replayCont->clear_game_id(); - currentReplay->add_event_list()->CopyFrom(*replayCont); - delete replayCont; - - startTimeOfThisGame = secondsElapsed; - } else - firstGameStarted = true; - - sendGameStateToPlayers(); - - activePlayer = -1; - nextTurn(); - - locker.unlock(); - - ServerInfo_Game gameInfo; - gameInfo.set_room_id(room->getId()); - gameInfo.set_game_id(gameId); - gameInfo.set_started(true); - emit gameInfoChanged(gameInfo); + gameStarted = true; + playerIterator.toFront(); + while (playerIterator.hasNext()) { + Server_Player *player = playerIterator.next().value(); + player->setConceded(false); + player->setReadyStart(false); + } + + if (firstGameStarted) { + currentReplay->set_duration_seconds(secondsElapsed - startTimeOfThisGame); + replayList.append(currentReplay); + currentReplay = new GameReplay; + currentReplay->set_replay_id(databaseInterface->getNextReplayId()); + ServerInfo_Game *gameInfo = currentReplay->mutable_game_info(); + getInfo(*gameInfo); + gameInfo->set_started(false); + + Event_GameStateChanged omniscientEvent; + createGameStateChangedEvent(&omniscientEvent, 0, true, true); + + GameEventContainer *replayCont = prepareGameEvent(omniscientEvent, -1); + replayCont->set_seconds_elapsed(0); + replayCont->clear_game_id(); + currentReplay->add_event_list()->CopyFrom(*replayCont); + delete replayCont; + + startTimeOfThisGame = secondsElapsed; + } else + firstGameStarted = true; + + sendGameStateToPlayers(); + + activePlayer = -1; + nextTurn(); + + locker.unlock(); + + ServerInfo_Game gameInfo; + gameInfo.set_room_id(room->getId()); + gameInfo.set_game_id(gameId); + gameInfo.set_started(true); + emit gameInfoChanged(gameInfo); } void Server_Game::startGameIfReady() { - emit sigStartGameIfReady(); + emit sigStartGameIfReady(); } void Server_Game::stopGameIfFinished() { - QMutexLocker locker(&gameMutex); - - QMapIterator playerIterator(players); - int playing = 0; - while (playerIterator.hasNext()) { - Server_Player *p = playerIterator.next().value(); - if (!p->getConceded() && !p->getSpectator()) - ++playing; - } - if (playing > 1) - return; + QMutexLocker locker(&gameMutex); + + QMapIterator playerIterator(players); + int playing = 0; + while (playerIterator.hasNext()) { + Server_Player *p = playerIterator.next().value(); + if (!p->getConceded() && !p->getSpectator()) + ++playing; + } + if (playing > 1) + return; - gameStarted = false; + gameStarted = false; - playerIterator.toFront(); - while (playerIterator.hasNext()) { - Server_Player *p = playerIterator.next().value(); - p->clearZones(); - p->setConceded(false); - } + playerIterator.toFront(); + while (playerIterator.hasNext()) { + Server_Player *p = playerIterator.next().value(); + p->clearZones(); + p->setConceded(false); + } - sendGameStateToPlayers(); - - locker.unlock(); - - ServerInfo_Game gameInfo; - gameInfo.set_room_id(room->getId()); - gameInfo.set_game_id(gameId); - gameInfo.set_started(false); - emit gameInfoChanged(gameInfo); + sendGameStateToPlayers(); + + locker.unlock(); + + ServerInfo_Game gameInfo; + gameInfo.set_room_id(room->getId()); + gameInfo.set_game_id(gameId); + gameInfo.set_started(false); + emit gameInfoChanged(gameInfo); } Response::ResponseCode Server_Game::checkJoin(ServerInfo_User *user, const QString &_password, bool spectator, bool overrideRestrictions) { - Server_DatabaseInterface *databaseInterface = room->getServer()->getDatabaseInterface(); - { - QMapIterator playerIterator(players); - while (playerIterator.hasNext()) - if (playerIterator.next().value()->getUserInfo()->name() == user->name()) - return Response::RespContextError; - } - if (!(overrideRestrictions && (user->user_level() & ServerInfo_User::IsModerator))) { - if ((_password != password) && !(spectator && !spectatorsNeedPassword)) - return Response::RespWrongPassword; - if (!(user->user_level() & ServerInfo_User::IsRegistered) && onlyRegistered) - return Response::RespUserLevelTooLow; - if (onlyBuddies && (user->name() != creatorInfo->name())) - if (!databaseInterface->isInBuddyList(QString::fromStdString(creatorInfo->name()), QString::fromStdString(user->name()))) - return Response::RespOnlyBuddies; - if (databaseInterface->isInIgnoreList(QString::fromStdString(creatorInfo->name()), QString::fromStdString(user->name()))) - return Response::RespInIgnoreList; - if (spectator) { - if (!spectatorsAllowed) - return Response::RespSpectatorsNotAllowed; - } - } - if (!spectator && (gameStarted || (getPlayerCount() >= getMaxPlayers()))) - return Response::RespGameFull; - - return Response::RespOk; + Server_DatabaseInterface *databaseInterface = room->getServer()->getDatabaseInterface(); + { + QMapIterator playerIterator(players); + while (playerIterator.hasNext()) + if (playerIterator.next().value()->getUserInfo()->name() == user->name()) + return Response::RespContextError; + } + if (!(overrideRestrictions && (user->user_level() & ServerInfo_User::IsModerator))) { + if ((_password != password) && !(spectator && !spectatorsNeedPassword)) + return Response::RespWrongPassword; + if (!(user->user_level() & ServerInfo_User::IsRegistered) && onlyRegistered) + return Response::RespUserLevelTooLow; + if (onlyBuddies && (user->name() != creatorInfo->name())) + if (!databaseInterface->isInBuddyList(QString::fromStdString(creatorInfo->name()), QString::fromStdString(user->name()))) + return Response::RespOnlyBuddies; + if (databaseInterface->isInIgnoreList(QString::fromStdString(creatorInfo->name()), QString::fromStdString(user->name()))) + return Response::RespInIgnoreList; + if (spectator) { + if (!spectatorsAllowed) + return Response::RespSpectatorsNotAllowed; + } + } + if (!spectator && (gameStarted || (getPlayerCount() >= getMaxPlayers()))) + return Response::RespGameFull; + + return Response::RespOk; } bool Server_Game::containsUser(const QString &userName) const { - QMutexLocker locker(&gameMutex); - - QMapIterator playerIterator(players); - while (playerIterator.hasNext()) - if (playerIterator.next().value()->getUserInfo()->name() == userName.toStdString()) - return true; - return false; + QMutexLocker locker(&gameMutex); + + QMapIterator playerIterator(players); + while (playerIterator.hasNext()) + if (playerIterator.next().value()->getUserInfo()->name() == userName.toStdString()) + return true; + return false; } void Server_Game::addPlayer(Server_AbstractUserInterface *userInterface, ResponseContainer &rc, bool spectator, bool broadcastUpdate) { - QMutexLocker locker(&gameMutex); - - Server_Player *newPlayer = new Server_Player(this, nextPlayerId++, userInterface->copyUserInfo(true, true), spectator, userInterface); - newPlayer->moveToThread(thread()); - - Event_Join joinEvent; - newPlayer->getProperties(*joinEvent.mutable_player_properties(), true); - sendGameEventContainer(prepareGameEvent(joinEvent, -1)); - - const QString playerName = QString::fromStdString(newPlayer->getUserInfo()->name()); - if (spectator) - allSpectatorsEver.insert(playerName); - else - allPlayersEver.insert(playerName); - players.insert(newPlayer->getPlayerId(), newPlayer); - if (newPlayer->getUserInfo()->name() == creatorInfo->name()) { - hostId = newPlayer->getPlayerId(); - sendGameEventContainer(prepareGameEvent(Event_GameHostChanged(), hostId)); - } - - if (broadcastUpdate) { - ServerInfo_Game gameInfo; - gameInfo.set_room_id(room->getId()); - gameInfo.set_game_id(gameId); - gameInfo.set_player_count(getPlayerCount()); - gameInfo.set_spectators_count(getSpectatorCount()); - emit gameInfoChanged(gameInfo); - } - - if ((newPlayer->getUserInfo()->user_level() & ServerInfo_User::IsRegistered) && !spectator) - room->getServer()->addPersistentPlayer(playerName, room->getId(), gameId, newPlayer->getPlayerId()); - - userInterface->playerAddedToGame(gameId, room->getId(), newPlayer->getPlayerId()); - - createGameJoinedEvent(newPlayer, rc, false); + QMutexLocker locker(&gameMutex); + + Server_Player *newPlayer = new Server_Player(this, nextPlayerId++, userInterface->copyUserInfo(true, true), spectator, userInterface); + newPlayer->moveToThread(thread()); + + Event_Join joinEvent; + newPlayer->getProperties(*joinEvent.mutable_player_properties(), true); + sendGameEventContainer(prepareGameEvent(joinEvent, -1)); + + const QString playerName = QString::fromStdString(newPlayer->getUserInfo()->name()); + if (spectator) + allSpectatorsEver.insert(playerName); + else + allPlayersEver.insert(playerName); + players.insert(newPlayer->getPlayerId(), newPlayer); + if (newPlayer->getUserInfo()->name() == creatorInfo->name()) { + hostId = newPlayer->getPlayerId(); + sendGameEventContainer(prepareGameEvent(Event_GameHostChanged(), hostId)); + } + + if (broadcastUpdate) { + ServerInfo_Game gameInfo; + gameInfo.set_room_id(room->getId()); + gameInfo.set_game_id(gameId); + gameInfo.set_player_count(getPlayerCount()); + gameInfo.set_spectators_count(getSpectatorCount()); + emit gameInfoChanged(gameInfo); + } + + if ((newPlayer->getUserInfo()->user_level() & ServerInfo_User::IsRegistered) && !spectator) + room->getServer()->addPersistentPlayer(playerName, room->getId(), gameId, newPlayer->getPlayerId()); + + userInterface->playerAddedToGame(gameId, room->getId(), newPlayer->getPlayerId()); + + createGameJoinedEvent(newPlayer, rc, false); } void Server_Game::removePlayer(Server_Player *player) { - room->getServer()->removePersistentPlayer(QString::fromStdString(player->getUserInfo()->name()), room->getId(), gameId, player->getPlayerId()); - players.remove(player->getPlayerId()); - - GameEventStorage ges; - removeArrowsRelatedToPlayer(ges, player); - unattachCards(ges, player); - ges.enqueueGameEvent(Event_Leave(), player->getPlayerId()); - ges.sendToGame(this); - - bool playerActive = activePlayer == player->getPlayerId(); - bool playerHost = hostId == player->getPlayerId(); - bool spectator = player->getSpectator(); - player->prepareDestroy(); - - if (!getPlayerCount()) { - gameClosed = true; - deleteLater(); - return; - } else if (!spectator) { - if (playerHost) { - int newHostId = -1; - QMapIterator playerIterator(players); - while (playerIterator.hasNext()) { - Server_Player *p = playerIterator.next().value(); - if (!p->getSpectator()) { - newHostId = p->getPlayerId(); - break; - } - } - if (newHostId != -1) { - hostId = newHostId; - sendGameEventContainer(prepareGameEvent(Event_GameHostChanged(), hostId)); - } - } - stopGameIfFinished(); - if (gameStarted && playerActive) - nextTurn(); - } - - ServerInfo_Game gameInfo; - gameInfo.set_room_id(room->getId()); - gameInfo.set_game_id(gameId); - gameInfo.set_player_count(getPlayerCount()); - gameInfo.set_spectators_count(getSpectatorCount()); - emit gameInfoChanged(gameInfo); + room->getServer()->removePersistentPlayer(QString::fromStdString(player->getUserInfo()->name()), room->getId(), gameId, player->getPlayerId()); + players.remove(player->getPlayerId()); + + GameEventStorage ges; + removeArrowsRelatedToPlayer(ges, player); + unattachCards(ges, player); + ges.enqueueGameEvent(Event_Leave(), player->getPlayerId()); + ges.sendToGame(this); + + bool playerActive = activePlayer == player->getPlayerId(); + bool playerHost = hostId == player->getPlayerId(); + bool spectator = player->getSpectator(); + player->prepareDestroy(); + + if (!getPlayerCount()) { + gameClosed = true; + deleteLater(); + return; + } else if (!spectator) { + if (playerHost) { + int newHostId = -1; + QMapIterator playerIterator(players); + while (playerIterator.hasNext()) { + Server_Player *p = playerIterator.next().value(); + if (!p->getSpectator()) { + newHostId = p->getPlayerId(); + break; + } + } + if (newHostId != -1) { + hostId = newHostId; + sendGameEventContainer(prepareGameEvent(Event_GameHostChanged(), hostId)); + } + } + stopGameIfFinished(); + if (gameStarted && playerActive) + nextTurn(); + } + + ServerInfo_Game gameInfo; + gameInfo.set_room_id(room->getId()); + gameInfo.set_game_id(gameId); + gameInfo.set_player_count(getPlayerCount()); + gameInfo.set_spectators_count(getSpectatorCount()); + emit gameInfoChanged(gameInfo); } void Server_Game::removeArrowsRelatedToPlayer(GameEventStorage &ges, Server_Player *player) { - QMutexLocker locker(&gameMutex); - - // Remove all arrows of other players pointing to the player being removed or to one of his cards. - // Also remove all arrows starting at one of his cards. This is necessary since players can create - // arrows that start at another person's cards. - QMapIterator playerIterator(players); - while (playerIterator.hasNext()) { - Server_Player *p = playerIterator.next().value(); - QList arrows = p->getArrows().values(); - QList toDelete; - for (int i = 0; i < arrows.size(); ++i) { - Server_Arrow *a = arrows[i]; - Server_Card *targetCard = qobject_cast(a->getTargetItem()); - if (targetCard) { - if (targetCard->getZone()->getPlayer() == player) - toDelete.append(a); - } else if (static_cast(a->getTargetItem()) == player) - toDelete.append(a); - - // Don't use else here! It has to happen regardless of whether targetCard == 0. - if (a->getStartCard()->getZone()->getPlayer() == player) - toDelete.append(a); - } - for (int i = 0; i < toDelete.size(); ++i) { - Event_DeleteArrow event; - event.set_arrow_id(toDelete[i]->getId()); - ges.enqueueGameEvent(event, p->getPlayerId()); - - p->deleteArrow(toDelete[i]->getId()); - } - } + QMutexLocker locker(&gameMutex); + + // Remove all arrows of other players pointing to the player being removed or to one of his cards. + // Also remove all arrows starting at one of his cards. This is necessary since players can create + // arrows that start at another person's cards. + QMapIterator playerIterator(players); + while (playerIterator.hasNext()) { + Server_Player *p = playerIterator.next().value(); + QList arrows = p->getArrows().values(); + QList toDelete; + for (int i = 0; i < arrows.size(); ++i) { + Server_Arrow *a = arrows[i]; + Server_Card *targetCard = qobject_cast(a->getTargetItem()); + if (targetCard) { + if (targetCard->getZone()->getPlayer() == player) + toDelete.append(a); + } else if (static_cast(a->getTargetItem()) == player) + toDelete.append(a); + + // Don't use else here! It has to happen regardless of whether targetCard == 0. + if (a->getStartCard()->getZone()->getPlayer() == player) + toDelete.append(a); + } + for (int i = 0; i < toDelete.size(); ++i) { + Event_DeleteArrow event; + event.set_arrow_id(toDelete[i]->getId()); + ges.enqueueGameEvent(event, p->getPlayerId()); + + p->deleteArrow(toDelete[i]->getId()); + } + } } void Server_Game::unattachCards(GameEventStorage &ges, Server_Player *player) { - QMutexLocker locker(&gameMutex); - - QMapIterator zoneIterator(player->getZones()); - while (zoneIterator.hasNext()) { - Server_CardZone *zone = zoneIterator.next().value(); - for (int i = 0; i < zone->getCards().size(); ++i) { - Server_Card *card = zone->getCards().at(i); - - // Make a copy of the list because the original one gets modified during the loop - QList attachedCards = card->getAttachedCards(); - for (int i = 0; i < attachedCards.size(); ++i) - attachedCards[i]->getZone()->getPlayer()->unattachCard(ges, attachedCards[i]); - } - } + QMutexLocker locker(&gameMutex); + + QMapIterator zoneIterator(player->getZones()); + while (zoneIterator.hasNext()) { + Server_CardZone *zone = zoneIterator.next().value(); + for (int i = 0; i < zone->getCards().size(); ++i) { + Server_Card *card = zone->getCards().at(i); + + // Make a copy of the list because the original one gets modified during the loop + QList attachedCards = card->getAttachedCards(); + for (int i = 0; i < attachedCards.size(); ++i) + attachedCards[i]->getZone()->getPlayer()->unattachCard(ges, attachedCards[i]); + } + } } bool Server_Game::kickPlayer(int playerId) { - QMutexLocker locker(&gameMutex); - - Server_Player *playerToKick = players.value(playerId); - if (!playerToKick) - return false; - - GameEventContainer *gec = prepareGameEvent(Event_Kicked(), -1); - playerToKick->sendGameEvent(*gec); - delete gec; - - removePlayer(playerToKick); - - return true; + QMutexLocker locker(&gameMutex); + + Server_Player *playerToKick = players.value(playerId); + if (!playerToKick) + return false; + + GameEventContainer *gec = prepareGameEvent(Event_Kicked(), -1); + playerToKick->sendGameEvent(*gec); + delete gec; + + removePlayer(playerToKick); + + return true; } void Server_Game::setActivePlayer(int _activePlayer) { - QMutexLocker locker(&gameMutex); - - activePlayer = _activePlayer; - - Event_SetActivePlayer event; - event.set_active_player_id(activePlayer); - sendGameEventContainer(prepareGameEvent(event, -1)); - - setActivePhase(0); + QMutexLocker locker(&gameMutex); + + activePlayer = _activePlayer; + + Event_SetActivePlayer event; + event.set_active_player_id(activePlayer); + sendGameEventContainer(prepareGameEvent(event, -1)); + + setActivePhase(0); } void Server_Game::setActivePhase(int _activePhase) { - QMutexLocker locker(&gameMutex); - - QMapIterator playerIterator(players); - while (playerIterator.hasNext()) { - Server_Player *player = playerIterator.next().value(); - QList toDelete = player->getArrows().values(); - for (int i = 0; i < toDelete.size(); ++i) { - Server_Arrow *a = toDelete[i]; - - Event_DeleteArrow event; - event.set_arrow_id(a->getId()); - sendGameEventContainer(prepareGameEvent(event, player->getPlayerId())); - - player->deleteArrow(a->getId()); - } - } - - activePhase = _activePhase; - - Event_SetActivePhase event; - event.set_phase(activePhase); - sendGameEventContainer(prepareGameEvent(event, -1)); + QMutexLocker locker(&gameMutex); + + QMapIterator playerIterator(players); + while (playerIterator.hasNext()) { + Server_Player *player = playerIterator.next().value(); + QList toDelete = player->getArrows().values(); + for (int i = 0; i < toDelete.size(); ++i) { + Server_Arrow *a = toDelete[i]; + + Event_DeleteArrow event; + event.set_arrow_id(a->getId()); + sendGameEventContainer(prepareGameEvent(event, player->getPlayerId())); + + player->deleteArrow(a->getId()); + } + } + + activePhase = _activePhase; + + Event_SetActivePhase event; + event.set_phase(activePhase); + sendGameEventContainer(prepareGameEvent(event, -1)); } void Server_Game::nextTurn() { - QMutexLocker locker(&gameMutex); - - const QList keys = players.keys(); - int listPos = -1; - if (activePlayer != -1) - listPos = keys.indexOf(activePlayer); - do { - ++listPos; - if (listPos == keys.size()) - listPos = 0; - } while (players.value(keys[listPos])->getSpectator() || players.value(keys[listPos])->getConceded()); - - setActivePlayer(keys[listPos]); + QMutexLocker locker(&gameMutex); + + const QList keys = players.keys(); + int listPos = -1; + if (activePlayer != -1) + listPos = keys.indexOf(activePlayer); + do { + ++listPos; + if (listPos == keys.size()) + listPos = 0; + } while (players.value(keys[listPos])->getSpectator() || players.value(keys[listPos])->getConceded()); + + setActivePlayer(keys[listPos]); } void Server_Game::createGameJoinedEvent(Server_Player *player, ResponseContainer &rc, bool resuming) { - Event_GameJoined event1; - getInfo(*event1.mutable_game_info()); - event1.set_host_id(hostId); - event1.set_player_id(player->getPlayerId()); - event1.set_spectator(player->getSpectator()); - event1.set_resuming(resuming); - if (resuming) { - const QStringList &allGameTypes = room->getGameTypes(); - for (int i = 0; i < allGameTypes.size(); ++i) { - ServerInfo_GameType *newGameType = event1.add_game_types(); - newGameType->set_game_type_id(i); - newGameType->set_description(allGameTypes[i].toStdString()); - } - } - rc.enqueuePostResponseItem(ServerMessage::SESSION_EVENT, Server_AbstractUserInterface::prepareSessionEvent(event1)); - - Event_GameStateChanged event2; - event2.set_seconds_elapsed(secondsElapsed); - event2.set_game_started(gameStarted); - event2.set_active_player_id(activePlayer); - event2.set_active_phase(activePhase); - - QMapIterator playerIterator(players); - while (playerIterator.hasNext()) - playerIterator.next().value()->getInfo(event2.add_player_list(), player, player->getSpectator() && spectatorsSeeEverything, true); + Event_GameJoined event1; + getInfo(*event1.mutable_game_info()); + event1.set_host_id(hostId); + event1.set_player_id(player->getPlayerId()); + event1.set_spectator(player->getSpectator()); + event1.set_resuming(resuming); + if (resuming) { + const QStringList &allGameTypes = room->getGameTypes(); + for (int i = 0; i < allGameTypes.size(); ++i) { + ServerInfo_GameType *newGameType = event1.add_game_types(); + newGameType->set_game_type_id(i); + newGameType->set_description(allGameTypes[i].toStdString()); + } + } + rc.enqueuePostResponseItem(ServerMessage::SESSION_EVENT, Server_AbstractUserInterface::prepareSessionEvent(event1)); + + Event_GameStateChanged event2; + event2.set_seconds_elapsed(secondsElapsed); + event2.set_game_started(gameStarted); + event2.set_active_player_id(activePlayer); + event2.set_active_phase(activePhase); + + QMapIterator playerIterator(players); + while (playerIterator.hasNext()) + playerIterator.next().value()->getInfo(event2.add_player_list(), player, player->getSpectator() && spectatorsSeeEverything, true); - rc.enqueuePostResponseItem(ServerMessage::GAME_EVENT_CONTAINER, prepareGameEvent(event2, -1)); + rc.enqueuePostResponseItem(ServerMessage::GAME_EVENT_CONTAINER, prepareGameEvent(event2, -1)); } void Server_Game::sendGameEventContainer(GameEventContainer *cont, GameEventStorageItem::EventRecipients recipients, int privatePlayerId) { - QMutexLocker locker(&gameMutex); - - cont->set_game_id(gameId); - QMapIterator playerIterator(players); - while (playerIterator.hasNext()) { - Server_Player *p = playerIterator.next().value(); - const bool playerPrivate = (p->getPlayerId() == privatePlayerId) || (p->getSpectator() && spectatorsSeeEverything); - if ((recipients.testFlag(GameEventStorageItem::SendToPrivate) && playerPrivate) || (recipients.testFlag(GameEventStorageItem::SendToOthers) && !playerPrivate)) - p->sendGameEvent(*cont); - } - if (recipients.testFlag(GameEventStorageItem::SendToPrivate)) { - cont->set_seconds_elapsed(secondsElapsed - startTimeOfThisGame); - cont->clear_game_id(); - currentReplay->add_event_list()->CopyFrom(*cont); - } - - delete cont; + QMutexLocker locker(&gameMutex); + + cont->set_game_id(gameId); + QMapIterator playerIterator(players); + while (playerIterator.hasNext()) { + Server_Player *p = playerIterator.next().value(); + const bool playerPrivate = (p->getPlayerId() == privatePlayerId) || (p->getSpectator() && spectatorsSeeEverything); + if ((recipients.testFlag(GameEventStorageItem::SendToPrivate) && playerPrivate) || (recipients.testFlag(GameEventStorageItem::SendToOthers) && !playerPrivate)) + p->sendGameEvent(*cont); + } + if (recipients.testFlag(GameEventStorageItem::SendToPrivate)) { + cont->set_seconds_elapsed(secondsElapsed - startTimeOfThisGame); + cont->clear_game_id(); + currentReplay->add_event_list()->CopyFrom(*cont); + } + + delete cont; } GameEventContainer *Server_Game::prepareGameEvent(const ::google::protobuf::Message &gameEvent, int playerId, GameEventContext *context) { - GameEventContainer *cont = new GameEventContainer; - cont->set_game_id(gameId); - if (context) - cont->mutable_context()->CopyFrom(*context); - GameEvent *event = cont->add_event_list(); - if (playerId != -1) - event->set_player_id(playerId); - event->GetReflection()->MutableMessage(event, gameEvent.GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(gameEvent); - return cont; + GameEventContainer *cont = new GameEventContainer; + cont->set_game_id(gameId); + if (context) + cont->mutable_context()->CopyFrom(*context); + GameEvent *event = cont->add_event_list(); + if (playerId != -1) + event->set_player_id(playerId); + event->GetReflection()->MutableMessage(event, gameEvent.GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(gameEvent); + return cont; } void Server_Game::getInfo(ServerInfo_Game &result) const { - QMutexLocker locker(&gameMutex); - - result.set_room_id(room->getId()); - result.set_game_id(gameId); - if (gameClosed) - result.set_closed(true); - else { - for (int i = 0; i < gameTypes.size(); ++i) - result.add_game_types(gameTypes[i]); - - result.set_max_players(getMaxPlayers()); - result.set_description(getDescription().toStdString()); - result.set_with_password(!getPassword().isEmpty()); - result.set_player_count(getPlayerCount()); - result.set_started(gameStarted); - result.mutable_creator_info()->CopyFrom(*getCreatorInfo()); - result.set_only_buddies(onlyBuddies); - result.set_only_registered(onlyRegistered); - result.set_spectators_allowed(getSpectatorsAllowed()); - result.set_spectators_need_password(getSpectatorsNeedPassword()); - result.set_spectators_can_chat(spectatorsCanTalk); - result.set_spectators_omniscient(spectatorsSeeEverything); - result.set_spectators_count(getSpectatorCount()); - result.set_start_time(startTime.toTime_t()); - } + QMutexLocker locker(&gameMutex); + + result.set_room_id(room->getId()); + result.set_game_id(gameId); + if (gameClosed) + result.set_closed(true); + else { + for (int i = 0; i < gameTypes.size(); ++i) + result.add_game_types(gameTypes[i]); + + result.set_max_players(getMaxPlayers()); + result.set_description(getDescription().toStdString()); + result.set_with_password(!getPassword().isEmpty()); + result.set_player_count(getPlayerCount()); + result.set_started(gameStarted); + result.mutable_creator_info()->CopyFrom(*getCreatorInfo()); + result.set_only_buddies(onlyBuddies); + result.set_only_registered(onlyRegistered); + result.set_spectators_allowed(getSpectatorsAllowed()); + result.set_spectators_need_password(getSpectatorsNeedPassword()); + result.set_spectators_can_chat(spectatorsCanTalk); + result.set_spectators_omniscient(spectatorsSeeEverything); + result.set_spectators_count(getSpectatorCount()); + result.set_start_time(startTime.toTime_t()); + } } diff --git a/common/server_game.h b/common/server_game.h index f6ddbf92..cf7eb086 100644 --- a/common/server_game.h +++ b/common/server_game.h @@ -42,86 +42,86 @@ class Server_AbstractUserInterface; class Event_GameStateChanged; class Server_Game : public QObject { - Q_OBJECT + Q_OBJECT private: - Server_Room *room; - int nextPlayerId; - int hostId; - ServerInfo_User *creatorInfo; - QMap players; - QSet allPlayersEver, allSpectatorsEver; - bool gameStarted; - bool gameClosed; - int gameId; - QString description; - QString password; - int maxPlayers; - QList gameTypes; - int activePlayer, activePhase; - bool onlyBuddies, onlyRegistered; - bool spectatorsAllowed; - bool spectatorsNeedPassword; - bool spectatorsCanTalk; - bool spectatorsSeeEverything; - int inactivityCounter; - int startTimeOfThisGame, secondsElapsed; - bool firstGameStarted; - QDateTime startTime; - QTimer *pingClock; - QList replayList; - GameReplay *currentReplay; - - void createGameStateChangedEvent(Event_GameStateChanged *event, Server_Player *playerWhosAsking, bool omniscient, bool withUserInfo); - void sendGameStateToPlayers(); - void storeGameInformation(); + Server_Room *room; + int nextPlayerId; + int hostId; + ServerInfo_User *creatorInfo; + QMap players; + QSet allPlayersEver, allSpectatorsEver; + bool gameStarted; + bool gameClosed; + int gameId; + QString description; + QString password; + int maxPlayers; + QList gameTypes; + int activePlayer, activePhase; + bool onlyBuddies, onlyRegistered; + bool spectatorsAllowed; + bool spectatorsNeedPassword; + bool spectatorsCanTalk; + bool spectatorsSeeEverything; + int inactivityCounter; + int startTimeOfThisGame, secondsElapsed; + bool firstGameStarted; + QDateTime startTime; + QTimer *pingClock; + QList replayList; + GameReplay *currentReplay; + + void createGameStateChangedEvent(Event_GameStateChanged *event, Server_Player *playerWhosAsking, bool omniscient, bool withUserInfo); + void sendGameStateToPlayers(); + void storeGameInformation(); signals: - void sigStartGameIfReady(); - void gameInfoChanged(ServerInfo_Game gameInfo); + void sigStartGameIfReady(); + void gameInfoChanged(ServerInfo_Game gameInfo); private slots: - void pingClockTimeout(); - void doStartGameIfReady(); + void pingClockTimeout(); + void doStartGameIfReady(); public: - mutable QMutex gameMutex; - Server_Game(const ServerInfo_User &_creatorInfo, int _gameId, const QString &_description, const QString &_password, int _maxPlayers, const QList &_gameTypes, bool _onlyBuddies, bool _onlyRegistered, bool _spectatorsAllowed, bool _spectatorsNeedPassword, bool _spectatorsCanTalk, bool _spectatorsSeeEverything, Server_Room *parent); - ~Server_Game(); - Server_Room *getRoom() const { return room; } - void getInfo(ServerInfo_Game &result) const; - int getHostId() const { return hostId; } - ServerInfo_User *getCreatorInfo() const { return creatorInfo; } - bool getGameStarted() const { return gameStarted; } - int getPlayerCount() const; - int getSpectatorCount() const; - const QMap &getPlayers() const { return players; } - int getGameId() const { return gameId; } - QString getDescription() const { return description; } - QString getPassword() const { return password; } - int getMaxPlayers() const { return maxPlayers; } - bool getSpectatorsAllowed() const { return spectatorsAllowed; } - bool getSpectatorsNeedPassword() const { return spectatorsNeedPassword; } - bool getSpectatorsCanTalk() const { return spectatorsCanTalk; } - bool getSpectatorsSeeEverything() const { return spectatorsSeeEverything; } - Response::ResponseCode checkJoin(ServerInfo_User *user, const QString &_password, bool spectator, bool overrideRestrictions); - bool containsUser(const QString &userName) const; - void addPlayer(Server_AbstractUserInterface *userInterface, ResponseContainer &rc, bool spectator, bool broadcastUpdate = true); - void removePlayer(Server_Player *player); - void removeArrowsRelatedToPlayer(GameEventStorage &ges, Server_Player *player); - void unattachCards(GameEventStorage &ges, Server_Player *player); - bool kickPlayer(int playerId); - void startGameIfReady(); - void stopGameIfFinished(); - int getActivePlayer() const { return activePlayer; } - int getActivePhase() const { return activePhase; } - void setActivePlayer(int _activePlayer); - void setActivePhase(int _activePhase); - void nextTurn(); - int getSecondsElapsed() const { return secondsElapsed; } + mutable QMutex gameMutex; + Server_Game(const ServerInfo_User &_creatorInfo, int _gameId, const QString &_description, const QString &_password, int _maxPlayers, const QList &_gameTypes, bool _onlyBuddies, bool _onlyRegistered, bool _spectatorsAllowed, bool _spectatorsNeedPassword, bool _spectatorsCanTalk, bool _spectatorsSeeEverything, Server_Room *parent); + ~Server_Game(); + Server_Room *getRoom() const { return room; } + void getInfo(ServerInfo_Game &result) const; + int getHostId() const { return hostId; } + ServerInfo_User *getCreatorInfo() const { return creatorInfo; } + bool getGameStarted() const { return gameStarted; } + int getPlayerCount() const; + int getSpectatorCount() const; + const QMap &getPlayers() const { return players; } + int getGameId() const { return gameId; } + QString getDescription() const { return description; } + QString getPassword() const { return password; } + int getMaxPlayers() const { return maxPlayers; } + bool getSpectatorsAllowed() const { return spectatorsAllowed; } + bool getSpectatorsNeedPassword() const { return spectatorsNeedPassword; } + bool getSpectatorsCanTalk() const { return spectatorsCanTalk; } + bool getSpectatorsSeeEverything() const { return spectatorsSeeEverything; } + Response::ResponseCode checkJoin(ServerInfo_User *user, const QString &_password, bool spectator, bool overrideRestrictions); + bool containsUser(const QString &userName) const; + void addPlayer(Server_AbstractUserInterface *userInterface, ResponseContainer &rc, bool spectator, bool broadcastUpdate = true); + void removePlayer(Server_Player *player); + void removeArrowsRelatedToPlayer(GameEventStorage &ges, Server_Player *player); + void unattachCards(GameEventStorage &ges, Server_Player *player); + bool kickPlayer(int playerId); + void startGameIfReady(); + void stopGameIfFinished(); + int getActivePlayer() const { return activePlayer; } + int getActivePhase() const { return activePhase; } + void setActivePlayer(int _activePlayer); + void setActivePhase(int _activePhase); + void nextTurn(); + int getSecondsElapsed() const { return secondsElapsed; } - void createGameJoinedEvent(Server_Player *player, ResponseContainer &rc, bool resuming); - - GameEventContainer *prepareGameEvent(const ::google::protobuf::Message &gameEvent, int playerId, GameEventContext *context = 0); - GameEventContext prepareGameEventContext(const ::google::protobuf::Message &gameEventContext); - - void sendGameEventContainer(GameEventContainer *cont, GameEventStorageItem::EventRecipients recipients = GameEventStorageItem::SendToPrivate | GameEventStorageItem::SendToOthers, int privatePlayerId = -1); + void createGameJoinedEvent(Server_Player *player, ResponseContainer &rc, bool resuming); + + GameEventContainer *prepareGameEvent(const ::google::protobuf::Message &gameEvent, int playerId, GameEventContext *context = 0); + GameEventContext prepareGameEventContext(const ::google::protobuf::Message &gameEventContext); + + void sendGameEventContainer(GameEventContainer *cont, GameEventStorageItem::EventRecipients recipients = GameEventStorageItem::SendToPrivate | GameEventStorageItem::SendToOthers, int privatePlayerId = -1); }; #endif diff --git a/common/server_player.cpp b/common/server_player.cpp index 76cd260d..c25151e8 100644 --- a/common/server_player.cpp +++ b/common/server_player.cpp @@ -84,7 +84,7 @@ #include Server_Player::Server_Player(Server_Game *_game, int _playerId, const ServerInfo_User &_userInfo, bool _spectator, Server_AbstractUserInterface *_userInterface) - : ServerInfo_User_Container(_userInfo), game(_game), userInterface(_userInterface), deck(0), pingTime(0), playerId(_playerId), spectator(_spectator), nextCardId(0), readyStart(false), conceded(false), sideboardLocked(true) + : ServerInfo_User_Container(_userInfo), game(_game), userInterface(_userInterface), deck(0), pingTime(0), playerId(_playerId), spectator(_spectator), nextCardId(0), readyStart(false), conceded(false), sideboardLocked(true) { } @@ -94,1624 +94,1624 @@ Server_Player::~Server_Player() void Server_Player::prepareDestroy() { - delete deck; - - playerMutex.lock(); - if (userInterface) - userInterface->playerRemovedFromGame(game); - playerMutex.unlock(); - - clearZones(); - - deleteLater(); + delete deck; + + playerMutex.lock(); + if (userInterface) + userInterface->playerRemovedFromGame(game); + playerMutex.unlock(); + + clearZones(); + + deleteLater(); } int Server_Player::newCardId() { - return nextCardId++; + return nextCardId++; } int Server_Player::newCounterId() const { - int id = 0; - QMapIterator i(counters); - while (i.hasNext()) { - Server_Counter *c = i.next().value(); - if (c->getId() > id) - id = c->getId(); - } - return id + 1; + int id = 0; + QMapIterator i(counters); + while (i.hasNext()) { + Server_Counter *c = i.next().value(); + if (c->getId() > id) + id = c->getId(); + } + return id + 1; } int Server_Player::newArrowId() const { - int id = 0; - QMapIterator i(arrows); - while (i.hasNext()) { - Server_Arrow *a = i.next().value(); - if (a->getId() > id) - id = a->getId(); - } - return id + 1; + int id = 0; + QMapIterator i(arrows); + while (i.hasNext()) { + Server_Arrow *a = i.next().value(); + if (a->getId() > id) + id = a->getId(); + } + return id + 1; } void Server_Player::setupZones() { - // This may need to be customized according to the game rules. - // ------------------------------------------------------------------ + // This may need to be customized according to the game rules. + // ------------------------------------------------------------------ - // Create zones - Server_CardZone *deckZone = new Server_CardZone(this, "deck", false, ServerInfo_Zone::HiddenZone); - addZone(deckZone); - Server_CardZone *sbZone = new Server_CardZone(this, "sb", false, ServerInfo_Zone::HiddenZone); - addZone(sbZone); - addZone(new Server_CardZone(this, "table", true, ServerInfo_Zone::PublicZone)); - addZone(new Server_CardZone(this, "hand", false, ServerInfo_Zone::PrivateZone)); - addZone(new Server_CardZone(this, "stack", false, ServerInfo_Zone::PublicZone)); - addZone(new Server_CardZone(this, "grave", false, ServerInfo_Zone::PublicZone)); - addZone(new Server_CardZone(this, "rfg", false, ServerInfo_Zone::PublicZone)); + // Create zones + Server_CardZone *deckZone = new Server_CardZone(this, "deck", false, ServerInfo_Zone::HiddenZone); + addZone(deckZone); + Server_CardZone *sbZone = new Server_CardZone(this, "sb", false, ServerInfo_Zone::HiddenZone); + addZone(sbZone); + addZone(new Server_CardZone(this, "table", true, ServerInfo_Zone::PublicZone)); + addZone(new Server_CardZone(this, "hand", false, ServerInfo_Zone::PrivateZone)); + addZone(new Server_CardZone(this, "stack", false, ServerInfo_Zone::PublicZone)); + addZone(new Server_CardZone(this, "grave", false, ServerInfo_Zone::PublicZone)); + addZone(new Server_CardZone(this, "rfg", false, ServerInfo_Zone::PublicZone)); - addCounter(new Server_Counter(0, "life", makeColor(255, 255, 255), 25, 20)); - addCounter(new Server_Counter(1, "w", makeColor(255, 255, 150), 20, 0)); - addCounter(new Server_Counter(2, "u", makeColor(150, 150, 255), 20, 0)); - addCounter(new Server_Counter(3, "b", makeColor(150, 150, 150), 20, 0)); - addCounter(new Server_Counter(4, "r", makeColor(250, 150, 150), 20, 0)); - addCounter(new Server_Counter(5, "g", makeColor(150, 255, 150), 20, 0)); - addCounter(new Server_Counter(6, "x", makeColor(255, 255, 255), 20, 0)); - addCounter(new Server_Counter(7, "storm", makeColor(255, 255, 255), 20, 0)); + addCounter(new Server_Counter(0, "life", makeColor(255, 255, 255), 25, 20)); + addCounter(new Server_Counter(1, "w", makeColor(255, 255, 150), 20, 0)); + addCounter(new Server_Counter(2, "u", makeColor(150, 150, 255), 20, 0)); + addCounter(new Server_Counter(3, "b", makeColor(150, 150, 150), 20, 0)); + addCounter(new Server_Counter(4, "r", makeColor(250, 150, 150), 20, 0)); + addCounter(new Server_Counter(5, "g", makeColor(150, 255, 150), 20, 0)); + addCounter(new Server_Counter(6, "x", makeColor(255, 255, 255), 20, 0)); + addCounter(new Server_Counter(7, "storm", makeColor(255, 255, 255), 20, 0)); - initialCards = 7; + initialCards = 7; - // ------------------------------------------------------------------ + // ------------------------------------------------------------------ - // Assign card ids and create deck from decklist - InnerDecklistNode *listRoot = deck->getRoot(); - nextCardId = 0; - for (int i = 0; i < listRoot->size(); ++i) { - InnerDecklistNode *currentZone = dynamic_cast(listRoot->at(i)); - Server_CardZone *z; - if (currentZone->getName() == "main") - z = deckZone; - else if (currentZone->getName() == "side") - z = sbZone; - else - continue; - - for (int j = 0; j < currentZone->size(); ++j) { - DecklistCardNode *currentCard = dynamic_cast(currentZone->at(j)); - if (!currentCard) - continue; - for (int k = 0; k < currentCard->getNumber(); ++k) - z->insertCard(new Server_Card(currentCard->getName(), nextCardId++, 0, 0, z), -1, 0); - } - } - - const QList &sideboardPlan = deck->getCurrentSideboardPlan(); - for (int i = 0; i < sideboardPlan.size(); ++i) { - const MoveCard_ToZone &m = sideboardPlan[i]; - const QString startZone = QString::fromStdString(m.start_zone()); - const QString targetZone = QString::fromStdString(m.target_zone()); - - Server_CardZone *start, *target; - if (startZone == "main") - start = deckZone; - else if (startZone == "side") - start = sbZone; - else - continue; - if (targetZone == "main") - target = deckZone; - else if (targetZone == "side") - target = sbZone; - else - continue; - - for (int j = 0; j < start->getCards().size(); ++j) - if (start->getCards()[j]->getName() == QString::fromStdString(m.card_name())) { - Server_Card *card = start->getCard(j, NULL, true); - target->insertCard(card, -1, 0); - break; - } - } - - deckZone->shuffle(); + // Assign card ids and create deck from decklist + InnerDecklistNode *listRoot = deck->getRoot(); + nextCardId = 0; + for (int i = 0; i < listRoot->size(); ++i) { + InnerDecklistNode *currentZone = dynamic_cast(listRoot->at(i)); + Server_CardZone *z; + if (currentZone->getName() == "main") + z = deckZone; + else if (currentZone->getName() == "side") + z = sbZone; + else + continue; + + for (int j = 0; j < currentZone->size(); ++j) { + DecklistCardNode *currentCard = dynamic_cast(currentZone->at(j)); + if (!currentCard) + continue; + for (int k = 0; k < currentCard->getNumber(); ++k) + z->insertCard(new Server_Card(currentCard->getName(), nextCardId++, 0, 0, z), -1, 0); + } + } + + const QList &sideboardPlan = deck->getCurrentSideboardPlan(); + for (int i = 0; i < sideboardPlan.size(); ++i) { + const MoveCard_ToZone &m = sideboardPlan[i]; + const QString startZone = QString::fromStdString(m.start_zone()); + const QString targetZone = QString::fromStdString(m.target_zone()); + + Server_CardZone *start, *target; + if (startZone == "main") + start = deckZone; + else if (startZone == "side") + start = sbZone; + else + continue; + if (targetZone == "main") + target = deckZone; + else if (targetZone == "side") + target = sbZone; + else + continue; + + for (int j = 0; j < start->getCards().size(); ++j) + if (start->getCards()[j]->getName() == QString::fromStdString(m.card_name())) { + Server_Card *card = start->getCard(j, NULL, true); + target->insertCard(card, -1, 0); + break; + } + } + + deckZone->shuffle(); } void Server_Player::clearZones() { - QMapIterator zoneIterator(zones); - while (zoneIterator.hasNext()) - delete zoneIterator.next().value(); - zones.clear(); + QMapIterator zoneIterator(zones); + while (zoneIterator.hasNext()) + delete zoneIterator.next().value(); + zones.clear(); - QMapIterator counterIterator(counters); - while (counterIterator.hasNext()) - delete counterIterator.next().value(); - counters.clear(); - - QMapIterator arrowIterator(arrows); - while (arrowIterator.hasNext()) - delete arrowIterator.next().value(); - arrows.clear(); + QMapIterator counterIterator(counters); + while (counterIterator.hasNext()) + delete counterIterator.next().value(); + counters.clear(); + + QMapIterator arrowIterator(arrows); + while (arrowIterator.hasNext()) + delete arrowIterator.next().value(); + arrows.clear(); - lastDrawList.clear(); + lastDrawList.clear(); } void Server_Player::getProperties(ServerInfo_PlayerProperties &result, bool withUserInfo) { - result.set_player_id(playerId); - if (withUserInfo) - copyUserInfo(*(result.mutable_user_info()), true); - result.set_spectator(spectator); - if (!spectator) { - result.set_conceded(conceded); - result.set_sideboard_locked(sideboardLocked); - result.set_ready_start(readyStart); - } - if (deck) - result.set_deck_hash(deck->getDeckHash().toStdString()); - result.set_ping_seconds(pingTime); + result.set_player_id(playerId); + if (withUserInfo) + copyUserInfo(*(result.mutable_user_info()), true); + result.set_spectator(spectator); + if (!spectator) { + result.set_conceded(conceded); + result.set_sideboard_locked(sideboardLocked); + result.set_ready_start(readyStart); + } + if (deck) + result.set_deck_hash(deck->getDeckHash().toStdString()); + result.set_ping_seconds(pingTime); } void Server_Player::addZone(Server_CardZone *zone) { - zones.insert(zone->getName(), zone); + zones.insert(zone->getName(), zone); } void Server_Player::addArrow(Server_Arrow *arrow) { - arrows.insert(arrow->getId(), arrow); + arrows.insert(arrow->getId(), arrow); } bool Server_Player::deleteArrow(int arrowId) { - Server_Arrow *arrow = arrows.value(arrowId, 0); - if (!arrow) - return false; - arrows.remove(arrowId); - delete arrow; - return true; + Server_Arrow *arrow = arrows.value(arrowId, 0); + if (!arrow) + return false; + arrows.remove(arrowId); + delete arrow; + return true; } void Server_Player::addCounter(Server_Counter *counter) { - counters.insert(counter->getId(), counter); + counters.insert(counter->getId(), counter); } Response::ResponseCode Server_Player::drawCards(GameEventStorage &ges, int number) { - Server_CardZone *deckZone = zones.value("deck"); - Server_CardZone *handZone = zones.value("hand"); - if (deckZone->getCards().size() < number) - number = deckZone->getCards().size(); - - Event_DrawCards eventOthers; - eventOthers.set_number(number); - Event_DrawCards eventPrivate(eventOthers); - - for (int i = 0; i < number; ++i) { - Server_Card *card = deckZone->getCard(0, NULL, true); - handZone->insertCard(card, -1, 0); - lastDrawList.append(card->getId()); - - ServerInfo_Card *cardInfo = eventPrivate.add_cards(); - cardInfo->set_id(card->getId()); - cardInfo->set_name(card->getName().toStdString()); - } - - ges.enqueueGameEvent(eventPrivate, playerId, GameEventStorageItem::SendToPrivate, playerId); - ges.enqueueGameEvent(eventOthers, playerId, GameEventStorageItem::SendToOthers); - - if (deckZone->getAlwaysRevealTopCard() && !deckZone->getCards().isEmpty()) { - Event_RevealCards revealEvent; - revealEvent.set_zone_name(deckZone->getName().toStdString()); - revealEvent.set_card_id(0); - deckZone->getCards().first()->getInfo(revealEvent.add_cards()); - - ges.enqueueGameEvent(revealEvent, playerId); - } - - return Response::RespOk; + Server_CardZone *deckZone = zones.value("deck"); + Server_CardZone *handZone = zones.value("hand"); + if (deckZone->getCards().size() < number) + number = deckZone->getCards().size(); + + Event_DrawCards eventOthers; + eventOthers.set_number(number); + Event_DrawCards eventPrivate(eventOthers); + + for (int i = 0; i < number; ++i) { + Server_Card *card = deckZone->getCard(0, NULL, true); + handZone->insertCard(card, -1, 0); + lastDrawList.append(card->getId()); + + ServerInfo_Card *cardInfo = eventPrivate.add_cards(); + cardInfo->set_id(card->getId()); + cardInfo->set_name(card->getName().toStdString()); + } + + ges.enqueueGameEvent(eventPrivate, playerId, GameEventStorageItem::SendToPrivate, playerId); + ges.enqueueGameEvent(eventOthers, playerId, GameEventStorageItem::SendToOthers); + + if (deckZone->getAlwaysRevealTopCard() && !deckZone->getCards().isEmpty()) { + Event_RevealCards revealEvent; + revealEvent.set_zone_name(deckZone->getName().toStdString()); + revealEvent.set_card_id(0); + deckZone->getCards().first()->getInfo(revealEvent.add_cards()); + + ges.enqueueGameEvent(revealEvent, playerId); + } + + return Response::RespOk; } class Server_Player::MoveCardCompareFunctor { private: - int x; + int x; public: - MoveCardCompareFunctor(int _x) : x(_x) { } - inline bool operator()(QPair a, QPair b) - { - if (a.second < x) { - if (b.second >= x) - return false; - else - return (a.second > b.second); - } else { - if (b.second < x) - return true; - else - return (a.second < b.second); - } - } + MoveCardCompareFunctor(int _x) : x(_x) { } + inline bool operator()(QPair a, QPair b) + { + if (a.second < x) { + if (b.second >= x) + return false; + else + return (a.second > b.second); + } else { + if (b.second < x) + return true; + else + return (a.second < b.second); + } + } }; Response::ResponseCode Server_Player::moveCard(GameEventStorage &ges, Server_CardZone *startzone, const QList &_cards, Server_CardZone *targetzone, int x, int y, bool fixFreeSpaces, bool undoingDraw) { - // Disallow controller change to other zones than the table. - if (((targetzone->getType() != ServerInfo_Zone::PublicZone) || !targetzone->hasCoords()) && (startzone->getPlayer() != targetzone->getPlayer())) - return Response::RespContextError; - - if (!targetzone->hasCoords() && (x == -1)) - x = targetzone->getCards().size(); - - QList > cardsToMove; - QMap cardProperties; - QSet cardIdsToMove; - for (int i = 0; i < _cards.size(); ++i) { - // The same card being moved twice would lead to undefined behaviour. - if (cardIdsToMove.contains(_cards[i]->card_id())) - continue; - cardIdsToMove.insert(_cards[i]->card_id()); - - // Consistency checks. In case the command contains illegal moves, try to resolve the legal ones still. - int position; - Server_Card *card = startzone->getCard(_cards[i]->card_id(), &position); - if (!card) - return Response::RespNameNotFound; - if (card->getParentCard()) - continue; - if (!card->getAttachedCards().isEmpty() && !targetzone->isColumnEmpty(x, y)) - continue; - cardsToMove.append(QPair(card, position)); - cardProperties.insert(card, _cards[i]); - } - // In case all moves were filtered out, abort. - if (cardsToMove.isEmpty()) - return Response::RespContextError; - - MoveCardCompareFunctor cmp(startzone == targetzone ? -1 : x); - qSort(cardsToMove.begin(), cardsToMove.end(), cmp); - - bool secondHalf = false; - int xIndex = -1; - for (int cardIndex = 0; cardIndex < cardsToMove.size(); ++cardIndex) { - Server_Card *card = cardsToMove[cardIndex].first; - const CardToMove *thisCardProperties = cardProperties.value(card); - bool faceDown = thisCardProperties->has_face_down() ? thisCardProperties->face_down() : card->getFaceDown(); - if (!targetzone->hasCoords()) - faceDown = false; - - int originalPosition = cardsToMove[cardIndex].second; - int position = startzone->removeCard(card); - if (startzone->getName() == "hand") { - if (undoingDraw) - lastDrawList.removeAt(lastDrawList.indexOf(card->getId())); - else if (lastDrawList.contains(card->getId())) - lastDrawList.clear(); - } - - if ((startzone == targetzone) && !startzone->hasCoords()) { - if (!secondHalf && (originalPosition < x)) { - xIndex = -1; - secondHalf = true; - } else if (secondHalf) - --xIndex; - else - ++xIndex; - } else - ++xIndex; - int newX = x + xIndex; - - // Attachment relationships can be retained when moving a card onto the opponent's table - if (startzone->getName() != targetzone->getName()) { - // Delete all attachment relationships - if (card->getParentCard()) - card->setParentCard(0); - - // Make a copy of the list because the original one gets modified during the loop - QList attachedCards = card->getAttachedCards(); - for (int i = 0; i < attachedCards.size(); ++i) - attachedCards[i]->getZone()->getPlayer()->unattachCard(ges, attachedCards[i]); - } - - if (startzone != targetzone) { - // Delete all arrows from and to the card - const QList &players = game->getPlayers().values(); - for (int i = 0; i < players.size(); ++i) { - QList arrowsToDelete; - QMapIterator arrowIterator(players[i]->getArrows()); - while (arrowIterator.hasNext()) { - Server_Arrow *arrow = arrowIterator.next().value(); - if ((arrow->getStartCard() == card) || (arrow->getTargetItem() == card)) - arrowsToDelete.append(arrow->getId()); - } - for (int j = 0; j < arrowsToDelete.size(); ++j) - players[i]->deleteArrow(arrowsToDelete[j]); - } - } - - int publicNewX; - if (card->getDestroyOnZoneChange() && (startzone->getName() != targetzone->getName())) { - Event_DestroyCard event; - event.set_zone_name(startzone->getName().toStdString()); - event.set_card_id(card->getId()); - ges.enqueueGameEvent(event, playerId); - - card->deleteLater(); - } else { - if (!targetzone->hasCoords()) { - y = 0; - card->resetState(); - } else - newX = targetzone->getFreeGridColumn(newX, y, card->getName()); - - targetzone->insertCard(card, newX, y); - - bool targetBeingLookedAt = (targetzone->getType() != ServerInfo_Zone::HiddenZone) || (targetzone->getCardsBeingLookedAt() > newX) || (targetzone->getCardsBeingLookedAt() == -1); - bool sourceBeingLookedAt = (startzone->getType() != ServerInfo_Zone::HiddenZone) || (startzone->getCardsBeingLookedAt() > position) || (startzone->getCardsBeingLookedAt() == -1); - - bool targetHiddenToPlayer = faceDown || !targetBeingLookedAt; - bool targetHiddenToOthers = faceDown || (targetzone->getType() != ServerInfo_Zone::PublicZone); - bool sourceHiddenToPlayer = card->getFaceDown() || !sourceBeingLookedAt; - bool sourceHiddenToOthers = card->getFaceDown() || (startzone->getType() != ServerInfo_Zone::PublicZone); - - QString privateCardName, publicCardName; - if (!(sourceHiddenToPlayer && targetHiddenToPlayer)) - privateCardName = card->getName(); - if (!(sourceHiddenToOthers && targetHiddenToOthers)) - publicCardName = card->getName(); - - int oldCardId = card->getId(); - if ((faceDown && (startzone != targetzone)) || (targetzone->getPlayer() != startzone->getPlayer())) - card->setId(targetzone->getPlayer()->newCardId()); - card->setFaceDown(faceDown); - - // The player does not get to see which card he moved if it moves between two parts of hidden zones which - // are not being looked at. - int privateNewCardId = card->getId(); - int privateOldCardId = oldCardId; - if (!targetBeingLookedAt && !sourceBeingLookedAt) { - privateOldCardId = -1; - privateNewCardId = -1; - privateCardName = QString(); - } - int privatePosition = -1; - if (startzone->getType() == ServerInfo_Zone::HiddenZone) - privatePosition = position; - - publicNewX = newX; - - Event_MoveCard eventOthers; - eventOthers.set_start_player_id(startzone->getPlayer()->getPlayerId()); - eventOthers.set_start_zone(startzone->getName().toStdString()); - eventOthers.set_target_player_id(targetzone->getPlayer()->getPlayerId()); - if (startzone != targetzone) - eventOthers.set_target_zone(targetzone->getName().toStdString()); - eventOthers.set_y(y); - eventOthers.set_face_down(faceDown); - - Event_MoveCard eventPrivate(eventOthers); - eventPrivate.set_card_id(privateOldCardId); - if (!privateCardName.isEmpty()) - eventPrivate.set_card_name(privateCardName.toStdString()); - eventPrivate.set_position(privatePosition); - eventPrivate.set_new_card_id(privateNewCardId); - eventPrivate.set_x(newX); - - // Other players do not get to see the start and/or target position of the card if the respective - // part of the zone is being looked at. The information is not needed anyway because in hidden zones, - // all cards are equal. - if ( - ((startzone->getType() == ServerInfo_Zone::HiddenZone) && ((startzone->getCardsBeingLookedAt() > position) || (startzone->getCardsBeingLookedAt() == -1))) - || (startzone->getType() == ServerInfo_Zone::PublicZone) - ) - position = -1; - if ((targetzone->getType() == ServerInfo_Zone::HiddenZone) && ((targetzone->getCardsBeingLookedAt() > newX) || (targetzone->getCardsBeingLookedAt() == -1))) - publicNewX = -1; - - eventOthers.set_x(publicNewX); - eventOthers.set_position(position); - if ((startzone->getType() == ServerInfo_Zone::PublicZone) || (targetzone->getType() == ServerInfo_Zone::PublicZone)) { - eventOthers.set_card_id(oldCardId); - if (!publicCardName.isEmpty()) - eventOthers.set_card_name(publicCardName.toStdString()); - eventOthers.set_new_card_id(card->getId()); - } - - ges.enqueueGameEvent(eventPrivate, playerId, GameEventStorageItem::SendToPrivate, playerId); - ges.enqueueGameEvent(eventOthers, playerId, GameEventStorageItem::SendToOthers); - - if (thisCardProperties->tapped()) - setCardAttrHelper(ges, targetzone->getName(), card->getId(), AttrTapped, "1"); - QString ptString = QString::fromStdString(thisCardProperties->pt()); - if (!ptString.isEmpty() && !faceDown) - setCardAttrHelper(ges, targetzone->getName(), card->getId(), AttrPT, ptString); - } - if (startzone->getAlwaysRevealTopCard() && !startzone->getCards().isEmpty() && (originalPosition == 0)) { - Event_RevealCards revealEvent; - revealEvent.set_zone_name(startzone->getName().toStdString()); - revealEvent.set_card_id(0); - startzone->getCards().first()->getInfo(revealEvent.add_cards()); - - ges.enqueueGameEvent(revealEvent, playerId); - } - if (targetzone->getAlwaysRevealTopCard() && !targetzone->getCards().isEmpty() && (newX == 0)) { - Event_RevealCards revealEvent; - revealEvent.set_zone_name(targetzone->getName().toStdString()); - revealEvent.set_card_id(0); - targetzone->getCards().first()->getInfo(revealEvent.add_cards()); - - ges.enqueueGameEvent(revealEvent, playerId); - } - } - if (undoingDraw) - ges.setGameEventContext(Context_UndoDraw()); - else - ges.setGameEventContext(Context_MoveCard()); - - if (startzone->hasCoords() && fixFreeSpaces) - startzone->fixFreeSpaces(ges); - - return Response::RespOk; + // Disallow controller change to other zones than the table. + if (((targetzone->getType() != ServerInfo_Zone::PublicZone) || !targetzone->hasCoords()) && (startzone->getPlayer() != targetzone->getPlayer())) + return Response::RespContextError; + + if (!targetzone->hasCoords() && (x == -1)) + x = targetzone->getCards().size(); + + QList > cardsToMove; + QMap cardProperties; + QSet cardIdsToMove; + for (int i = 0; i < _cards.size(); ++i) { + // The same card being moved twice would lead to undefined behaviour. + if (cardIdsToMove.contains(_cards[i]->card_id())) + continue; + cardIdsToMove.insert(_cards[i]->card_id()); + + // Consistency checks. In case the command contains illegal moves, try to resolve the legal ones still. + int position; + Server_Card *card = startzone->getCard(_cards[i]->card_id(), &position); + if (!card) + return Response::RespNameNotFound; + if (card->getParentCard()) + continue; + if (!card->getAttachedCards().isEmpty() && !targetzone->isColumnEmpty(x, y)) + continue; + cardsToMove.append(QPair(card, position)); + cardProperties.insert(card, _cards[i]); + } + // In case all moves were filtered out, abort. + if (cardsToMove.isEmpty()) + return Response::RespContextError; + + MoveCardCompareFunctor cmp(startzone == targetzone ? -1 : x); + qSort(cardsToMove.begin(), cardsToMove.end(), cmp); + + bool secondHalf = false; + int xIndex = -1; + for (int cardIndex = 0; cardIndex < cardsToMove.size(); ++cardIndex) { + Server_Card *card = cardsToMove[cardIndex].first; + const CardToMove *thisCardProperties = cardProperties.value(card); + bool faceDown = thisCardProperties->has_face_down() ? thisCardProperties->face_down() : card->getFaceDown(); + if (!targetzone->hasCoords()) + faceDown = false; + + int originalPosition = cardsToMove[cardIndex].second; + int position = startzone->removeCard(card); + if (startzone->getName() == "hand") { + if (undoingDraw) + lastDrawList.removeAt(lastDrawList.indexOf(card->getId())); + else if (lastDrawList.contains(card->getId())) + lastDrawList.clear(); + } + + if ((startzone == targetzone) && !startzone->hasCoords()) { + if (!secondHalf && (originalPosition < x)) { + xIndex = -1; + secondHalf = true; + } else if (secondHalf) + --xIndex; + else + ++xIndex; + } else + ++xIndex; + int newX = x + xIndex; + + // Attachment relationships can be retained when moving a card onto the opponent's table + if (startzone->getName() != targetzone->getName()) { + // Delete all attachment relationships + if (card->getParentCard()) + card->setParentCard(0); + + // Make a copy of the list because the original one gets modified during the loop + QList attachedCards = card->getAttachedCards(); + for (int i = 0; i < attachedCards.size(); ++i) + attachedCards[i]->getZone()->getPlayer()->unattachCard(ges, attachedCards[i]); + } + + if (startzone != targetzone) { + // Delete all arrows from and to the card + const QList &players = game->getPlayers().values(); + for (int i = 0; i < players.size(); ++i) { + QList arrowsToDelete; + QMapIterator arrowIterator(players[i]->getArrows()); + while (arrowIterator.hasNext()) { + Server_Arrow *arrow = arrowIterator.next().value(); + if ((arrow->getStartCard() == card) || (arrow->getTargetItem() == card)) + arrowsToDelete.append(arrow->getId()); + } + for (int j = 0; j < arrowsToDelete.size(); ++j) + players[i]->deleteArrow(arrowsToDelete[j]); + } + } + + int publicNewX; + if (card->getDestroyOnZoneChange() && (startzone->getName() != targetzone->getName())) { + Event_DestroyCard event; + event.set_zone_name(startzone->getName().toStdString()); + event.set_card_id(card->getId()); + ges.enqueueGameEvent(event, playerId); + + card->deleteLater(); + } else { + if (!targetzone->hasCoords()) { + y = 0; + card->resetState(); + } else + newX = targetzone->getFreeGridColumn(newX, y, card->getName()); + + targetzone->insertCard(card, newX, y); + + bool targetBeingLookedAt = (targetzone->getType() != ServerInfo_Zone::HiddenZone) || (targetzone->getCardsBeingLookedAt() > newX) || (targetzone->getCardsBeingLookedAt() == -1); + bool sourceBeingLookedAt = (startzone->getType() != ServerInfo_Zone::HiddenZone) || (startzone->getCardsBeingLookedAt() > position) || (startzone->getCardsBeingLookedAt() == -1); + + bool targetHiddenToPlayer = faceDown || !targetBeingLookedAt; + bool targetHiddenToOthers = faceDown || (targetzone->getType() != ServerInfo_Zone::PublicZone); + bool sourceHiddenToPlayer = card->getFaceDown() || !sourceBeingLookedAt; + bool sourceHiddenToOthers = card->getFaceDown() || (startzone->getType() != ServerInfo_Zone::PublicZone); + + QString privateCardName, publicCardName; + if (!(sourceHiddenToPlayer && targetHiddenToPlayer)) + privateCardName = card->getName(); + if (!(sourceHiddenToOthers && targetHiddenToOthers)) + publicCardName = card->getName(); + + int oldCardId = card->getId(); + if ((faceDown && (startzone != targetzone)) || (targetzone->getPlayer() != startzone->getPlayer())) + card->setId(targetzone->getPlayer()->newCardId()); + card->setFaceDown(faceDown); + + // The player does not get to see which card he moved if it moves between two parts of hidden zones which + // are not being looked at. + int privateNewCardId = card->getId(); + int privateOldCardId = oldCardId; + if (!targetBeingLookedAt && !sourceBeingLookedAt) { + privateOldCardId = -1; + privateNewCardId = -1; + privateCardName = QString(); + } + int privatePosition = -1; + if (startzone->getType() == ServerInfo_Zone::HiddenZone) + privatePosition = position; + + publicNewX = newX; + + Event_MoveCard eventOthers; + eventOthers.set_start_player_id(startzone->getPlayer()->getPlayerId()); + eventOthers.set_start_zone(startzone->getName().toStdString()); + eventOthers.set_target_player_id(targetzone->getPlayer()->getPlayerId()); + if (startzone != targetzone) + eventOthers.set_target_zone(targetzone->getName().toStdString()); + eventOthers.set_y(y); + eventOthers.set_face_down(faceDown); + + Event_MoveCard eventPrivate(eventOthers); + eventPrivate.set_card_id(privateOldCardId); + if (!privateCardName.isEmpty()) + eventPrivate.set_card_name(privateCardName.toStdString()); + eventPrivate.set_position(privatePosition); + eventPrivate.set_new_card_id(privateNewCardId); + eventPrivate.set_x(newX); + + // Other players do not get to see the start and/or target position of the card if the respective + // part of the zone is being looked at. The information is not needed anyway because in hidden zones, + // all cards are equal. + if ( + ((startzone->getType() == ServerInfo_Zone::HiddenZone) && ((startzone->getCardsBeingLookedAt() > position) || (startzone->getCardsBeingLookedAt() == -1))) + || (startzone->getType() == ServerInfo_Zone::PublicZone) + ) + position = -1; + if ((targetzone->getType() == ServerInfo_Zone::HiddenZone) && ((targetzone->getCardsBeingLookedAt() > newX) || (targetzone->getCardsBeingLookedAt() == -1))) + publicNewX = -1; + + eventOthers.set_x(publicNewX); + eventOthers.set_position(position); + if ((startzone->getType() == ServerInfo_Zone::PublicZone) || (targetzone->getType() == ServerInfo_Zone::PublicZone)) { + eventOthers.set_card_id(oldCardId); + if (!publicCardName.isEmpty()) + eventOthers.set_card_name(publicCardName.toStdString()); + eventOthers.set_new_card_id(card->getId()); + } + + ges.enqueueGameEvent(eventPrivate, playerId, GameEventStorageItem::SendToPrivate, playerId); + ges.enqueueGameEvent(eventOthers, playerId, GameEventStorageItem::SendToOthers); + + if (thisCardProperties->tapped()) + setCardAttrHelper(ges, targetzone->getName(), card->getId(), AttrTapped, "1"); + QString ptString = QString::fromStdString(thisCardProperties->pt()); + if (!ptString.isEmpty() && !faceDown) + setCardAttrHelper(ges, targetzone->getName(), card->getId(), AttrPT, ptString); + } + if (startzone->getAlwaysRevealTopCard() && !startzone->getCards().isEmpty() && (originalPosition == 0)) { + Event_RevealCards revealEvent; + revealEvent.set_zone_name(startzone->getName().toStdString()); + revealEvent.set_card_id(0); + startzone->getCards().first()->getInfo(revealEvent.add_cards()); + + ges.enqueueGameEvent(revealEvent, playerId); + } + if (targetzone->getAlwaysRevealTopCard() && !targetzone->getCards().isEmpty() && (newX == 0)) { + Event_RevealCards revealEvent; + revealEvent.set_zone_name(targetzone->getName().toStdString()); + revealEvent.set_card_id(0); + targetzone->getCards().first()->getInfo(revealEvent.add_cards()); + + ges.enqueueGameEvent(revealEvent, playerId); + } + } + if (undoingDraw) + ges.setGameEventContext(Context_UndoDraw()); + else + ges.setGameEventContext(Context_MoveCard()); + + if (startzone->hasCoords() && fixFreeSpaces) + startzone->fixFreeSpaces(ges); + + return Response::RespOk; } void Server_Player::unattachCard(GameEventStorage &ges, Server_Card *card) { - Server_CardZone *zone = card->getZone(); - Server_Card *parentCard = card->getParentCard(); - card->setParentCard(0); - - Event_AttachCard event; - event.set_start_zone(zone->getName().toStdString()); - event.set_card_id(card->getId()); - ges.enqueueGameEvent(event, playerId); - - CardToMove *cardToMove = new CardToMove; - cardToMove->set_card_id(card->getId()); - moveCard(ges, zone, QList() << cardToMove, zone, -1, card->getY(), card->getFaceDown()); - delete cardToMove; - - if (parentCard->getZone()) - parentCard->getZone()->updateCardCoordinates(parentCard, parentCard->getX(), parentCard->getY()); + Server_CardZone *zone = card->getZone(); + Server_Card *parentCard = card->getParentCard(); + card->setParentCard(0); + + Event_AttachCard event; + event.set_start_zone(zone->getName().toStdString()); + event.set_card_id(card->getId()); + ges.enqueueGameEvent(event, playerId); + + CardToMove *cardToMove = new CardToMove; + cardToMove->set_card_id(card->getId()); + moveCard(ges, zone, QList() << cardToMove, zone, -1, card->getY(), card->getFaceDown()); + delete cardToMove; + + if (parentCard->getZone()) + parentCard->getZone()->updateCardCoordinates(parentCard, parentCard->getX(), parentCard->getY()); } Response::ResponseCode Server_Player::setCardAttrHelper(GameEventStorage &ges, const QString &zoneName, int cardId, CardAttribute attribute, const QString &attrValue) { - Server_CardZone *zone = getZones().value(zoneName); - if (!zone) - return Response::RespNameNotFound; - if (!zone->hasCoords()) - return Response::RespContextError; + Server_CardZone *zone = getZones().value(zoneName); + if (!zone) + return Response::RespNameNotFound; + if (!zone->hasCoords()) + return Response::RespContextError; - QString result; - if (cardId == -1) { - QListIterator CardIterator(zone->getCards()); - while (CardIterator.hasNext()) { - result = CardIterator.next()->setAttribute(attribute, attrValue, true); - if (result.isNull()) - return Response::RespInvalidCommand; - } - } else { - Server_Card *card = zone->getCard(cardId); - if (!card) - return Response::RespNameNotFound; - result = card->setAttribute(attribute, attrValue, false); - if (result.isNull()) - return Response::RespInvalidCommand; - } - - Event_SetCardAttr event; - event.set_zone_name(zone->getName().toStdString()); - if (cardId != -1) - event.set_card_id(cardId); - event.set_attribute(attribute); - event.set_attr_value(result.toStdString()); - ges.enqueueGameEvent(event, playerId); - - return Response::RespOk; + QString result; + if (cardId == -1) { + QListIterator CardIterator(zone->getCards()); + while (CardIterator.hasNext()) { + result = CardIterator.next()->setAttribute(attribute, attrValue, true); + if (result.isNull()) + return Response::RespInvalidCommand; + } + } else { + Server_Card *card = zone->getCard(cardId); + if (!card) + return Response::RespNameNotFound; + result = card->setAttribute(attribute, attrValue, false); + if (result.isNull()) + return Response::RespInvalidCommand; + } + + Event_SetCardAttr event; + event.set_zone_name(zone->getName().toStdString()); + if (cardId != -1) + event.set_card_id(cardId); + event.set_attribute(attribute); + event.set_attr_value(result.toStdString()); + ges.enqueueGameEvent(event, playerId); + + return Response::RespOk; } Response::ResponseCode Server_Player::cmdLeaveGame(const Command_LeaveGame & /*cmd*/, ResponseContainer & /*rc*/, GameEventStorage & /*ges*/) { - game->removePlayer(this); - return Response::RespOk; + game->removePlayer(this); + return Response::RespOk; } Response::ResponseCode Server_Player::cmdKickFromGame(const Command_KickFromGame &cmd, ResponseContainer & /*rc*/, GameEventStorage & /*ges*/) { - if ((game->getHostId() != playerId) && !(userInfo->user_level() & ServerInfo_User::IsModerator)) - return Response::RespFunctionNotAllowed; - - if (!game->kickPlayer(cmd.player_id())) - return Response::RespNameNotFound; - - return Response::RespOk; + if ((game->getHostId() != playerId) && !(userInfo->user_level() & ServerInfo_User::IsModerator)) + return Response::RespFunctionNotAllowed; + + if (!game->kickPlayer(cmd.player_id())) + return Response::RespNameNotFound; + + return Response::RespOk; } Response::ResponseCode Server_Player::cmdDeckSelect(const Command_DeckSelect &cmd, ResponseContainer &rc, GameEventStorage &ges) { - if (spectator) - return Response::RespFunctionNotAllowed; - - DeckList *newDeck; - if (cmd.has_deck_id()) { - try { - newDeck = game->getRoom()->getServer()->getDatabaseInterface()->getDeckFromDatabase(cmd.deck_id(), userInfo->id()); - } catch(Response::ResponseCode r) { - return r; - } - } else - newDeck = new DeckList(QString::fromStdString(cmd.deck())); - - if (!newDeck) - return Response::RespInternalError; - - delete deck; - deck = newDeck; - sideboardLocked = true; - - Event_PlayerPropertiesChanged event; - event.mutable_player_properties()->set_sideboard_locked(true); - event.mutable_player_properties()->set_deck_hash(deck->getDeckHash().toStdString()); - ges.enqueueGameEvent(event, playerId); - - Context_DeckSelect context; - context.set_deck_hash(deck->getDeckHash().toStdString()); + if (spectator) + return Response::RespFunctionNotAllowed; + + DeckList *newDeck; + if (cmd.has_deck_id()) { + try { + newDeck = game->getRoom()->getServer()->getDatabaseInterface()->getDeckFromDatabase(cmd.deck_id(), userInfo->id()); + } catch(Response::ResponseCode r) { + return r; + } + } else + newDeck = new DeckList(QString::fromStdString(cmd.deck())); + + if (!newDeck) + return Response::RespInternalError; + + delete deck; + deck = newDeck; + sideboardLocked = true; + + Event_PlayerPropertiesChanged event; + event.mutable_player_properties()->set_sideboard_locked(true); + event.mutable_player_properties()->set_deck_hash(deck->getDeckHash().toStdString()); + ges.enqueueGameEvent(event, playerId); + + Context_DeckSelect context; + context.set_deck_hash(deck->getDeckHash().toStdString()); context.set_sideboard_size(deck->getSideboardSize()); - ges.setGameEventContext(context); - - Response_DeckDownload *re = new Response_DeckDownload; - re->set_deck(deck->writeToString_Native().toStdString()); - - rc.setResponseExtension(re); - return Response::RespOk; + ges.setGameEventContext(context); + + Response_DeckDownload *re = new Response_DeckDownload; + re->set_deck(deck->writeToString_Native().toStdString()); + + rc.setResponseExtension(re); + return Response::RespOk; } Response::ResponseCode Server_Player::cmdSetSideboardPlan(const Command_SetSideboardPlan &cmd, ResponseContainer & /*rc*/, GameEventStorage & /*ges*/) { - if (spectator) - return Response::RespFunctionNotAllowed; - if (readyStart) - return Response::RespContextError; - if (!deck) - return Response::RespContextError; - if (sideboardLocked) - return Response::RespContextError; - - QList sideboardPlan; - for (int i = 0; i < cmd.move_list_size(); ++i) - sideboardPlan.append(cmd.move_list(i)); - deck->setCurrentSideboardPlan(sideboardPlan); - - return Response::RespOk; + if (spectator) + return Response::RespFunctionNotAllowed; + if (readyStart) + return Response::RespContextError; + if (!deck) + return Response::RespContextError; + if (sideboardLocked) + return Response::RespContextError; + + QList sideboardPlan; + for (int i = 0; i < cmd.move_list_size(); ++i) + sideboardPlan.append(cmd.move_list(i)); + deck->setCurrentSideboardPlan(sideboardPlan); + + return Response::RespOk; } Response::ResponseCode Server_Player::cmdSetSideboardLock(const Command_SetSideboardLock &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) - return Response::RespFunctionNotAllowed; - if (readyStart) - return Response::RespContextError; - if (!deck) - return Response::RespContextError; - if (sideboardLocked == cmd.locked()) - return Response::RespContextError; - - sideboardLocked = cmd.locked(); - if (sideboardLocked) - deck->setCurrentSideboardPlan(QList()); - - Event_PlayerPropertiesChanged event; - event.mutable_player_properties()->set_sideboard_locked(sideboardLocked); - ges.enqueueGameEvent(event, playerId); - ges.setGameEventContext(Context_SetSideboardLock()); - - return Response::RespOk; + if (spectator) + return Response::RespFunctionNotAllowed; + if (readyStart) + return Response::RespContextError; + if (!deck) + return Response::RespContextError; + if (sideboardLocked == cmd.locked()) + return Response::RespContextError; + + sideboardLocked = cmd.locked(); + if (sideboardLocked) + deck->setCurrentSideboardPlan(QList()); + + Event_PlayerPropertiesChanged event; + event.mutable_player_properties()->set_sideboard_locked(sideboardLocked); + ges.enqueueGameEvent(event, playerId); + ges.setGameEventContext(Context_SetSideboardLock()); + + return Response::RespOk; } Response::ResponseCode Server_Player::cmdConcede(const Command_Concede & /*cmd*/, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) - return Response::RespFunctionNotAllowed; - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (conceded) - return Response::RespContextError; - - setConceded(true); - game->removeArrowsRelatedToPlayer(ges, this); - game->unattachCards(ges, this); - clearZones(); - - Event_PlayerPropertiesChanged event; - event.mutable_player_properties()->set_conceded(true); - ges.enqueueGameEvent(event, playerId); - ges.setGameEventContext(Context_Concede()); - - game->stopGameIfFinished(); - if (game->getGameStarted() && (game->getActivePlayer() == playerId)) - game->nextTurn(); - - return Response::RespOk; + if (spectator) + return Response::RespFunctionNotAllowed; + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + setConceded(true); + game->removeArrowsRelatedToPlayer(ges, this); + game->unattachCards(ges, this); + clearZones(); + + Event_PlayerPropertiesChanged event; + event.mutable_player_properties()->set_conceded(true); + ges.enqueueGameEvent(event, playerId); + ges.setGameEventContext(Context_Concede()); + + game->stopGameIfFinished(); + if (game->getGameStarted() && (game->getActivePlayer() == playerId)) + game->nextTurn(); + + return Response::RespOk; } Response::ResponseCode Server_Player::cmdReadyStart(const Command_ReadyStart &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) - return Response::RespFunctionNotAllowed; - - if (!deck || game->getGameStarted()) - return Response::RespContextError; + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!deck || game->getGameStarted()) + return Response::RespContextError; - if (readyStart == cmd.ready()) - return Response::RespContextError; - - setReadyStart(cmd.ready()); - - Event_PlayerPropertiesChanged event; - event.mutable_player_properties()->set_ready_start(cmd.ready()); - ges.enqueueGameEvent(event, playerId); - ges.setGameEventContext(Context_ReadyStart()); - - if (cmd.ready()) - game->startGameIfReady(); - - return Response::RespOk; + if (readyStart == cmd.ready()) + return Response::RespContextError; + + setReadyStart(cmd.ready()); + + Event_PlayerPropertiesChanged event; + event.mutable_player_properties()->set_ready_start(cmd.ready()); + ges.enqueueGameEvent(event, playerId); + ges.setGameEventContext(Context_ReadyStart()); + + if (cmd.ready()) + game->startGameIfReady(); + + return Response::RespOk; } Response::ResponseCode Server_Player::cmdGameSay(const Command_GameSay &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator && !game->getSpectatorsCanTalk() && !(userInfo->user_level() & ServerInfo_User::IsModerator)) - return Response::RespFunctionNotAllowed; - - Event_GameSay event; - event.set_message(cmd.message()); - ges.enqueueGameEvent(event, playerId); - - return Response::RespOk; + if (spectator && !game->getSpectatorsCanTalk() && !(userInfo->user_level() & ServerInfo_User::IsModerator)) + return Response::RespFunctionNotAllowed; + + Event_GameSay event; + event.set_message(cmd.message()); + ges.enqueueGameEvent(event, playerId); + + return Response::RespOk; } Response::ResponseCode Server_Player::cmdShuffle(const Command_Shuffle & /*cmd*/, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) - return Response::RespFunctionNotAllowed; - - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (conceded) - return Response::RespContextError; - - Server_CardZone *deckZone = zones.value("deck"); - deckZone->shuffle(); - - Event_Shuffle event; - event.set_zone_name("deck"); - ges.enqueueGameEvent(event, playerId); - - if (deckZone->getAlwaysRevealTopCard() && !deckZone->getCards().isEmpty()) { - Event_RevealCards revealEvent; - revealEvent.set_zone_name(deckZone->getName().toStdString()); - revealEvent.set_card_id(0); - deckZone->getCards().first()->getInfo(revealEvent.add_cards()); - - ges.enqueueGameEvent(revealEvent, playerId); - } - - return Response::RespOk; + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + Server_CardZone *deckZone = zones.value("deck"); + deckZone->shuffle(); + + Event_Shuffle event; + event.set_zone_name("deck"); + ges.enqueueGameEvent(event, playerId); + + if (deckZone->getAlwaysRevealTopCard() && !deckZone->getCards().isEmpty()) { + Event_RevealCards revealEvent; + revealEvent.set_zone_name(deckZone->getName().toStdString()); + revealEvent.set_card_id(0); + deckZone->getCards().first()->getInfo(revealEvent.add_cards()); + + ges.enqueueGameEvent(revealEvent, playerId); + } + + return Response::RespOk; } Response::ResponseCode Server_Player::cmdMulligan(const Command_Mulligan & /*cmd*/, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) - return Response::RespFunctionNotAllowed; - - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (conceded) - return Response::RespContextError; - - Server_CardZone *hand = zones.value("hand"); - int number = (hand->getCards().size() <= 1) ? initialCards : hand->getCards().size() - 1; - - Server_CardZone *deck = zones.value("deck"); - while (!hand->getCards().isEmpty()) { - CardToMove *cardToMove = new CardToMove; - cardToMove->set_card_id(hand->getCards().first()->getId()); - moveCard(ges, hand, QList() << cardToMove, deck, 0, 0, false); - delete cardToMove; - } - - deck->shuffle(); - ges.enqueueGameEvent(Event_Shuffle(), playerId); + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + Server_CardZone *hand = zones.value("hand"); + int number = (hand->getCards().size() <= 1) ? initialCards : hand->getCards().size() - 1; + + Server_CardZone *deck = zones.value("deck"); + while (!hand->getCards().isEmpty()) { + CardToMove *cardToMove = new CardToMove; + cardToMove->set_card_id(hand->getCards().first()->getId()); + moveCard(ges, hand, QList() << cardToMove, deck, 0, 0, false); + delete cardToMove; + } + + deck->shuffle(); + ges.enqueueGameEvent(Event_Shuffle(), playerId); - drawCards(ges, number); - - if (number == initialCards) - number = -1; - - Context_Mulligan context; - context.set_number(number); - ges.setGameEventContext(context); + drawCards(ges, number); + + if (number == initialCards) + number = -1; + + Context_Mulligan context; + context.set_number(number); + ges.setGameEventContext(context); - return Response::RespOk; + return Response::RespOk; } Response::ResponseCode Server_Player::cmdRollDie(const Command_RollDie &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) - return Response::RespFunctionNotAllowed; - if (conceded) - return Response::RespContextError; - - Event_RollDie event; - event.set_sides(cmd.sides()); - event.set_value(rng->rand(1, cmd.sides())); - ges.enqueueGameEvent(event, playerId); - - return Response::RespOk; + if (spectator) + return Response::RespFunctionNotAllowed; + if (conceded) + return Response::RespContextError; + + Event_RollDie event; + event.set_sides(cmd.sides()); + event.set_value(rng->rand(1, cmd.sides())); + ges.enqueueGameEvent(event, playerId); + + return Response::RespOk; } Response::ResponseCode Server_Player::cmdDrawCards(const Command_DrawCards &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) - return Response::RespFunctionNotAllowed; - - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (conceded) - return Response::RespContextError; - - return drawCards(ges, cmd.number()); + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + return drawCards(ges, cmd.number()); } Response::ResponseCode Server_Player::cmdUndoDraw(const Command_UndoDraw & /*cmd*/, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) - return Response::RespFunctionNotAllowed; - - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (conceded) - return Response::RespContextError; - - if (lastDrawList.isEmpty()) - return Response::RespContextError; - - Response::ResponseCode retVal; - CardToMove *cardToMove = new CardToMove; - cardToMove->set_card_id(lastDrawList.takeLast()); - retVal = moveCard(ges, zones.value("hand"), QList() << cardToMove, zones.value("deck"), 0, 0, false, true); - delete cardToMove; - - return retVal; + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + if (lastDrawList.isEmpty()) + return Response::RespContextError; + + Response::ResponseCode retVal; + CardToMove *cardToMove = new CardToMove; + cardToMove->set_card_id(lastDrawList.takeLast()); + retVal = moveCard(ges, zones.value("hand"), QList() << cardToMove, zones.value("deck"), 0, 0, false, true); + delete cardToMove; + + return retVal; } Response::ResponseCode Server_Player::cmdMoveCard(const Command_MoveCard &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) - return Response::RespFunctionNotAllowed; - - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (conceded) - return Response::RespContextError; - - Server_Player *startPlayer = game->getPlayers().value(cmd.has_start_player_id() ? cmd.start_player_id() : playerId); - if (!startPlayer) - return Response::RespNameNotFound; - Server_CardZone *startZone = startPlayer->getZones().value(QString::fromStdString(cmd.start_zone())); - if (!startZone) - return Response::RespNameNotFound; - - if ((startPlayer != this) && (!startZone->getPlayersWithWritePermission().contains(playerId))) - return Response::RespContextError; - - Server_Player *targetPlayer = game->getPlayers().value(cmd.target_player_id()); - if (!targetPlayer) - return Response::RespNameNotFound; - Server_CardZone *targetZone = targetPlayer->getZones().value(QString::fromStdString(cmd.target_zone())); - if (!targetZone) - return Response::RespNameNotFound; - - if ((startPlayer != this) && (targetPlayer != this)) - return Response::RespContextError; - - QList cardsToMove; - for (int i = 0; i < cmd.cards_to_move().card_size(); ++i) - cardsToMove.append(&cmd.cards_to_move().card(i)); - - return moveCard(ges, startZone, cardsToMove, targetZone, cmd.x(), cmd.y()); + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + Server_Player *startPlayer = game->getPlayers().value(cmd.has_start_player_id() ? cmd.start_player_id() : playerId); + if (!startPlayer) + return Response::RespNameNotFound; + Server_CardZone *startZone = startPlayer->getZones().value(QString::fromStdString(cmd.start_zone())); + if (!startZone) + return Response::RespNameNotFound; + + if ((startPlayer != this) && (!startZone->getPlayersWithWritePermission().contains(playerId))) + return Response::RespContextError; + + Server_Player *targetPlayer = game->getPlayers().value(cmd.target_player_id()); + if (!targetPlayer) + return Response::RespNameNotFound; + Server_CardZone *targetZone = targetPlayer->getZones().value(QString::fromStdString(cmd.target_zone())); + if (!targetZone) + return Response::RespNameNotFound; + + if ((startPlayer != this) && (targetPlayer != this)) + return Response::RespContextError; + + QList cardsToMove; + for (int i = 0; i < cmd.cards_to_move().card_size(); ++i) + cardsToMove.append(&cmd.cards_to_move().card(i)); + + return moveCard(ges, startZone, cardsToMove, targetZone, cmd.x(), cmd.y()); } Response::ResponseCode Server_Player::cmdFlipCard(const Command_FlipCard &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) - return Response::RespFunctionNotAllowed; - - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (conceded) - return Response::RespContextError; - - Server_CardZone *zone = zones.value(QString::fromStdString(cmd.zone())); - if (!zone) - return Response::RespNameNotFound; - if (!zone->hasCoords()) - return Response::RespContextError; - - Server_Card *card = zone->getCard(cmd.card_id()); - if (!card) - return Response::RespNameNotFound; - - const bool faceDown = cmd.face_down(); - if (faceDown == card->getFaceDown()) - return Response::RespContextError; - - card->setFaceDown(faceDown); - - Event_FlipCard event; - event.set_zone_name(zone->getName().toStdString()); - event.set_card_id(card->getId()); - if (!faceDown) - event.set_card_name(card->getName().toStdString()); - event.set_face_down(faceDown); - ges.enqueueGameEvent(event, playerId); - - return Response::RespOk; + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + Server_CardZone *zone = zones.value(QString::fromStdString(cmd.zone())); + if (!zone) + return Response::RespNameNotFound; + if (!zone->hasCoords()) + return Response::RespContextError; + + Server_Card *card = zone->getCard(cmd.card_id()); + if (!card) + return Response::RespNameNotFound; + + const bool faceDown = cmd.face_down(); + if (faceDown == card->getFaceDown()) + return Response::RespContextError; + + card->setFaceDown(faceDown); + + Event_FlipCard event; + event.set_zone_name(zone->getName().toStdString()); + event.set_card_id(card->getId()); + if (!faceDown) + event.set_card_name(card->getName().toStdString()); + event.set_face_down(faceDown); + ges.enqueueGameEvent(event, playerId); + + return Response::RespOk; } Response::ResponseCode Server_Player::cmdAttachCard(const Command_AttachCard &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) - return Response::RespFunctionNotAllowed; - - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (conceded) - return Response::RespContextError; - - Server_CardZone *startzone = zones.value(QString::fromStdString(cmd.start_zone())); - if (!startzone) - return Response::RespNameNotFound; - - Server_Card *card = startzone->getCard(cmd.card_id()); - if (!card) - return Response::RespNameNotFound; + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + Server_CardZone *startzone = zones.value(QString::fromStdString(cmd.start_zone())); + if (!startzone) + return Response::RespNameNotFound; + + Server_Card *card = startzone->getCard(cmd.card_id()); + if (!card) + return Response::RespNameNotFound; - Server_Player *targetPlayer = 0; - Server_CardZone *targetzone = 0; - Server_Card *targetCard = 0; - - if (cmd.has_target_player_id()) { - targetPlayer = game->getPlayers().value(cmd.target_player_id()); - if (!targetPlayer) - return Response::RespNameNotFound; - } else if (!card->getParentCard()) - return Response::RespContextError; - if (targetPlayer) - targetzone = targetPlayer->getZones().value(QString::fromStdString(cmd.target_zone())); - if (targetzone) { - // This is currently enough to make sure cards don't get attached to a card that is not on the table. - // Possibly a flag will have to be introduced for this sometime. - if (!targetzone->hasCoords()) - return Response::RespContextError; - if (cmd.has_target_card_id()) - targetCard = targetzone->getCard(cmd.target_card_id()); - if (targetCard) { - if (targetCard->getParentCard()) - return Response::RespContextError; - } else - return Response::RespNameNotFound; - } - if (!startzone->hasCoords()) - return Response::RespContextError; - - // Get all arrows pointing to or originating from the card being attached and delete them. - QMapIterator playerIterator(game->getPlayers()); - while (playerIterator.hasNext()) { - Server_Player *p = playerIterator.next().value(); - QList arrows = p->getArrows().values(); - QList toDelete; - for (int i = 0; i < arrows.size(); ++i) { - Server_Arrow *a = arrows[i]; - Server_Card *tCard = qobject_cast(a->getTargetItem()); - if ((tCard == card) || (a->getStartCard() == card)) - toDelete.append(a); - } - for (int i = 0; i < toDelete.size(); ++i) { - Event_DeleteArrow event; - event.set_arrow_id(toDelete[i]->getId()); - ges.enqueueGameEvent(event, p->getPlayerId()); - p->deleteArrow(toDelete[i]->getId()); - } - } + Server_Player *targetPlayer = 0; + Server_CardZone *targetzone = 0; + Server_Card *targetCard = 0; + + if (cmd.has_target_player_id()) { + targetPlayer = game->getPlayers().value(cmd.target_player_id()); + if (!targetPlayer) + return Response::RespNameNotFound; + } else if (!card->getParentCard()) + return Response::RespContextError; + if (targetPlayer) + targetzone = targetPlayer->getZones().value(QString::fromStdString(cmd.target_zone())); + if (targetzone) { + // This is currently enough to make sure cards don't get attached to a card that is not on the table. + // Possibly a flag will have to be introduced for this sometime. + if (!targetzone->hasCoords()) + return Response::RespContextError; + if (cmd.has_target_card_id()) + targetCard = targetzone->getCard(cmd.target_card_id()); + if (targetCard) { + if (targetCard->getParentCard()) + return Response::RespContextError; + } else + return Response::RespNameNotFound; + } + if (!startzone->hasCoords()) + return Response::RespContextError; + + // Get all arrows pointing to or originating from the card being attached and delete them. + QMapIterator playerIterator(game->getPlayers()); + while (playerIterator.hasNext()) { + Server_Player *p = playerIterator.next().value(); + QList arrows = p->getArrows().values(); + QList toDelete; + for (int i = 0; i < arrows.size(); ++i) { + Server_Arrow *a = arrows[i]; + Server_Card *tCard = qobject_cast(a->getTargetItem()); + if ((tCard == card) || (a->getStartCard() == card)) + toDelete.append(a); + } + for (int i = 0; i < toDelete.size(); ++i) { + Event_DeleteArrow event; + event.set_arrow_id(toDelete[i]->getId()); + ges.enqueueGameEvent(event, p->getPlayerId()); + p->deleteArrow(toDelete[i]->getId()); + } + } - if (targetCard) { - // Unattach all cards attached to the card being attached. - // Make a copy of the list because its contents change during the loop otherwise. - QList attachedList = card->getAttachedCards(); - for (int i = 0; i < attachedList.size(); ++i) - attachedList[i]->getZone()->getPlayer()->unattachCard(ges, attachedList[i]); - - card->setParentCard(targetCard); - const int oldX = card->getX(); - card->setCoords(-1, card->getY()); - startzone->updateCardCoordinates(card, oldX, card->getY()); - - if (targetzone->isColumnStacked(targetCard->getX(), targetCard->getY())) { - CardToMove *cardToMove = new CardToMove; - cardToMove->set_card_id(targetCard->getId()); - targetPlayer->moveCard(ges, targetzone, QList() << cardToMove, targetzone, targetzone->getFreeGridColumn(-2, targetCard->getY(), targetCard->getName()), targetCard->getY(), targetCard->getFaceDown()); - delete cardToMove; - } - - Event_AttachCard event; - event.set_start_zone(startzone->getName().toStdString()); - event.set_card_id(card->getId()); - event.set_target_player_id(targetPlayer->getPlayerId()); - event.set_target_zone(targetzone->getName().toStdString()); - event.set_target_card_id(targetCard->getId()); - ges.enqueueGameEvent(event, playerId); - - startzone->fixFreeSpaces(ges); - } else - unattachCard(ges, card); - - return Response::RespOk; + if (targetCard) { + // Unattach all cards attached to the card being attached. + // Make a copy of the list because its contents change during the loop otherwise. + QList attachedList = card->getAttachedCards(); + for (int i = 0; i < attachedList.size(); ++i) + attachedList[i]->getZone()->getPlayer()->unattachCard(ges, attachedList[i]); + + card->setParentCard(targetCard); + const int oldX = card->getX(); + card->setCoords(-1, card->getY()); + startzone->updateCardCoordinates(card, oldX, card->getY()); + + if (targetzone->isColumnStacked(targetCard->getX(), targetCard->getY())) { + CardToMove *cardToMove = new CardToMove; + cardToMove->set_card_id(targetCard->getId()); + targetPlayer->moveCard(ges, targetzone, QList() << cardToMove, targetzone, targetzone->getFreeGridColumn(-2, targetCard->getY(), targetCard->getName()), targetCard->getY(), targetCard->getFaceDown()); + delete cardToMove; + } + + Event_AttachCard event; + event.set_start_zone(startzone->getName().toStdString()); + event.set_card_id(card->getId()); + event.set_target_player_id(targetPlayer->getPlayerId()); + event.set_target_zone(targetzone->getName().toStdString()); + event.set_target_card_id(targetCard->getId()); + ges.enqueueGameEvent(event, playerId); + + startzone->fixFreeSpaces(ges); + } else + unattachCard(ges, card); + + return Response::RespOk; } Response::ResponseCode Server_Player::cmdCreateToken(const Command_CreateToken &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) - return Response::RespFunctionNotAllowed; - - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (conceded) - return Response::RespContextError; - - Server_CardZone *zone = zones.value(QString::fromStdString(cmd.zone())); - if (!zone) - return Response::RespNameNotFound; + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + Server_CardZone *zone = zones.value(QString::fromStdString(cmd.zone())); + if (!zone) + return Response::RespNameNotFound; - QString cardName = QString::fromStdString(cmd.card_name()); - int x = cmd.x(); - int y = cmd.y(); - if (zone->hasCoords()) - x = zone->getFreeGridColumn(x, y, cardName); - if (x < 0) - x = 0; - if (y < 0) - y = 0; + QString cardName = QString::fromStdString(cmd.card_name()); + int x = cmd.x(); + int y = cmd.y(); + if (zone->hasCoords()) + x = zone->getFreeGridColumn(x, y, cardName); + if (x < 0) + x = 0; + if (y < 0) + y = 0; - Server_Card *card = new Server_Card(cardName, newCardId(), x, y); - card->moveToThread(thread()); - card->setPT(QString::fromStdString(cmd.pt())); - card->setColor(QString::fromStdString(cmd.color())); - card->setAnnotation(QString::fromStdString(cmd.annotation())); - card->setDestroyOnZoneChange(cmd.destroy_on_zone_change()); - - zone->insertCard(card, x, y); - - Event_CreateToken event; - event.set_zone_name(zone->getName().toStdString()); - event.set_card_id(card->getId()); - event.set_card_name(card->getName().toStdString()); - event.set_color(card->getColor().toStdString()); - event.set_pt(card->getPT().toStdString()); - event.set_annotation(card->getAnnotation().toStdString()); - event.set_destroy_on_zone_change(card->getDestroyOnZoneChange()); - event.set_x(x); - event.set_y(y); - ges.enqueueGameEvent(event, playerId); - - return Response::RespOk; + Server_Card *card = new Server_Card(cardName, newCardId(), x, y); + card->moveToThread(thread()); + card->setPT(QString::fromStdString(cmd.pt())); + card->setColor(QString::fromStdString(cmd.color())); + card->setAnnotation(QString::fromStdString(cmd.annotation())); + card->setDestroyOnZoneChange(cmd.destroy_on_zone_change()); + + zone->insertCard(card, x, y); + + Event_CreateToken event; + event.set_zone_name(zone->getName().toStdString()); + event.set_card_id(card->getId()); + event.set_card_name(card->getName().toStdString()); + event.set_color(card->getColor().toStdString()); + event.set_pt(card->getPT().toStdString()); + event.set_annotation(card->getAnnotation().toStdString()); + event.set_destroy_on_zone_change(card->getDestroyOnZoneChange()); + event.set_x(x); + event.set_y(y); + ges.enqueueGameEvent(event, playerId); + + return Response::RespOk; } Response::ResponseCode Server_Player::cmdCreateArrow(const Command_CreateArrow &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) - return Response::RespFunctionNotAllowed; - - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (conceded) - return Response::RespContextError; - - Server_Player *startPlayer = game->getPlayers().value(cmd.start_player_id()); - Server_Player *targetPlayer = game->getPlayers().value(cmd.target_player_id()); - if (!startPlayer || !targetPlayer) - return Response::RespNameNotFound; - QString startZoneName = QString::fromStdString(cmd.start_zone()); - Server_CardZone *startZone = startPlayer->getZones().value(startZoneName); - bool playerTarget = !cmd.has_target_zone(); - Server_CardZone *targetZone = 0; - if (!playerTarget) - targetZone = targetPlayer->getZones().value(QString::fromStdString(cmd.target_zone())); - if (!startZone || (!targetZone && !playerTarget)) - return Response::RespNameNotFound; - if (startZone->getType() != ServerInfo_Zone::PublicZone) - return Response::RespContextError; - Server_Card *startCard = startZone->getCard(cmd.start_card_id()); - if (!startCard) - return Response::RespNameNotFound; - Server_Card *targetCard = 0; - if (!playerTarget) { - if (targetZone->getType() != ServerInfo_Zone::PublicZone) - return Response::RespContextError; - targetCard = targetZone->getCard(cmd.target_card_id()); - } - - Server_ArrowTarget *targetItem; - if (playerTarget) - targetItem = targetPlayer; - else - targetItem = targetCard; - if (!targetItem) - return Response::RespNameNotFound; + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + Server_Player *startPlayer = game->getPlayers().value(cmd.start_player_id()); + Server_Player *targetPlayer = game->getPlayers().value(cmd.target_player_id()); + if (!startPlayer || !targetPlayer) + return Response::RespNameNotFound; + QString startZoneName = QString::fromStdString(cmd.start_zone()); + Server_CardZone *startZone = startPlayer->getZones().value(startZoneName); + bool playerTarget = !cmd.has_target_zone(); + Server_CardZone *targetZone = 0; + if (!playerTarget) + targetZone = targetPlayer->getZones().value(QString::fromStdString(cmd.target_zone())); + if (!startZone || (!targetZone && !playerTarget)) + return Response::RespNameNotFound; + if (startZone->getType() != ServerInfo_Zone::PublicZone) + return Response::RespContextError; + Server_Card *startCard = startZone->getCard(cmd.start_card_id()); + if (!startCard) + return Response::RespNameNotFound; + Server_Card *targetCard = 0; + if (!playerTarget) { + if (targetZone->getType() != ServerInfo_Zone::PublicZone) + return Response::RespContextError; + targetCard = targetZone->getCard(cmd.target_card_id()); + } + + Server_ArrowTarget *targetItem; + if (playerTarget) + targetItem = targetPlayer; + else + targetItem = targetCard; + if (!targetItem) + return Response::RespNameNotFound; - QMapIterator arrowIterator(arrows); - while (arrowIterator.hasNext()) { - Server_Arrow *temp = arrowIterator.next().value(); - if ((temp->getStartCard() == startCard) && (temp->getTargetItem() == targetItem)) - return Response::RespContextError; - } - - Server_Arrow *arrow = new Server_Arrow(newArrowId(), startCard, targetItem, cmd.arrow_color()); - addArrow(arrow); - - Event_CreateArrow event; - ServerInfo_Arrow *arrowInfo = event.mutable_arrow_info(); - arrowInfo->set_id(arrow->getId()); - arrowInfo->set_start_player_id(startPlayer->getPlayerId()); - arrowInfo->set_start_zone(startZoneName.toStdString()); - arrowInfo->set_start_card_id(startCard->getId()); - arrowInfo->set_target_player_id(targetPlayer->getPlayerId()); - if (!playerTarget) { - arrowInfo->set_target_zone(cmd.target_zone()); - arrowInfo->set_target_card_id(cmd.target_card_id()); - } - arrowInfo->mutable_arrow_color()->CopyFrom(cmd.arrow_color()); - ges.enqueueGameEvent(event, playerId); - - return Response::RespOk; + QMapIterator arrowIterator(arrows); + while (arrowIterator.hasNext()) { + Server_Arrow *temp = arrowIterator.next().value(); + if ((temp->getStartCard() == startCard) && (temp->getTargetItem() == targetItem)) + return Response::RespContextError; + } + + Server_Arrow *arrow = new Server_Arrow(newArrowId(), startCard, targetItem, cmd.arrow_color()); + addArrow(arrow); + + Event_CreateArrow event; + ServerInfo_Arrow *arrowInfo = event.mutable_arrow_info(); + arrowInfo->set_id(arrow->getId()); + arrowInfo->set_start_player_id(startPlayer->getPlayerId()); + arrowInfo->set_start_zone(startZoneName.toStdString()); + arrowInfo->set_start_card_id(startCard->getId()); + arrowInfo->set_target_player_id(targetPlayer->getPlayerId()); + if (!playerTarget) { + arrowInfo->set_target_zone(cmd.target_zone()); + arrowInfo->set_target_card_id(cmd.target_card_id()); + } + arrowInfo->mutable_arrow_color()->CopyFrom(cmd.arrow_color()); + ges.enqueueGameEvent(event, playerId); + + return Response::RespOk; } Response::ResponseCode Server_Player::cmdDeleteArrow(const Command_DeleteArrow &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) - return Response::RespFunctionNotAllowed; - - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (conceded) - return Response::RespContextError; - - if (!deleteArrow(cmd.arrow_id())) - return Response::RespNameNotFound; - - Event_DeleteArrow event; - event.set_arrow_id(cmd.arrow_id()); - ges.enqueueGameEvent(event, playerId); - - return Response::RespOk; + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + if (!deleteArrow(cmd.arrow_id())) + return Response::RespNameNotFound; + + Event_DeleteArrow event; + event.set_arrow_id(cmd.arrow_id()); + ges.enqueueGameEvent(event, playerId); + + return Response::RespOk; } Response::ResponseCode Server_Player::cmdSetCardAttr(const Command_SetCardAttr &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) - return Response::RespFunctionNotAllowed; - - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (conceded) - return Response::RespContextError; - - return setCardAttrHelper(ges, QString::fromStdString(cmd.zone()), cmd.card_id(), cmd.attribute(), QString::fromStdString(cmd.attr_value())); + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + return setCardAttrHelper(ges, QString::fromStdString(cmd.zone()), cmd.card_id(), cmd.attribute(), QString::fromStdString(cmd.attr_value())); } Response::ResponseCode Server_Player::cmdSetCardCounter(const Command_SetCardCounter &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) - return Response::RespFunctionNotAllowed; - - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (conceded) - return Response::RespContextError; - - Server_CardZone *zone = zones.value(QString::fromStdString(cmd.zone())); - if (!zone) - return Response::RespNameNotFound; - if (!zone->hasCoords()) - return Response::RespContextError; + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + Server_CardZone *zone = zones.value(QString::fromStdString(cmd.zone())); + if (!zone) + return Response::RespNameNotFound; + if (!zone->hasCoords()) + return Response::RespContextError; - Server_Card *card = zone->getCard(cmd.card_id()); - if (!card) - return Response::RespNameNotFound; - - card->setCounter(cmd.counter_id(), cmd.counter_value()); - - Event_SetCardCounter event; - event.set_zone_name(zone->getName().toStdString()); - event.set_card_id(card->getId()); - event.set_counter_id(cmd.counter_id()); - event.set_counter_value(cmd.counter_value()); - ges.enqueueGameEvent(event, playerId); - - return Response::RespOk; + Server_Card *card = zone->getCard(cmd.card_id()); + if (!card) + return Response::RespNameNotFound; + + card->setCounter(cmd.counter_id(), cmd.counter_value()); + + Event_SetCardCounter event; + event.set_zone_name(zone->getName().toStdString()); + event.set_card_id(card->getId()); + event.set_counter_id(cmd.counter_id()); + event.set_counter_value(cmd.counter_value()); + ges.enqueueGameEvent(event, playerId); + + return Response::RespOk; } Response::ResponseCode Server_Player::cmdIncCardCounter(const Command_IncCardCounter &cmd, ResponseContainer &/*rc*/, GameEventStorage &ges) { - if (spectator) - return Response::RespFunctionNotAllowed; - - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (conceded) - return Response::RespContextError; - - Server_CardZone *zone = zones.value(QString::fromStdString(cmd.zone())); - if (!zone) - return Response::RespNameNotFound; - if (!zone->hasCoords()) - return Response::RespContextError; + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + Server_CardZone *zone = zones.value(QString::fromStdString(cmd.zone())); + if (!zone) + return Response::RespNameNotFound; + if (!zone->hasCoords()) + return Response::RespContextError; - Server_Card *card = zone->getCard(cmd.card_id()); - if (!card) - return Response::RespNameNotFound; - - int newValue = card->getCounter(cmd.counter_id()) + cmd.counter_delta(); - card->setCounter(cmd.counter_id(), newValue); - - Event_SetCardCounter event; - event.set_zone_name(zone->getName().toStdString()); - event.set_card_id(card->getId()); - event.set_counter_id(cmd.counter_id()); - event.set_counter_value(newValue); - ges.enqueueGameEvent(event, playerId); - - return Response::RespOk; + Server_Card *card = zone->getCard(cmd.card_id()); + if (!card) + return Response::RespNameNotFound; + + int newValue = card->getCounter(cmd.counter_id()) + cmd.counter_delta(); + card->setCounter(cmd.counter_id(), newValue); + + Event_SetCardCounter event; + event.set_zone_name(zone->getName().toStdString()); + event.set_card_id(card->getId()); + event.set_counter_id(cmd.counter_id()); + event.set_counter_value(newValue); + ges.enqueueGameEvent(event, playerId); + + return Response::RespOk; } Response::ResponseCode Server_Player::cmdIncCounter(const Command_IncCounter &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) - return Response::RespFunctionNotAllowed; - - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (conceded) - return Response::RespContextError; - - Server_Counter *c = counters.value(cmd.counter_id(), 0); - if (!c) - return Response::RespNameNotFound; - - c->setCount(c->getCount() + cmd.delta()); - - Event_SetCounter event; - event.set_counter_id(c->getId()); - event.set_value(c->getCount()); - ges.enqueueGameEvent(event, playerId); - - return Response::RespOk; + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + Server_Counter *c = counters.value(cmd.counter_id(), 0); + if (!c) + return Response::RespNameNotFound; + + c->setCount(c->getCount() + cmd.delta()); + + Event_SetCounter event; + event.set_counter_id(c->getId()); + event.set_value(c->getCount()); + ges.enqueueGameEvent(event, playerId); + + return Response::RespOk; } Response::ResponseCode Server_Player::cmdCreateCounter(const Command_CreateCounter &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) - return Response::RespFunctionNotAllowed; - - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (conceded) - return Response::RespContextError; - - Server_Counter *c = new Server_Counter(newCounterId(), QString::fromStdString(cmd.counter_name()), cmd.counter_color(), cmd.radius(), cmd.value()); - addCounter(c); - - Event_CreateCounter event; - ServerInfo_Counter *counterInfo = event.mutable_counter_info(); - counterInfo->set_id(c->getId()); - counterInfo->set_name(c->getName().toStdString()); - counterInfo->mutable_counter_color()->CopyFrom(cmd.counter_color()); - counterInfo->set_radius(c->getRadius()); - counterInfo->set_count(c->getCount()); - ges.enqueueGameEvent(event, playerId); - - return Response::RespOk; + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + Server_Counter *c = new Server_Counter(newCounterId(), QString::fromStdString(cmd.counter_name()), cmd.counter_color(), cmd.radius(), cmd.value()); + addCounter(c); + + Event_CreateCounter event; + ServerInfo_Counter *counterInfo = event.mutable_counter_info(); + counterInfo->set_id(c->getId()); + counterInfo->set_name(c->getName().toStdString()); + counterInfo->mutable_counter_color()->CopyFrom(cmd.counter_color()); + counterInfo->set_radius(c->getRadius()); + counterInfo->set_count(c->getCount()); + ges.enqueueGameEvent(event, playerId); + + return Response::RespOk; } Response::ResponseCode Server_Player::cmdSetCounter(const Command_SetCounter &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) - return Response::RespFunctionNotAllowed; - - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (conceded) - return Response::RespContextError; - - Server_Counter *c = counters.value(cmd.counter_id(), 0);; - if (!c) - return Response::RespNameNotFound; - - c->setCount(cmd.value()); - - Event_SetCounter event; - event.set_counter_id(c->getId()); - event.set_value(c->getCount()); - ges.enqueueGameEvent(event, playerId); - - return Response::RespOk; + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + Server_Counter *c = counters.value(cmd.counter_id(), 0);; + if (!c) + return Response::RespNameNotFound; + + c->setCount(cmd.value()); + + Event_SetCounter event; + event.set_counter_id(c->getId()); + event.set_value(c->getCount()); + ges.enqueueGameEvent(event, playerId); + + return Response::RespOk; } Response::ResponseCode Server_Player::cmdDelCounter(const Command_DelCounter &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) - return Response::RespFunctionNotAllowed; - - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (conceded) - return Response::RespContextError; - - Server_Counter *counter = counters.value(cmd.counter_id(), 0); - if (!counter) - return Response::RespNameNotFound; - counters.remove(cmd.counter_id()); - delete counter; - - Event_DelCounter event; - event.set_counter_id(cmd.counter_id()); - ges.enqueueGameEvent(event, playerId); - - return Response::RespOk; + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + Server_Counter *counter = counters.value(cmd.counter_id(), 0); + if (!counter) + return Response::RespNameNotFound; + counters.remove(cmd.counter_id()); + delete counter; + + Event_DelCounter event; + event.set_counter_id(cmd.counter_id()); + ges.enqueueGameEvent(event, playerId); + + return Response::RespOk; } Response::ResponseCode Server_Player::cmdNextTurn(const Command_NextTurn & /*cmd*/, ResponseContainer & /*rc*/, GameEventStorage & /*ges*/) { - if (spectator) - return Response::RespFunctionNotAllowed; - - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (conceded) - return Response::RespContextError; - - game->nextTurn(); - return Response::RespOk; + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + game->nextTurn(); + return Response::RespOk; } Response::ResponseCode Server_Player::cmdSetActivePhase(const Command_SetActivePhase &cmd, ResponseContainer & /*rc*/, GameEventStorage & /*ges*/) { - if (spectator) - return Response::RespFunctionNotAllowed; - - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (conceded) - return Response::RespContextError; - - if (game->getActivePlayer() != playerId) - return Response::RespContextError; - game->setActivePhase(cmd.phase()); - - return Response::RespOk; + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + if (game->getActivePlayer() != playerId) + return Response::RespContextError; + game->setActivePhase(cmd.phase()); + + return Response::RespOk; } Response::ResponseCode Server_Player::cmdDumpZone(const Command_DumpZone &cmd, ResponseContainer &rc, GameEventStorage &ges) { - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - - Server_Player *otherPlayer = game->getPlayers().value(cmd.player_id()); - if (!otherPlayer) - return Response::RespNameNotFound; - Server_CardZone *zone = otherPlayer->getZones().value(QString::fromStdString(cmd.zone_name())); - if (!zone) - return Response::RespNameNotFound; - if (!((zone->getType() == ServerInfo_Zone::PublicZone) || (this == otherPlayer))) - return Response::RespContextError; - - int numberCards = cmd.number_cards(); - const QList &cards = zone->getCards(); - - Response_DumpZone *re = new Response_DumpZone; - ServerInfo_Zone *zoneInfo = re->mutable_zone_info(); - zoneInfo->set_name(zone->getName().toStdString()); - zoneInfo->set_type(zone->getType()); - zoneInfo->set_with_coords(zone->hasCoords()); - zoneInfo->set_card_count(numberCards < cards.size() ? cards.size() : numberCards); - - for (int i = 0; (i < cards.size()) && (i < numberCards || numberCards == -1); ++i) { - Server_Card *card = cards[i]; - QString displayedName = card->getFaceDown() ? QString() : card->getName(); - ServerInfo_Card *cardInfo = zoneInfo->add_card_list(); - cardInfo->set_name(displayedName.toStdString()); - if (zone->getType() == ServerInfo_Zone::HiddenZone) - cardInfo->set_id(i); - else { - cardInfo->set_id(card->getId()); - cardInfo->set_x(card->getX()); - cardInfo->set_y(card->getY()); - cardInfo->set_face_down(card->getFaceDown()); - cardInfo->set_tapped(card->getTapped()); - cardInfo->set_attacking(card->getAttacking()); - cardInfo->set_color(card->getColor().toStdString()); - cardInfo->set_pt(card->getPT().toStdString()); - cardInfo->set_annotation(card->getAnnotation().toStdString()); - cardInfo->set_destroy_on_zone_change(card->getDestroyOnZoneChange()); - cardInfo->set_doesnt_untap(card->getDoesntUntap()); - - QMapIterator cardCounterIterator(card->getCounters()); - while (cardCounterIterator.hasNext()) { - cardCounterIterator.next(); - ServerInfo_CardCounter *counterInfo = cardInfo->add_counter_list(); - counterInfo->set_id(cardCounterIterator.key()); - counterInfo->set_value(cardCounterIterator.value()); - } + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + + Server_Player *otherPlayer = game->getPlayers().value(cmd.player_id()); + if (!otherPlayer) + return Response::RespNameNotFound; + Server_CardZone *zone = otherPlayer->getZones().value(QString::fromStdString(cmd.zone_name())); + if (!zone) + return Response::RespNameNotFound; + if (!((zone->getType() == ServerInfo_Zone::PublicZone) || (this == otherPlayer))) + return Response::RespContextError; + + int numberCards = cmd.number_cards(); + const QList &cards = zone->getCards(); + + Response_DumpZone *re = new Response_DumpZone; + ServerInfo_Zone *zoneInfo = re->mutable_zone_info(); + zoneInfo->set_name(zone->getName().toStdString()); + zoneInfo->set_type(zone->getType()); + zoneInfo->set_with_coords(zone->hasCoords()); + zoneInfo->set_card_count(numberCards < cards.size() ? cards.size() : numberCards); + + for (int i = 0; (i < cards.size()) && (i < numberCards || numberCards == -1); ++i) { + Server_Card *card = cards[i]; + QString displayedName = card->getFaceDown() ? QString() : card->getName(); + ServerInfo_Card *cardInfo = zoneInfo->add_card_list(); + cardInfo->set_name(displayedName.toStdString()); + if (zone->getType() == ServerInfo_Zone::HiddenZone) + cardInfo->set_id(i); + else { + cardInfo->set_id(card->getId()); + cardInfo->set_x(card->getX()); + cardInfo->set_y(card->getY()); + cardInfo->set_face_down(card->getFaceDown()); + cardInfo->set_tapped(card->getTapped()); + cardInfo->set_attacking(card->getAttacking()); + cardInfo->set_color(card->getColor().toStdString()); + cardInfo->set_pt(card->getPT().toStdString()); + cardInfo->set_annotation(card->getAnnotation().toStdString()); + cardInfo->set_destroy_on_zone_change(card->getDestroyOnZoneChange()); + cardInfo->set_doesnt_untap(card->getDoesntUntap()); + + QMapIterator cardCounterIterator(card->getCounters()); + while (cardCounterIterator.hasNext()) { + cardCounterIterator.next(); + ServerInfo_CardCounter *counterInfo = cardInfo->add_counter_list(); + counterInfo->set_id(cardCounterIterator.key()); + counterInfo->set_value(cardCounterIterator.value()); + } - if (card->getParentCard()) { - cardInfo->set_attach_player_id(card->getParentCard()->getZone()->getPlayer()->getPlayerId()); - cardInfo->set_attach_zone(card->getParentCard()->getZone()->getName().toStdString()); - cardInfo->set_attach_card_id(card->getParentCard()->getId()); - } - } - } - if (zone->getType() == ServerInfo_Zone::HiddenZone) { - zone->setCardsBeingLookedAt(numberCards); - - Event_DumpZone event; - event.set_zone_owner_id(otherPlayer->getPlayerId()); - event.set_zone_name(zone->getName().toStdString()); - event.set_number_cards(numberCards); - ges.enqueueGameEvent(event, playerId); - } - rc.setResponseExtension(re); - return Response::RespOk; + if (card->getParentCard()) { + cardInfo->set_attach_player_id(card->getParentCard()->getZone()->getPlayer()->getPlayerId()); + cardInfo->set_attach_zone(card->getParentCard()->getZone()->getName().toStdString()); + cardInfo->set_attach_card_id(card->getParentCard()->getId()); + } + } + } + if (zone->getType() == ServerInfo_Zone::HiddenZone) { + zone->setCardsBeingLookedAt(numberCards); + + Event_DumpZone event; + event.set_zone_owner_id(otherPlayer->getPlayerId()); + event.set_zone_name(zone->getName().toStdString()); + event.set_number_cards(numberCards); + ges.enqueueGameEvent(event, playerId); + } + rc.setResponseExtension(re); + return Response::RespOk; } Response::ResponseCode Server_Player::cmdStopDumpZone(const Command_StopDumpZone &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (conceded) - return Response::RespContextError; - - Server_Player *otherPlayer = game->getPlayers().value(cmd.player_id()); - if (!otherPlayer) - return Response::RespNameNotFound; - Server_CardZone *zone = otherPlayer->getZones().value(QString::fromStdString(cmd.zone_name())); - if (!zone) - return Response::RespNameNotFound; - - if (zone->getType() == ServerInfo_Zone::HiddenZone) { - zone->setCardsBeingLookedAt(0); - - Event_StopDumpZone event; - event.set_zone_owner_id(cmd.player_id()); - event.set_zone_name(zone->getName().toStdString()); - ges.enqueueGameEvent(event, playerId); - } - return Response::RespOk; + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + Server_Player *otherPlayer = game->getPlayers().value(cmd.player_id()); + if (!otherPlayer) + return Response::RespNameNotFound; + Server_CardZone *zone = otherPlayer->getZones().value(QString::fromStdString(cmd.zone_name())); + if (!zone) + return Response::RespNameNotFound; + + if (zone->getType() == ServerInfo_Zone::HiddenZone) { + zone->setCardsBeingLookedAt(0); + + Event_StopDumpZone event; + event.set_zone_owner_id(cmd.player_id()); + event.set_zone_name(zone->getName().toStdString()); + ges.enqueueGameEvent(event, playerId); + } + return Response::RespOk; } Response::ResponseCode Server_Player::cmdRevealCards(const Command_RevealCards &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) - return Response::RespFunctionNotAllowed; - - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (conceded) - return Response::RespContextError; - - Server_Player *otherPlayer = 0; - if (cmd.has_player_id()) { - otherPlayer = game->getPlayers().value(cmd.player_id()); - if (!otherPlayer) - return Response::RespNameNotFound; - } - Server_CardZone *zone = zones.value(QString::fromStdString(cmd.zone_name())); - if (!zone) - return Response::RespNameNotFound; - - QList cardsToReveal; - if (!cmd.has_card_id()) - cardsToReveal = zone->getCards(); - else if (cmd.card_id() == -2) { - if (zone->getCards().isEmpty()) - return Response::RespContextError; - cardsToReveal.append(zone->getCards().at(rng->rand(0, zone->getCards().size() - 1))); - } else { - Server_Card *card = zone->getCard(cmd.card_id()); - if (!card) - return Response::RespNameNotFound; - cardsToReveal.append(card); - } - - Event_RevealCards eventOthers; - eventOthers.set_grant_write_access(cmd.grant_write_access()); - eventOthers.set_zone_name(zone->getName().toStdString()); - if (cmd.has_card_id()) - eventOthers.set_card_id(cmd.card_id()); - if (cmd.has_player_id()) - eventOthers.set_other_player_id(cmd.player_id()); - - Event_RevealCards eventPrivate(eventOthers); - - for (int i = 0; i < cardsToReveal.size(); ++i) { - Server_Card *card = cardsToReveal[i]; - ServerInfo_Card *cardInfo = eventPrivate.add_cards(); + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + Server_Player *otherPlayer = 0; + if (cmd.has_player_id()) { + otherPlayer = game->getPlayers().value(cmd.player_id()); + if (!otherPlayer) + return Response::RespNameNotFound; + } + Server_CardZone *zone = zones.value(QString::fromStdString(cmd.zone_name())); + if (!zone) + return Response::RespNameNotFound; + + QList cardsToReveal; + if (!cmd.has_card_id()) + cardsToReveal = zone->getCards(); + else if (cmd.card_id() == -2) { + if (zone->getCards().isEmpty()) + return Response::RespContextError; + cardsToReveal.append(zone->getCards().at(rng->rand(0, zone->getCards().size() - 1))); + } else { + Server_Card *card = zone->getCard(cmd.card_id()); + if (!card) + return Response::RespNameNotFound; + cardsToReveal.append(card); + } + + Event_RevealCards eventOthers; + eventOthers.set_grant_write_access(cmd.grant_write_access()); + eventOthers.set_zone_name(zone->getName().toStdString()); + if (cmd.has_card_id()) + eventOthers.set_card_id(cmd.card_id()); + if (cmd.has_player_id()) + eventOthers.set_other_player_id(cmd.player_id()); + + Event_RevealCards eventPrivate(eventOthers); + + for (int i = 0; i < cardsToReveal.size(); ++i) { + Server_Card *card = cardsToReveal[i]; + ServerInfo_Card *cardInfo = eventPrivate.add_cards(); - cardInfo->set_id(card->getId()); - cardInfo->set_name(card->getName().toStdString()); - cardInfo->set_x(card->getX()); - cardInfo->set_y(card->getY()); - cardInfo->set_face_down(card->getFaceDown()); - cardInfo->set_tapped(card->getTapped()); - cardInfo->set_attacking(card->getAttacking()); - cardInfo->set_color(card->getColor().toStdString()); - cardInfo->set_pt(card->getPT().toStdString()); - cardInfo->set_annotation(card->getAnnotation().toStdString()); - cardInfo->set_destroy_on_zone_change(card->getDestroyOnZoneChange()); - cardInfo->set_doesnt_untap(card->getDoesntUntap()); - - QMapIterator cardCounterIterator(card->getCounters()); - while (cardCounterIterator.hasNext()) { - cardCounterIterator.next(); - ServerInfo_CardCounter *counterInfo = cardInfo->add_counter_list(); - counterInfo->set_id(cardCounterIterator.key()); - counterInfo->set_value(cardCounterIterator.value()); - } - - if (card->getParentCard()) { - cardInfo->set_attach_player_id(card->getParentCard()->getZone()->getPlayer()->getPlayerId()); - cardInfo->set_attach_zone(card->getParentCard()->getZone()->getName().toStdString()); - cardInfo->set_attach_card_id(card->getParentCard()->getId()); - } - } - - if (cmd.has_player_id()) { - if (cmd.grant_write_access()) - zone->addWritePermission(cmd.player_id()); - - ges.enqueueGameEvent(eventPrivate, playerId, GameEventStorageItem::SendToPrivate, cmd.player_id()); - ges.enqueueGameEvent(eventOthers, playerId, GameEventStorageItem::SendToOthers); - } else { - if (cmd.grant_write_access()) { - const QList &playerIds = game->getPlayers().keys(); - for (int i = 0; i < playerIds.size(); ++i) - zone->addWritePermission(playerIds[i]); - } - - ges.enqueueGameEvent(eventPrivate, playerId); - } - - return Response::RespOk; + cardInfo->set_id(card->getId()); + cardInfo->set_name(card->getName().toStdString()); + cardInfo->set_x(card->getX()); + cardInfo->set_y(card->getY()); + cardInfo->set_face_down(card->getFaceDown()); + cardInfo->set_tapped(card->getTapped()); + cardInfo->set_attacking(card->getAttacking()); + cardInfo->set_color(card->getColor().toStdString()); + cardInfo->set_pt(card->getPT().toStdString()); + cardInfo->set_annotation(card->getAnnotation().toStdString()); + cardInfo->set_destroy_on_zone_change(card->getDestroyOnZoneChange()); + cardInfo->set_doesnt_untap(card->getDoesntUntap()); + + QMapIterator cardCounterIterator(card->getCounters()); + while (cardCounterIterator.hasNext()) { + cardCounterIterator.next(); + ServerInfo_CardCounter *counterInfo = cardInfo->add_counter_list(); + counterInfo->set_id(cardCounterIterator.key()); + counterInfo->set_value(cardCounterIterator.value()); + } + + if (card->getParentCard()) { + cardInfo->set_attach_player_id(card->getParentCard()->getZone()->getPlayer()->getPlayerId()); + cardInfo->set_attach_zone(card->getParentCard()->getZone()->getName().toStdString()); + cardInfo->set_attach_card_id(card->getParentCard()->getId()); + } + } + + if (cmd.has_player_id()) { + if (cmd.grant_write_access()) + zone->addWritePermission(cmd.player_id()); + + ges.enqueueGameEvent(eventPrivate, playerId, GameEventStorageItem::SendToPrivate, cmd.player_id()); + ges.enqueueGameEvent(eventOthers, playerId, GameEventStorageItem::SendToOthers); + } else { + if (cmd.grant_write_access()) { + const QList &playerIds = game->getPlayers().keys(); + for (int i = 0; i < playerIds.size(); ++i) + zone->addWritePermission(playerIds[i]); + } + + ges.enqueueGameEvent(eventPrivate, playerId); + } + + return Response::RespOk; } Response::ResponseCode Server_Player::cmdChangeZoneProperties(const Command_ChangeZoneProperties &cmd, ResponseContainer &rc, GameEventStorage &ges) { - Server_CardZone *zone = zones.value(QString::fromStdString(cmd.zone_name())); - if (!zone) - return Response::RespNameNotFound; - - Event_ChangeZoneProperties event; - event.set_zone_name(cmd.zone_name()); - - if (cmd.has_always_reveal_top_card()) { - if (zone->getAlwaysRevealTopCard() == cmd.always_reveal_top_card()) - return Response::RespContextError; - zone->setAlwaysRevealTopCard(cmd.always_reveal_top_card()); - event.set_always_reveal_top_card(cmd.always_reveal_top_card()); - - ges.enqueueGameEvent(event, playerId); - - if (!zone->getCards().isEmpty() && cmd.always_reveal_top_card()) { - Event_RevealCards revealEvent; - revealEvent.set_zone_name(zone->getName().toStdString()); - revealEvent.set_card_id(0); - zone->getCards().first()->getInfo(revealEvent.add_cards()); - - ges.enqueueGameEvent(revealEvent, playerId); - } - return Response::RespOk; - } else - return Response::RespContextError; + Server_CardZone *zone = zones.value(QString::fromStdString(cmd.zone_name())); + if (!zone) + return Response::RespNameNotFound; + + Event_ChangeZoneProperties event; + event.set_zone_name(cmd.zone_name()); + + if (cmd.has_always_reveal_top_card()) { + if (zone->getAlwaysRevealTopCard() == cmd.always_reveal_top_card()) + return Response::RespContextError; + zone->setAlwaysRevealTopCard(cmd.always_reveal_top_card()); + event.set_always_reveal_top_card(cmd.always_reveal_top_card()); + + ges.enqueueGameEvent(event, playerId); + + if (!zone->getCards().isEmpty() && cmd.always_reveal_top_card()) { + Event_RevealCards revealEvent; + revealEvent.set_zone_name(zone->getName().toStdString()); + revealEvent.set_card_id(0); + zone->getCards().first()->getInfo(revealEvent.add_cards()); + + ges.enqueueGameEvent(revealEvent, playerId); + } + return Response::RespOk; + } else + return Response::RespContextError; } Response::ResponseCode Server_Player::processGameCommand(const GameCommand &command, ResponseContainer &rc, GameEventStorage &ges) { - switch ((GameCommand::GameCommandType) getPbExtension(command)) { - case GameCommand::KICK_FROM_GAME: return cmdKickFromGame(command.GetExtension(Command_KickFromGame::ext), rc, ges); break; - case GameCommand::LEAVE_GAME: return cmdLeaveGame(command.GetExtension(Command_LeaveGame::ext), rc, ges); break; - case GameCommand::GAME_SAY: return cmdGameSay(command.GetExtension(Command_GameSay::ext), rc, ges); break; - case GameCommand::SHUFFLE: return cmdShuffle(command.GetExtension(Command_Shuffle::ext), rc, ges); break; - case GameCommand::MULLIGAN: return cmdMulligan(command.GetExtension(Command_Mulligan::ext), rc, ges); break; - case GameCommand::ROLL_DIE: return cmdRollDie(command.GetExtension(Command_RollDie::ext), rc, ges); break; - case GameCommand::DRAW_CARDS: return cmdDrawCards(command.GetExtension(Command_DrawCards::ext), rc, ges); break; - case GameCommand::UNDO_DRAW: return cmdUndoDraw(command.GetExtension(Command_UndoDraw::ext), rc, ges); break; - case GameCommand::FLIP_CARD: return cmdFlipCard(command.GetExtension(Command_FlipCard::ext), rc, ges); break; - case GameCommand::ATTACH_CARD: return cmdAttachCard(command.GetExtension(Command_AttachCard::ext), rc, ges); break; - case GameCommand::CREATE_TOKEN: return cmdCreateToken(command.GetExtension(Command_CreateToken::ext), rc, ges); break; - case GameCommand::CREATE_ARROW: return cmdCreateArrow(command.GetExtension(Command_CreateArrow::ext), rc, ges); break; - case GameCommand::DELETE_ARROW: return cmdDeleteArrow(command.GetExtension(Command_DeleteArrow::ext), rc, ges); break; - case GameCommand::SET_CARD_ATTR: return cmdSetCardAttr(command.GetExtension(Command_SetCardAttr::ext), rc, ges); break; - case GameCommand::SET_CARD_COUNTER: return cmdSetCardCounter(command.GetExtension(Command_SetCardCounter::ext), rc, ges); break; - case GameCommand::INC_CARD_COUNTER: return cmdIncCardCounter(command.GetExtension(Command_IncCardCounter::ext), rc, ges); break; - case GameCommand::READY_START: return cmdReadyStart(command.GetExtension(Command_ReadyStart::ext), rc, ges); break; - case GameCommand::CONCEDE: return cmdConcede(command.GetExtension(Command_Concede::ext), rc, ges); break; - case GameCommand::INC_COUNTER: return cmdIncCounter(command.GetExtension(Command_IncCounter::ext), rc, ges); break; - case GameCommand::CREATE_COUNTER: return cmdCreateCounter(command.GetExtension(Command_CreateCounter::ext), rc, ges); break; - case GameCommand::SET_COUNTER: return cmdSetCounter(command.GetExtension(Command_SetCounter::ext), rc, ges); break; - case GameCommand::DEL_COUNTER: return cmdDelCounter(command.GetExtension(Command_DelCounter::ext), rc, ges); break; - case GameCommand::NEXT_TURN: return cmdNextTurn(command.GetExtension(Command_NextTurn::ext), rc, ges); break; - case GameCommand::SET_ACTIVE_PHASE: return cmdSetActivePhase(command.GetExtension(Command_SetActivePhase::ext), rc, ges); break; - case GameCommand::DUMP_ZONE: return cmdDumpZone(command.GetExtension(Command_DumpZone::ext), rc, ges); break; - case GameCommand::STOP_DUMP_ZONE: return cmdStopDumpZone(command.GetExtension(Command_StopDumpZone::ext), rc, ges); break; - case GameCommand::REVEAL_CARDS: return cmdRevealCards(command.GetExtension(Command_RevealCards::ext), rc, ges); break; - case GameCommand::MOVE_CARD: return cmdMoveCard(command.GetExtension(Command_MoveCard::ext), rc, ges); break; - case GameCommand::SET_SIDEBOARD_PLAN: return cmdSetSideboardPlan(command.GetExtension(Command_SetSideboardPlan::ext), rc, ges); break; - case GameCommand::DECK_SELECT: return cmdDeckSelect(command.GetExtension(Command_DeckSelect::ext), rc, ges); break; - case GameCommand::SET_SIDEBOARD_LOCK: return cmdSetSideboardLock(command.GetExtension(Command_SetSideboardLock::ext), rc, ges); break; - case GameCommand::CHANGE_ZONE_PROPERTIES: return cmdChangeZoneProperties(command.GetExtension(Command_ChangeZoneProperties::ext), rc, ges); break; - default: return Response::RespInvalidCommand; - } + switch ((GameCommand::GameCommandType) getPbExtension(command)) { + case GameCommand::KICK_FROM_GAME: return cmdKickFromGame(command.GetExtension(Command_KickFromGame::ext), rc, ges); break; + case GameCommand::LEAVE_GAME: return cmdLeaveGame(command.GetExtension(Command_LeaveGame::ext), rc, ges); break; + case GameCommand::GAME_SAY: return cmdGameSay(command.GetExtension(Command_GameSay::ext), rc, ges); break; + case GameCommand::SHUFFLE: return cmdShuffle(command.GetExtension(Command_Shuffle::ext), rc, ges); break; + case GameCommand::MULLIGAN: return cmdMulligan(command.GetExtension(Command_Mulligan::ext), rc, ges); break; + case GameCommand::ROLL_DIE: return cmdRollDie(command.GetExtension(Command_RollDie::ext), rc, ges); break; + case GameCommand::DRAW_CARDS: return cmdDrawCards(command.GetExtension(Command_DrawCards::ext), rc, ges); break; + case GameCommand::UNDO_DRAW: return cmdUndoDraw(command.GetExtension(Command_UndoDraw::ext), rc, ges); break; + case GameCommand::FLIP_CARD: return cmdFlipCard(command.GetExtension(Command_FlipCard::ext), rc, ges); break; + case GameCommand::ATTACH_CARD: return cmdAttachCard(command.GetExtension(Command_AttachCard::ext), rc, ges); break; + case GameCommand::CREATE_TOKEN: return cmdCreateToken(command.GetExtension(Command_CreateToken::ext), rc, ges); break; + case GameCommand::CREATE_ARROW: return cmdCreateArrow(command.GetExtension(Command_CreateArrow::ext), rc, ges); break; + case GameCommand::DELETE_ARROW: return cmdDeleteArrow(command.GetExtension(Command_DeleteArrow::ext), rc, ges); break; + case GameCommand::SET_CARD_ATTR: return cmdSetCardAttr(command.GetExtension(Command_SetCardAttr::ext), rc, ges); break; + case GameCommand::SET_CARD_COUNTER: return cmdSetCardCounter(command.GetExtension(Command_SetCardCounter::ext), rc, ges); break; + case GameCommand::INC_CARD_COUNTER: return cmdIncCardCounter(command.GetExtension(Command_IncCardCounter::ext), rc, ges); break; + case GameCommand::READY_START: return cmdReadyStart(command.GetExtension(Command_ReadyStart::ext), rc, ges); break; + case GameCommand::CONCEDE: return cmdConcede(command.GetExtension(Command_Concede::ext), rc, ges); break; + case GameCommand::INC_COUNTER: return cmdIncCounter(command.GetExtension(Command_IncCounter::ext), rc, ges); break; + case GameCommand::CREATE_COUNTER: return cmdCreateCounter(command.GetExtension(Command_CreateCounter::ext), rc, ges); break; + case GameCommand::SET_COUNTER: return cmdSetCounter(command.GetExtension(Command_SetCounter::ext), rc, ges); break; + case GameCommand::DEL_COUNTER: return cmdDelCounter(command.GetExtension(Command_DelCounter::ext), rc, ges); break; + case GameCommand::NEXT_TURN: return cmdNextTurn(command.GetExtension(Command_NextTurn::ext), rc, ges); break; + case GameCommand::SET_ACTIVE_PHASE: return cmdSetActivePhase(command.GetExtension(Command_SetActivePhase::ext), rc, ges); break; + case GameCommand::DUMP_ZONE: return cmdDumpZone(command.GetExtension(Command_DumpZone::ext), rc, ges); break; + case GameCommand::STOP_DUMP_ZONE: return cmdStopDumpZone(command.GetExtension(Command_StopDumpZone::ext), rc, ges); break; + case GameCommand::REVEAL_CARDS: return cmdRevealCards(command.GetExtension(Command_RevealCards::ext), rc, ges); break; + case GameCommand::MOVE_CARD: return cmdMoveCard(command.GetExtension(Command_MoveCard::ext), rc, ges); break; + case GameCommand::SET_SIDEBOARD_PLAN: return cmdSetSideboardPlan(command.GetExtension(Command_SetSideboardPlan::ext), rc, ges); break; + case GameCommand::DECK_SELECT: return cmdDeckSelect(command.GetExtension(Command_DeckSelect::ext), rc, ges); break; + case GameCommand::SET_SIDEBOARD_LOCK: return cmdSetSideboardLock(command.GetExtension(Command_SetSideboardLock::ext), rc, ges); break; + case GameCommand::CHANGE_ZONE_PROPERTIES: return cmdChangeZoneProperties(command.GetExtension(Command_ChangeZoneProperties::ext), rc, ges); break; + default: return Response::RespInvalidCommand; + } } void Server_Player::sendGameEvent(const GameEventContainer &cont) { - QMutexLocker locker(&playerMutex); - - if (userInterface) - userInterface->sendProtocolItem(cont); + QMutexLocker locker(&playerMutex); + + if (userInterface) + userInterface->sendProtocolItem(cont); } void Server_Player::setUserInterface(Server_AbstractUserInterface *_userInterface) { - playerMutex.lock(); - userInterface = _userInterface; - playerMutex.unlock(); - - pingTime = _userInterface ? 0 : -1; - - Event_PlayerPropertiesChanged event; - event.mutable_player_properties()->set_ping_seconds(pingTime); - - GameEventStorage ges; - ges.setGameEventContext(Context_ConnectionStateChanged()); - ges.enqueueGameEvent(event, playerId); - ges.sendToGame(game); + playerMutex.lock(); + userInterface = _userInterface; + playerMutex.unlock(); + + pingTime = _userInterface ? 0 : -1; + + Event_PlayerPropertiesChanged event; + event.mutable_player_properties()->set_ping_seconds(pingTime); + + GameEventStorage ges; + ges.setGameEventContext(Context_ConnectionStateChanged()); + ges.enqueueGameEvent(event, playerId); + ges.sendToGame(game); } void Server_Player::disconnectClient() { - if (!(userInfo->user_level() & ServerInfo_User::IsRegistered) || spectator) - game->removePlayer(this); - else - setUserInterface(0); + if (!(userInfo->user_level() & ServerInfo_User::IsRegistered) || spectator) + game->removePlayer(this); + else + setUserInterface(0); } void Server_Player::getInfo(ServerInfo_Player *info, Server_Player *playerWhosAsking, bool omniscient, bool withUserInfo) { - getProperties(*info->mutable_properties(), withUserInfo); - if (playerWhosAsking == this) - if (deck) - info->set_deck_list(deck->writeToString_Native().toStdString()); - - QMapIterator arrowIterator(arrows); - while (arrowIterator.hasNext()) - arrowIterator.next().value()->getInfo(info->add_arrow_list()); - - QMapIterator counterIterator(counters); - while (counterIterator.hasNext()) - counterIterator.next().value()->getInfo(info->add_counter_list()); - - QMapIterator zoneIterator(zones); - while (zoneIterator.hasNext()) - zoneIterator.next().value()->getInfo(info->add_zone_list(), playerWhosAsking, omniscient); + getProperties(*info->mutable_properties(), withUserInfo); + if (playerWhosAsking == this) + if (deck) + info->set_deck_list(deck->writeToString_Native().toStdString()); + + QMapIterator arrowIterator(arrows); + while (arrowIterator.hasNext()) + arrowIterator.next().value()->getInfo(info->add_arrow_list()); + + QMapIterator counterIterator(counters); + while (counterIterator.hasNext()) + counterIterator.next().value()->getInfo(info->add_counter_list()); + + QMapIterator zoneIterator(zones); + while (zoneIterator.hasNext()) + zoneIterator.next().value()->getInfo(info->add_zone_list(), playerWhosAsking, omniscient); } diff --git a/common/server_player.h b/common/server_player.h index 61e29bab..873a4a76 100644 --- a/common/server_player.h +++ b/common/server_player.h @@ -62,104 +62,104 @@ class Command_SetSideboardLock; class Command_ChangeZoneProperties; class Server_Player : public Server_ArrowTarget, public ServerInfo_User_Container { - Q_OBJECT + Q_OBJECT private: - class MoveCardCompareFunctor; - Server_Game *game; - Server_AbstractUserInterface *userInterface; - DeckList *deck; - QMap zones; - QMap counters; - QMap arrows; - QList lastDrawList; - int pingTime; - int playerId; - bool spectator; - int initialCards; - int nextCardId; - bool readyStart; - bool conceded; - bool sideboardLocked; + class MoveCardCompareFunctor; + Server_Game *game; + Server_AbstractUserInterface *userInterface; + DeckList *deck; + QMap zones; + QMap counters; + QMap arrows; + QList lastDrawList; + int pingTime; + int playerId; + bool spectator; + int initialCards; + int nextCardId; + bool readyStart; + bool conceded; + bool sideboardLocked; public: - mutable QMutex playerMutex; - Server_Player(Server_Game *_game, int _playerId, const ServerInfo_User &_userInfo, bool _spectator, Server_AbstractUserInterface *_handler); - ~Server_Player(); - void prepareDestroy(); - Server_AbstractUserInterface *getUserInterface() const { return userInterface; } - void setUserInterface(Server_AbstractUserInterface *_userInterface); - void disconnectClient(); - - void setPlayerId(int _id) { playerId = _id; } - bool getReadyStart() const { return readyStart; } - void setReadyStart(bool _readyStart) { readyStart = _readyStart; } - int getPlayerId() const { return playerId; } - bool getSpectator() const { return spectator; } - bool getConceded() const { return conceded; } - void setConceded(bool _conceded) { conceded = _conceded; } - DeckList *getDeck() const { return deck; } - Server_Game *getGame() const { return game; } - const QMap &getZones() const { return zones; } - const QMap &getCounters() const { return counters; } - const QMap &getArrows() const { return arrows; } - - int getPingTime() const { return pingTime; } - void setPingTime(int _pingTime) { pingTime = _pingTime; } - void getProperties(ServerInfo_PlayerProperties &result, bool withUserInfo); - - int newCardId(); - int newCounterId() const; - int newArrowId() const; - - void addZone(Server_CardZone *zone); - void addArrow(Server_Arrow *arrow); - bool deleteArrow(int arrowId); - void addCounter(Server_Counter *counter); - - void clearZones(); - void setupZones(); + mutable QMutex playerMutex; + Server_Player(Server_Game *_game, int _playerId, const ServerInfo_User &_userInfo, bool _spectator, Server_AbstractUserInterface *_handler); + ~Server_Player(); + void prepareDestroy(); + Server_AbstractUserInterface *getUserInterface() const { return userInterface; } + void setUserInterface(Server_AbstractUserInterface *_userInterface); + void disconnectClient(); + + void setPlayerId(int _id) { playerId = _id; } + bool getReadyStart() const { return readyStart; } + void setReadyStart(bool _readyStart) { readyStart = _readyStart; } + int getPlayerId() const { return playerId; } + bool getSpectator() const { return spectator; } + bool getConceded() const { return conceded; } + void setConceded(bool _conceded) { conceded = _conceded; } + DeckList *getDeck() const { return deck; } + Server_Game *getGame() const { return game; } + const QMap &getZones() const { return zones; } + const QMap &getCounters() const { return counters; } + const QMap &getArrows() const { return arrows; } + + int getPingTime() const { return pingTime; } + void setPingTime(int _pingTime) { pingTime = _pingTime; } + void getProperties(ServerInfo_PlayerProperties &result, bool withUserInfo); + + int newCardId(); + int newCounterId() const; + int newArrowId() const; + + void addZone(Server_CardZone *zone); + void addArrow(Server_Arrow *arrow); + bool deleteArrow(int arrowId); + void addCounter(Server_Counter *counter); + + void clearZones(); + void setupZones(); - Response::ResponseCode drawCards(GameEventStorage &ges, int number); - Response::ResponseCode moveCard(GameEventStorage &ges, Server_CardZone *startzone, const QList &_cards, Server_CardZone *targetzone, int x, int y, bool fixFreeSpaces = true, bool undoingDraw = false); - void unattachCard(GameEventStorage &ges, Server_Card *card); - Response::ResponseCode setCardAttrHelper(GameEventStorage &ges, const QString &zone, int cardId, CardAttribute attribute, const QString &attrValue); + Response::ResponseCode drawCards(GameEventStorage &ges, int number); + Response::ResponseCode moveCard(GameEventStorage &ges, Server_CardZone *startzone, const QList &_cards, Server_CardZone *targetzone, int x, int y, bool fixFreeSpaces = true, bool undoingDraw = false); + void unattachCard(GameEventStorage &ges, Server_Card *card); + Response::ResponseCode setCardAttrHelper(GameEventStorage &ges, const QString &zone, int cardId, CardAttribute attribute, const QString &attrValue); - Response::ResponseCode cmdLeaveGame(const Command_LeaveGame &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdKickFromGame(const Command_KickFromGame &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdConcede(const Command_Concede &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdReadyStart(const Command_ReadyStart &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdDeckSelect(const Command_DeckSelect &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdSetSideboardPlan(const Command_SetSideboardPlan &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdSetSideboardLock(const Command_SetSideboardLock &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdGameSay(const Command_GameSay &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdShuffle(const Command_Shuffle &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdMulligan(const Command_Mulligan &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdRollDie(const Command_RollDie &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdDrawCards(const Command_DrawCards &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdUndoDraw(const Command_UndoDraw &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdMoveCard(const Command_MoveCard &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdFlipCard(const Command_FlipCard &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdAttachCard(const Command_AttachCard &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdCreateToken(const Command_CreateToken &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdCreateArrow(const Command_CreateArrow &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdDeleteArrow(const Command_DeleteArrow &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdSetCardAttr(const Command_SetCardAttr &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdSetCardCounter(const Command_SetCardCounter &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdIncCardCounter(const Command_IncCardCounter &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdIncCounter(const Command_IncCounter &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdCreateCounter(const Command_CreateCounter &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdSetCounter(const Command_SetCounter &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdDelCounter(const Command_DelCounter &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdNextTurn(const Command_NextTurn &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdSetActivePhase(const Command_SetActivePhase &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdDumpZone(const Command_DumpZone &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdStopDumpZone(const Command_StopDumpZone &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdRevealCards(const Command_RevealCards &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdChangeZoneProperties(const Command_ChangeZoneProperties &cmd, ResponseContainer &rc, GameEventStorage &ges); - - Response::ResponseCode processGameCommand(const GameCommand &command, ResponseContainer &rc, GameEventStorage &ges); - void sendGameEvent(const GameEventContainer &event); - - void getInfo(ServerInfo_Player *info, Server_Player *playerWhosAsking, bool omniscient, bool withUserInfo); + Response::ResponseCode cmdLeaveGame(const Command_LeaveGame &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdKickFromGame(const Command_KickFromGame &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdConcede(const Command_Concede &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdReadyStart(const Command_ReadyStart &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdDeckSelect(const Command_DeckSelect &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdSetSideboardPlan(const Command_SetSideboardPlan &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdSetSideboardLock(const Command_SetSideboardLock &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdGameSay(const Command_GameSay &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdShuffle(const Command_Shuffle &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdMulligan(const Command_Mulligan &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdRollDie(const Command_RollDie &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdDrawCards(const Command_DrawCards &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdUndoDraw(const Command_UndoDraw &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdMoveCard(const Command_MoveCard &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdFlipCard(const Command_FlipCard &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdAttachCard(const Command_AttachCard &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdCreateToken(const Command_CreateToken &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdCreateArrow(const Command_CreateArrow &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdDeleteArrow(const Command_DeleteArrow &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdSetCardAttr(const Command_SetCardAttr &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdSetCardCounter(const Command_SetCardCounter &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdIncCardCounter(const Command_IncCardCounter &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdIncCounter(const Command_IncCounter &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdCreateCounter(const Command_CreateCounter &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdSetCounter(const Command_SetCounter &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdDelCounter(const Command_DelCounter &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdNextTurn(const Command_NextTurn &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdSetActivePhase(const Command_SetActivePhase &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdDumpZone(const Command_DumpZone &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdStopDumpZone(const Command_StopDumpZone &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdRevealCards(const Command_RevealCards &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdChangeZoneProperties(const Command_ChangeZoneProperties &cmd, ResponseContainer &rc, GameEventStorage &ges); + + Response::ResponseCode processGameCommand(const GameCommand &command, ResponseContainer &rc, GameEventStorage &ges); + void sendGameEvent(const GameEventContainer &event); + + void getInfo(ServerInfo_Player *info, Server_Player *playerWhosAsking, bool omniscient, bool withUserInfo); }; #endif diff --git a/common/server_player_reference.h b/common/server_player_reference.h index fc784a1a..868b40b6 100644 --- a/common/server_player_reference.h +++ b/common/server_player_reference.h @@ -3,15 +3,15 @@ class PlayerReference { private: - int roomId; - int gameId; - int playerId; + int roomId; + int gameId; + int playerId; public: - PlayerReference(int _roomId, int _gameId, int _playerId) : roomId(_roomId), gameId(_gameId), playerId(_playerId) { } - int getRoomId() const { return roomId; } - int getGameId() const { return gameId; } - int getPlayerId() const { return playerId; } - bool operator==(const PlayerReference &other) { return ((roomId == other.roomId) && (gameId == other.gameId) && (playerId == other.playerId)); } + PlayerReference(int _roomId, int _gameId, int _playerId) : roomId(_roomId), gameId(_gameId), playerId(_playerId) { } + int getRoomId() const { return roomId; } + int getGameId() const { return gameId; } + int getPlayerId() const { return playerId; } + bool operator==(const PlayerReference &other) { return ((roomId == other.roomId) && (gameId == other.gameId) && (playerId == other.playerId)); } }; #endif diff --git a/common/server_protocolhandler.cpp b/common/server_protocolhandler.cpp index eb8322d0..f7561b2a 100644 --- a/common/server_protocolhandler.cpp +++ b/common/server_protocolhandler.cpp @@ -21,17 +21,17 @@ #include Server_ProtocolHandler::Server_ProtocolHandler(Server *_server, Server_DatabaseInterface *_databaseInterface, QObject *parent) - : QObject(parent), - Server_AbstractUserInterface(_server), - deleted(false), - databaseInterface(_databaseInterface), - authState(NotLoggedIn), - acceptsUserListChanges(false), - acceptsRoomListChanges(false), - timeRunning(0), - lastDataReceived(0) + : QObject(parent), + Server_AbstractUserInterface(_server), + deleted(false), + databaseInterface(_databaseInterface), + authState(NotLoggedIn), + acceptsUserListChanges(false), + acceptsRoomListChanges(false), + timeRunning(0), + lastDataReceived(0) { - connect(server, SIGNAL(pingClockTimeout()), this, SLOT(pingClockTimeout())); + connect(server, SIGNAL(pingClockTimeout()), this, SLOT(pingClockTimeout())); } Server_ProtocolHandler::~Server_ProtocolHandler() @@ -42,540 +42,540 @@ Server_ProtocolHandler::~Server_ProtocolHandler() // The thread must not hold any server locks when calling this (e.g. clientsLock, roomsLock). void Server_ProtocolHandler::prepareDestroy() { - if (deleted) - return; - deleted = true; - - QMapIterator roomIterator(rooms); - while (roomIterator.hasNext()) - roomIterator.next().value()->removeClient(this); - - QMap > tempGames(getGames()); - - server->roomsLock.lockForRead(); - QMapIterator > gameIterator(tempGames); - while (gameIterator.hasNext()) { - gameIterator.next(); - - Server_Room *r = server->getRooms().value(gameIterator.value().first); - if (!r) - continue; - r->gamesLock.lockForRead(); - Server_Game *g = r->getGames().value(gameIterator.key()); - if (!g) { - r->gamesLock.unlock(); - continue; - } - g->gameMutex.lock(); - Server_Player *p = g->getPlayers().value(gameIterator.value().second); - if (!p) { - g->gameMutex.unlock(); - r->gamesLock.unlock(); - continue; - } - - p->disconnectClient(); - - g->gameMutex.unlock(); - r->gamesLock.unlock(); - } - server->roomsLock.unlock(); - - server->removeClient(this); - - deleteLater(); + if (deleted) + return; + deleted = true; + + QMapIterator roomIterator(rooms); + while (roomIterator.hasNext()) + roomIterator.next().value()->removeClient(this); + + QMap > tempGames(getGames()); + + server->roomsLock.lockForRead(); + QMapIterator > gameIterator(tempGames); + while (gameIterator.hasNext()) { + gameIterator.next(); + + Server_Room *r = server->getRooms().value(gameIterator.value().first); + if (!r) + continue; + r->gamesLock.lockForRead(); + Server_Game *g = r->getGames().value(gameIterator.key()); + if (!g) { + r->gamesLock.unlock(); + continue; + } + g->gameMutex.lock(); + Server_Player *p = g->getPlayers().value(gameIterator.value().second); + if (!p) { + g->gameMutex.unlock(); + r->gamesLock.unlock(); + continue; + } + + p->disconnectClient(); + + g->gameMutex.unlock(); + r->gamesLock.unlock(); + } + server->roomsLock.unlock(); + + server->removeClient(this); + + deleteLater(); } void Server_ProtocolHandler::sendProtocolItem(const Response &item) { - ServerMessage msg; - msg.mutable_response()->CopyFrom(item); - msg.set_message_type(ServerMessage::RESPONSE); - - transmitProtocolItem(msg); + ServerMessage msg; + msg.mutable_response()->CopyFrom(item); + msg.set_message_type(ServerMessage::RESPONSE); + + transmitProtocolItem(msg); } void Server_ProtocolHandler::sendProtocolItem(const SessionEvent &item) { - ServerMessage msg; - msg.mutable_session_event()->CopyFrom(item); - msg.set_message_type(ServerMessage::SESSION_EVENT); - - transmitProtocolItem(msg); + ServerMessage msg; + msg.mutable_session_event()->CopyFrom(item); + msg.set_message_type(ServerMessage::SESSION_EVENT); + + transmitProtocolItem(msg); } void Server_ProtocolHandler::sendProtocolItem(const GameEventContainer &item) { - ServerMessage msg; - msg.mutable_game_event_container()->CopyFrom(item); - msg.set_message_type(ServerMessage::GAME_EVENT_CONTAINER); - - transmitProtocolItem(msg); + ServerMessage msg; + msg.mutable_game_event_container()->CopyFrom(item); + msg.set_message_type(ServerMessage::GAME_EVENT_CONTAINER); + + transmitProtocolItem(msg); } void Server_ProtocolHandler::sendProtocolItem(const RoomEvent &item) { - ServerMessage msg; - msg.mutable_room_event()->CopyFrom(item); - msg.set_message_type(ServerMessage::ROOM_EVENT); - - transmitProtocolItem(msg); + ServerMessage msg; + msg.mutable_room_event()->CopyFrom(item); + msg.set_message_type(ServerMessage::ROOM_EVENT); + + transmitProtocolItem(msg); } Response::ResponseCode Server_ProtocolHandler::processSessionCommandContainer(const CommandContainer &cont, ResponseContainer &rc) { - Response::ResponseCode finalResponseCode = Response::RespOk; - for (int i = cont.session_command_size() - 1; i >= 0; --i) { - Response::ResponseCode resp = Response::RespInvalidCommand; - const SessionCommand &sc = cont.session_command(i); - const int num = getPbExtension(sc); - if (num != SessionCommand::PING) { // don't log ping commands - if (num == SessionCommand::LOGIN) { // log login commands, but hide passwords - SessionCommand debugSc(sc); - debugSc.MutableExtension(Command_Login::ext)->clear_password(); - logDebugMessage(QString::fromStdString(debugSc.ShortDebugString())); - } else - logDebugMessage(QString::fromStdString(sc.ShortDebugString())); - } - switch ((SessionCommand::SessionCommandType) num) { - case SessionCommand::PING: resp = cmdPing(sc.GetExtension(Command_Ping::ext), rc); break; - case SessionCommand::LOGIN: resp = cmdLogin(sc.GetExtension(Command_Login::ext), rc); break; - case SessionCommand::MESSAGE: resp = cmdMessage(sc.GetExtension(Command_Message::ext), rc); break; - case SessionCommand::GET_GAMES_OF_USER: resp = cmdGetGamesOfUser(sc.GetExtension(Command_GetGamesOfUser::ext), rc); break; - case SessionCommand::GET_USER_INFO: resp = cmdGetUserInfo(sc.GetExtension(Command_GetUserInfo::ext), rc); break; - case SessionCommand::LIST_ROOMS: resp = cmdListRooms(sc.GetExtension(Command_ListRooms::ext), rc); break; - case SessionCommand::JOIN_ROOM: resp = cmdJoinRoom(sc.GetExtension(Command_JoinRoom::ext), rc); break; - case SessionCommand::LIST_USERS: resp = cmdListUsers(sc.GetExtension(Command_ListUsers::ext), rc); break; - default: resp = processExtendedSessionCommand(num, sc, rc); - } - if (resp != Response::RespOk) - finalResponseCode = resp; - } - return finalResponseCode; + Response::ResponseCode finalResponseCode = Response::RespOk; + for (int i = cont.session_command_size() - 1; i >= 0; --i) { + Response::ResponseCode resp = Response::RespInvalidCommand; + const SessionCommand &sc = cont.session_command(i); + const int num = getPbExtension(sc); + if (num != SessionCommand::PING) { // don't log ping commands + if (num == SessionCommand::LOGIN) { // log login commands, but hide passwords + SessionCommand debugSc(sc); + debugSc.MutableExtension(Command_Login::ext)->clear_password(); + logDebugMessage(QString::fromStdString(debugSc.ShortDebugString())); + } else + logDebugMessage(QString::fromStdString(sc.ShortDebugString())); + } + switch ((SessionCommand::SessionCommandType) num) { + case SessionCommand::PING: resp = cmdPing(sc.GetExtension(Command_Ping::ext), rc); break; + case SessionCommand::LOGIN: resp = cmdLogin(sc.GetExtension(Command_Login::ext), rc); break; + case SessionCommand::MESSAGE: resp = cmdMessage(sc.GetExtension(Command_Message::ext), rc); break; + case SessionCommand::GET_GAMES_OF_USER: resp = cmdGetGamesOfUser(sc.GetExtension(Command_GetGamesOfUser::ext), rc); break; + case SessionCommand::GET_USER_INFO: resp = cmdGetUserInfo(sc.GetExtension(Command_GetUserInfo::ext), rc); break; + case SessionCommand::LIST_ROOMS: resp = cmdListRooms(sc.GetExtension(Command_ListRooms::ext), rc); break; + case SessionCommand::JOIN_ROOM: resp = cmdJoinRoom(sc.GetExtension(Command_JoinRoom::ext), rc); break; + case SessionCommand::LIST_USERS: resp = cmdListUsers(sc.GetExtension(Command_ListUsers::ext), rc); break; + default: resp = processExtendedSessionCommand(num, sc, rc); + } + if (resp != Response::RespOk) + finalResponseCode = resp; + } + return finalResponseCode; } Response::ResponseCode Server_ProtocolHandler::processRoomCommandContainer(const CommandContainer &cont, ResponseContainer &rc) { - if (authState == NotLoggedIn) - return Response::RespLoginNeeded; + if (authState == NotLoggedIn) + return Response::RespLoginNeeded; - QReadLocker locker(&server->roomsLock); - Server_Room *room = rooms.value(cont.room_id(), 0); - if (!room) - return Response::RespNotInRoom; - - Response::ResponseCode finalResponseCode = Response::RespOk; - for (int i = cont.room_command_size() - 1; i >= 0; --i) { - Response::ResponseCode resp = Response::RespInvalidCommand; - const RoomCommand &sc = cont.room_command(i); - const int num = getPbExtension(sc); - logDebugMessage(QString::fromStdString(sc.ShortDebugString())); - switch ((RoomCommand::RoomCommandType) num) { - case RoomCommand::LEAVE_ROOM: resp = cmdLeaveRoom(sc.GetExtension(Command_LeaveRoom::ext), room, rc); break; - case RoomCommand::ROOM_SAY: resp = cmdRoomSay(sc.GetExtension(Command_RoomSay::ext), room, rc); break; - case RoomCommand::CREATE_GAME: resp = cmdCreateGame(sc.GetExtension(Command_CreateGame::ext), room, rc); break; - case RoomCommand::JOIN_GAME: resp = cmdJoinGame(sc.GetExtension(Command_JoinGame::ext), room, rc); break; - } - if (resp != Response::RespOk) - finalResponseCode = resp; - } - return finalResponseCode; + QReadLocker locker(&server->roomsLock); + Server_Room *room = rooms.value(cont.room_id(), 0); + if (!room) + return Response::RespNotInRoom; + + Response::ResponseCode finalResponseCode = Response::RespOk; + for (int i = cont.room_command_size() - 1; i >= 0; --i) { + Response::ResponseCode resp = Response::RespInvalidCommand; + const RoomCommand &sc = cont.room_command(i); + const int num = getPbExtension(sc); + logDebugMessage(QString::fromStdString(sc.ShortDebugString())); + switch ((RoomCommand::RoomCommandType) num) { + case RoomCommand::LEAVE_ROOM: resp = cmdLeaveRoom(sc.GetExtension(Command_LeaveRoom::ext), room, rc); break; + case RoomCommand::ROOM_SAY: resp = cmdRoomSay(sc.GetExtension(Command_RoomSay::ext), room, rc); break; + case RoomCommand::CREATE_GAME: resp = cmdCreateGame(sc.GetExtension(Command_CreateGame::ext), room, rc); break; + case RoomCommand::JOIN_GAME: resp = cmdJoinGame(sc.GetExtension(Command_JoinGame::ext), room, rc); break; + } + if (resp != Response::RespOk) + finalResponseCode = resp; + } + return finalResponseCode; } Response::ResponseCode Server_ProtocolHandler::processGameCommandContainer(const CommandContainer &cont, ResponseContainer &rc) { - if (authState == NotLoggedIn) - return Response::RespLoginNeeded; - - QMap > gameMap = getGames(); - if (!gameMap.contains(cont.game_id())) - return Response::RespNotInRoom; - const QPair roomIdAndPlayerId = gameMap.value(cont.game_id()); - - QReadLocker roomsLocker(&server->roomsLock); - Server_Room *room = server->getRooms().value(roomIdAndPlayerId.first); - if (!room) - return Response::RespNotInRoom; - - QReadLocker roomGamesLocker(&room->gamesLock); - Server_Game *game = room->getGames().value(cont.game_id()); - if (!game) { - if (room->getExternalGames().contains(cont.game_id())) { - server->sendIsl_GameCommand(cont, - room->getExternalGames().value(cont.game_id()).server_id(), - userInfo->session_id(), - roomIdAndPlayerId.first, - roomIdAndPlayerId.second - ); - return Response::RespNothing; - } - return Response::RespNotInRoom; - } - - QMutexLocker gameLocker(&game->gameMutex); - Server_Player *player = game->getPlayers().value(roomIdAndPlayerId.second); - if (!player) - return Response::RespNotInRoom; - - GameEventStorage ges; - Response::ResponseCode finalResponseCode = Response::RespOk; - for (int i = cont.game_command_size() - 1; i >= 0; --i) { - const GameCommand &sc = cont.game_command(i); - logDebugMessage(QString("game %1 player %2: ").arg(cont.game_id()).arg(roomIdAndPlayerId.second) + QString::fromStdString(sc.ShortDebugString())); - - Response::ResponseCode resp = player->processGameCommand(sc, rc, ges); + if (authState == NotLoggedIn) + return Response::RespLoginNeeded; + + QMap > gameMap = getGames(); + if (!gameMap.contains(cont.game_id())) + return Response::RespNotInRoom; + const QPair roomIdAndPlayerId = gameMap.value(cont.game_id()); + + QReadLocker roomsLocker(&server->roomsLock); + Server_Room *room = server->getRooms().value(roomIdAndPlayerId.first); + if (!room) + return Response::RespNotInRoom; + + QReadLocker roomGamesLocker(&room->gamesLock); + Server_Game *game = room->getGames().value(cont.game_id()); + if (!game) { + if (room->getExternalGames().contains(cont.game_id())) { + server->sendIsl_GameCommand(cont, + room->getExternalGames().value(cont.game_id()).server_id(), + userInfo->session_id(), + roomIdAndPlayerId.first, + roomIdAndPlayerId.second + ); + return Response::RespNothing; + } + return Response::RespNotInRoom; + } + + QMutexLocker gameLocker(&game->gameMutex); + Server_Player *player = game->getPlayers().value(roomIdAndPlayerId.second); + if (!player) + return Response::RespNotInRoom; + + GameEventStorage ges; + Response::ResponseCode finalResponseCode = Response::RespOk; + for (int i = cont.game_command_size() - 1; i >= 0; --i) { + const GameCommand &sc = cont.game_command(i); + logDebugMessage(QString("game %1 player %2: ").arg(cont.game_id()).arg(roomIdAndPlayerId.second) + QString::fromStdString(sc.ShortDebugString())); + + Response::ResponseCode resp = player->processGameCommand(sc, rc, ges); - if (resp != Response::RespOk) - finalResponseCode = resp; - } - ges.sendToGame(game); - - return finalResponseCode; + if (resp != Response::RespOk) + finalResponseCode = resp; + } + ges.sendToGame(game); + + return finalResponseCode; } Response::ResponseCode Server_ProtocolHandler::processModeratorCommandContainer(const CommandContainer &cont, ResponseContainer &rc) { - if (!userInfo) - return Response::RespLoginNeeded; - if (!(userInfo->user_level() & ServerInfo_User::IsModerator)) - return Response::RespLoginNeeded; + if (!userInfo) + return Response::RespLoginNeeded; + if (!(userInfo->user_level() & ServerInfo_User::IsModerator)) + return Response::RespLoginNeeded; - Response::ResponseCode finalResponseCode = Response::RespOk; - for (int i = cont.moderator_command_size() - 1; i >= 0; --i) { - Response::ResponseCode resp = Response::RespInvalidCommand; - const ModeratorCommand &sc = cont.moderator_command(i); - const int num = getPbExtension(sc); - logDebugMessage(QString::fromStdString(sc.ShortDebugString())); - - resp = processExtendedModeratorCommand(num, sc, rc); - if (resp != Response::RespOk) - finalResponseCode = resp; - } - return finalResponseCode; + Response::ResponseCode finalResponseCode = Response::RespOk; + for (int i = cont.moderator_command_size() - 1; i >= 0; --i) { + Response::ResponseCode resp = Response::RespInvalidCommand; + const ModeratorCommand &sc = cont.moderator_command(i); + const int num = getPbExtension(sc); + logDebugMessage(QString::fromStdString(sc.ShortDebugString())); + + resp = processExtendedModeratorCommand(num, sc, rc); + if (resp != Response::RespOk) + finalResponseCode = resp; + } + return finalResponseCode; } Response::ResponseCode Server_ProtocolHandler::processAdminCommandContainer(const CommandContainer &cont, ResponseContainer &rc) { - if (!userInfo) - return Response::RespLoginNeeded; - if (!(userInfo->user_level() & ServerInfo_User::IsAdmin)) - return Response::RespLoginNeeded; + if (!userInfo) + return Response::RespLoginNeeded; + if (!(userInfo->user_level() & ServerInfo_User::IsAdmin)) + return Response::RespLoginNeeded; - Response::ResponseCode finalResponseCode = Response::RespOk; - for (int i = cont.admin_command_size() - 1; i >= 0; --i) { - Response::ResponseCode resp = Response::RespInvalidCommand; - const AdminCommand &sc = cont.admin_command(i); - const int num = getPbExtension(sc); - logDebugMessage(QString::fromStdString(sc.ShortDebugString())); - - resp = processExtendedAdminCommand(num, sc, rc); - if (resp != Response::RespOk) - finalResponseCode = resp; - } - return finalResponseCode; + Response::ResponseCode finalResponseCode = Response::RespOk; + for (int i = cont.admin_command_size() - 1; i >= 0; --i) { + Response::ResponseCode resp = Response::RespInvalidCommand; + const AdminCommand &sc = cont.admin_command(i); + const int num = getPbExtension(sc); + logDebugMessage(QString::fromStdString(sc.ShortDebugString())); + + resp = processExtendedAdminCommand(num, sc, rc); + if (resp != Response::RespOk) + finalResponseCode = resp; + } + return finalResponseCode; } void Server_ProtocolHandler::processCommandContainer(const CommandContainer &cont) { - // Command processing must be disabled after prepareDestroy() has been called. - if (deleted) - return; - - lastDataReceived = timeRunning; - - ResponseContainer responseContainer(cont.has_cmd_id() ? cont.cmd_id() : -1); - Response::ResponseCode finalResponseCode; - - if (cont.game_command_size()) - finalResponseCode = processGameCommandContainer(cont, responseContainer); - else if (cont.room_command_size()) - finalResponseCode = processRoomCommandContainer(cont, responseContainer); - else if (cont.session_command_size()) - finalResponseCode = processSessionCommandContainer(cont, responseContainer); - else if (cont.moderator_command_size()) - finalResponseCode = processModeratorCommandContainer(cont, responseContainer); - else if (cont.admin_command_size()) - finalResponseCode = processAdminCommandContainer(cont, responseContainer); - else - finalResponseCode = Response::RespInvalidCommand; - - if ((finalResponseCode != Response::RespNothing)) - sendResponseContainer(responseContainer, finalResponseCode); + // Command processing must be disabled after prepareDestroy() has been called. + if (deleted) + return; + + lastDataReceived = timeRunning; + + ResponseContainer responseContainer(cont.has_cmd_id() ? cont.cmd_id() : -1); + Response::ResponseCode finalResponseCode; + + if (cont.game_command_size()) + finalResponseCode = processGameCommandContainer(cont, responseContainer); + else if (cont.room_command_size()) + finalResponseCode = processRoomCommandContainer(cont, responseContainer); + else if (cont.session_command_size()) + finalResponseCode = processSessionCommandContainer(cont, responseContainer); + else if (cont.moderator_command_size()) + finalResponseCode = processModeratorCommandContainer(cont, responseContainer); + else if (cont.admin_command_size()) + finalResponseCode = processAdminCommandContainer(cont, responseContainer); + else + finalResponseCode = Response::RespInvalidCommand; + + if ((finalResponseCode != Response::RespNothing)) + sendResponseContainer(responseContainer, finalResponseCode); } void Server_ProtocolHandler::pingClockTimeout() { - int interval = server->getMessageCountingInterval(); - if (interval > 0) { - messageSizeOverTime.prepend(0); - if (messageSizeOverTime.size() > server->getMessageCountingInterval()) - messageSizeOverTime.removeLast(); - messageCountOverTime.prepend(0); - if (messageCountOverTime.size() > server->getMessageCountingInterval()) - messageCountOverTime.removeLast(); - } - - if (timeRunning - lastDataReceived > server->getMaxPlayerInactivityTime()) - prepareDestroy(); - ++timeRunning; + int interval = server->getMessageCountingInterval(); + if (interval > 0) { + messageSizeOverTime.prepend(0); + if (messageSizeOverTime.size() > server->getMessageCountingInterval()) + messageSizeOverTime.removeLast(); + messageCountOverTime.prepend(0); + if (messageCountOverTime.size() > server->getMessageCountingInterval()) + messageCountOverTime.removeLast(); + } + + if (timeRunning - lastDataReceived > server->getMaxPlayerInactivityTime()) + prepareDestroy(); + ++timeRunning; } Response::ResponseCode Server_ProtocolHandler::cmdPing(const Command_Ping & /*cmd*/, ResponseContainer & /*rc*/) { - return Response::RespOk; + return Response::RespOk; } Response::ResponseCode Server_ProtocolHandler::cmdLogin(const Command_Login &cmd, ResponseContainer &rc) { - QString userName = QString::fromStdString(cmd.user_name()).simplified(); - if (userName.isEmpty() || (userInfo != 0)) - return Response::RespContextError; - QString reasonStr; - int banSecondsLeft = 0; - AuthenticationResult res = server->loginUser(this, userName, QString::fromStdString(cmd.password()), reasonStr, banSecondsLeft); - switch (res) { - case UserIsBanned: { - Response_Login *re = new Response_Login; - re->set_denied_reason_str(reasonStr.toStdString()); - if (banSecondsLeft != 0) - re->set_denied_end_time(QDateTime::currentDateTime().addSecs(banSecondsLeft).toTime_t()); - rc.setResponseExtension(re); - return Response::RespUserIsBanned; - } - case NotLoggedIn: return Response::RespWrongPassword; - case WouldOverwriteOldSession: return Response::RespWouldOverwriteOldSession; - case UsernameInvalid: return Response::RespUsernameInvalid; - default: authState = res; - } - - userName = QString::fromStdString(userInfo->name()); - Event_ServerMessage event; - event.set_message(server->getLoginMessage().toStdString()); - rc.enqueuePostResponseItem(ServerMessage::SESSION_EVENT, prepareSessionEvent(event)); - - Response_Login *re = new Response_Login; - re->mutable_user_info()->CopyFrom(copyUserInfo(true)); - - if (authState == PasswordRight) { - QMapIterator buddyIterator(databaseInterface->getBuddyList(userName)); - while (buddyIterator.hasNext()) - re->add_buddy_list()->CopyFrom(buddyIterator.next().value()); - - QMapIterator ignoreIterator(databaseInterface->getIgnoreList(userName)); - while (ignoreIterator.hasNext()) - re->add_ignore_list()->CopyFrom(ignoreIterator.next().value()); - } - - joinPersistentGames(rc); - - rc.setResponseExtension(re); - return Response::RespOk; + QString userName = QString::fromStdString(cmd.user_name()).simplified(); + if (userName.isEmpty() || (userInfo != 0)) + return Response::RespContextError; + QString reasonStr; + int banSecondsLeft = 0; + AuthenticationResult res = server->loginUser(this, userName, QString::fromStdString(cmd.password()), reasonStr, banSecondsLeft); + switch (res) { + case UserIsBanned: { + Response_Login *re = new Response_Login; + re->set_denied_reason_str(reasonStr.toStdString()); + if (banSecondsLeft != 0) + re->set_denied_end_time(QDateTime::currentDateTime().addSecs(banSecondsLeft).toTime_t()); + rc.setResponseExtension(re); + return Response::RespUserIsBanned; + } + case NotLoggedIn: return Response::RespWrongPassword; + case WouldOverwriteOldSession: return Response::RespWouldOverwriteOldSession; + case UsernameInvalid: return Response::RespUsernameInvalid; + default: authState = res; + } + + userName = QString::fromStdString(userInfo->name()); + Event_ServerMessage event; + event.set_message(server->getLoginMessage().toStdString()); + rc.enqueuePostResponseItem(ServerMessage::SESSION_EVENT, prepareSessionEvent(event)); + + Response_Login *re = new Response_Login; + re->mutable_user_info()->CopyFrom(copyUserInfo(true)); + + if (authState == PasswordRight) { + QMapIterator buddyIterator(databaseInterface->getBuddyList(userName)); + while (buddyIterator.hasNext()) + re->add_buddy_list()->CopyFrom(buddyIterator.next().value()); + + QMapIterator ignoreIterator(databaseInterface->getIgnoreList(userName)); + while (ignoreIterator.hasNext()) + re->add_ignore_list()->CopyFrom(ignoreIterator.next().value()); + } + + joinPersistentGames(rc); + + rc.setResponseExtension(re); + return Response::RespOk; } Response::ResponseCode Server_ProtocolHandler::cmdMessage(const Command_Message &cmd, ResponseContainer &rc) { - if (authState == NotLoggedIn) - return Response::RespLoginNeeded; - - QReadLocker locker(&server->clientsLock); - - QString receiver = QString::fromStdString(cmd.user_name()); - Server_AbstractUserInterface *userInterface = server->findUser(receiver); - if (!userInterface) - return Response::RespNameNotFound; - if (databaseInterface->isInIgnoreList(receiver, QString::fromStdString(userInfo->name()))) - return Response::RespInIgnoreList; - - Event_UserMessage event; - event.set_sender_name(userInfo->name()); - event.set_receiver_name(cmd.user_name()); - event.set_message(cmd.message()); - - SessionEvent *se = prepareSessionEvent(event); - userInterface->sendProtocolItem(*se); - rc.enqueuePreResponseItem(ServerMessage::SESSION_EVENT, se); - - return Response::RespOk; + if (authState == NotLoggedIn) + return Response::RespLoginNeeded; + + QReadLocker locker(&server->clientsLock); + + QString receiver = QString::fromStdString(cmd.user_name()); + Server_AbstractUserInterface *userInterface = server->findUser(receiver); + if (!userInterface) + return Response::RespNameNotFound; + if (databaseInterface->isInIgnoreList(receiver, QString::fromStdString(userInfo->name()))) + return Response::RespInIgnoreList; + + Event_UserMessage event; + event.set_sender_name(userInfo->name()); + event.set_receiver_name(cmd.user_name()); + event.set_message(cmd.message()); + + SessionEvent *se = prepareSessionEvent(event); + userInterface->sendProtocolItem(*se); + rc.enqueuePreResponseItem(ServerMessage::SESSION_EVENT, se); + + return Response::RespOk; } Response::ResponseCode Server_ProtocolHandler::cmdGetGamesOfUser(const Command_GetGamesOfUser &cmd, ResponseContainer &rc) { - if (authState == NotLoggedIn) - return Response::RespLoginNeeded; - - // We don't need to check whether the user is logged in; persistent games should also work. - // The client needs to deal with an empty result list. - - Response_GetGamesOfUser *re = new Response_GetGamesOfUser; - server->roomsLock.lockForRead(); - QMapIterator roomIterator(server->getRooms()); - while (roomIterator.hasNext()) { - Server_Room *room = roomIterator.next().value(); - room->gamesLock.lockForRead(); - room->getInfo(*re->add_room_list(), false, true); - QListIterator gameIterator(room->getGamesOfUser(QString::fromStdString(cmd.user_name()))); - while (gameIterator.hasNext()) - re->add_game_list()->CopyFrom(gameIterator.next()); - room->gamesLock.unlock(); - } - server->roomsLock.unlock(); - - rc.setResponseExtension(re); - return Response::RespOk; + if (authState == NotLoggedIn) + return Response::RespLoginNeeded; + + // We don't need to check whether the user is logged in; persistent games should also work. + // The client needs to deal with an empty result list. + + Response_GetGamesOfUser *re = new Response_GetGamesOfUser; + server->roomsLock.lockForRead(); + QMapIterator roomIterator(server->getRooms()); + while (roomIterator.hasNext()) { + Server_Room *room = roomIterator.next().value(); + room->gamesLock.lockForRead(); + room->getInfo(*re->add_room_list(), false, true); + QListIterator gameIterator(room->getGamesOfUser(QString::fromStdString(cmd.user_name()))); + while (gameIterator.hasNext()) + re->add_game_list()->CopyFrom(gameIterator.next()); + room->gamesLock.unlock(); + } + server->roomsLock.unlock(); + + rc.setResponseExtension(re); + return Response::RespOk; } Response::ResponseCode Server_ProtocolHandler::cmdGetUserInfo(const Command_GetUserInfo &cmd, ResponseContainer &rc) { - if (authState == NotLoggedIn) - return Response::RespLoginNeeded; - - QString userName = QString::fromStdString(cmd.user_name()); - Response_GetUserInfo *re = new Response_GetUserInfo; - if (userName.isEmpty()) - re->mutable_user_info()->CopyFrom(*userInfo); - else { - - QReadLocker locker(&server->clientsLock); - - ServerInfo_User_Container *infoSource = server->findUser(userName); - if (!infoSource) - return Response::RespNameNotFound; - - re->mutable_user_info()->CopyFrom(infoSource->copyUserInfo(true, false, userInfo->user_level() & ServerInfo_User::IsModerator)); - } - - rc.setResponseExtension(re); - return Response::RespOk; + if (authState == NotLoggedIn) + return Response::RespLoginNeeded; + + QString userName = QString::fromStdString(cmd.user_name()); + Response_GetUserInfo *re = new Response_GetUserInfo; + if (userName.isEmpty()) + re->mutable_user_info()->CopyFrom(*userInfo); + else { + + QReadLocker locker(&server->clientsLock); + + ServerInfo_User_Container *infoSource = server->findUser(userName); + if (!infoSource) + return Response::RespNameNotFound; + + re->mutable_user_info()->CopyFrom(infoSource->copyUserInfo(true, false, userInfo->user_level() & ServerInfo_User::IsModerator)); + } + + rc.setResponseExtension(re); + return Response::RespOk; } Response::ResponseCode Server_ProtocolHandler::cmdListRooms(const Command_ListRooms & /*cmd*/, ResponseContainer &rc) { - if (authState == NotLoggedIn) - return Response::RespLoginNeeded; - - Event_ListRooms event; - QMapIterator roomIterator(server->getRooms()); - while (roomIterator.hasNext()) - roomIterator.next().value()->getInfo(*event.add_room_list(), false); - rc.enqueuePreResponseItem(ServerMessage::SESSION_EVENT, prepareSessionEvent(event)); - - acceptsRoomListChanges = true; - return Response::RespOk; + if (authState == NotLoggedIn) + return Response::RespLoginNeeded; + + Event_ListRooms event; + QMapIterator roomIterator(server->getRooms()); + while (roomIterator.hasNext()) + roomIterator.next().value()->getInfo(*event.add_room_list(), false); + rc.enqueuePreResponseItem(ServerMessage::SESSION_EVENT, prepareSessionEvent(event)); + + acceptsRoomListChanges = true; + return Response::RespOk; } Response::ResponseCode Server_ProtocolHandler::cmdJoinRoom(const Command_JoinRoom &cmd, ResponseContainer &rc) { - if (authState == NotLoggedIn) - return Response::RespLoginNeeded; - - if (rooms.contains(cmd.room_id())) - return Response::RespContextError; - - QReadLocker serverLocker(&server->roomsLock); - Server_Room *r = server->getRooms().value(cmd.room_id(), 0); - if (!r) - return Response::RespNameNotFound; - - r->addClient(this); - rooms.insert(r->getId(), r); - - Event_RoomSay joinMessageEvent; - joinMessageEvent.set_message(r->getJoinMessage().toStdString()); - rc.enqueuePostResponseItem(ServerMessage::ROOM_EVENT, r->prepareRoomEvent(joinMessageEvent)); - - Response_JoinRoom *re = new Response_JoinRoom; - r->getInfo(*re->mutable_room_info(), true); - - rc.setResponseExtension(re); - return Response::RespOk; + if (authState == NotLoggedIn) + return Response::RespLoginNeeded; + + if (rooms.contains(cmd.room_id())) + return Response::RespContextError; + + QReadLocker serverLocker(&server->roomsLock); + Server_Room *r = server->getRooms().value(cmd.room_id(), 0); + if (!r) + return Response::RespNameNotFound; + + r->addClient(this); + rooms.insert(r->getId(), r); + + Event_RoomSay joinMessageEvent; + joinMessageEvent.set_message(r->getJoinMessage().toStdString()); + rc.enqueuePostResponseItem(ServerMessage::ROOM_EVENT, r->prepareRoomEvent(joinMessageEvent)); + + Response_JoinRoom *re = new Response_JoinRoom; + r->getInfo(*re->mutable_room_info(), true); + + rc.setResponseExtension(re); + return Response::RespOk; } Response::ResponseCode Server_ProtocolHandler::cmdListUsers(const Command_ListUsers & /*cmd*/, ResponseContainer &rc) { - if (authState == NotLoggedIn) - return Response::RespLoginNeeded; - - Response_ListUsers *re = new Response_ListUsers; - server->clientsLock.lockForRead(); - QMapIterator userIterator = server->getUsers(); - while (userIterator.hasNext()) - re->add_user_list()->CopyFrom(userIterator.next().value()->copyUserInfo(false)); - QMapIterator extIterator = server->getExternalUsers(); - while (extIterator.hasNext()) - re->add_user_list()->CopyFrom(extIterator.next().value()->copyUserInfo(false)); - - acceptsUserListChanges = true; - server->clientsLock.unlock(); - - rc.setResponseExtension(re); - return Response::RespOk; + if (authState == NotLoggedIn) + return Response::RespLoginNeeded; + + Response_ListUsers *re = new Response_ListUsers; + server->clientsLock.lockForRead(); + QMapIterator userIterator = server->getUsers(); + while (userIterator.hasNext()) + re->add_user_list()->CopyFrom(userIterator.next().value()->copyUserInfo(false)); + QMapIterator extIterator = server->getExternalUsers(); + while (extIterator.hasNext()) + re->add_user_list()->CopyFrom(extIterator.next().value()->copyUserInfo(false)); + + acceptsUserListChanges = true; + server->clientsLock.unlock(); + + rc.setResponseExtension(re); + return Response::RespOk; } Response::ResponseCode Server_ProtocolHandler::cmdLeaveRoom(const Command_LeaveRoom & /*cmd*/, Server_Room *room, ResponseContainer & /*rc*/) { - rooms.remove(room->getId()); - room->removeClient(this); - return Response::RespOk; + rooms.remove(room->getId()); + room->removeClient(this); + return Response::RespOk; } Response::ResponseCode Server_ProtocolHandler::cmdRoomSay(const Command_RoomSay &cmd, Server_Room *room, ResponseContainer & /*rc*/) { - QString msg = QString::fromStdString(cmd.message()); - - if (server->getMessageCountingInterval() > 0) { - int totalSize = 0, totalCount = 0; - if (messageSizeOverTime.isEmpty()) - messageSizeOverTime.prepend(0); - messageSizeOverTime[0] += msg.size(); - for (int i = 0; i < messageSizeOverTime.size(); ++i) - totalSize += messageSizeOverTime[i]; - - if (messageCountOverTime.isEmpty()) - messageCountOverTime.prepend(0); - ++messageCountOverTime[0]; - for (int i = 0; i < messageCountOverTime.size(); ++i) - totalCount += messageCountOverTime[i]; - - if ((totalSize > server->getMaxMessageSizePerInterval()) || (totalCount > server->getMaxMessageCountPerInterval())) - return Response::RespChatFlood; - } - msg.replace(QChar('\n'), QChar(' ')); - - room->say(QString::fromStdString(userInfo->name()), msg); - return Response::RespOk; + QString msg = QString::fromStdString(cmd.message()); + + if (server->getMessageCountingInterval() > 0) { + int totalSize = 0, totalCount = 0; + if (messageSizeOverTime.isEmpty()) + messageSizeOverTime.prepend(0); + messageSizeOverTime[0] += msg.size(); + for (int i = 0; i < messageSizeOverTime.size(); ++i) + totalSize += messageSizeOverTime[i]; + + if (messageCountOverTime.isEmpty()) + messageCountOverTime.prepend(0); + ++messageCountOverTime[0]; + for (int i = 0; i < messageCountOverTime.size(); ++i) + totalCount += messageCountOverTime[i]; + + if ((totalSize > server->getMaxMessageSizePerInterval()) || (totalCount > server->getMaxMessageCountPerInterval())) + return Response::RespChatFlood; + } + msg.replace(QChar('\n'), QChar(' ')); + + room->say(QString::fromStdString(userInfo->name()), msg); + return Response::RespOk; } Response::ResponseCode Server_ProtocolHandler::cmdCreateGame(const Command_CreateGame &cmd, Server_Room *room, ResponseContainer &rc) { - if (authState == NotLoggedIn) - return Response::RespLoginNeeded; - const int gameId = databaseInterface->getNextGameId(); - if (gameId == -1) - return Response::RespInternalError; - - if (server->getMaxGamesPerUser() > 0) - if (room->getGamesCreatedByUser(QString::fromStdString(userInfo->name())) >= server->getMaxGamesPerUser()) - return Response::RespContextError; - - QList gameTypes; - for (int i = cmd.game_type_ids_size() - 1; i >= 0; --i) - gameTypes.append(cmd.game_type_ids(i)); - - QString description = QString::fromStdString(cmd.description()); - if (description.size() > 60) - description = description.left(60); - - Server_Game *game = new Server_Game(copyUserInfo(false), gameId, description, QString::fromStdString(cmd.password()), cmd.max_players(), gameTypes, cmd.only_buddies(), cmd.only_registered(), cmd.spectators_allowed(), cmd.spectators_need_password(), cmd.spectators_can_talk(), cmd.spectators_see_everything(), room); - game->addPlayer(this, rc, false, false); - room->addGame(game); - - return Response::RespOk; + if (authState == NotLoggedIn) + return Response::RespLoginNeeded; + const int gameId = databaseInterface->getNextGameId(); + if (gameId == -1) + return Response::RespInternalError; + + if (server->getMaxGamesPerUser() > 0) + if (room->getGamesCreatedByUser(QString::fromStdString(userInfo->name())) >= server->getMaxGamesPerUser()) + return Response::RespContextError; + + QList gameTypes; + for (int i = cmd.game_type_ids_size() - 1; i >= 0; --i) + gameTypes.append(cmd.game_type_ids(i)); + + QString description = QString::fromStdString(cmd.description()); + if (description.size() > 60) + description = description.left(60); + + Server_Game *game = new Server_Game(copyUserInfo(false), gameId, description, QString::fromStdString(cmd.password()), cmd.max_players(), gameTypes, cmd.only_buddies(), cmd.only_registered(), cmd.spectators_allowed(), cmd.spectators_need_password(), cmd.spectators_can_talk(), cmd.spectators_see_everything(), room); + game->addPlayer(this, rc, false, false); + room->addGame(game); + + return Response::RespOk; } Response::ResponseCode Server_ProtocolHandler::cmdJoinGame(const Command_JoinGame &cmd, Server_Room *room, ResponseContainer &rc) { - if (authState == NotLoggedIn) - return Response::RespLoginNeeded; - - return room->processJoinGameCommand(cmd, rc, this); + if (authState == NotLoggedIn) + return Response::RespLoginNeeded; + + return room->processJoinGameCommand(cmd, rc, this); } diff --git a/common/server_protocolhandler.h b/common/server_protocolhandler.h index 56165c80..0cea37ae 100644 --- a/common/server_protocolhandler.h +++ b/common/server_protocolhandler.h @@ -40,64 +40,64 @@ class Command_CreateGame; class Command_JoinGame; class Server_ProtocolHandler : public QObject, public Server_AbstractUserInterface { - Q_OBJECT + Q_OBJECT protected: - QMap rooms; - - bool deleted; - Server_DatabaseInterface *databaseInterface; - AuthenticationResult authState; - bool acceptsUserListChanges; - bool acceptsRoomListChanges; - virtual void logDebugMessage(const QString &message) { } + QMap rooms; + + bool deleted; + Server_DatabaseInterface *databaseInterface; + AuthenticationResult authState; + bool acceptsUserListChanges; + bool acceptsRoomListChanges; + virtual void logDebugMessage(const QString &message) { } private: - QList messageSizeOverTime, messageCountOverTime; - int timeRunning, lastDataReceived; - QTimer *pingClock; + QList messageSizeOverTime, messageCountOverTime; + int timeRunning, lastDataReceived; + QTimer *pingClock; - virtual void transmitProtocolItem(const ServerMessage &item) = 0; - - Response::ResponseCode cmdPing(const Command_Ping &cmd, ResponseContainer &rc); - Response::ResponseCode cmdLogin(const Command_Login &cmd, ResponseContainer &rc); - Response::ResponseCode cmdMessage(const Command_Message &cmd, ResponseContainer &rc); - Response::ResponseCode cmdGetGamesOfUser(const Command_GetGamesOfUser &cmd, ResponseContainer &rc); - Response::ResponseCode cmdGetUserInfo(const Command_GetUserInfo &cmd, ResponseContainer &rc); - Response::ResponseCode cmdListRooms(const Command_ListRooms &cmd, ResponseContainer &rc); - Response::ResponseCode cmdJoinRoom(const Command_JoinRoom &cmd, ResponseContainer &rc); - Response::ResponseCode cmdListUsers(const Command_ListUsers &cmd, ResponseContainer &rc); - Response::ResponseCode cmdLeaveRoom(const Command_LeaveRoom &cmd, Server_Room *room, ResponseContainer &rc); - Response::ResponseCode cmdRoomSay(const Command_RoomSay &cmd, Server_Room *room, ResponseContainer &rc); - Response::ResponseCode cmdCreateGame(const Command_CreateGame &cmd, Server_Room *room, ResponseContainer &rc); - Response::ResponseCode cmdJoinGame(const Command_JoinGame &cmd, Server_Room *room, ResponseContainer &rc); - - Response::ResponseCode processSessionCommandContainer(const CommandContainer &cont, ResponseContainer &rc); - virtual Response::ResponseCode processExtendedSessionCommand(int cmdType, const SessionCommand &cmd, ResponseContainer &rc) { return Response::RespFunctionNotAllowed; } - Response::ResponseCode processRoomCommandContainer(const CommandContainer &cont, ResponseContainer &rc); - Response::ResponseCode processGameCommandContainer(const CommandContainer &cont, ResponseContainer &rc); - Response::ResponseCode processModeratorCommandContainer(const CommandContainer &cont, ResponseContainer &rc); - virtual Response::ResponseCode processExtendedModeratorCommand(int cmdType, const ModeratorCommand &cmd, ResponseContainer &rc) { return Response::RespFunctionNotAllowed; } - Response::ResponseCode processAdminCommandContainer(const CommandContainer &cont, ResponseContainer &rc); - virtual Response::ResponseCode processExtendedAdminCommand(int cmdType, const AdminCommand &cmd, ResponseContainer &rc) { return Response::RespFunctionNotAllowed; } + virtual void transmitProtocolItem(const ServerMessage &item) = 0; + + Response::ResponseCode cmdPing(const Command_Ping &cmd, ResponseContainer &rc); + Response::ResponseCode cmdLogin(const Command_Login &cmd, ResponseContainer &rc); + Response::ResponseCode cmdMessage(const Command_Message &cmd, ResponseContainer &rc); + Response::ResponseCode cmdGetGamesOfUser(const Command_GetGamesOfUser &cmd, ResponseContainer &rc); + Response::ResponseCode cmdGetUserInfo(const Command_GetUserInfo &cmd, ResponseContainer &rc); + Response::ResponseCode cmdListRooms(const Command_ListRooms &cmd, ResponseContainer &rc); + Response::ResponseCode cmdJoinRoom(const Command_JoinRoom &cmd, ResponseContainer &rc); + Response::ResponseCode cmdListUsers(const Command_ListUsers &cmd, ResponseContainer &rc); + Response::ResponseCode cmdLeaveRoom(const Command_LeaveRoom &cmd, Server_Room *room, ResponseContainer &rc); + Response::ResponseCode cmdRoomSay(const Command_RoomSay &cmd, Server_Room *room, ResponseContainer &rc); + Response::ResponseCode cmdCreateGame(const Command_CreateGame &cmd, Server_Room *room, ResponseContainer &rc); + Response::ResponseCode cmdJoinGame(const Command_JoinGame &cmd, Server_Room *room, ResponseContainer &rc); + + Response::ResponseCode processSessionCommandContainer(const CommandContainer &cont, ResponseContainer &rc); + virtual Response::ResponseCode processExtendedSessionCommand(int cmdType, const SessionCommand &cmd, ResponseContainer &rc) { return Response::RespFunctionNotAllowed; } + Response::ResponseCode processRoomCommandContainer(const CommandContainer &cont, ResponseContainer &rc); + Response::ResponseCode processGameCommandContainer(const CommandContainer &cont, ResponseContainer &rc); + Response::ResponseCode processModeratorCommandContainer(const CommandContainer &cont, ResponseContainer &rc); + virtual Response::ResponseCode processExtendedModeratorCommand(int cmdType, const ModeratorCommand &cmd, ResponseContainer &rc) { return Response::RespFunctionNotAllowed; } + Response::ResponseCode processAdminCommandContainer(const CommandContainer &cont, ResponseContainer &rc); + virtual Response::ResponseCode processExtendedAdminCommand(int cmdType, const AdminCommand &cmd, ResponseContainer &rc) { return Response::RespFunctionNotAllowed; } private slots: - void pingClockTimeout(); + void pingClockTimeout(); public slots: - void prepareDestroy(); + void prepareDestroy(); public: - Server_ProtocolHandler(Server *_server, Server_DatabaseInterface *_databaseInterface, QObject *parent = 0); - ~Server_ProtocolHandler(); - - bool getAcceptsUserListChanges() const { return acceptsUserListChanges; } - bool getAcceptsRoomListChanges() const { return acceptsRoomListChanges; } - virtual QString getAddress() const = 0; - Server_DatabaseInterface *getDatabaseInterface() const { return databaseInterface; } + Server_ProtocolHandler(Server *_server, Server_DatabaseInterface *_databaseInterface, QObject *parent = 0); + ~Server_ProtocolHandler(); + + bool getAcceptsUserListChanges() const { return acceptsUserListChanges; } + bool getAcceptsRoomListChanges() const { return acceptsRoomListChanges; } + virtual QString getAddress() const = 0; + Server_DatabaseInterface *getDatabaseInterface() const { return databaseInterface; } - int getLastCommandTime() const { return timeRunning - lastDataReceived; } - void processCommandContainer(const CommandContainer &cont); - - void sendProtocolItem(const Response &item); - void sendProtocolItem(const SessionEvent &item); - void sendProtocolItem(const GameEventContainer &item); - void sendProtocolItem(const RoomEvent &item); + int getLastCommandTime() const { return timeRunning - lastDataReceived; } + void processCommandContainer(const CommandContainer &cont); + + void sendProtocolItem(const Response &item); + void sendProtocolItem(const SessionEvent &item); + void sendProtocolItem(const GameEventContainer &item); + void sendProtocolItem(const RoomEvent &item); }; #endif diff --git a/common/server_remoteuserinterface.cpp b/common/server_remoteuserinterface.cpp index cd0e3031..7bbcf963 100644 --- a/common/server_remoteuserinterface.cpp +++ b/common/server_remoteuserinterface.cpp @@ -4,20 +4,20 @@ void Server_RemoteUserInterface::sendProtocolItem(const Response &item) { - server->sendIsl_Response(item, userInfo->server_id(), userInfo->session_id()); + server->sendIsl_Response(item, userInfo->server_id(), userInfo->session_id()); } void Server_RemoteUserInterface::sendProtocolItem(const SessionEvent &item) { - server->sendIsl_SessionEvent(item, userInfo->server_id(), userInfo->session_id()); + server->sendIsl_SessionEvent(item, userInfo->server_id(), userInfo->session_id()); } void Server_RemoteUserInterface::sendProtocolItem(const GameEventContainer &item) { - server->sendIsl_GameEventContainer(item, userInfo->server_id(), userInfo->session_id()); + server->sendIsl_GameEventContainer(item, userInfo->server_id(), userInfo->session_id()); } void Server_RemoteUserInterface::sendProtocolItem(const RoomEvent &item) { - server->sendIsl_RoomEvent(item, userInfo->server_id(), userInfo->session_id()); + server->sendIsl_RoomEvent(item, userInfo->server_id(), userInfo->session_id()); } diff --git a/common/server_remoteuserinterface.h b/common/server_remoteuserinterface.h index d85b54a3..311f0516 100644 --- a/common/server_remoteuserinterface.h +++ b/common/server_remoteuserinterface.h @@ -5,14 +5,14 @@ class Server_RemoteUserInterface : public Server_AbstractUserInterface { public: - Server_RemoteUserInterface(Server *_server, const ServerInfo_User_Container &_userInfoContainer) : Server_AbstractUserInterface(_server, _userInfoContainer) { } - - int getLastCommandTime() const { return 0; } - - void sendProtocolItem(const Response &item); - void sendProtocolItem(const SessionEvent &item); - void sendProtocolItem(const GameEventContainer &item); - void sendProtocolItem(const RoomEvent &item); + Server_RemoteUserInterface(Server *_server, const ServerInfo_User_Container &_userInfoContainer) : Server_AbstractUserInterface(_server, _userInfoContainer) { } + + int getLastCommandTime() const { return 0; } + + void sendProtocolItem(const Response &item); + void sendProtocolItem(const SessionEvent &item); + void sendProtocolItem(const GameEventContainer &item); + void sendProtocolItem(const RoomEvent &item); }; #endif diff --git a/common/server_response_containers.cpp b/common/server_response_containers.cpp index bc36222e..0c95e537 100644 --- a/common/server_response_containers.cpp +++ b/common/server_response_containers.cpp @@ -3,64 +3,64 @@ #include "server_game.h" GameEventStorageItem::GameEventStorageItem(const ::google::protobuf::Message &_event, int _playerId, EventRecipients _recipients) - : event(new GameEvent), recipients(_recipients) + : event(new GameEvent), recipients(_recipients) { - event->GetReflection()->MutableMessage(event, _event.GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(_event); - event->set_player_id(_playerId); + event->GetReflection()->MutableMessage(event, _event.GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(_event); + event->set_player_id(_playerId); } GameEventStorageItem::~GameEventStorageItem() { - delete event; + delete event; } GameEventStorage::GameEventStorage() - : gameEventContext(0) + : gameEventContext(0) { } GameEventStorage::~GameEventStorage() { - delete gameEventContext; - for (int i = 0; i < gameEventList.size(); ++i) - delete gameEventList[i]; + delete gameEventContext; + for (int i = 0; i < gameEventList.size(); ++i) + delete gameEventList[i]; } void GameEventStorage::setGameEventContext(const ::google::protobuf::Message &_gameEventContext) { - delete gameEventContext; - gameEventContext = new GameEventContext; - gameEventContext->GetReflection()->MutableMessage(gameEventContext, _gameEventContext.GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(_gameEventContext); + delete gameEventContext; + gameEventContext = new GameEventContext; + gameEventContext->GetReflection()->MutableMessage(gameEventContext, _gameEventContext.GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(_gameEventContext); } void GameEventStorage::enqueueGameEvent(const ::google::protobuf::Message &event, int playerId, GameEventStorageItem::EventRecipients recipients, int _privatePlayerId) { - gameEventList.append(new GameEventStorageItem(event, playerId, recipients)); - if (_privatePlayerId != -1) - privatePlayerId = _privatePlayerId; + gameEventList.append(new GameEventStorageItem(event, playerId, recipients)); + if (_privatePlayerId != -1) + privatePlayerId = _privatePlayerId; } void GameEventStorage::sendToGame(Server_Game *game) { - if (gameEventList.isEmpty()) - return; - - GameEventContainer *contPrivate = new GameEventContainer; - GameEventContainer *contOthers = new GameEventContainer; - for (int i = 0; i < gameEventList.size(); ++i) { - const GameEvent &event = gameEventList[i]->getGameEvent(); - const GameEventStorageItem::EventRecipients recipients = gameEventList[i]->getRecipients(); - if (recipients.testFlag(GameEventStorageItem::SendToPrivate)) - contPrivate->add_event_list()->CopyFrom(event); - if (recipients.testFlag(GameEventStorageItem::SendToOthers)) - contOthers->add_event_list()->CopyFrom(event); - } - if (gameEventContext) { - contPrivate->mutable_context()->CopyFrom(*gameEventContext); - contOthers->mutable_context()->CopyFrom(*gameEventContext); - } - game->sendGameEventContainer(contPrivate, GameEventStorageItem::SendToPrivate, privatePlayerId); - game->sendGameEventContainer(contOthers, GameEventStorageItem::SendToOthers, privatePlayerId); + if (gameEventList.isEmpty()) + return; + + GameEventContainer *contPrivate = new GameEventContainer; + GameEventContainer *contOthers = new GameEventContainer; + for (int i = 0; i < gameEventList.size(); ++i) { + const GameEvent &event = gameEventList[i]->getGameEvent(); + const GameEventStorageItem::EventRecipients recipients = gameEventList[i]->getRecipients(); + if (recipients.testFlag(GameEventStorageItem::SendToPrivate)) + contPrivate->add_event_list()->CopyFrom(event); + if (recipients.testFlag(GameEventStorageItem::SendToOthers)) + contOthers->add_event_list()->CopyFrom(event); + } + if (gameEventContext) { + contPrivate->mutable_context()->CopyFrom(*gameEventContext); + contOthers->mutable_context()->CopyFrom(*gameEventContext); + } + game->sendGameEventContainer(contPrivate, GameEventStorageItem::SendToPrivate, privatePlayerId); + game->sendGameEventContainer(contOthers, GameEventStorageItem::SendToOthers, privatePlayerId); } ResponseContainer::ResponseContainer(int _cmdId) @@ -70,9 +70,9 @@ ResponseContainer::ResponseContainer(int _cmdId) ResponseContainer::~ResponseContainer() { - delete responseExtension; - for (int i = 0; i < preResponseQueue.size(); ++i) - delete preResponseQueue[i].second; - for (int i = 0; i < postResponseQueue.size(); ++i) - delete postResponseQueue[i].second; + delete responseExtension; + for (int i = 0; i < preResponseQueue.size(); ++i) + delete preResponseQueue[i].second; + for (int i = 0; i < postResponseQueue.size(); ++i) + delete postResponseQueue[i].second; } diff --git a/common/server_response_containers.h b/common/server_response_containers.h index 9220cdac..c6c9da74 100644 --- a/common/server_response_containers.h +++ b/common/server_response_containers.h @@ -9,54 +9,54 @@ class Server_Game; class GameEventStorageItem { public: - enum EventRecipient { SendToPrivate = 0x01, SendToOthers = 0x02}; - Q_DECLARE_FLAGS(EventRecipients, EventRecipient) + enum EventRecipient { SendToPrivate = 0x01, SendToOthers = 0x02}; + Q_DECLARE_FLAGS(EventRecipients, EventRecipient) private: - GameEvent *event; - EventRecipients recipients; + GameEvent *event; + EventRecipients recipients; public: - GameEventStorageItem(const ::google::protobuf::Message &_event, int _playerId, EventRecipients _recipients); - ~GameEventStorageItem(); - - const GameEvent &getGameEvent() const { return *event; } - EventRecipients getRecipients() const { return recipients; } + GameEventStorageItem(const ::google::protobuf::Message &_event, int _playerId, EventRecipients _recipients); + ~GameEventStorageItem(); + + const GameEvent &getGameEvent() const { return *event; } + EventRecipients getRecipients() const { return recipients; } }; Q_DECLARE_OPERATORS_FOR_FLAGS(GameEventStorageItem::EventRecipients) class GameEventStorage { private: - ::google::protobuf::Message *gameEventContext; - QList gameEventList; - int privatePlayerId; + ::google::protobuf::Message *gameEventContext; + QList gameEventList; + int privatePlayerId; public: - GameEventStorage(); - ~GameEventStorage(); - - void setGameEventContext(const ::google::protobuf::Message &_gameEventContext); - ::google::protobuf::Message *getGameEventContext() const { return gameEventContext; } - const QList &getGameEventList() const { return gameEventList; } - int getPrivatePlayerId() const { return privatePlayerId; } - - void enqueueGameEvent(const ::google::protobuf::Message &event, int playerId, GameEventStorageItem::EventRecipients recipients = GameEventStorageItem::SendToPrivate | GameEventStorageItem::SendToOthers, int _privatePlayerId = -1); - void sendToGame(Server_Game *game); + GameEventStorage(); + ~GameEventStorage(); + + void setGameEventContext(const ::google::protobuf::Message &_gameEventContext); + ::google::protobuf::Message *getGameEventContext() const { return gameEventContext; } + const QList &getGameEventList() const { return gameEventList; } + int getPrivatePlayerId() const { return privatePlayerId; } + + void enqueueGameEvent(const ::google::protobuf::Message &event, int playerId, GameEventStorageItem::EventRecipients recipients = GameEventStorageItem::SendToPrivate | GameEventStorageItem::SendToOthers, int _privatePlayerId = -1); + void sendToGame(Server_Game *game); }; class ResponseContainer { private: - int cmdId; - ::google::protobuf::Message *responseExtension; - QList > preResponseQueue, postResponseQueue; + int cmdId; + ::google::protobuf::Message *responseExtension; + QList > preResponseQueue, postResponseQueue; public: - ResponseContainer(int _cmdId); - ~ResponseContainer(); - - int getCmdId() const { return cmdId; } - void setResponseExtension(::google::protobuf::Message *_responseExtension) { responseExtension = _responseExtension; } - ::google::protobuf::Message *getResponseExtension() const { return responseExtension; } - void enqueuePreResponseItem(ServerMessage::MessageType type, ::google::protobuf::Message *item) { preResponseQueue.append(qMakePair(type, item)); } - void enqueuePostResponseItem(ServerMessage::MessageType type, ::google::protobuf::Message *item) { postResponseQueue.append(qMakePair(type, item)); } - const QList > &getPreResponseQueue() const { return preResponseQueue; } - const QList > &getPostResponseQueue() const { return postResponseQueue; } + ResponseContainer(int _cmdId); + ~ResponseContainer(); + + int getCmdId() const { return cmdId; } + void setResponseExtension(::google::protobuf::Message *_responseExtension) { responseExtension = _responseExtension; } + ::google::protobuf::Message *getResponseExtension() const { return responseExtension; } + void enqueuePreResponseItem(ServerMessage::MessageType type, ::google::protobuf::Message *item) { preResponseQueue.append(qMakePair(type, item)); } + void enqueuePostResponseItem(ServerMessage::MessageType type, ::google::protobuf::Message *item) { postResponseQueue.append(qMakePair(type, item)); } + const QList > &getPreResponseQueue() const { return preResponseQueue; } + const QList > &getPostResponseQueue() const { return postResponseQueue; } }; #endif diff --git a/common/server_room.cpp b/common/server_room.cpp index 4369e129..985fb543 100644 --- a/common/server_room.cpp +++ b/common/server_room.cpp @@ -13,326 +13,326 @@ #include 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), gamesLock(QReadWriteLock::Recursive) + : QObject(parent), id(_id), name(_name), description(_description), autoJoin(_autoJoin), joinMessage(_joinMessage), gameTypes(_gameTypes), gamesLock(QReadWriteLock::Recursive) { - connect(this, SIGNAL(gameListChanged(ServerInfo_Game)), this, SLOT(broadcastGameListUpdate(ServerInfo_Game)), Qt::QueuedConnection); + connect(this, SIGNAL(gameListChanged(ServerInfo_Game)), this, SLOT(broadcastGameListUpdate(ServerInfo_Game)), Qt::QueuedConnection); } Server_Room::~Server_Room() { - qDebug("Server_Room destructor"); - - gamesLock.lockForWrite(); - const QList gameList = games.values(); - for (int i = 0; i < gameList.size(); ++i) - delete gameList[i]; - games.clear(); - gamesLock.unlock(); - - usersLock.lockForWrite(); - users.clear(); - usersLock.unlock(); + qDebug("Server_Room destructor"); + + gamesLock.lockForWrite(); + const QList gameList = games.values(); + for (int i = 0; i < gameList.size(); ++i) + delete gameList[i]; + games.clear(); + gamesLock.unlock(); + + usersLock.lockForWrite(); + users.clear(); + usersLock.unlock(); } Server *Server_Room::getServer() const { - return static_cast(parent()); + return static_cast(parent()); } const ServerInfo_Room &Server_Room::getInfo(ServerInfo_Room &result, bool complete, bool showGameTypes, bool includeExternalData) const { - result.set_room_id(id); - - result.set_name(name.toStdString()); - result.set_description(description.toStdString()); - result.set_auto_join(autoJoin); - - gamesLock.lockForRead(); - result.set_game_count(games.size() + externalGames.size()); - if (complete) { - QMapIterator gameIterator(games); - while (gameIterator.hasNext()) - gameIterator.next().value()->getInfo(*result.add_game_list()); - if (includeExternalData) { - QMapIterator externalGameIterator(externalGames); - while (externalGameIterator.hasNext()) - result.add_game_list()->CopyFrom(externalGameIterator.next().value()); - } - } - gamesLock.unlock(); - - usersLock.lockForRead(); - result.set_player_count(users.size() + externalUsers.size()); - if (complete) { - QMapIterator userIterator(users); - while (userIterator.hasNext()) - result.add_user_list()->CopyFrom(userIterator.next().value()->copyUserInfo(false)); - if (includeExternalData) { - QMapIterator externalUserIterator(externalUsers); - while (externalUserIterator.hasNext()) - result.add_user_list()->CopyFrom(externalUserIterator.next().value().copyUserInfo(false)); - } - } - usersLock.unlock(); - - if (complete || showGameTypes) - for (int i = 0; i < gameTypes.size(); ++i) { - ServerInfo_GameType *gameTypeInfo = result.add_gametype_list(); - gameTypeInfo->set_game_type_id(i); - gameTypeInfo->set_description(gameTypes[i].toStdString()); - } - - return result; + result.set_room_id(id); + + result.set_name(name.toStdString()); + result.set_description(description.toStdString()); + result.set_auto_join(autoJoin); + + gamesLock.lockForRead(); + result.set_game_count(games.size() + externalGames.size()); + if (complete) { + QMapIterator gameIterator(games); + while (gameIterator.hasNext()) + gameIterator.next().value()->getInfo(*result.add_game_list()); + if (includeExternalData) { + QMapIterator externalGameIterator(externalGames); + while (externalGameIterator.hasNext()) + result.add_game_list()->CopyFrom(externalGameIterator.next().value()); + } + } + gamesLock.unlock(); + + usersLock.lockForRead(); + result.set_player_count(users.size() + externalUsers.size()); + if (complete) { + QMapIterator userIterator(users); + while (userIterator.hasNext()) + result.add_user_list()->CopyFrom(userIterator.next().value()->copyUserInfo(false)); + if (includeExternalData) { + QMapIterator externalUserIterator(externalUsers); + while (externalUserIterator.hasNext()) + result.add_user_list()->CopyFrom(externalUserIterator.next().value().copyUserInfo(false)); + } + } + usersLock.unlock(); + + if (complete || showGameTypes) + for (int i = 0; i < gameTypes.size(); ++i) { + ServerInfo_GameType *gameTypeInfo = result.add_gametype_list(); + gameTypeInfo->set_game_type_id(i); + gameTypeInfo->set_description(gameTypes[i].toStdString()); + } + + return result; } RoomEvent *Server_Room::prepareRoomEvent(const ::google::protobuf::Message &roomEvent) { - RoomEvent *event = new RoomEvent; - event->set_room_id(id); - event->GetReflection()->MutableMessage(event, roomEvent.GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(roomEvent); - return event; + RoomEvent *event = new RoomEvent; + event->set_room_id(id); + event->GetReflection()->MutableMessage(event, roomEvent.GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(roomEvent); + return event; } void Server_Room::addClient(Server_ProtocolHandler *client) { - Event_JoinRoom event; - event.mutable_user_info()->CopyFrom(client->copyUserInfo(false)); - sendRoomEvent(prepareRoomEvent(event)); - - ServerInfo_Room roomInfo; - roomInfo.set_room_id(id); - - usersLock.lockForWrite(); - users.insert(QString::fromStdString(client->getUserInfo()->name()), client); - roomInfo.set_player_count(users.size() + externalUsers.size()); - usersLock.unlock(); - - // XXX This can be removed during the next client update. - gamesLock.lockForRead(); - roomInfo.set_game_count(games.size() + externalGames.size()); - gamesLock.unlock(); - // ----------- - - emit roomInfoChanged(roomInfo); + Event_JoinRoom event; + event.mutable_user_info()->CopyFrom(client->copyUserInfo(false)); + sendRoomEvent(prepareRoomEvent(event)); + + ServerInfo_Room roomInfo; + roomInfo.set_room_id(id); + + usersLock.lockForWrite(); + users.insert(QString::fromStdString(client->getUserInfo()->name()), client); + roomInfo.set_player_count(users.size() + externalUsers.size()); + usersLock.unlock(); + + // XXX This can be removed during the next client update. + gamesLock.lockForRead(); + roomInfo.set_game_count(games.size() + externalGames.size()); + gamesLock.unlock(); + // ----------- + + emit roomInfoChanged(roomInfo); } void Server_Room::removeClient(Server_ProtocolHandler *client) { - usersLock.lockForWrite(); - users.remove(QString::fromStdString(client->getUserInfo()->name())); - - ServerInfo_Room roomInfo; - roomInfo.set_room_id(id); - roomInfo.set_player_count(users.size() + externalUsers.size()); - usersLock.unlock(); - - Event_LeaveRoom event; - event.set_name(client->getUserInfo()->name()); - sendRoomEvent(prepareRoomEvent(event)); - - // XXX This can be removed during the next client update. - gamesLock.lockForRead(); - roomInfo.set_game_count(games.size() + externalGames.size()); - gamesLock.unlock(); - // ----------- - - emit roomInfoChanged(roomInfo); + usersLock.lockForWrite(); + users.remove(QString::fromStdString(client->getUserInfo()->name())); + + ServerInfo_Room roomInfo; + roomInfo.set_room_id(id); + roomInfo.set_player_count(users.size() + externalUsers.size()); + usersLock.unlock(); + + Event_LeaveRoom event; + event.set_name(client->getUserInfo()->name()); + sendRoomEvent(prepareRoomEvent(event)); + + // XXX This can be removed during the next client update. + gamesLock.lockForRead(); + roomInfo.set_game_count(games.size() + externalGames.size()); + gamesLock.unlock(); + // ----------- + + emit roomInfoChanged(roomInfo); } void Server_Room::addExternalUser(const ServerInfo_User &userInfo) { - // This function is always called from the Server thread with server->roomsMutex locked. - ServerInfo_User_Container userInfoContainer(userInfo); - Event_JoinRoom event; - event.mutable_user_info()->CopyFrom(userInfoContainer.copyUserInfo(false)); - sendRoomEvent(prepareRoomEvent(event), false); - - ServerInfo_Room roomInfo; - roomInfo.set_room_id(id); + // This function is always called from the Server thread with server->roomsMutex locked. + ServerInfo_User_Container userInfoContainer(userInfo); + Event_JoinRoom event; + event.mutable_user_info()->CopyFrom(userInfoContainer.copyUserInfo(false)); + sendRoomEvent(prepareRoomEvent(event), false); + + ServerInfo_Room roomInfo; + roomInfo.set_room_id(id); - usersLock.lockForWrite(); - externalUsers.insert(QString::fromStdString(userInfo.name()), userInfoContainer); - roomInfo.set_player_count(users.size() + externalUsers.size()); - usersLock.unlock(); - - emit roomInfoChanged(roomInfo); + usersLock.lockForWrite(); + externalUsers.insert(QString::fromStdString(userInfo.name()), userInfoContainer); + roomInfo.set_player_count(users.size() + externalUsers.size()); + usersLock.unlock(); + + emit roomInfoChanged(roomInfo); } void Server_Room::removeExternalUser(const QString &name) { - // This function is always called from the Server thread with server->roomsMutex locked. - ServerInfo_Room roomInfo; - roomInfo.set_room_id(id); - - usersLock.lockForWrite(); - if (externalUsers.contains(name)) - externalUsers.remove(name); - roomInfo.set_player_count(users.size() + externalUsers.size()); - usersLock.unlock(); - - Event_LeaveRoom event; - event.set_name(name.toStdString()); - sendRoomEvent(prepareRoomEvent(event), false); - - emit roomInfoChanged(roomInfo); + // This function is always called from the Server thread with server->roomsMutex locked. + ServerInfo_Room roomInfo; + roomInfo.set_room_id(id); + + usersLock.lockForWrite(); + if (externalUsers.contains(name)) + externalUsers.remove(name); + roomInfo.set_player_count(users.size() + externalUsers.size()); + usersLock.unlock(); + + Event_LeaveRoom event; + event.set_name(name.toStdString()); + sendRoomEvent(prepareRoomEvent(event), false); + + emit roomInfoChanged(roomInfo); } void Server_Room::updateExternalGameList(const ServerInfo_Game &gameInfo) { - // This function is always called from the Server thread with server->roomsMutex locked. - ServerInfo_Room roomInfo; - roomInfo.set_room_id(id); - - gamesLock.lockForWrite(); - if (!gameInfo.has_player_count() && externalGames.contains(gameInfo.game_id())) - externalGames.remove(gameInfo.game_id()); - else - externalGames.insert(gameInfo.game_id(), gameInfo); - roomInfo.set_game_count(games.size() + externalGames.size()); - gamesLock.unlock(); - - broadcastGameListUpdate(gameInfo, false); - emit roomInfoChanged(roomInfo); + // This function is always called from the Server thread with server->roomsMutex locked. + ServerInfo_Room roomInfo; + roomInfo.set_room_id(id); + + gamesLock.lockForWrite(); + if (!gameInfo.has_player_count() && externalGames.contains(gameInfo.game_id())) + externalGames.remove(gameInfo.game_id()); + else + externalGames.insert(gameInfo.game_id(), gameInfo); + roomInfo.set_game_count(games.size() + externalGames.size()); + gamesLock.unlock(); + + broadcastGameListUpdate(gameInfo, false); + emit roomInfoChanged(roomInfo); } Response::ResponseCode Server_Room::processJoinGameCommand(const Command_JoinGame &cmd, ResponseContainer &rc, Server_AbstractUserInterface *userInterface) { - // This function is called from the Server thread and from the S_PH thread. - // server->roomsMutex is always locked. - - QReadLocker roomGamesLocker(&gamesLock); - Server_Game *g = games.value(cmd.game_id()); - if (!g) { - if (externalGames.contains(cmd.game_id())) { - CommandContainer cont; - cont.set_cmd_id(rc.getCmdId()); - RoomCommand *roomCommand = cont.add_room_command(); - roomCommand->GetReflection()->MutableMessage(roomCommand, cmd.GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(cmd); - getServer()->sendIsl_RoomCommand(cont, externalGames.value(cmd.game_id()).server_id(), userInterface->getUserInfo()->session_id(), id); - - return Response::RespNothing; - } else - return Response::RespNameNotFound; - } - - QMutexLocker gameLocker(&g->gameMutex); - - Response::ResponseCode result = g->checkJoin(userInterface->getUserInfo(), QString::fromStdString(cmd.password()), cmd.spectator(), cmd.override_restrictions()); - if (result == Response::RespOk) - g->addPlayer(userInterface, rc, cmd.spectator()); - - return result; + // This function is called from the Server thread and from the S_PH thread. + // server->roomsMutex is always locked. + + QReadLocker roomGamesLocker(&gamesLock); + Server_Game *g = games.value(cmd.game_id()); + if (!g) { + if (externalGames.contains(cmd.game_id())) { + CommandContainer cont; + cont.set_cmd_id(rc.getCmdId()); + RoomCommand *roomCommand = cont.add_room_command(); + roomCommand->GetReflection()->MutableMessage(roomCommand, cmd.GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(cmd); + getServer()->sendIsl_RoomCommand(cont, externalGames.value(cmd.game_id()).server_id(), userInterface->getUserInfo()->session_id(), id); + + return Response::RespNothing; + } else + return Response::RespNameNotFound; + } + + QMutexLocker gameLocker(&g->gameMutex); + + Response::ResponseCode result = g->checkJoin(userInterface->getUserInfo(), QString::fromStdString(cmd.password()), cmd.spectator(), cmd.override_restrictions()); + if (result == Response::RespOk) + g->addPlayer(userInterface, rc, cmd.spectator()); + + return result; } void Server_Room::say(const QString &userName, const QString &s, bool sendToIsl) { - Event_RoomSay event; - event.set_name(userName.toStdString()); - event.set_message(s.toStdString()); - sendRoomEvent(prepareRoomEvent(event), sendToIsl); + Event_RoomSay event; + event.set_name(userName.toStdString()); + event.set_message(s.toStdString()); + sendRoomEvent(prepareRoomEvent(event), sendToIsl); } void Server_Room::sendRoomEvent(RoomEvent *event, bool sendToIsl) { - usersLock.lockForRead(); - { - QMapIterator userIterator(users); - while (userIterator.hasNext()) - userIterator.next().value()->sendProtocolItem(*event); - } - usersLock.unlock(); - - if (sendToIsl) - static_cast(parent())->sendIsl_RoomEvent(*event); - - delete event; + usersLock.lockForRead(); + { + QMapIterator userIterator(users); + while (userIterator.hasNext()) + userIterator.next().value()->sendProtocolItem(*event); + } + usersLock.unlock(); + + if (sendToIsl) + static_cast(parent())->sendIsl_RoomEvent(*event); + + delete event; } void Server_Room::broadcastGameListUpdate(const ServerInfo_Game &gameInfo, bool sendToIsl) { - Event_ListGames event; - event.add_game_list()->CopyFrom(gameInfo); - sendRoomEvent(prepareRoomEvent(event), sendToIsl); + Event_ListGames event; + event.add_game_list()->CopyFrom(gameInfo); + sendRoomEvent(prepareRoomEvent(event), sendToIsl); } void Server_Room::addGame(Server_Game *game) { - ServerInfo_Room roomInfo; - roomInfo.set_room_id(id); - - gamesLock.lockForWrite(); - connect(game, SIGNAL(gameInfoChanged(ServerInfo_Game)), this, SLOT(broadcastGameListUpdate(ServerInfo_Game))); - - game->gameMutex.lock(); - games.insert(game->getGameId(), game); - ServerInfo_Game gameInfo; - game->getInfo(gameInfo); - roomInfo.set_game_count(games.size() + externalGames.size()); - game->gameMutex.unlock(); - gamesLock.unlock(); - - // XXX This can be removed during the next client update. - usersLock.lockForRead(); - roomInfo.set_player_count(users.size() + externalUsers.size()); - usersLock.unlock(); - // ----------- + ServerInfo_Room roomInfo; + roomInfo.set_room_id(id); + + gamesLock.lockForWrite(); + connect(game, SIGNAL(gameInfoChanged(ServerInfo_Game)), this, SLOT(broadcastGameListUpdate(ServerInfo_Game))); + + game->gameMutex.lock(); + games.insert(game->getGameId(), game); + ServerInfo_Game gameInfo; + game->getInfo(gameInfo); + roomInfo.set_game_count(games.size() + externalGames.size()); + game->gameMutex.unlock(); + gamesLock.unlock(); + + // XXX This can be removed during the next client update. + usersLock.lockForRead(); + roomInfo.set_player_count(users.size() + externalUsers.size()); + usersLock.unlock(); + // ----------- - emit gameListChanged(gameInfo); - emit roomInfoChanged(roomInfo); + emit gameListChanged(gameInfo); + emit roomInfoChanged(roomInfo); } void Server_Room::removeGame(Server_Game *game) { - // No need to lock gamesLock or gameMutex. This method is only - // called from ~Server_Game, which locks both mutexes anyway beforehand. - - disconnect(game, 0, this, 0); - - ServerInfo_Game gameInfo; - game->getInfo(gameInfo); - emit gameListChanged(gameInfo); - - games.remove(game->getGameId()); - - ServerInfo_Room roomInfo; - roomInfo.set_room_id(id); - roomInfo.set_game_count(games.size() + externalGames.size()); - - // XXX This can be removed during the next client update. - usersLock.lockForRead(); - roomInfo.set_player_count(users.size() + externalUsers.size()); - usersLock.unlock(); - // ----------- - - emit roomInfoChanged(roomInfo); + // No need to lock gamesLock or gameMutex. This method is only + // called from ~Server_Game, which locks both mutexes anyway beforehand. + + disconnect(game, 0, this, 0); + + ServerInfo_Game gameInfo; + game->getInfo(gameInfo); + emit gameListChanged(gameInfo); + + games.remove(game->getGameId()); + + ServerInfo_Room roomInfo; + roomInfo.set_room_id(id); + roomInfo.set_game_count(games.size() + externalGames.size()); + + // XXX This can be removed during the next client update. + usersLock.lockForRead(); + roomInfo.set_player_count(users.size() + externalUsers.size()); + usersLock.unlock(); + // ----------- + + emit roomInfoChanged(roomInfo); } int Server_Room::getGamesCreatedByUser(const QString &userName) const { - QReadLocker locker(&gamesLock); - - QMapIterator gamesIterator(games); - int result = 0; - while (gamesIterator.hasNext()) - if (gamesIterator.next().value()->getCreatorInfo()->name() == userName.toStdString()) - ++result; - return result; + QReadLocker locker(&gamesLock); + + QMapIterator gamesIterator(games); + int result = 0; + while (gamesIterator.hasNext()) + if (gamesIterator.next().value()->getCreatorInfo()->name() == userName.toStdString()) + ++result; + return result; } QList Server_Room::getGamesOfUser(const QString &userName) const { - QReadLocker locker(&gamesLock); - - QList result; - QMapIterator gamesIterator(games); - while (gamesIterator.hasNext()) { - Server_Game *game = gamesIterator.next().value(); - if (game->containsUser(userName)) { - ServerInfo_Game gameInfo; - game->getInfo(gameInfo); - result.append(gameInfo); - } - } - return result; + QReadLocker locker(&gamesLock); + + QList result; + QMapIterator gamesIterator(games); + while (gamesIterator.hasNext()) { + Server_Game *game = gamesIterator.next().value(); + if (game->containsUser(userName)) { + ServerInfo_Game gameInfo; + game->getInfo(gameInfo); + result.append(gameInfo); + } + } + return result; } diff --git a/common/server_room.h b/common/server_room.h index 355d89d2..bf91510c 100644 --- a/common/server_room.h +++ b/common/server_room.h @@ -24,58 +24,58 @@ class ResponseContainer; class Server_AbstractUserInterface; class Server_Room : public QObject { - Q_OBJECT + Q_OBJECT signals: - void roomInfoChanged(const ServerInfo_Room &roomInfo); - void gameListChanged(const ServerInfo_Game &gameInfo); + void roomInfoChanged(const ServerInfo_Room &roomInfo); + void gameListChanged(const ServerInfo_Game &gameInfo); private: - int id; - QString name; - QString description; - bool autoJoin; - QString joinMessage; - QStringList gameTypes; - QMap games; - QMap externalGames; - QMap users; - QMap externalUsers; + int id; + QString name; + QString description; + bool autoJoin; + QString joinMessage; + QStringList gameTypes; + QMap games; + QMap externalGames; + QMap users; + QMap externalUsers; private slots: - void broadcastGameListUpdate(const ServerInfo_Game &gameInfo, bool sendToIsl = true); + void broadcastGameListUpdate(const ServerInfo_Game &gameInfo, bool sendToIsl = true); public: - mutable QReadWriteLock usersLock; - mutable QReadWriteLock gamesLock; - Server_Room(int _id, const QString &_name, const QString &_description, bool _autoJoin, const QString &_joinMessage, const QStringList &_gameTypes, Server *parent); - ~Server_Room(); - int getId() const { return id; } - QString getName() const { return name; } - QString getDescription() const { return description; } - bool getAutoJoin() const { return autoJoin; } - QString getJoinMessage() const { return joinMessage; } - const QStringList &getGameTypes() const { return gameTypes; } - const QMap &getGames() const { return games; } - const QMap &getExternalGames() const { return externalGames; } - Server *getServer() const; - const ServerInfo_Room &getInfo(ServerInfo_Room &result, bool complete, bool showGameTypes = false, bool includeExternalData = true) const; - int getGamesCreatedByUser(const QString &name) const; - QList getGamesOfUser(const QString &name) const; - - void addClient(Server_ProtocolHandler *client); - void removeClient(Server_ProtocolHandler *client); - - void addExternalUser(const ServerInfo_User &userInfo); - void removeExternalUser(const QString &name); - const QMap &getExternalUsers() const { return externalUsers; } - void updateExternalGameList(const ServerInfo_Game &gameInfo); - - Response::ResponseCode processJoinGameCommand(const Command_JoinGame &cmd, ResponseContainer &rc, Server_AbstractUserInterface *userInterface); - - void say(const QString &userName, const QString &s, bool sendToIsl = true); - - void addGame(Server_Game *game); - void removeGame(Server_Game *game); - - void sendRoomEvent(RoomEvent *event, bool sendToIsl = true); - RoomEvent *prepareRoomEvent(const ::google::protobuf::Message &roomEvent); + mutable QReadWriteLock usersLock; + mutable QReadWriteLock gamesLock; + Server_Room(int _id, const QString &_name, const QString &_description, bool _autoJoin, const QString &_joinMessage, const QStringList &_gameTypes, Server *parent); + ~Server_Room(); + int getId() const { return id; } + QString getName() const { return name; } + QString getDescription() const { return description; } + bool getAutoJoin() const { return autoJoin; } + QString getJoinMessage() const { return joinMessage; } + const QStringList &getGameTypes() const { return gameTypes; } + const QMap &getGames() const { return games; } + const QMap &getExternalGames() const { return externalGames; } + Server *getServer() const; + const ServerInfo_Room &getInfo(ServerInfo_Room &result, bool complete, bool showGameTypes = false, bool includeExternalData = true) const; + int getGamesCreatedByUser(const QString &name) const; + QList getGamesOfUser(const QString &name) const; + + void addClient(Server_ProtocolHandler *client); + void removeClient(Server_ProtocolHandler *client); + + void addExternalUser(const ServerInfo_User &userInfo); + void removeExternalUser(const QString &name); + const QMap &getExternalUsers() const { return externalUsers; } + void updateExternalGameList(const ServerInfo_Game &gameInfo); + + Response::ResponseCode processJoinGameCommand(const Command_JoinGame &cmd, ResponseContainer &rc, Server_AbstractUserInterface *userInterface); + + void say(const QString &userName, const QString &s, bool sendToIsl = true); + + void addGame(Server_Game *game); + void removeGame(Server_Game *game); + + void sendRoomEvent(RoomEvent *event, bool sendToIsl = true); + RoomEvent *prepareRoomEvent(const ::google::protobuf::Message &roomEvent); }; #endif diff --git a/common/serverinfo_user_container.cpp b/common/serverinfo_user_container.cpp index deead4e0..14435f75 100644 --- a/common/serverinfo_user_container.cpp +++ b/common/serverinfo_user_container.cpp @@ -7,46 +7,46 @@ ServerInfo_User_Container::ServerInfo_User_Container(ServerInfo_User *_userInfo) } ServerInfo_User_Container::ServerInfo_User_Container(const ServerInfo_User &_userInfo) - : userInfo(new ServerInfo_User(_userInfo)) + : userInfo(new ServerInfo_User(_userInfo)) { } ServerInfo_User_Container::ServerInfo_User_Container(const ServerInfo_User_Container &other) { - if (other.userInfo) - userInfo = new ServerInfo_User(*other.userInfo); - else - userInfo = 0; + if (other.userInfo) + userInfo = new ServerInfo_User(*other.userInfo); + else + userInfo = 0; } ServerInfo_User_Container::~ServerInfo_User_Container() { - delete userInfo; + delete userInfo; } void ServerInfo_User_Container::setUserInfo(const ServerInfo_User &_userInfo) { - userInfo = new ServerInfo_User(_userInfo); + userInfo = new ServerInfo_User(_userInfo); } ServerInfo_User &ServerInfo_User_Container::copyUserInfo(ServerInfo_User &result, bool complete, bool internalInfo, bool sessionInfo) const { - if (userInfo) { - result.CopyFrom(*userInfo); - if (!sessionInfo) { - result.clear_session_id(); - result.clear_address(); - } - if (!internalInfo) - result.clear_id(); - if (!complete) - result.clear_avatar_bmp(); - } - return result; + if (userInfo) { + result.CopyFrom(*userInfo); + if (!sessionInfo) { + result.clear_session_id(); + result.clear_address(); + } + if (!internalInfo) + result.clear_id(); + if (!complete) + result.clear_avatar_bmp(); + } + return result; } ServerInfo_User ServerInfo_User_Container::copyUserInfo(bool complete, bool internalInfo, bool sessionInfo) const { - ServerInfo_User result; - return copyUserInfo(result, complete, internalInfo, sessionInfo); + ServerInfo_User result; + return copyUserInfo(result, complete, internalInfo, sessionInfo); } diff --git a/common/serverinfo_user_container.h b/common/serverinfo_user_container.h index 6cf87ab1..d7fb76f8 100644 --- a/common/serverinfo_user_container.h +++ b/common/serverinfo_user_container.h @@ -5,16 +5,16 @@ class ServerInfo_User; class ServerInfo_User_Container { protected: - ServerInfo_User *userInfo; + ServerInfo_User *userInfo; public: - ServerInfo_User_Container(ServerInfo_User *_userInfo = 0); - ServerInfo_User_Container(const ServerInfo_User &_userInfo); - ServerInfo_User_Container(const ServerInfo_User_Container &other); - virtual ~ServerInfo_User_Container(); - ServerInfo_User *getUserInfo() const { return userInfo; } - void setUserInfo(const ServerInfo_User &_userInfo); - ServerInfo_User ©UserInfo(ServerInfo_User &result, bool complete, bool internalInfo = false, bool sessionInfo = false) const; - ServerInfo_User copyUserInfo(bool complete, bool internalInfo = false, bool sessionInfo = false) const; + ServerInfo_User_Container(ServerInfo_User *_userInfo = 0); + ServerInfo_User_Container(const ServerInfo_User &_userInfo); + ServerInfo_User_Container(const ServerInfo_User_Container &other); + virtual ~ServerInfo_User_Container(); + ServerInfo_User *getUserInfo() const { return userInfo; } + void setUserInfo(const ServerInfo_User &_userInfo); + ServerInfo_User ©UserInfo(ServerInfo_User &result, bool complete, bool internalInfo = false, bool sessionInfo = false) const; + ServerInfo_User copyUserInfo(bool complete, bool internalInfo = false, bool sessionInfo = false) const; }; #endif From 04e80304ef1f4754e760e39b2dcf06d5f6ffc8b1 Mon Sep 17 00:00:00 2001 From: arxanas Date: Tue, 8 Jul 2014 22:56:18 -0400 Subject: [PATCH 45/51] Fix #184: Deck loader reads 4x cardname correctly. --- common/decklist.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/common/decklist.cpp b/common/decklist.cpp index 8e877ba9..52ef6415 100644 --- a/common/decklist.cpp +++ b/common/decklist.cpp @@ -547,14 +547,21 @@ bool DeckList::loadFromStream_Plain(QTextStream &in) line.remove(rx); line = line.simplified(); - int i = line.indexOf(' '); + int cardNameStart = i + 1; + + // If the count ends with an 'x', ignore it. For example, + // "4x Storm Crow" will count 4 correctly. + if (i > 0 && line[i - 1] == 'x') { + i--; + } + bool ok; int number = line.left(i).toInt(&ok); if (!ok) continue; - QString cardName = line.mid(i + 1); + QString cardName = line.mid(cardNameStart); // Common differences between cockatrice's card names // and what's commonly used in decklists rx.setPattern("’"); From a6f299b2475748d9f46a9752a10eba433b9a4950 Mon Sep 17 00:00:00 2001 From: Fabio Bas Date: Wed, 9 Jul 2014 17:40:50 +0200 Subject: [PATCH 46/51] fix #203 --- cockatrice/src/carditem.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cockatrice/src/carditem.cpp b/cockatrice/src/carditem.cpp index a6b582ad..e7ce6482 100644 --- a/cockatrice/src/carditem.cpp +++ b/cockatrice/src/carditem.cpp @@ -233,7 +233,8 @@ CardDragItem *CardItem::createDragItem(int _id, const QPointF &_pos, const QPoin void CardItem::deleteDragItem() { - dragItem->deleteLater(); + if(dragItem) + dragItem->deleteLater(); dragItem = NULL; } From 86fa8f304da8ef07a128a8549b22e6aea8fa2aa3 Mon Sep 17 00:00:00 2001 From: Gavin Bisesi Date: Wed, 9 Jul 2014 19:06:31 -0400 Subject: [PATCH 47/51] Change client send-ping timer back to 1sec 9sec was causing too many timeout issues. Timeout from both client and server perspective needs to be revisited --- cockatrice/src/remoteclient.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cockatrice/src/remoteclient.cpp b/cockatrice/src/remoteclient.cpp index e0d3d860..4f8deaed 100644 --- a/cockatrice/src/remoteclient.cpp +++ b/cockatrice/src/remoteclient.cpp @@ -15,7 +15,7 @@ RemoteClient::RemoteClient(QObject *parent) : AbstractClient(parent), timeRunning(0), lastDataReceived(0), messageInProgress(false), handshakeStarted(false), messageLength(0) { timer = new QTimer(this); - timer->setInterval(9000); + timer->setInterval(1000); connect(timer, SIGNAL(timeout()), this, SLOT(ping())); socket = new QTcpSocket(this); From c07b53999ddf5563465bbe0aeb492a06bdd15b97 Mon Sep 17 00:00:00 2001 From: Fabio Bas Date: Sat, 12 Jul 2014 00:11:48 +0200 Subject: [PATCH 48/51] Fix: ensure git is always run from the project directory When trying to obtain the version hash --- cmake/getversion.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/cmake/getversion.cmake b/cmake/getversion.cmake index 9db61040..e434e992 100644 --- a/cmake/getversion.cmake +++ b/cmake/getversion.cmake @@ -2,6 +2,7 @@ find_package(Git) if(GIT_FOUND) execute_process( COMMAND ${GIT_EXECUTABLE} describe --long --always + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} RESULT_VARIABLE res_var OUTPUT_VARIABLE GIT_COM_ID ) From 23b0a6c0dfd6d4a2055f87ae2a4e7efbe1d18bed Mon Sep 17 00:00:00 2001 From: Fabio Bas Date: Sat, 12 Jul 2014 01:38:00 +0200 Subject: [PATCH 49/51] Windows + CPack: fix packaging MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Package the correct cpack’s temporary directory --- cmake/NSIS.definitions.nsh.in | 4 +--- cmake/NSIS.template.in | 6 ++++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/cmake/NSIS.definitions.nsh.in b/cmake/NSIS.definitions.nsh.in index 0d98b666..cc4b014c 100644 --- a/cmake/NSIS.definitions.nsh.in +++ b/cmake/NSIS.definitions.nsh.in @@ -1,3 +1 @@ -!define NSIS_PROJECT_NAME "@PROJECT_NAME@" -!define NSIS_SOURCE_PATH "@PROJECT_SOURCE_DIR@" -!define NSIS_BINARY_PATH "@PROJECT_BINARY_DIR@" \ No newline at end of file +!define NSIS_SOURCE_PATH "@PROJECT_SOURCE_DIR@" \ No newline at end of file diff --git a/cmake/NSIS.template.in b/cmake/NSIS.template.in index b2c60d11..c04169c8 100644 --- a/cmake/NSIS.template.in +++ b/cmake/NSIS.template.in @@ -2,10 +2,11 @@ !include "MUI2.nsh" !include "FileFunc.nsh" -Name "${NSIS_PROJECT_NAME}" +Name "@CPACK_PACKAGE_NAME@" OutFile "@CPACK_TOPLEVEL_DIRECTORY@/@CPACK_OUTPUT_FILE_NAME@" SetCompressor /SOLID lzma InstallDir "$PROGRAMFILES\Cockatrice" +!define INST_DIR "@CPACK_TEMPORARY_DIRECTORY@" !define MUI_ABORTWARNING !define MUI_WELCOMEFINISHPAGE_BITMAP "${NSIS_SOURCE_PATH}\cmake\leftimage.bmp" @@ -35,7 +36,8 @@ Section "Application" SecApplication SetShellVarContext all SetOutPath "$INSTDIR" - File /r "${NSIS_BINARY_PATH}\Release\*.*" + @CPACK_NSIS_EXTRA_PREINSTALL_COMMANDS@ + @CPACK_NSIS_FULL_INSTALL@ WriteUninstaller "$INSTDIR\uninstall.exe" ${GetSize} "$INSTDIR" "/S=0K" $0 $1 $2 From 1137179b8828adc6a8e4d5aa8b3293c45b5eaf64 Mon Sep 17 00:00:00 2001 From: Gavin Bisesi Date: Sun, 13 Jul 2014 09:08:32 -0400 Subject: [PATCH 50/51] Add WITH_QT4 note to README --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ca8796b4..61b44ed4 100644 --- a/README.md +++ b/README.md @@ -33,8 +33,9 @@ To compile: The following flags can be passed to `cmake`: -- `-DWITH_SERVER=1` build the server -- `-DWITHOUT_CLIENT=1` do not build the client +- `-DWITH_SERVER=1` Build the server +- `-DWITHOUT_CLIENT=1` Do not build the client +- `-DWITH_QT4=1` Force compilation to use Qt4 instead of Qt5. # Running From 4df46b13e6ea9ee13b7854eb1f0ab8f9d5fd8f8d Mon Sep 17 00:00:00 2001 From: Waleed Khan Date: Sat, 19 Jul 2014 18:27:44 -0400 Subject: [PATCH 51/51] Removed cmake from Travis's OS X dependencies. --- travis-dependencies.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/travis-dependencies.sh b/travis-dependencies.sh index 0c6c62e6..10af11cd 100755 --- a/travis-dependencies.sh +++ b/travis-dependencies.sh @@ -2,7 +2,7 @@ if [[ $TRAVIS_OS_NAME == "osx" ]] ; then brew update - brew install qt cmake protobuf libgcrypt + brew install qt protobuf libgcrypt else sudo apt-get update -qq sudo apt-get install -y qtmobility-dev libprotobuf-dev protobuf-compiler libqt4-dev