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/CMakeLists.txt b/CMakeLists.txt index 400eb161..825ed5cb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,13 +7,21 @@ cmake_minimum_required(VERSION 2.6) -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} ) +if(POLICY CMP0020) + cmake_policy(SET CMP0020 OLD) +endif() -# Defualt to "Release" build type +if(POLICY CMP0043) + cmake_policy(SET CMP0043 OLD) +endif() + +if(POLICY CMP0048) + cmake_policy(SET CMP0048 OLD) +endif() + +set(PROJECT_NAME "Cockatrice") + +# 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") @@ -24,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) @@ -71,8 +89,33 @@ 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 +# 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}") + + 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) + # 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!") + ENDIF() +ENDIF() set(CMAKE_AUTOMOC TRUE) @@ -83,8 +126,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}") @@ -96,7 +139,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 @@ -107,13 +150,13 @@ 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_NSIS_MODIFY_PATH ON) + set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}_win32_git-${PROJECT_VERSION}") + + # Configure file with custom definitions for NSIS. + configure_file( + ${CMAKE_MODULE_PATH}/NSIS.definitions.nsh.in + ${PROJECT_BINARY_DIR}/NSIS.definitions.nsh + ) endif() include(CPack) 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 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/cmake/NSIS.definitions.nsh.in b/cmake/NSIS.definitions.nsh.in new file mode 100644 index 00000000..cc4b014c --- /dev/null +++ b/cmake/NSIS.definitions.nsh.in @@ -0,0 +1 @@ +!define NSIS_SOURCE_PATH "@PROJECT_SOURCE_DIR@" \ No newline at end of file diff --git a/nsis/cockatrice.nsi b/cmake/NSIS.template.in similarity index 66% rename from nsis/cockatrice.nsi rename to cmake/NSIS.template.in index 27f55ce3..c04169c8 100644 --- a/nsis/cockatrice.nsi +++ b/cmake/NSIS.template.in @@ -1,30 +1,26 @@ +!include ..\..\..\NSIS.definitions.nsh !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" +Name "@CPACK_PACKAGE_NAME@" +OutFile "@CPACK_TOPLEVEL_DIRECTORY@/@CPACK_OUTPUT_FILE_NAME@" 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 INST_DIR "@CPACK_TEMPORARY_DIRECTORY@" !define MUI_ABORTWARNING -!define MUI_WELCOMEFINISHPAGE_BITMAP "leftimage.bmp" -!define MUI_UNWELCOMEFINISHPAGE_BITMAP "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 "headerimage.bmp" -!define MUI_HEADERIMAGE_UNBITMAP "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" !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 @@ -39,37 +35,9 @@ InstallDir "$PROGRAMFILES\Cockatrice" 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 + @CPACK_NSIS_EXTRA_PREINSTALL_COMMANDS@ + @CPACK_NSIS_FULL_INSTALL@ WriteUninstaller "$INSTDIR\uninstall.exe" ${GetSize} "$INSTDIR" "/S=0K" $0 $1 $2 @@ -107,12 +75,10 @@ SetShellVarContext all 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" + Delete "$INSTDIR\Qt*.dll" + Delete "$INSTDIR\icu*.dll" + Delete "$INSTDIR\qt.conf" + Delete "$INSTDIR\qdebug.txt" RMDir "$INSTDIR" RMDir "$SMPROGRAMS\Cockatrice" 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..e434e992 100644 --- a/common/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 ) @@ -15,15 +16,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 b4de656a..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) @@ -125,41 +125,119 @@ if(APPLE) set(cockatrice_SOURCES ${cockatrice_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/resources/appicon.icns) ENDIF(APPLE) -if (NOT QT_QTMULTIMEDIA_FOUND) - SET(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}) - 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() + + 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() + + # 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) + 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 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 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 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(MSVC) - set_target_properties(cockatrice PROPERTIES LINK_FLAGS "/SUBSYSTEM:WINDOWS") -endif(MSVC) +if(Qt4_FOUND) + if(MSVC) + set(QT_USE_QTMAIN true) + endif() + TARGET_LINK_LIBRARIES(cockatrice cockatrice_common ${COCKATRICE_LIBS}) +endif() +if(Qt5Widgets_FOUND) + 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(UNIX) if(APPLE) @@ -178,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) @@ -215,3 +288,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/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..a77bbd12 100644 --- a/cockatrice/src/carddatabasemodel.cpp +++ b/cockatrice/src/carddatabasemodel.cpp @@ -68,6 +68,8 @@ QVariant CardDatabaseModel::headerData(int section, Qt::Orientation orientation, void CardDatabaseModel::updateCardList() { + beginResetModel(); + for (int i = 0; i < cardList.size(); ++i) disconnect(cardList[i], 0, this, 0); @@ -75,7 +77,7 @@ void CardDatabaseModel::updateCardList() for (int i = 0; i < cardList.size(); ++i) connect(cardList[i], SIGNAL(cardInfoChanged(CardInfo *)), this, SLOT(cardInfoChanged(CardInfo *))); - reset(); + endResetModel(); } void CardDatabaseModel::cardInfoChanged(CardInfo *card) 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; } diff --git a/cockatrice/src/decklistmodel.cpp b/cockatrice/src/decklistmodel.cpp index a98ee261..ec10ff05 100644 --- a/cockatrice/src/decklistmodel.cpp +++ b/cockatrice/src/decklistmodel.cpp @@ -30,6 +30,8 @@ DeckListModel::~DeckListModel() void DeckListModel::rebuildTree() { + beginResetModel(); + root->clearTree(); InnerDecklistNode *listRoot = deckList->getRoot(); for (int i = 0; i < listRoot->size(); i++) { @@ -55,7 +57,7 @@ void DeckListModel::rebuildTree() } } - reset(); + endResetModel(); } int DeckListModel::rowCount(const QModelIndex &parent) const diff --git a/cockatrice/src/deckstats_interface.cpp b/cockatrice/src/deckstats_interface.cpp index eae4caae..245e04c2 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) { @@ -39,12 +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; params.addQueryItem("deck", deck->writeToString_Plain()); + 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); + data->append(params.query(QUrl::EncodeReserved)); +} +#endif + + +void DeckStatsInterface::analyzeDeck(DeckList *deck) +{ QByteArray data; - data.append(params.encodedQuery()); + 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); 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/dlg_filter_games.cpp b/cockatrice/src/dlg_filter_games.cpp index 5e402294..eb2e8f78 100644 --- a/cockatrice/src/dlg_filter_games.cpp +++ b/cockatrice/src/dlg_filter_games.cpp @@ -9,26 +9,53 @@ #include #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/" + hashGameType(gameTypesIterator.value()), + false + ).toBool() + ); + gameTypeFilterCheckBoxes.insert(gameTypesIterator.key(), temp); gameTypeFilterLayout->addWidget(temp); } @@ -43,14 +70,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 +114,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 +125,42 @@ 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/" + hashGameType(gameTypeIterator.value()), + checkboxIterator.value()->isChecked() + ); + } + + settings.setValue("min_players", maxPlayersFilterMinSpinBox->value()); + settings.setValue("max_players", maxPlayersFilterMaxSpinBox->value()); + + 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 8059da45..2480e642 100644 --- a/cockatrice/src/dlg_filter_games.h +++ b/cockatrice/src/dlg_filter_games.h @@ -19,6 +19,16 @@ private: QMap gameTypeFilterCheckBoxes; QSpinBox *maxPlayersFilterMinSpinBox; 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: DlgFilterGames(const QMap &allGameTypes, QWidget *parent = 0); diff --git a/cockatrice/src/gameselector.cpp b/cockatrice/src/gameselector.cpp index 6a05d905..25bf2ebd 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())); @@ -81,12 +84,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; diff --git a/cockatrice/src/main.cpp b/cockatrice/src/main.cpp index 22e1fe12..b7e2c0ea 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 static void myMessageOutput(QtMsgType /*type*/, const char *msg) { QFile file("qdebug.txt"); @@ -63,6 +64,16 @@ static void myMessageOutput(QtMsgType /*type*/, const char *msg) out << msg << endl; file.close(); } +#else +static 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,11 +98,21 @@ 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_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"); @@ -114,8 +135,13 @@ int main(int argc, char *argv[]) installNewTranslator(); 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).first(); +#endif if (!db->getLoadSuccess()) if (db->loadCardDatabase(dataDir + "/cards.xml")) settingsCache->setCardDatabasePath(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/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/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); diff --git a/cockatrice/src/remotedecklist_treewidget.cpp b/cockatrice/src/remotedecklist_treewidget.cpp index b72df671..cb96ef7f 100644 --- a/cockatrice/src/remotedecklist_treewidget.cpp +++ b/cockatrice/src/remotedecklist_treewidget.cpp @@ -258,8 +258,11 @@ void RemoteDeckList_TreeModel::deckListFinished(const Response &r) { const Response_DeckList &resp = r.GetExtension(Response_DeckList::ext); + beginResetModel(); + root->clearTree(); - reset(); + + endResetModel(); ServerInfo_DeckStorage_TreeItem tempRoot; tempRoot.set_id(0); @@ -280,7 +283,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.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_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_message.cpp b/cockatrice/src/tab_message.cpp index 80a56154..6369f2a6 100644 --- a/cockatrice/src/tab_message.cpp +++ b/cockatrice/src/tab_message.cpp @@ -49,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_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_room.cpp b/cockatrice/src/tab_room.cpp index 79673e0f..a4bb9ce0 100644 --- a/cockatrice/src/tab_room.cpp +++ b/cockatrice/src/tab_room.cpp @@ -121,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_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/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(); } 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)); 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/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..52ef6415 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,194 @@ 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(' '); + int cardNameStart = i + 1; - int i = line.indexOf(' '); - bool ok; - int number = line.left(i).toInt(&ok); - if (!ok) - continue; + // 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--; + } - QString cardName = line.mid(i + 1); + bool ok; + int number = line.left(i).toInt(&ok); + if (!ok) + continue; + + QString cardName = line.mid(cardNameStart); // 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 +647,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 +657,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 c4d81220..b930c3d4 100644 --- a/common/server.cpp +++ b/common/server.cpp @@ -139,7 +139,7 @@ AuthenticationResult Server::loginUser(Server_ProtocolHandler *session, QString databaseInterface->unlockSessionTables(); return RegistrationRequired; } - + QString tempName = name; int i = 0; while (users.contains(tempName) || databaseInterface->userExists(tempName) || databaseInterface->userSessionExists(tempName)) diff --git a/common/server.h b/common/server.h index 2cf4cc57..f86b26fe 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.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..5363f802 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; } } @@ -9,54 +10,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 diff --git a/oracle/CMakeLists.txt b/oracle/CMakeLists.txt index 05bcd494..c3431571 100644 --- a/oracle/CMakeLists.txt +++ b/oracle/CMakeLists.txt @@ -16,21 +16,77 @@ SET(oracle_SOURCES ../cockatrice/src/qt-json/json.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) + + # 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) + 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() + + # 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 -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(MSVC) - set_target_properties(oracle PROPERTIES LINK_FLAGS "/SUBSYSTEM:WINDOWS") -endif(MSVC) +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(UNIX) if(APPLE) @@ -78,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/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/oracleimporter.cpp b/oracle/src/oracleimporter.cpp index 241924e3..3562d5cc 100644 --- a/oracle/src/oracleimporter.cpp +++ b/oracle/src/oracleimporter.cpp @@ -1,5 +1,9 @@ #include "oracleimporter.h" -#include +#if QT_VERSION < 0x050000 + #include +#else + #include +#endif #include #include "qt-json/json.h" diff --git a/oracle/src/oraclewizard.cpp b/oracle/src/oraclewizard.cpp index 75381b1d..96b78145 100644 --- a/oracle/src/oraclewizard.cpp +++ b/oracle/src/oraclewizard.cpp @@ -1,8 +1,25 @@ #include +#if QT_VERSION < 0x050000 + #include +#else + #include + #include +#endif +#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); diff --git a/servatrice/CMakeLists.txt b/servatrice/CMakeLists.txt index c1aefed1..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,15 +15,50 @@ 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(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() + + # 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) # Include directories -INCLUDE(${QT_USE_FILE}) INCLUDE_DIRECTORIES(../common) INCLUDE_DIRECTORIES(${LIBGCRYPT_INCLUDE_DIR}) INCLUDE_DIRECTORIES(${PROTOBUF_INCLUDE_DIR}) @@ -34,13 +67,21 @@ 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}) -#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 -) +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) + 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() # install rules if(UNIX) @@ -85,3 +126,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 diff --git a/servatrice/scripts/maint_replays b/servatrice/scripts/maint_replays new file mode 100644 index 00000000..1ce1b400 --- /dev/null +++ b/servatrice/scripts/maint_replays @@ -0,0 +1,3 @@ +#!/bin/bash +# 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 new file mode 100644 index 00000000..2c41da6d --- /dev/null +++ b/servatrice/scripts/maint_sessions @@ -0,0 +1,3 @@ +#!/bin/bash +# 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)" diff --git a/servatrice/scripts/mysql.cnf.example b/servatrice/scripts/mysql.cnf.example new file mode 100644 index 00000000..e5d901be --- /dev/null +++ b/servatrice/scripts/mysql.cnf.example @@ -0,0 +1,3 @@ +[client] +user={db_username} +password={db_password} diff --git a/servatrice/src/main.cpp b/servatrice/src/main.cpp index 0f7f0112..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,6 +93,18 @@ void myMessageOutput2(QtMsgType /*type*/, const char *msg) logger->logMessage(msg); std::cerr << msg << std::endl; } +#else +void myMessageOutput(QtMsgType /*type*/, const QMessageLogContext &, const QString &msg) +{ + logger->logMessage(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) @@ -121,9 +134,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 +149,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(myMessageOutput); + else + qInstallMessageHandler(myMessageOutput2); +#endif + #ifdef Q_OS_UNIX struct sigaction hup; hup.sa_handler = ServerLogger::hupSignalHandler; @@ -173,8 +197,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(myMessageOutput); +#endif retval = app.exec(); std::cerr << "Server quit." << std::endl; diff --git a/servatrice/src/passwordhasher.cpp b/servatrice/src/passwordhasher.cpp index 1cc8528c..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).toAscii(); + 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 4c12975b..4c9b4a06 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; @@ -231,82 +235,90 @@ bool Servatrice::initServer() maxMessageSizePerInterval = settings->value("security/max_message_size_per_interval").toInt(); maxGamesPerUser = settings->value("security/max_games_per_user").toInt(); - try { if (settings->value("servernetwork/active", 0).toInt()) { - qDebug() << "Connecting to ISL network."; - const QString certFileName = settings->value("servernetwork/ssl_cert").toString(); - const QString keyFileName = settings->value("servernetwork/ssl_key").toString(); - qDebug() << "Loading certificate..."; - QFile certFile(certFileName); - if (!certFile.open(QIODevice::ReadOnly)) - throw QString("Error opening certificate file: %1").arg(certFileName); - QSslCertificate cert(&certFile); - if (!cert.isValid()) - throw(QString("Invalid certificate.")); - qDebug() << "Loading private key..."; - QFile keyFile(keyFileName); - if (!keyFile.open(QIODevice::ReadOnly)) - throw QString("Error opening private key file: %1").arg(keyFileName); - QSslKey key(&keyFile, QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey); - if (key.isNull()) - throw QString("Invalid private key."); - - QMutableListIterator serverIterator(serverList); - while (serverIterator.hasNext()) { - const ServerProperties &prop = serverIterator.next(); - if (prop.cert == cert) { - serverIterator.remove(); - continue; - } - - QThread *thread = new QThread; - thread->setObjectName("isl_" + QString::number(prop.id)); - connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); - - IslInterface *interface = new IslInterface(prop.id, prop.hostname, prop.address.toString(), prop.controlPort, prop.cert, cert, key, this); - interface->moveToThread(thread); - connect(interface, SIGNAL(destroyed()), thread, SLOT(quit())); - - thread->start(); - QMetaObject::invokeMethod(interface, "initClient", Qt::BlockingQueuedConnection); - } - - const int networkPort = settings->value("servernetwork/port", 14747).toInt(); - qDebug() << "Starting ISL server on port" << networkPort; - - islServer = new Servatrice_IslServer(this, cert, key, this); - if (islServer->listen(QHostAddress::Any, networkPort)) - qDebug() << "ISL server listening."; - else - throw QString("islServer->listen()"); - } } catch (QString error) { - qDebug() << "ERROR --" << error; - return false; - } - - pingClock = new QTimer(this); - connect(pingClock, SIGNAL(timeout()), this, SIGNAL(pingClockTimeout())); - pingClock->start(1000); - - int statusUpdateTime = settings->value("server/statusupdate").toInt(); - statusUpdateClock = new QTimer(this); - connect(statusUpdateClock, SIGNAL(timeout()), this, SLOT(statusUpdate())); - if (statusUpdateTime != 0) { - qDebug() << "Starting status update clock, interval " << statusUpdateTime << " ms"; - statusUpdateClock->start(statusUpdateTime); - } - - const int numberPools = settings->value("server/number_pools", 1).toInt(); - gameServer = new Servatrice_GameServer(this, numberPools, servatriceDatabaseInterface->getDatabase(), this); - gameServer->setMaxPendingConnections(1000); - const int gamePort = settings->value("server/port", 4747).toInt(); - qDebug() << "Starting server on port" << gamePort; - if (gameServer->listen(QHostAddress::Any, gamePort)) - qDebug() << "Server listening."; - else { - qDebug() << "gameServer->listen(): Error."; - return false; - } - return true; + try { if (settings->value("servernetwork/active", 0).toInt()) { + qDebug() << "Connecting to ISL network."; + const QString certFileName = settings->value("servernetwork/ssl_cert").toString(); + const QString keyFileName = settings->value("servernetwork/ssl_key").toString(); + qDebug() << "Loading certificate..."; + QFile certFile(certFileName); + 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)) + throw QString("Error opening private key file: %1").arg(keyFileName); + QSslKey key(&keyFile, QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey); + if (key.isNull()) + throw QString("Invalid private key."); + + QMutableListIterator serverIterator(serverList); + while (serverIterator.hasNext()) { + const ServerProperties &prop = serverIterator.next(); + if (prop.cert == cert) { + serverIterator.remove(); + continue; + } + + QThread *thread = new QThread; + thread->setObjectName("isl_" + QString::number(prop.id)); + connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); + + IslInterface *interface = new IslInterface(prop.id, prop.hostname, prop.address.toString(), prop.controlPort, prop.cert, cert, key, this); + interface->moveToThread(thread); + connect(interface, SIGNAL(destroyed()), thread, SLOT(quit())); + + thread->start(); + QMetaObject::invokeMethod(interface, "initClient", Qt::BlockingQueuedConnection); + } + + const int networkPort = settings->value("servernetwork/port", 14747).toInt(); + qDebug() << "Starting ISL server on port" << networkPort; + + islServer = new Servatrice_IslServer(this, cert, key, this); + if (islServer->listen(QHostAddress::Any, networkPort)) + qDebug() << "ISL server listening."; + else + throw QString("islServer->listen()"); + } } catch (QString error) { + qDebug() << "ERROR --" << error; + return false; + } + + pingClock = new QTimer(this); + connect(pingClock, SIGNAL(timeout()), this, SIGNAL(pingClockTimeout())); + pingClock->start(1000); + + int statusUpdateTime = settings->value("server/statusupdate").toInt(); + statusUpdateClock = new QTimer(this); + connect(statusUpdateClock, SIGNAL(timeout()), this, SLOT(statusUpdate())); + if (statusUpdateTime != 0) { + qDebug() << "Starting status update clock, interval " << statusUpdateTime << " ms"; + statusUpdateClock->start(statusUpdateTime); + } + + const int numberPools = settings->value("server/number_pools", 1).toInt(); + gameServer = new Servatrice_GameServer(this, numberPools, servatriceDatabaseInterface->getDatabase(), this); + gameServer->setMaxPendingConnections(1000); + const int gamePort = settings->value("server/port", 4747).toInt(); + qDebug() << "Starting server on port" << gamePort; + if (gameServer->listen(QHostAddress::Any, gamePort)) + qDebug() << "Server listening."; + else { + qDebug() << "gameServer->listen(): Error."; + return false; + } + return true; } void Servatrice::addDatabaseInterface(QThread *thread, Servatrice_DatabaseInterface *databaseInterface) @@ -316,21 +328,21 @@ void Servatrice::addDatabaseInterface(QThread *thread, Servatrice_DatabaseInterf void Servatrice::updateServerList() { - qDebug() << "Updating server list..."; - - serverListMutex.lock(); - serverList.clear(); - - QSqlQuery query(servatriceDatabaseInterface->getDatabase()); - 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()); - 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); - } - - serverListMutex.unlock(); + qDebug() << "Updating server list..."; + + serverListMutex.lock(); + serverList.clear(); + + QSqlQuery query(servatriceDatabaseInterface->getDatabase()); + 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().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); + } + + serverListMutex.unlock(); } QList Servatrice::getServerList() const 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 {