mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-07-14 06:22:15 -07:00
Merge branch 'master' into valgrind
This commit is contained in:
commit
954489e6c0
105 changed files with 5903 additions and 4729 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -2,3 +2,4 @@ tags
|
||||||
build*
|
build*
|
||||||
*.qm
|
*.qm
|
||||||
.directory
|
.directory
|
||||||
|
mysql.cnf
|
||||||
|
|
|
||||||
|
|
@ -76,8 +76,19 @@ IF(MSVC)
|
||||||
#set(CMAKE_CXX_FLAGS_DEBUG "/Zi")
|
#set(CMAKE_CXX_FLAGS_DEBUG "/Zi")
|
||||||
ELSEIF (CMAKE_COMPILER_IS_GNUCXX)
|
ELSEIF (CMAKE_COMPILER_IS_GNUCXX)
|
||||||
# linux/gcc, bsd/gcc, windows/mingw
|
# linux/gcc, bsd/gcc, windows/mingw
|
||||||
|
include(CheckCXXCompilerFlag)
|
||||||
|
|
||||||
set(CMAKE_CXX_FLAGS_RELEASE "-s -O2")
|
set(CMAKE_CXX_FLAGS_RELEASE "-s -O2")
|
||||||
set(CMAKE_CXX_FLAGS_DEBUG "-ggdb -O0 -Wall -Wextra -pedantic -Werror -Wcast-align -Wmissing-declarations -Winline -Wno-long-long -Wno-error=extra -Wno-error=unused-parameter -Wno-inline -Wno-error=delete-non-virtual-dtor -Wno-error=sign-compare -Wno-error=reorder -Wno-error=missing-declarations")
|
set(CMAKE_CXX_FLAGS_DEBUG "-ggdb -O0 -Wall -Wextra -pedantic -Werror")
|
||||||
|
|
||||||
|
set(ADDITIONAL_DEBUG_FLAGS -Wcast-align -Wmissing-declarations -Winline -Wno-long-long -Wno-error=extra -Wno-error=unused-parameter -Wno-inline -Wno-error=delete-non-virtual-dtor -Wno-error=sign-compare -Wno-error=reorder -Wno-error=missing-declarations)
|
||||||
|
|
||||||
|
FOREACH(FLAG ${ADDITIONAL_DEBUG_FLAGS})
|
||||||
|
CHECK_CXX_COMPILER_FLAG("${FLAG}" CXX_HAS_WARNING_${FLAG})
|
||||||
|
IF(CXX_HAS_WARNING_${FLAG})
|
||||||
|
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${FLAG}")
|
||||||
|
ENDIF()
|
||||||
|
ENDFOREACH()
|
||||||
ELSE()
|
ELSE()
|
||||||
# other: osx/llvm, bsd/llvm
|
# other: osx/llvm, bsd/llvm
|
||||||
set(CMAKE_CXX_FLAGS_RELEASE "-O2")
|
set(CMAKE_CXX_FLAGS_RELEASE "-O2")
|
||||||
|
|
@ -99,6 +110,11 @@ ENDIF()
|
||||||
|
|
||||||
IF(Qt5Widgets_FOUND)
|
IF(Qt5Widgets_FOUND)
|
||||||
MESSAGE(STATUS "Found Qt ${Qt5Widgets_VERSION_STRING}")
|
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()
|
ELSE()
|
||||||
FIND_PACKAGE(Qt4 4.8.0 REQUIRED)
|
FIND_PACKAGE(Qt4 4.8.0 REQUIRED)
|
||||||
IF(QT4_FOUND)
|
IF(QT4_FOUND)
|
||||||
|
|
|
||||||
134
CONTRIBUTING.md
Normal file
134
CONTRIBUTING.md
Normal file
|
|
@ -0,0 +1,134 @@
|
||||||
|
# Style Guide #
|
||||||
|
|
||||||
|
### Compatibility ###
|
||||||
|
|
||||||
|
Cockatrice is written in C++-03, so do not use C++11 constructs such as `auto`.
|
||||||
|
|
||||||
|
Cockatrice support both Qt 4 and Qt 5, so make sure that your code compiles
|
||||||
|
with both. If there have been breaking changes between Qt 4 and 5, use a
|
||||||
|
statement such as
|
||||||
|
|
||||||
|
#if QT_VERSION >= 0x500000
|
||||||
|
doSomethingWithQt5();
|
||||||
|
#else
|
||||||
|
doSomethingWithQt4();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
For consistency, use Qt data structures where possible, such as `QString` over
|
||||||
|
`std::string` or `QList` over `std::vector`.
|
||||||
|
|
||||||
|
### Header files ###
|
||||||
|
|
||||||
|
Use header files with the extension `.h` and source files with the extension
|
||||||
|
`.cpp`.
|
||||||
|
|
||||||
|
Use header guards in the form of `FILE_NAME_H`.
|
||||||
|
|
||||||
|
Simple functions, such as getters, may be written inline in the header file,
|
||||||
|
but other functions should be written in the source file.
|
||||||
|
|
||||||
|
Keep library includes and project includes grouped together. So this is okay:
|
||||||
|
|
||||||
|
// Good:
|
||||||
|
#include <QList>
|
||||||
|
#include <QString>
|
||||||
|
#include "card.h"
|
||||||
|
#include "deck.h"
|
||||||
|
|
||||||
|
// Good:
|
||||||
|
#include "card.h"
|
||||||
|
#include "deck.h"
|
||||||
|
#include <QList>
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
// Bad:
|
||||||
|
#include <QList>
|
||||||
|
#include "card.h"
|
||||||
|
#include <QString>
|
||||||
|
#include "deck.h"
|
||||||
|
|
||||||
|
### Naming ###
|
||||||
|
|
||||||
|
Use `UpperCamelCase` for classes, structs, enums, etc. and `lowerCamelCase` for
|
||||||
|
function and variable names.
|
||||||
|
|
||||||
|
Member variables aren't decorated in any way. Don't prefix or suffix with
|
||||||
|
underscores, etc.
|
||||||
|
|
||||||
|
For arguments to constructors which have the same names as member variables,
|
||||||
|
prefix those arguments with underscores:
|
||||||
|
|
||||||
|
MyClass::MyClass(int _myData)
|
||||||
|
: myData(_myData)
|
||||||
|
{}
|
||||||
|
|
||||||
|
Pointers and references should be denoted with the `*` or `&` going with the
|
||||||
|
variable name:
|
||||||
|
|
||||||
|
// Good:
|
||||||
|
Foo *foo1 = new Foo;
|
||||||
|
Foo &foo2 = *foo1;
|
||||||
|
|
||||||
|
// Bad:
|
||||||
|
Bar* bar1 = new Bar;
|
||||||
|
Bar& bar2 = *bar1;
|
||||||
|
|
||||||
|
Use `0` instead of `NULL` (or `nullptr`) for null pointers.
|
||||||
|
|
||||||
|
### Braces ###
|
||||||
|
|
||||||
|
Use K&R-style braces. Braces for function implementations go on their own
|
||||||
|
lines, but they go on the same line everywhere else:
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
if (someCondition) {
|
||||||
|
doSomething();
|
||||||
|
} else {
|
||||||
|
while (someOtherCondition) {
|
||||||
|
doSomethingElse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Braces can be omitted for single-statement if's and the like, as long as it is
|
||||||
|
still legible.
|
||||||
|
|
||||||
|
### Tabs ###
|
||||||
|
|
||||||
|
Use only spaces. Four spaces per tab.
|
||||||
|
|
||||||
|
### Lines ###
|
||||||
|
|
||||||
|
Do not have trailing whitespace in your lines.
|
||||||
|
|
||||||
|
Lines should be 80 characters or less, as a soft limit.
|
||||||
|
|
||||||
|
### Memory Management ###
|
||||||
|
|
||||||
|
New code should be written using references over pointers and stack allocation
|
||||||
|
over heap allocation wherever possible.
|
||||||
|
|
||||||
|
// Good: uses stack allocation and references
|
||||||
|
void showCard(const Card &card);
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
Card card;
|
||||||
|
showCard(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bad: relies on manual memory management and doesn't give us much
|
||||||
|
// null-safety.
|
||||||
|
void showCard(const Card *card);
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
Card *card = new Card;
|
||||||
|
showCard(card);
|
||||||
|
delete card;
|
||||||
|
}
|
||||||
|
|
||||||
|
(Remember to pass by `const` reference wherever possible, to avoid accidentally
|
||||||
|
mutating objects.)
|
||||||
|
|
||||||
|
When pointers can't be avoided, try to use a smart pointer of some sort, such
|
||||||
|
as `QScopedPointer`, or, less preferably, `QSharedPointer`.
|
||||||
|
|
@ -33,8 +33,11 @@ To compile:
|
||||||
|
|
||||||
The following flags can be passed to `cmake`:
|
The following flags can be passed to `cmake`:
|
||||||
|
|
||||||
- `-DWITH_SERVER=1` build the server
|
- `-DWITH_SERVER=1` Build the server
|
||||||
- `-DWITHOUT_CLIENT=1` do not build the client
|
- `-DWITH_CLIENT=0` Do not build the client
|
||||||
|
- `-DWITH_ORACLE=0` Do not build Oracle
|
||||||
|
- `-DWITH_QT4=1` Force compilation to use Qt4 instead of Qt5.
|
||||||
|
- `-DCMAKE_BUILD_TYPE=Debug` Compile in debug mode. Enables extra logging output, debug symbols, and much more verbose compiler warnings.
|
||||||
|
|
||||||
# Running
|
# Running
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1 @@
|
||||||
!define NSIS_PROJECT_NAME "@PROJECT_NAME@"
|
|
||||||
!define NSIS_SOURCE_PATH "@PROJECT_SOURCE_DIR@"
|
!define NSIS_SOURCE_PATH "@PROJECT_SOURCE_DIR@"
|
||||||
!define NSIS_BINARY_PATH "@PROJECT_BINARY_DIR@"
|
|
||||||
|
|
@ -2,10 +2,11 @@
|
||||||
!include "MUI2.nsh"
|
!include "MUI2.nsh"
|
||||||
!include "FileFunc.nsh"
|
!include "FileFunc.nsh"
|
||||||
|
|
||||||
Name "${NSIS_PROJECT_NAME}"
|
Name "@CPACK_PACKAGE_NAME@"
|
||||||
OutFile "@CPACK_TOPLEVEL_DIRECTORY@/@CPACK_OUTPUT_FILE_NAME@"
|
OutFile "@CPACK_TOPLEVEL_DIRECTORY@/@CPACK_OUTPUT_FILE_NAME@"
|
||||||
SetCompressor /SOLID lzma
|
SetCompressor /SOLID lzma
|
||||||
InstallDir "$PROGRAMFILES\Cockatrice"
|
InstallDir "$PROGRAMFILES\Cockatrice"
|
||||||
|
!define INST_DIR "@CPACK_TEMPORARY_DIRECTORY@"
|
||||||
|
|
||||||
!define MUI_ABORTWARNING
|
!define MUI_ABORTWARNING
|
||||||
!define MUI_WELCOMEFINISHPAGE_BITMAP "${NSIS_SOURCE_PATH}\cmake\leftimage.bmp"
|
!define MUI_WELCOMEFINISHPAGE_BITMAP "${NSIS_SOURCE_PATH}\cmake\leftimage.bmp"
|
||||||
|
|
@ -35,7 +36,8 @@ Section "Application" SecApplication
|
||||||
SetShellVarContext all
|
SetShellVarContext all
|
||||||
SetOutPath "$INSTDIR"
|
SetOutPath "$INSTDIR"
|
||||||
|
|
||||||
File /r "${NSIS_BINARY_PATH}\Release\*.*"
|
@CPACK_NSIS_EXTRA_PREINSTALL_COMMANDS@
|
||||||
|
@CPACK_NSIS_FULL_INSTALL@
|
||||||
|
|
||||||
WriteUninstaller "$INSTDIR\uninstall.exe"
|
WriteUninstaller "$INSTDIR\uninstall.exe"
|
||||||
${GetSize} "$INSTDIR" "/S=0K" $0 $1 $2
|
${GetSize} "$INSTDIR" "/S=0K" $0 $1 $2
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ find_package(Git)
|
||||||
if(GIT_FOUND)
|
if(GIT_FOUND)
|
||||||
execute_process(
|
execute_process(
|
||||||
COMMAND ${GIT_EXECUTABLE} describe --long --always
|
COMMAND ${GIT_EXECUTABLE} describe --long --always
|
||||||
|
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
|
||||||
RESULT_VARIABLE res_var
|
RESULT_VARIABLE res_var
|
||||||
OUTPUT_VARIABLE GIT_COM_ID
|
OUTPUT_VARIABLE GIT_COM_ID
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@
|
||||||
#include <QNetworkReply>
|
#include <QNetworkReply>
|
||||||
#include <QNetworkRequest>
|
#include <QNetworkRequest>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include <QImageReader>
|
||||||
|
|
||||||
const int CardDatabase::versionNeeded = 3;
|
const int CardDatabase::versionNeeded = 3;
|
||||||
|
|
||||||
|
|
@ -92,6 +93,14 @@ bool PictureToLoad::nextSet()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString PictureToLoad::getSetName() const
|
||||||
|
{
|
||||||
|
if (setIndex < sortedSets.size())
|
||||||
|
return sortedSets[setIndex]->getCorrectedShortName();
|
||||||
|
else
|
||||||
|
return QString("");
|
||||||
|
}
|
||||||
|
|
||||||
PictureLoader::PictureLoader(const QString &__picsPath, bool _picDownload, bool _picDownloadHq, QObject *parent)
|
PictureLoader::PictureLoader(const QString &__picsPath, bool _picDownload, bool _picDownloadHq, QObject *parent)
|
||||||
: QObject(parent),
|
: QObject(parent),
|
||||||
_picsPath(__picsPath), picDownload(_picDownload), picDownloadHq(_picDownloadHq),
|
_picsPath(__picsPath), picDownload(_picDownload), picDownloadHq(_picDownloadHq),
|
||||||
|
|
@ -124,41 +133,90 @@ void PictureLoader::processLoadQueue()
|
||||||
}
|
}
|
||||||
PictureToLoad ptl = loadQueue.takeFirst();
|
PictureToLoad ptl = loadQueue.takeFirst();
|
||||||
mutex.unlock();
|
mutex.unlock();
|
||||||
QString correctedName = ptl.getCard()->getCorrectedName();
|
|
||||||
QString picsPath = _picsPath;
|
//The list of paths to the folders in which to search for images
|
||||||
QString setName = ptl.getSetName();
|
QList<QString> picsPaths = QList<QString>() << _picsPath + "/CUSTOM/" + ptl.getCard()->getCorrectedName() + ".full";
|
||||||
|
|
||||||
|
|
||||||
|
QString setName=ptl.getSetName();
|
||||||
|
if(!setName.isEmpty())
|
||||||
|
{
|
||||||
|
picsPaths << _picsPath + "/" + setName + "/" + ptl.getCard()->getCorrectedName() + ".full"
|
||||||
|
<< _picsPath + "/downloadedPics/" + setName + "/" + ptl.getCard()->getCorrectedName() + ".full";
|
||||||
|
}
|
||||||
|
|
||||||
QImage image;
|
QImage image;
|
||||||
if (!image.load(QString("%1/%2/%3.full.jpg").arg(picsPath).arg(setName).arg(correctedName)))
|
QImageReader imgReader;
|
||||||
if (!image.load(QString("%1/%2/%3%4.full.jpg").arg(picsPath).arg(setName).arg(correctedName).arg(1)))
|
imgReader.setDecideFormatFromContent(true);
|
||||||
if (!image.load(QString("%1/%2/%3/%4.full.jpg").arg(picsPath).arg("downloadedPics").arg(setName).arg(correctedName))) {
|
bool found = false;
|
||||||
if (picDownload) {
|
|
||||||
cardsToDownload.append(ptl);
|
|
||||||
if (!downloadRunning)
|
|
||||||
startNextPicDownload();
|
|
||||||
} else {
|
|
||||||
if (ptl.nextSet())
|
|
||||||
loadQueue.prepend(ptl);
|
|
||||||
else
|
|
||||||
emit imageLoaded(ptl.getCard(), QImage());
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
emit imageLoaded(ptl.getCard(), image);
|
//Iterates through the list of paths, searching for images with the desired name with any QImageReader-supported extension
|
||||||
|
for (int i = 0; i < picsPaths.length() && !found; i ++) {
|
||||||
|
imgReader.setFileName(picsPaths.at(i));
|
||||||
|
if (imgReader.read(&image)) {
|
||||||
|
emit imageLoaded(ptl.getCard(), image);
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found) {
|
||||||
|
if (picDownload) {
|
||||||
|
cardsToDownload.append(ptl);
|
||||||
|
if (!downloadRunning)
|
||||||
|
startNextPicDownload();
|
||||||
|
} else {
|
||||||
|
if (ptl.nextSet())
|
||||||
|
loadQueue.prepend(ptl);
|
||||||
|
else
|
||||||
|
emit imageLoaded(ptl.getCard(), QImage());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString PictureLoader::getPicUrl(CardInfo *card)
|
QString PictureLoader::getPicUrl(CardInfo *card)
|
||||||
{
|
{
|
||||||
if (!picDownload) return 0;
|
if (!picDownload) return QString("");
|
||||||
|
|
||||||
QString picUrl = picDownloadHq ? settingsCache->getPicUrlHq() : settingsCache->getPicUrl();
|
|
||||||
picUrl.replace("!name!", QUrl::toPercentEncoding(card->getCorrectedName()));
|
|
||||||
CardSet *set = card->getPreferredSet();
|
CardSet *set = card->getPreferredSet();
|
||||||
picUrl.replace("!setcode!", QUrl::toPercentEncoding(set->getShortName()));
|
QString picUrl = QString("");
|
||||||
picUrl.replace("!setname!", QUrl::toPercentEncoding(set->getLongName()));
|
|
||||||
picUrl.replace("!cardid!", QUrl::toPercentEncoding(QString::number(card->getPreferredMuId())));
|
// if sets have been defined for the card, they can contain custom picUrls
|
||||||
|
if(set)
|
||||||
|
{
|
||||||
|
// first check if Hq is enabled and a custom Hq card url exists in cards.xml
|
||||||
|
if(picDownloadHq)
|
||||||
|
{
|
||||||
|
picUrl = card->getCustomPicURLHq(set->getShortName());
|
||||||
|
if (!picUrl.isEmpty())
|
||||||
|
return picUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// then, test for a custom, non-Hq card url in cards.xml
|
||||||
|
picUrl = card->getCustomPicURL(set->getShortName());
|
||||||
|
if (!picUrl.isEmpty())
|
||||||
|
return picUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// otherwise, fallback to the default url
|
||||||
|
picUrl = picDownloadHq ? settingsCache->getPicUrlHq() : settingsCache->getPicUrl();
|
||||||
|
picUrl.replace("!name!", QUrl::toPercentEncoding(card->getCorrectedName()));
|
||||||
|
|
||||||
|
if (set) {
|
||||||
|
picUrl.replace("!setcode!", QUrl::toPercentEncoding(set->getShortName()));
|
||||||
|
picUrl.replace("!setname!", QUrl::toPercentEncoding(set->getLongName()));
|
||||||
|
}
|
||||||
|
int muid = card->getPreferredMuId();
|
||||||
|
if (muid)
|
||||||
|
picUrl.replace("!cardid!", QUrl::toPercentEncoding(QString::number(muid)));
|
||||||
|
|
||||||
|
if (picUrl.contains("!name!") ||
|
||||||
|
picUrl.contains("!setcode!") ||
|
||||||
|
picUrl.contains("!setname!") ||
|
||||||
|
picUrl.contains("!cardid!")) {
|
||||||
|
qDebug() << "Insufficient card data to download" << card->getName() << "Url:" << picUrl;
|
||||||
|
return QString("");
|
||||||
|
}
|
||||||
|
|
||||||
return picUrl;
|
return picUrl;
|
||||||
}
|
}
|
||||||
|
|
@ -175,8 +233,13 @@ void PictureLoader::startNextPicDownload()
|
||||||
|
|
||||||
cardBeingDownloaded = cardsToDownload.takeFirst();
|
cardBeingDownloaded = cardsToDownload.takeFirst();
|
||||||
|
|
||||||
// TODO: Do something useful when picUrl is 0 or empty, etc
|
|
||||||
QString picUrl = getPicUrl(cardBeingDownloaded.getCard());
|
QString picUrl = getPicUrl(cardBeingDownloaded.getCard());
|
||||||
|
if (picUrl.isEmpty()) {
|
||||||
|
qDebug() << "No url for" << cardBeingDownloaded.getCard()->getName();
|
||||||
|
cardBeingDownloaded = 0;
|
||||||
|
downloadRunning = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
QUrl url(picUrl);
|
QUrl url(picUrl);
|
||||||
|
|
||||||
|
|
@ -192,29 +255,35 @@ void PictureLoader::picDownloadFinished(QNetworkReply *reply)
|
||||||
qDebug() << "Download failed:" << reply->errorString();
|
qDebug() << "Download failed:" << reply->errorString();
|
||||||
}
|
}
|
||||||
|
|
||||||
const QByteArray &picData = reply->readAll();
|
const QByteArray &picData = reply->peek(reply->size()); //peek is used to keep the data in the buffer for use by QImageReader
|
||||||
QImage testImage;
|
QImage testImage;
|
||||||
if (testImage.loadFromData(picData)) {
|
|
||||||
if (!QDir(QString(picsPath + "/downloadedPics/")).exists()) {
|
QImageReader imgReader;
|
||||||
QDir dir(picsPath);
|
imgReader.setDecideFormatFromContent(true);
|
||||||
if (!dir.exists())
|
imgReader.setDevice(reply);
|
||||||
|
QString extension = "." + imgReader.format(); //the format is determined prior to reading the QImageReader data into a QImage object, as that wipes the QImageReader buffer
|
||||||
|
if (extension == ".jpeg")
|
||||||
|
extension = ".jpg";
|
||||||
|
|
||||||
|
if (imgReader.read(&testImage)) {
|
||||||
|
QString setName = cardBeingDownloaded.getSetName();
|
||||||
|
if(!setName.isEmpty())
|
||||||
|
{
|
||||||
|
if (!QDir().mkpath(picsPath + "/downloadedPics/" + setName)) {
|
||||||
|
qDebug() << picsPath + "/downloadedPics/" + setName + " could not be created.";
|
||||||
return;
|
return;
|
||||||
dir.mkdir("downloadedPics");
|
}
|
||||||
}
|
|
||||||
if (!QDir(QString(picsPath + "/downloadedPics/" + cardBeingDownloaded.getSetName())).exists()) {
|
|
||||||
QDir dir(QString(picsPath + "/downloadedPics"));
|
|
||||||
dir.mkdir(cardBeingDownloaded.getSetName());
|
|
||||||
}
|
|
||||||
|
|
||||||
QString suffix;
|
QString suffix;
|
||||||
if (!cardBeingDownloaded.getStripped())
|
if (!cardBeingDownloaded.getStripped())
|
||||||
suffix = ".full";
|
suffix = ".full";
|
||||||
|
|
||||||
QFile newPic(picsPath + "/downloadedPics/" + cardBeingDownloaded.getSetName() + "/" + cardBeingDownloaded.getCard()->getCorrectedName() + suffix + ".jpg");
|
QFile newPic(picsPath + "/downloadedPics/" + setName + "/" + cardBeingDownloaded.getCard()->getCorrectedName() + suffix + extension);
|
||||||
if (!newPic.open(QIODevice::WriteOnly))
|
if (!newPic.open(QIODevice::WriteOnly))
|
||||||
return;
|
return;
|
||||||
newPic.write(picData);
|
newPic.write(picData);
|
||||||
newPic.close();
|
newPic.close();
|
||||||
|
}
|
||||||
|
|
||||||
emit imageLoaded(cardBeingDownloaded.getCard(), testImage);
|
emit imageLoaded(cardBeingDownloaded.getCard(), testImage);
|
||||||
} else if (cardBeingDownloaded.getHq()) {
|
} else if (cardBeingDownloaded.getHq()) {
|
||||||
|
|
@ -275,6 +344,8 @@ CardInfo::CardInfo(CardDatabase *_db,
|
||||||
bool _cipt,
|
bool _cipt,
|
||||||
int _tableRow,
|
int _tableRow,
|
||||||
const SetList &_sets,
|
const SetList &_sets,
|
||||||
|
const QStringMap &_customPicURLs,
|
||||||
|
const QStringMap &_customPicURLsHq,
|
||||||
MuidMap _muIds)
|
MuidMap _muIds)
|
||||||
: db(_db),
|
: db(_db),
|
||||||
name(_name),
|
name(_name),
|
||||||
|
|
@ -286,6 +357,8 @@ CardInfo::CardInfo(CardDatabase *_db,
|
||||||
text(_text),
|
text(_text),
|
||||||
colors(_colors),
|
colors(_colors),
|
||||||
loyalty(_loyalty),
|
loyalty(_loyalty),
|
||||||
|
customPicURLs(_customPicURLs),
|
||||||
|
customPicURLsHq(_customPicURLsHq),
|
||||||
muIds(_muIds),
|
muIds(_muIds),
|
||||||
cipt(_cipt),
|
cipt(_cipt),
|
||||||
tableRow(_tableRow),
|
tableRow(_tableRow),
|
||||||
|
|
@ -424,6 +497,8 @@ void CardInfo::updatePixmapCache()
|
||||||
|
|
||||||
CardSet* CardInfo::getPreferredSet()
|
CardSet* CardInfo::getPreferredSet()
|
||||||
{
|
{
|
||||||
|
if(sets.isEmpty())
|
||||||
|
return 0;
|
||||||
SetList sortedSets = sets;
|
SetList sortedSets = sets;
|
||||||
sortedSets.sortByKey();
|
sortedSets.sortByKey();
|
||||||
return sortedSets.first();
|
return sortedSets.first();
|
||||||
|
|
@ -431,7 +506,28 @@ CardSet* CardInfo::getPreferredSet()
|
||||||
|
|
||||||
int CardInfo::getPreferredMuId()
|
int CardInfo::getPreferredMuId()
|
||||||
{
|
{
|
||||||
return muIds[getPreferredSet()->getShortName()];
|
CardSet *set = getPreferredSet();
|
||||||
|
return set ? muIds[set->getShortName()] : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString CardInfo::simplifyName(const QString &name) {
|
||||||
|
QString simpleName(name);
|
||||||
|
|
||||||
|
// So Aetherling would work, but not Ætherling since 'Æ' would get replaced
|
||||||
|
// with nothing.
|
||||||
|
simpleName.replace("æ", "ae");
|
||||||
|
simpleName.replace("Æ", "AE");
|
||||||
|
|
||||||
|
// Replace Jötun Grunt with Jotun Grunt.
|
||||||
|
simpleName = simpleName.normalized(QString::NormalizationForm_KD);
|
||||||
|
|
||||||
|
// Replace dashes with spaces so that we can say "garruk the veil cursed"
|
||||||
|
// instead of the unintuitive "garruk the veilcursed".
|
||||||
|
simpleName = simpleName.replace("-", " ");
|
||||||
|
|
||||||
|
simpleName.remove(QRegExp("[^a-zA-Z0-9 ]"));
|
||||||
|
simpleName = simpleName.toLower();
|
||||||
|
return simpleName;
|
||||||
}
|
}
|
||||||
|
|
||||||
static QXmlStreamWriter &operator<<(QXmlStreamWriter &xml, const CardInfo *info)
|
static QXmlStreamWriter &operator<<(QXmlStreamWriter &xml, const CardInfo *info)
|
||||||
|
|
@ -448,6 +544,14 @@ static QXmlStreamWriter &operator<<(QXmlStreamWriter &xml, const CardInfo *info)
|
||||||
tmpSet=sets[i]->getShortName();
|
tmpSet=sets[i]->getShortName();
|
||||||
xml.writeAttribute("muId", QString::number(info->getMuId(tmpSet)));
|
xml.writeAttribute("muId", QString::number(info->getMuId(tmpSet)));
|
||||||
|
|
||||||
|
tmpString = info->getCustomPicURL(tmpSet);
|
||||||
|
if(!tmpString.isEmpty())
|
||||||
|
xml.writeAttribute("picURL", tmpString);
|
||||||
|
|
||||||
|
tmpString = info->getCustomPicURLHq(tmpSet);
|
||||||
|
if(!tmpString.isEmpty())
|
||||||
|
xml.writeAttribute("picURLHq", tmpString);
|
||||||
|
|
||||||
xml.writeCharacters(tmpSet);
|
xml.writeCharacters(tmpSet);
|
||||||
xml.writeEndElement();
|
xml.writeEndElement();
|
||||||
}
|
}
|
||||||
|
|
@ -507,55 +611,55 @@ CardDatabase::~CardDatabase()
|
||||||
|
|
||||||
void CardDatabase::clear()
|
void CardDatabase::clear()
|
||||||
{
|
{
|
||||||
QHashIterator<QString, CardSet *> setIt(setHash);
|
QHashIterator<QString, CardSet *> setIt(sets);
|
||||||
while (setIt.hasNext()) {
|
while (setIt.hasNext()) {
|
||||||
setIt.next();
|
setIt.next();
|
||||||
delete setIt.value();
|
delete setIt.value();
|
||||||
}
|
}
|
||||||
setHash.clear();
|
sets.clear();
|
||||||
|
|
||||||
QHashIterator<QString, CardInfo *> i(cardHash);
|
QHashIterator<QString, CardInfo *> i(cards);
|
||||||
while (i.hasNext()) {
|
while (i.hasNext()) {
|
||||||
i.next();
|
i.next();
|
||||||
delete i.value();
|
delete i.value();
|
||||||
}
|
}
|
||||||
cardHash.clear();
|
cards.clear();
|
||||||
|
|
||||||
|
// The pointers themselves were already deleted, so we don't delete them
|
||||||
|
// again.
|
||||||
|
simpleNameCards.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CardDatabase::addCard(CardInfo *card)
|
void CardDatabase::addCard(CardInfo *card)
|
||||||
{
|
{
|
||||||
cardHash.insert(card->getName(), card);
|
cards.insert(card->getName(), card);
|
||||||
|
simpleNameCards.insert(CardInfo::simplifyName(card->getName()), card);
|
||||||
emit cardAdded(card);
|
emit cardAdded(card);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CardDatabase::removeCard(CardInfo *card)
|
void CardDatabase::removeCard(CardInfo *card)
|
||||||
{
|
{
|
||||||
cardHash.remove(card->getName());
|
cards.remove(card->getName());
|
||||||
|
simpleNameCards.remove(CardInfo::simplifyName(card->getName()));
|
||||||
emit cardRemoved(card);
|
emit cardRemoved(card);
|
||||||
}
|
}
|
||||||
|
|
||||||
CardInfo *CardDatabase::getCard(const QString &cardName, bool createIfNotFound)
|
CardInfo *CardDatabase::getCard(const QString &cardName, bool createIfNotFound) {
|
||||||
{
|
return getCardFromMap(cards, cardName, createIfNotFound);
|
||||||
if (cardName.isEmpty())
|
}
|
||||||
return noCard;
|
|
||||||
else if (cardHash.contains(cardName))
|
CardInfo *CardDatabase::getCardBySimpleName(const QString &cardName, bool createIfNotFound) {
|
||||||
return cardHash.value(cardName);
|
QString simpleName = CardInfo::simplifyName(cardName);
|
||||||
else if (createIfNotFound) {
|
return getCardFromMap(simpleNameCards, simpleName, createIfNotFound);
|
||||||
CardInfo *newCard = new CardInfo(this, cardName, true);
|
|
||||||
newCard->addToSet(getSet("TK"));
|
|
||||||
cardHash.insert(cardName, newCard);
|
|
||||||
return newCard;
|
|
||||||
} else
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CardSet *CardDatabase::getSet(const QString &setName)
|
CardSet *CardDatabase::getSet(const QString &setName)
|
||||||
{
|
{
|
||||||
if (setHash.contains(setName))
|
if (sets.contains(setName))
|
||||||
return setHash.value(setName);
|
return sets.value(setName);
|
||||||
else {
|
else {
|
||||||
CardSet *newSet = new CardSet(setName);
|
CardSet *newSet = new CardSet(setName);
|
||||||
setHash.insert(setName, newSet);
|
sets.insert(setName, newSet);
|
||||||
return newSet;
|
return newSet;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -563,7 +667,7 @@ CardSet *CardDatabase::getSet(const QString &setName)
|
||||||
SetList CardDatabase::getSetList() const
|
SetList CardDatabase::getSetList() const
|
||||||
{
|
{
|
||||||
SetList result;
|
SetList result;
|
||||||
QHashIterator<QString, CardSet *> i(setHash);
|
QHashIterator<QString, CardSet *> i(sets);
|
||||||
while (i.hasNext()) {
|
while (i.hasNext()) {
|
||||||
i.next();
|
i.next();
|
||||||
result << i.value();
|
result << i.value();
|
||||||
|
|
@ -573,7 +677,9 @@ SetList CardDatabase::getSetList() const
|
||||||
|
|
||||||
void CardDatabase::clearPixmapCache()
|
void CardDatabase::clearPixmapCache()
|
||||||
{
|
{
|
||||||
QHashIterator<QString, CardInfo *> i(cardHash);
|
// This also clears the cards in simpleNameCards since they point to the
|
||||||
|
// same object.
|
||||||
|
QHashIterator<QString, CardInfo *> i(cards);
|
||||||
while (i.hasNext()) {
|
while (i.hasNext()) {
|
||||||
i.next();
|
i.next();
|
||||||
i.value()->clearPixmapCache();
|
i.value()->clearPixmapCache();
|
||||||
|
|
@ -597,7 +703,7 @@ void CardDatabase::loadSetsFromXml(QXmlStreamReader &xml)
|
||||||
else if (xml.name() == "longname")
|
else if (xml.name() == "longname")
|
||||||
longName = xml.readElementText();
|
longName = xml.readElementText();
|
||||||
}
|
}
|
||||||
setHash.insert(shortName, new CardSet(shortName, longName));
|
sets.insert(shortName, new CardSet(shortName, longName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -610,6 +716,7 @@ void CardDatabase::loadCardsFromXml(QXmlStreamReader &xml)
|
||||||
if (xml.name() == "card") {
|
if (xml.name() == "card") {
|
||||||
QString name, manacost, type, pt, text;
|
QString name, manacost, type, pt, text;
|
||||||
QStringList colors;
|
QStringList colors;
|
||||||
|
QStringMap customPicURLs, customPicURLsHq;
|
||||||
MuidMap muids;
|
MuidMap muids;
|
||||||
SetList sets;
|
SetList sets;
|
||||||
int tableRow = 0;
|
int tableRow = 0;
|
||||||
|
|
@ -636,6 +743,12 @@ void CardDatabase::loadCardsFromXml(QXmlStreamReader &xml)
|
||||||
if (attrs.hasAttribute("muId")) {
|
if (attrs.hasAttribute("muId")) {
|
||||||
muids[setName] = attrs.value("muId").toString().toInt();
|
muids[setName] = attrs.value("muId").toString().toInt();
|
||||||
}
|
}
|
||||||
|
if (attrs.hasAttribute("picURL")) {
|
||||||
|
customPicURLs[setName] = attrs.value("picURL").toString();
|
||||||
|
}
|
||||||
|
if (attrs.hasAttribute("picURLHq")) {
|
||||||
|
customPicURLsHq[setName] = attrs.value("picURLHq").toString();
|
||||||
|
}
|
||||||
} else if (xml.name() == "color")
|
} else if (xml.name() == "color")
|
||||||
colors << xml.readElementText();
|
colors << xml.readElementText();
|
||||||
else if (xml.name() == "tablerow")
|
else if (xml.name() == "tablerow")
|
||||||
|
|
@ -647,46 +760,32 @@ void CardDatabase::loadCardsFromXml(QXmlStreamReader &xml)
|
||||||
else if (xml.name() == "token")
|
else if (xml.name() == "token")
|
||||||
isToken = xml.readElementText().toInt();
|
isToken = xml.readElementText().toInt();
|
||||||
}
|
}
|
||||||
cardHash.insert(name, new CardInfo(this, name, isToken, manacost, type, pt, text, colors, loyalty, cipt, tableRow, sets, muids));
|
addCard(new CardInfo(this, name, isToken, manacost, type, pt, text, colors, loyalty, cipt, tableRow, sets, customPicURLs, customPicURLsHq, muids));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LoadStatus CardDatabase::loadFromFile(const QString &fileName, bool tokens)
|
CardInfo *CardDatabase::getCardFromMap(CardNameMap &cardMap, const QString &cardName, bool createIfNotFound) {
|
||||||
|
if (cardName.isEmpty())
|
||||||
|
return noCard;
|
||||||
|
else if (cardMap.contains(cardName))
|
||||||
|
return cardMap.value(cardName);
|
||||||
|
else if (createIfNotFound) {
|
||||||
|
CardInfo *newCard = new CardInfo(this, cardName, true);
|
||||||
|
newCard->addToSet(getSet("TK"));
|
||||||
|
cardMap.insert(cardName, newCard);
|
||||||
|
return newCard;
|
||||||
|
} else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
LoadStatus CardDatabase::loadFromFile(const QString &fileName)
|
||||||
{
|
{
|
||||||
QFile file(fileName);
|
QFile file(fileName);
|
||||||
file.open(QIODevice::ReadOnly);
|
file.open(QIODevice::ReadOnly);
|
||||||
if (!file.isOpen())
|
if (!file.isOpen())
|
||||||
return FileError;
|
return FileError;
|
||||||
|
|
||||||
if (tokens) {
|
|
||||||
QMutableHashIterator<QString, CardInfo *> i(cardHash);
|
|
||||||
while (i.hasNext()) {
|
|
||||||
i.next();
|
|
||||||
if (i.value()->getIsToken()) {
|
|
||||||
delete i.value();
|
|
||||||
i.remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
QHashIterator<QString, CardSet *> setIt(setHash);
|
|
||||||
while (setIt.hasNext()) {
|
|
||||||
setIt.next();
|
|
||||||
delete setIt.value();
|
|
||||||
}
|
|
||||||
setHash.clear();
|
|
||||||
|
|
||||||
QMutableHashIterator<QString, CardInfo *> i(cardHash);
|
|
||||||
while (i.hasNext()) {
|
|
||||||
i.next();
|
|
||||||
if (!i.value()->getIsToken()) {
|
|
||||||
delete i.value();
|
|
||||||
i.remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cardHash.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
QXmlStreamReader xml(&file);
|
QXmlStreamReader xml(&file);
|
||||||
while (!xml.atEnd()) {
|
while (!xml.atEnd()) {
|
||||||
if (xml.readNext() == QXmlStreamReader::StartElement) {
|
if (xml.readNext() == QXmlStreamReader::StartElement) {
|
||||||
|
|
@ -707,9 +806,9 @@ LoadStatus CardDatabase::loadFromFile(const QString &fileName, bool tokens)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
qDebug() << cardHash.size() << "cards in" << setHash.size() << "sets loaded";
|
qDebug() << cards.size() << "cards in" << sets.size() << "sets loaded";
|
||||||
|
|
||||||
if (cardHash.isEmpty()) return NoCards;
|
if (cards.isEmpty()) return NoCards;
|
||||||
|
|
||||||
return Ok;
|
return Ok;
|
||||||
}
|
}
|
||||||
|
|
@ -728,18 +827,17 @@ bool CardDatabase::saveToFile(const QString &fileName, bool tokens)
|
||||||
|
|
||||||
if (!tokens) {
|
if (!tokens) {
|
||||||
xml.writeStartElement("sets");
|
xml.writeStartElement("sets");
|
||||||
QHashIterator<QString, CardSet *> setIterator(setHash);
|
QHashIterator<QString, CardSet *> setIterator(sets);
|
||||||
while (setIterator.hasNext())
|
while (setIterator.hasNext())
|
||||||
xml << setIterator.next().value();
|
xml << setIterator.next().value();
|
||||||
xml.writeEndElement(); // sets
|
xml.writeEndElement(); // sets
|
||||||
}
|
}
|
||||||
|
|
||||||
xml.writeStartElement("cards");
|
xml.writeStartElement("cards");
|
||||||
QHashIterator<QString, CardInfo *> cardIterator(cardHash);
|
QHashIterator<QString, CardInfo *> cardIterator(cards);
|
||||||
while (cardIterator.hasNext()) {
|
while (cardIterator.hasNext()) {
|
||||||
CardInfo *card = cardIterator.next().value();
|
CardInfo *card = cardIterator.next().value();
|
||||||
if (card->getIsToken() == tokens)
|
xml << card;
|
||||||
xml << card;
|
|
||||||
}
|
}
|
||||||
xml.writeEndElement(); // cards
|
xml.writeEndElement(); // cards
|
||||||
|
|
||||||
|
|
@ -753,7 +851,7 @@ void CardDatabase::picDownloadChanged()
|
||||||
{
|
{
|
||||||
pictureLoader->setPicDownload(settingsCache->getPicDownload());
|
pictureLoader->setPicDownload(settingsCache->getPicDownload());
|
||||||
if (settingsCache->getPicDownload()) {
|
if (settingsCache->getPicDownload()) {
|
||||||
QHashIterator<QString, CardInfo *> cardIterator(cardHash);
|
QHashIterator<QString, CardInfo *> cardIterator(cards);
|
||||||
while (cardIterator.hasNext())
|
while (cardIterator.hasNext())
|
||||||
cardIterator.next().value()->clearPixmapCacheMiss();
|
cardIterator.next().value()->clearPixmapCacheMiss();
|
||||||
}
|
}
|
||||||
|
|
@ -763,7 +861,7 @@ void CardDatabase::picDownloadHqChanged()
|
||||||
{
|
{
|
||||||
pictureLoader->setPicDownloadHq(settingsCache->getPicDownloadHq());
|
pictureLoader->setPicDownloadHq(settingsCache->getPicDownloadHq());
|
||||||
if (settingsCache->getPicDownloadHq()) {
|
if (settingsCache->getPicDownloadHq()) {
|
||||||
QHashIterator<QString, CardInfo *> cardIterator(cardHash);
|
QHashIterator<QString, CardInfo *> cardIterator(cards);
|
||||||
while (cardIterator.hasNext())
|
while (cardIterator.hasNext())
|
||||||
cardIterator.next().value()->clearPixmapCacheMiss();
|
cardIterator.next().value()->clearPixmapCacheMiss();
|
||||||
}
|
}
|
||||||
|
|
@ -773,11 +871,11 @@ LoadStatus CardDatabase::loadCardDatabase(const QString &path, bool tokens)
|
||||||
{
|
{
|
||||||
LoadStatus tempLoadStatus = NotLoaded;
|
LoadStatus tempLoadStatus = NotLoaded;
|
||||||
if (!path.isEmpty())
|
if (!path.isEmpty())
|
||||||
tempLoadStatus = loadFromFile(path, tokens);
|
tempLoadStatus = loadFromFile(path);
|
||||||
|
|
||||||
if (tempLoadStatus == Ok) {
|
if (tempLoadStatus == Ok) {
|
||||||
SetList allSets;
|
SetList allSets;
|
||||||
QHashIterator<QString, CardSet *> setsIterator(setHash);
|
QHashIterator<QString, CardSet *> setsIterator(sets);
|
||||||
while (setsIterator.hasNext())
|
while (setsIterator.hasNext())
|
||||||
allSets.append(setsIterator.next().value());
|
allSets.append(setsIterator.next().value());
|
||||||
allSets.sortByKey();
|
allSets.sortByKey();
|
||||||
|
|
@ -809,7 +907,7 @@ void CardDatabase::loadTokenDatabase()
|
||||||
QStringList CardDatabase::getAllColors() const
|
QStringList CardDatabase::getAllColors() const
|
||||||
{
|
{
|
||||||
QSet<QString> colors;
|
QSet<QString> colors;
|
||||||
QHashIterator<QString, CardInfo *> cardIterator(cardHash);
|
QHashIterator<QString, CardInfo *> cardIterator(cards);
|
||||||
while (cardIterator.hasNext()) {
|
while (cardIterator.hasNext()) {
|
||||||
const QStringList &cardColors = cardIterator.next().value()->getColors();
|
const QStringList &cardColors = cardIterator.next().value()->getColors();
|
||||||
if (cardColors.isEmpty())
|
if (cardColors.isEmpty())
|
||||||
|
|
@ -824,7 +922,7 @@ QStringList CardDatabase::getAllColors() const
|
||||||
QStringList CardDatabase::getAllMainCardTypes() const
|
QStringList CardDatabase::getAllMainCardTypes() const
|
||||||
{
|
{
|
||||||
QSet<QString> types;
|
QSet<QString> types;
|
||||||
QHashIterator<QString, CardInfo *> cardIterator(cardHash);
|
QHashIterator<QString, CardInfo *> cardIterator(cards);
|
||||||
while (cardIterator.hasNext())
|
while (cardIterator.hasNext())
|
||||||
types.insert(cardIterator.next().value()->getMainCardType());
|
types.insert(cardIterator.next().value()->getMainCardType());
|
||||||
return types.toList();
|
return types.toList();
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ public:
|
||||||
PictureToLoad(CardInfo *_card = 0, bool _stripped = false, bool _hq = true);
|
PictureToLoad(CardInfo *_card = 0, bool _stripped = false, bool _hq = true);
|
||||||
CardInfo *getCard() const { return card; }
|
CardInfo *getCard() const { return card; }
|
||||||
bool getStripped() const { return stripped; }
|
bool getStripped() const { return stripped; }
|
||||||
QString getSetName() const { return sortedSets[setIndex]->getCorrectedShortName(); }
|
QString getSetName() const;
|
||||||
bool nextSet();
|
bool nextSet();
|
||||||
bool getHq() const { return hq; }
|
bool getHq() const { return hq; }
|
||||||
void setHq(bool _hq) { hq = _hq; }
|
void setHq(bool _hq) { hq = _hq; }
|
||||||
|
|
@ -95,6 +95,13 @@ private:
|
||||||
CardDatabase *db;
|
CardDatabase *db;
|
||||||
|
|
||||||
QString name;
|
QString name;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The name without punctuation or capitalization, for better card tag name
|
||||||
|
* recognition.
|
||||||
|
*/
|
||||||
|
QString simpleName;
|
||||||
|
|
||||||
bool isToken;
|
bool isToken;
|
||||||
SetList sets;
|
SetList sets;
|
||||||
QString manacost;
|
QString manacost;
|
||||||
|
|
@ -103,6 +110,7 @@ private:
|
||||||
QString text;
|
QString text;
|
||||||
QStringList colors;
|
QStringList colors;
|
||||||
int loyalty;
|
int loyalty;
|
||||||
|
QStringMap customPicURLs, customPicURLsHq;
|
||||||
MuidMap muIds;
|
MuidMap muIds;
|
||||||
bool cipt;
|
bool cipt;
|
||||||
int tableRow;
|
int tableRow;
|
||||||
|
|
@ -121,6 +129,8 @@ public:
|
||||||
bool _cipt = false,
|
bool _cipt = false,
|
||||||
int _tableRow = 0,
|
int _tableRow = 0,
|
||||||
const SetList &_sets = SetList(),
|
const SetList &_sets = SetList(),
|
||||||
|
const QStringMap &_customPicURLs = QStringMap(),
|
||||||
|
const QStringMap &_customPicURLsHq = QStringMap(),
|
||||||
MuidMap muids = MuidMap());
|
MuidMap muids = MuidMap());
|
||||||
~CardInfo();
|
~CardInfo();
|
||||||
const QString &getName() const { return name; }
|
const QString &getName() const { return name; }
|
||||||
|
|
@ -138,12 +148,16 @@ public:
|
||||||
void setText(const QString &_text) { text = _text; emit cardInfoChanged(this); }
|
void setText(const QString &_text) { text = _text; emit cardInfoChanged(this); }
|
||||||
void setColors(const QStringList &_colors) { colors = _colors; emit cardInfoChanged(this); }
|
void setColors(const QStringList &_colors) { colors = _colors; emit cardInfoChanged(this); }
|
||||||
const QStringList &getColors() const { return colors; }
|
const QStringList &getColors() const { return colors; }
|
||||||
|
QString getCustomPicURL(const QString &set) const { return customPicURLs.value(set); }
|
||||||
|
QString getCustomPicURLHq(const QString &set) const { return customPicURLsHq.value(set); }
|
||||||
int getMuId(const QString &set) const { return muIds.value(set); }
|
int getMuId(const QString &set) const { return muIds.value(set); }
|
||||||
QString getMainCardType() const;
|
QString getMainCardType() const;
|
||||||
QString getCorrectedName() const;
|
QString getCorrectedName() const;
|
||||||
int getTableRow() const { return tableRow; }
|
int getTableRow() const { return tableRow; }
|
||||||
void setTableRow(int _tableRow) { tableRow = _tableRow; }
|
void setTableRow(int _tableRow) { tableRow = _tableRow; }
|
||||||
void setLoyalty(int _loyalty) { loyalty = _loyalty; emit cardInfoChanged(this); }
|
void setLoyalty(int _loyalty) { loyalty = _loyalty; emit cardInfoChanged(this); }
|
||||||
|
void setCustomPicURL(const QString &_set, const QString &_customPicURL) { customPicURLs.insert(_set, _customPicURL); }
|
||||||
|
void setCustomPicURLHq(const QString &_set, const QString &_customPicURL) { customPicURLsHq.insert(_set, _customPicURL); }
|
||||||
void setMuId(const QString &_set, const int &_muId) { muIds.insert(_set, _muId); }
|
void setMuId(const QString &_set, const int &_muId) { muIds.insert(_set, _muId); }
|
||||||
void addToSet(CardSet *set);
|
void addToSet(CardSet *set);
|
||||||
QPixmap *loadPixmap();
|
QPixmap *loadPixmap();
|
||||||
|
|
@ -153,6 +167,12 @@ public:
|
||||||
void imageLoaded(const QImage &image);
|
void imageLoaded(const QImage &image);
|
||||||
CardSet *getPreferredSet();
|
CardSet *getPreferredSet();
|
||||||
int getPreferredMuId();
|
int getPreferredMuId();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simplify a name to have no punctuation and lowercase all letters, for
|
||||||
|
* less strict name-matching.
|
||||||
|
*/
|
||||||
|
static QString simplifyName(const QString &name);
|
||||||
public slots:
|
public slots:
|
||||||
void updatePixmapCache();
|
void updatePixmapCache();
|
||||||
signals:
|
signals:
|
||||||
|
|
@ -162,11 +182,27 @@ signals:
|
||||||
|
|
||||||
enum LoadStatus { Ok, VersionTooOld, Invalid, NotLoaded, FileError, NoCards };
|
enum LoadStatus { Ok, VersionTooOld, Invalid, NotLoaded, FileError, NoCards };
|
||||||
|
|
||||||
|
typedef QHash<QString, CardInfo *> CardNameMap;
|
||||||
|
typedef QHash<QString, CardSet *> SetNameMap;
|
||||||
|
|
||||||
class CardDatabase : public QObject {
|
class CardDatabase : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
protected:
|
protected:
|
||||||
QHash<QString, CardInfo *> cardHash;
|
/*
|
||||||
QHash<QString, CardSet *> setHash;
|
* The cards, indexed by name.
|
||||||
|
*/
|
||||||
|
CardNameMap cards;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The cards, indexed by their simple name.
|
||||||
|
*/
|
||||||
|
CardNameMap simpleNameCards;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The sets, indexed by short name.
|
||||||
|
*/
|
||||||
|
SetNameMap sets;
|
||||||
|
|
||||||
CardInfo *noCard;
|
CardInfo *noCard;
|
||||||
|
|
||||||
QThread *pictureLoaderThread;
|
QThread *pictureLoaderThread;
|
||||||
|
|
@ -176,6 +212,8 @@ private:
|
||||||
static const int versionNeeded;
|
static const int versionNeeded;
|
||||||
void loadCardsFromXml(QXmlStreamReader &xml);
|
void loadCardsFromXml(QXmlStreamReader &xml);
|
||||||
void loadSetsFromXml(QXmlStreamReader &xml);
|
void loadSetsFromXml(QXmlStreamReader &xml);
|
||||||
|
|
||||||
|
CardInfo *getCardFromMap(CardNameMap &cardMap, const QString &cardName, bool createIfNotFound);
|
||||||
public:
|
public:
|
||||||
CardDatabase(QObject *parent = 0);
|
CardDatabase(QObject *parent = 0);
|
||||||
~CardDatabase();
|
~CardDatabase();
|
||||||
|
|
@ -183,10 +221,17 @@ public:
|
||||||
void addCard(CardInfo *card);
|
void addCard(CardInfo *card);
|
||||||
void removeCard(CardInfo *card);
|
void removeCard(CardInfo *card);
|
||||||
CardInfo *getCard(const QString &cardName = QString(), bool createIfNotFound = true);
|
CardInfo *getCard(const QString &cardName = QString(), bool createIfNotFound = true);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get a card by its simple name. The name will be simplified in this
|
||||||
|
* function, so you don't need to simplify it beforehand.
|
||||||
|
*/
|
||||||
|
CardInfo *getCardBySimpleName(const QString &cardName = QString(), bool createIfNotFound = true);
|
||||||
|
|
||||||
CardSet *getSet(const QString &setName);
|
CardSet *getSet(const QString &setName);
|
||||||
QList<CardInfo *> getCardList() const { return cardHash.values(); }
|
QList<CardInfo *> getCardList() const { return cards.values(); }
|
||||||
SetList getSetList() const;
|
SetList getSetList() const;
|
||||||
LoadStatus loadFromFile(const QString &fileName, bool tokens = false);
|
LoadStatus loadFromFile(const QString &fileName);
|
||||||
bool saveToFile(const QString &fileName, bool tokens = false);
|
bool saveToFile(const QString &fileName, bool tokens = false);
|
||||||
QStringList getAllColors() const;
|
QStringList getAllColors() const;
|
||||||
QStringList getAllMainCardTypes() const;
|
QStringList getAllMainCardTypes() const;
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,7 @@ CardInfoWidget::CardInfoWidget(ResizeMode _mode, const QString &cardName, QWidge
|
||||||
} else
|
} else
|
||||||
setFixedWidth(250);
|
setFixedWidth(250);
|
||||||
|
|
||||||
setCard(db->getCard(cardName));
|
setCard(getCard(cardName));
|
||||||
setMinimized(settingsCache->getCardInfoMinimized());
|
setMinimized(settingsCache->getCardInfoMinimized());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -166,7 +166,7 @@ void CardInfoWidget::setCard(CardInfo *card)
|
||||||
|
|
||||||
void CardInfoWidget::setCard(const QString &cardName)
|
void CardInfoWidget::setCard(const QString &cardName)
|
||||||
{
|
{
|
||||||
setCard(db->getCard(cardName));
|
setCard(getCard(cardName));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CardInfoWidget::setCard(AbstractCardItem *card)
|
void CardInfoWidget::setCard(AbstractCardItem *card)
|
||||||
|
|
@ -176,7 +176,11 @@ void CardInfoWidget::setCard(AbstractCardItem *card)
|
||||||
|
|
||||||
void CardInfoWidget::clear()
|
void CardInfoWidget::clear()
|
||||||
{
|
{
|
||||||
setCard(db->getCard());
|
setCard(getCard());
|
||||||
|
}
|
||||||
|
|
||||||
|
CardInfo *CardInfoWidget::getCard(const QString &cardName) {
|
||||||
|
return db->getCardBySimpleName(cardName);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CardInfoWidget::updatePixmap()
|
void CardInfoWidget::updatePixmap()
|
||||||
|
|
@ -188,7 +192,7 @@ void CardInfoWidget::updatePixmap()
|
||||||
if (resizedPixmap)
|
if (resizedPixmap)
|
||||||
cardPicture->setPixmap(*resizedPixmap);
|
cardPicture->setPixmap(*resizedPixmap);
|
||||||
else
|
else
|
||||||
cardPicture->setPixmap(*(db->getCard()->getPixmap(QSize(pixmapWidth, pixmapWidth * aspectRatio))));
|
cardPicture->setPixmap(*(getCard()->getPixmap(QSize(pixmapWidth, pixmapWidth * aspectRatio))));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CardInfoWidget::retranslateUi()
|
void CardInfoWidget::retranslateUi()
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,11 @@ private:
|
||||||
CardInfo *info;
|
CardInfo *info;
|
||||||
void setMinimized(int _minimized);
|
void setMinimized(int _minimized);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wrapper around db->getCardBySimpleName.
|
||||||
|
*/
|
||||||
|
CardInfo *getCard(const QString &cardName = QString());
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CardInfoWidget(ResizeMode _mode, const QString &cardName = QString(), QWidget *parent = 0, Qt::WindowFlags f = 0);
|
CardInfoWidget(ResizeMode _mode, const QString &cardName = QString(), QWidget *parent = 0, Qt::WindowFlags f = 0);
|
||||||
void retranslateUi();
|
void retranslateUi();
|
||||||
|
|
|
||||||
|
|
@ -233,7 +233,8 @@ CardDragItem *CardItem::createDragItem(int _id, const QPointF &_pos, const QPoin
|
||||||
|
|
||||||
void CardItem::deleteDragItem()
|
void CardItem::deleteDragItem()
|
||||||
{
|
{
|
||||||
dragItem->deleteLater();
|
if(dragItem)
|
||||||
|
dragItem->deleteLater();
|
||||||
dragItem = NULL;
|
dragItem = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -472,13 +472,7 @@ void DeckListModel::printDeckList(QPrinter *printer)
|
||||||
doc.print(printer);
|
doc.print(printer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeckListModel::pricesUpdated(InnerDecklistNode *node)
|
void DeckListModel::pricesUpdated()
|
||||||
{
|
{
|
||||||
if (!node)
|
emit layoutChanged();
|
||||||
node = root;
|
|
||||||
|
|
||||||
if (node->isEmpty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
emit dataChanged(createIndex(0, 2, node->at(0)), createIndex(node->size() - 1, 2, node->last()));
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ public:
|
||||||
void cleanList();
|
void cleanList();
|
||||||
DeckLoader *getDeckList() const { return deckList; }
|
DeckLoader *getDeckList() const { return deckList; }
|
||||||
void setDeckList(DeckLoader *_deck);
|
void setDeckList(DeckLoader *_deck);
|
||||||
void pricesUpdated(InnerDecklistNode *node = 0);
|
void pricesUpdated();
|
||||||
private:
|
private:
|
||||||
DeckLoader *deckList;
|
DeckLoader *deckList;
|
||||||
InnerDecklistNode *root;
|
InnerDecklistNode *root;
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,10 @@
|
||||||
#include <QUrlQuery>
|
#include <QUrlQuery>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DeckStatsInterface::DeckStatsInterface(QObject *parent)
|
DeckStatsInterface::DeckStatsInterface(
|
||||||
: QObject(parent)
|
CardDatabase &_cardDatabase,
|
||||||
|
QObject *parent
|
||||||
|
) : QObject(parent), cardDatabase(_cardDatabase)
|
||||||
{
|
{
|
||||||
manager = new QNetworkAccessManager(this);
|
manager = new QNetworkAccessManager(this);
|
||||||
connect(manager, SIGNAL(finished(QNetworkReply *)), this, SLOT(queryFinished(QNetworkReply *)));
|
connect(manager, SIGNAL(finished(QNetworkReply *)), this, SLOT(queryFinished(QNetworkReply *)));
|
||||||
|
|
@ -43,24 +45,23 @@ void DeckStatsInterface::queryFinished(QNetworkReply *reply)
|
||||||
deleteLater();
|
deleteLater();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DeckStatsInterface::getAnalyzeRequestData(DeckList *deck, QByteArray *data)
|
||||||
|
{
|
||||||
|
DeckList deckWithoutTokens;
|
||||||
|
copyDeckWithoutTokens(*deck, deckWithoutTokens);
|
||||||
|
|
||||||
#if QT_VERSION < 0x050000
|
#if QT_VERSION < 0x050000
|
||||||
void DeckStatsInterface::getAnalyzeRequestData(DeckList *deck, QByteArray *data)
|
|
||||||
{
|
|
||||||
QUrl params;
|
QUrl params;
|
||||||
params.addQueryItem("deck", deck->writeToString_Plain());
|
params.addQueryItem("deck", deckWithoutTokens.writeToString_Plain());
|
||||||
data->append(params.encodedQuery());
|
data->append(params.encodedQuery());
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
void DeckStatsInterface::getAnalyzeRequestData(DeckList *deck, QByteArray *data)
|
|
||||||
{
|
|
||||||
QUrl params;
|
QUrl params;
|
||||||
QUrlQuery urlQuery;
|
QUrlQuery urlQuery;
|
||||||
urlQuery.addQueryItem("deck", deck->writeToString_Plain());
|
urlQuery.addQueryItem("deck", deckWithoutTokens.writeToString_Plain());
|
||||||
params.setQuery(urlQuery);
|
params.setQuery(urlQuery);
|
||||||
data->append(params.query(QUrl::EncodeReserved));
|
data->append(params.query(QUrl::EncodeReserved));
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void DeckStatsInterface::analyzeDeck(DeckList *deck)
|
void DeckStatsInterface::analyzeDeck(DeckList *deck)
|
||||||
{
|
{
|
||||||
|
|
@ -72,3 +73,34 @@ void DeckStatsInterface::analyzeDeck(DeckList *deck)
|
||||||
|
|
||||||
manager->post(request, data);
|
manager->post(request, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct CopyIfNotAToken {
|
||||||
|
CardDatabase &cardDatabase;
|
||||||
|
DeckList &destination;
|
||||||
|
|
||||||
|
CopyIfNotAToken(
|
||||||
|
CardDatabase &_cardDatabase,
|
||||||
|
DeckList &_destination
|
||||||
|
) : cardDatabase(_cardDatabase), destination(_destination) {};
|
||||||
|
|
||||||
|
void operator()(
|
||||||
|
const InnerDecklistNode *node,
|
||||||
|
const DecklistCardNode *card
|
||||||
|
) const {
|
||||||
|
if (!cardDatabase.getCard(card->getName())->getIsToken()) {
|
||||||
|
DecklistCardNode *addedCard = destination.addCard(
|
||||||
|
card->getName(),
|
||||||
|
node->getName()
|
||||||
|
);
|
||||||
|
addedCard->setNumber(card->getNumber());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void DeckStatsInterface::copyDeckWithoutTokens(
|
||||||
|
const DeckList &source,
|
||||||
|
DeckList &destination
|
||||||
|
) {
|
||||||
|
CopyIfNotAToken copyIfNotAToken(cardDatabase, destination);
|
||||||
|
source.forEachCard(copyIfNotAToken);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
#ifndef DECKSTATS_INTERFACE_H
|
#ifndef DECKSTATS_INTERFACE_H
|
||||||
#define DECKSTATS_INTERFACE_H
|
#define DECKSTATS_INTERFACE_H
|
||||||
|
|
||||||
|
#include "carddatabase.h"
|
||||||
|
#include "decklist.h"
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
class QByteArray;
|
class QByteArray;
|
||||||
|
|
@ -12,11 +14,21 @@ class DeckStatsInterface : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
private:
|
private:
|
||||||
QNetworkAccessManager *manager;
|
QNetworkAccessManager *manager;
|
||||||
|
|
||||||
|
CardDatabase &cardDatabase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deckstats doesn't recognize token cards, and instead tries to find the
|
||||||
|
* closest non-token card instead. So we construct a new deck which has no
|
||||||
|
* tokens.
|
||||||
|
*/
|
||||||
|
void copyDeckWithoutTokens(const DeckList &source, DeckList& destination);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void queryFinished(QNetworkReply *reply);
|
void queryFinished(QNetworkReply *reply);
|
||||||
void getAnalyzeRequestData(DeckList *deck, QByteArray *data);
|
void getAnalyzeRequestData(DeckList *deck, QByteArray *data);
|
||||||
public:
|
public:
|
||||||
DeckStatsInterface(QObject *parent = 0);
|
DeckStatsInterface(CardDatabase &_cardDatabase, QObject *parent = 0);
|
||||||
void analyzeDeck(DeckList *deck);
|
void analyzeDeck(DeckList *deck);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -113,7 +113,7 @@ DlgEditTokens::DlgEditTokens(CardDatabaseModel *_cardDatabaseModel, QWidget *par
|
||||||
setWindowTitle(tr("Edit tokens"));
|
setWindowTitle(tr("Edit tokens"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void DlgEditTokens::tokenSelectionChanged(const QModelIndex ¤t, const QModelIndex &previous)
|
void DlgEditTokens::tokenSelectionChanged(const QModelIndex ¤t, const QModelIndex & /* previous */)
|
||||||
{
|
{
|
||||||
const QModelIndex realIndex = cardDatabaseDisplayModel->mapToSource(current);
|
const QModelIndex realIndex = cardDatabaseDisplayModel->mapToSource(current);
|
||||||
CardInfo *cardInfo = current.row() >= 0 ? cardDatabaseModel->getCard(realIndex.row()) : cardDatabaseModel->getDatabase()->getCard();
|
CardInfo *cardInfo = current.row() >= 0 ? cardDatabaseModel->getCard(realIndex.row()) : cardDatabaseModel->getDatabase()->getCard();
|
||||||
|
|
|
||||||
|
|
@ -9,26 +9,53 @@
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
#include <QGridLayout>
|
#include <QGridLayout>
|
||||||
#include <QDialogButtonBox>
|
#include <QDialogButtonBox>
|
||||||
|
#include <QSettings>
|
||||||
|
#include <QCryptographicHash>
|
||||||
|
|
||||||
DlgFilterGames::DlgFilterGames(const QMap<int, QString> &allGameTypes, QWidget *parent)
|
DlgFilterGames::DlgFilterGames(const QMap<int, QString> &_allGameTypes, QWidget *parent)
|
||||||
: QDialog(parent)
|
: QDialog(parent),
|
||||||
|
allGameTypes(_allGameTypes)
|
||||||
{
|
{
|
||||||
unavailableGamesVisibleCheckBox = new QCheckBox(tr("Show &unavailable games"));
|
QSettings settings;
|
||||||
passwordProtectedGamesVisibleCheckBox = new QCheckBox(tr("Show &password protected games"));
|
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 = new QLineEdit;
|
||||||
|
gameNameFilterEdit->setText(
|
||||||
|
settings.value("game_name_filter", "").toString()
|
||||||
|
);
|
||||||
|
QLabel *gameNameFilterLabel = new QLabel(tr("Game &description:"));
|
||||||
gameNameFilterLabel->setBuddy(gameNameFilterEdit);
|
gameNameFilterLabel->setBuddy(gameNameFilterEdit);
|
||||||
|
|
||||||
QLabel *creatorNameFilterLabel = new QLabel(tr("&Creator name:"));
|
|
||||||
creatorNameFilterEdit = new QLineEdit;
|
creatorNameFilterEdit = new QLineEdit;
|
||||||
|
creatorNameFilterEdit->setText(
|
||||||
|
settings.value("creator_name_filter", "").toString()
|
||||||
|
);
|
||||||
|
QLabel *creatorNameFilterLabel = new QLabel(tr("&Creator name:"));
|
||||||
creatorNameFilterLabel->setBuddy(creatorNameFilterEdit);
|
creatorNameFilterLabel->setBuddy(creatorNameFilterEdit);
|
||||||
|
|
||||||
QVBoxLayout *gameTypeFilterLayout = new QVBoxLayout;
|
QVBoxLayout *gameTypeFilterLayout = new QVBoxLayout;
|
||||||
QMapIterator<int, QString> gameTypesIterator(allGameTypes);
|
QMapIterator<int, QString> gameTypesIterator(allGameTypes);
|
||||||
while (gameTypesIterator.hasNext()) {
|
while (gameTypesIterator.hasNext()) {
|
||||||
gameTypesIterator.next();
|
gameTypesIterator.next();
|
||||||
|
|
||||||
QCheckBox *temp = new QCheckBox(gameTypesIterator.value());
|
QCheckBox *temp = new QCheckBox(gameTypesIterator.value());
|
||||||
|
temp->setChecked(
|
||||||
|
settings.value(
|
||||||
|
"game_type/" + hashGameType(gameTypesIterator.value()),
|
||||||
|
false
|
||||||
|
).toBool()
|
||||||
|
);
|
||||||
|
|
||||||
gameTypeFilterCheckBoxes.insert(gameTypesIterator.key(), temp);
|
gameTypeFilterCheckBoxes.insert(gameTypesIterator.key(), temp);
|
||||||
gameTypeFilterLayout->addWidget(temp);
|
gameTypeFilterLayout->addWidget(temp);
|
||||||
}
|
}
|
||||||
|
|
@ -43,14 +70,18 @@ DlgFilterGames::DlgFilterGames(const QMap<int, QString> &allGameTypes, QWidget *
|
||||||
maxPlayersFilterMinSpinBox = new QSpinBox;
|
maxPlayersFilterMinSpinBox = new QSpinBox;
|
||||||
maxPlayersFilterMinSpinBox->setMinimum(1);
|
maxPlayersFilterMinSpinBox->setMinimum(1);
|
||||||
maxPlayersFilterMinSpinBox->setMaximum(99);
|
maxPlayersFilterMinSpinBox->setMaximum(99);
|
||||||
maxPlayersFilterMinSpinBox->setValue(1);
|
maxPlayersFilterMinSpinBox->setValue(
|
||||||
|
settings.value("min_players", 1).toInt()
|
||||||
|
);
|
||||||
maxPlayersFilterMinLabel->setBuddy(maxPlayersFilterMinSpinBox);
|
maxPlayersFilterMinLabel->setBuddy(maxPlayersFilterMinSpinBox);
|
||||||
|
|
||||||
QLabel *maxPlayersFilterMaxLabel = new QLabel(tr("at &most:"));
|
QLabel *maxPlayersFilterMaxLabel = new QLabel(tr("at &most:"));
|
||||||
maxPlayersFilterMaxSpinBox = new QSpinBox;
|
maxPlayersFilterMaxSpinBox = new QSpinBox;
|
||||||
maxPlayersFilterMaxSpinBox->setMinimum(1);
|
maxPlayersFilterMaxSpinBox->setMinimum(1);
|
||||||
maxPlayersFilterMaxSpinBox->setMaximum(99);
|
maxPlayersFilterMaxSpinBox->setMaximum(99);
|
||||||
maxPlayersFilterMaxSpinBox->setValue(99);
|
maxPlayersFilterMaxSpinBox->setValue(
|
||||||
|
settings.value("max_players", 99).toInt()
|
||||||
|
);
|
||||||
maxPlayersFilterMaxLabel->setBuddy(maxPlayersFilterMaxSpinBox);
|
maxPlayersFilterMaxLabel->setBuddy(maxPlayersFilterMaxSpinBox);
|
||||||
|
|
||||||
QGridLayout *maxPlayersFilterLayout = new QGridLayout;
|
QGridLayout *maxPlayersFilterLayout = new QGridLayout;
|
||||||
|
|
@ -83,7 +114,7 @@ DlgFilterGames::DlgFilterGames(const QMap<int, QString> &allGameTypes, QWidget *
|
||||||
hbox->addLayout(rightColumn);
|
hbox->addLayout(rightColumn);
|
||||||
|
|
||||||
QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
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()));
|
connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
|
||||||
|
|
||||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||||
|
|
@ -94,6 +125,42 @@ DlgFilterGames::DlgFilterGames(const QMap<int, QString> &allGameTypes, QWidget *
|
||||||
setWindowTitle(tr("Filter games"));
|
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<int, QString> gameTypeIterator(allGameTypes);
|
||||||
|
QMapIterator<int, QCheckBox *> 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
|
bool DlgFilterGames::getUnavailableGamesVisible() const
|
||||||
{
|
{
|
||||||
return unavailableGamesVisibleCheckBox->isChecked();
|
return unavailableGamesVisibleCheckBox->isChecked();
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,16 @@ private:
|
||||||
QMap<int, QCheckBox *> gameTypeFilterCheckBoxes;
|
QMap<int, QCheckBox *> gameTypeFilterCheckBoxes;
|
||||||
QSpinBox *maxPlayersFilterMinSpinBox;
|
QSpinBox *maxPlayersFilterMinSpinBox;
|
||||||
QSpinBox *maxPlayersFilterMaxSpinBox;
|
QSpinBox *maxPlayersFilterMaxSpinBox;
|
||||||
|
|
||||||
|
const QMap<int, QString> &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:
|
public:
|
||||||
DlgFilterGames(const QMap<int, QString> &allGameTypes, QWidget *parent = 0);
|
DlgFilterGames(const QMap<int, QString> &allGameTypes, QWidget *parent = 0);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,11 +18,13 @@
|
||||||
#include <QInputDialog>
|
#include <QInputDialog>
|
||||||
#include <QSpinBox>
|
#include <QSpinBox>
|
||||||
#include <QDialogButtonBox>
|
#include <QDialogButtonBox>
|
||||||
|
#include <QRadioButton>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include "carddatabase.h"
|
#include "carddatabase.h"
|
||||||
#include "dlg_settings.h"
|
#include "dlg_settings.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "settingscache.h"
|
#include "settingscache.h"
|
||||||
|
#include "priceupdater.h"
|
||||||
|
|
||||||
GeneralSettingsPage::GeneralSettingsPage()
|
GeneralSettingsPage::GeneralSettingsPage()
|
||||||
{
|
{
|
||||||
|
|
@ -532,8 +534,29 @@ DeckEditorSettingsPage::DeckEditorSettingsPage()
|
||||||
priceTagsCheckBox->setChecked(settingsCache->getPriceTagFeature());
|
priceTagsCheckBox->setChecked(settingsCache->getPriceTagFeature());
|
||||||
connect(priceTagsCheckBox, SIGNAL(stateChanged(int)), settingsCache, SLOT(setPriceTagFeature(int)));
|
connect(priceTagsCheckBox, SIGNAL(stateChanged(int)), settingsCache, SLOT(setPriceTagFeature(int)));
|
||||||
|
|
||||||
|
priceTagSource0 = new QRadioButton;
|
||||||
|
priceTagSource1 = new QRadioButton;
|
||||||
|
|
||||||
|
switch(settingsCache->getPriceTagSource())
|
||||||
|
{
|
||||||
|
case AbstractPriceUpdater::DBPriceSource:
|
||||||
|
priceTagSource1->setChecked(true);
|
||||||
|
break;
|
||||||
|
case AbstractPriceUpdater::BLPPriceSource:
|
||||||
|
default:
|
||||||
|
priceTagSource0->setChecked(true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
connect(priceTagSource0, SIGNAL(toggled(bool)), this, SLOT(radioPriceTagSourceClicked(bool)));
|
||||||
|
connect(priceTagSource1, SIGNAL(toggled(bool)), this, SLOT(radioPriceTagSourceClicked(bool)));
|
||||||
|
|
||||||
|
connect(this, SIGNAL(priceTagSourceChanged(int)), settingsCache, SLOT(setPriceTagSource(int)));
|
||||||
|
|
||||||
QGridLayout *generalGrid = new QGridLayout;
|
QGridLayout *generalGrid = new QGridLayout;
|
||||||
generalGrid->addWidget(priceTagsCheckBox, 0, 0);
|
generalGrid->addWidget(priceTagsCheckBox, 0, 0);
|
||||||
|
generalGrid->addWidget(priceTagSource0, 1, 0);
|
||||||
|
generalGrid->addWidget(priceTagSource1, 2, 0);
|
||||||
|
|
||||||
generalGroupBox = new QGroupBox;
|
generalGroupBox = new QGroupBox;
|
||||||
generalGroupBox->setLayout(generalGrid);
|
generalGroupBox->setLayout(generalGrid);
|
||||||
|
|
@ -546,10 +569,26 @@ DeckEditorSettingsPage::DeckEditorSettingsPage()
|
||||||
|
|
||||||
void DeckEditorSettingsPage::retranslateUi()
|
void DeckEditorSettingsPage::retranslateUi()
|
||||||
{
|
{
|
||||||
priceTagsCheckBox->setText(tr("Enable &price tag feature (using data from blacklotusproject.com)"));
|
priceTagsCheckBox->setText(tr("Enable &price tag feature"));
|
||||||
|
priceTagSource0->setText(tr("using data from blacklotusproject.com"));
|
||||||
|
priceTagSource1->setText(tr("using data from deckbrew.com"));
|
||||||
generalGroupBox->setTitle(tr("General"));
|
generalGroupBox->setTitle(tr("General"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DeckEditorSettingsPage::radioPriceTagSourceClicked(bool checked)
|
||||||
|
{
|
||||||
|
if(!checked)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int source=AbstractPriceUpdater::BLPPriceSource;
|
||||||
|
if(priceTagSource0->isChecked())
|
||||||
|
source=AbstractPriceUpdater::BLPPriceSource;
|
||||||
|
if(priceTagSource1->isChecked())
|
||||||
|
source=AbstractPriceUpdater::DBPriceSource;
|
||||||
|
|
||||||
|
emit priceTagSourceChanged(source);
|
||||||
|
}
|
||||||
|
|
||||||
MessagesSettingsPage::MessagesSettingsPage()
|
MessagesSettingsPage::MessagesSettingsPage()
|
||||||
{
|
{
|
||||||
aAdd = new QAction(this);
|
aAdd = new QAction(this);
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ class QCheckBox;
|
||||||
class QLabel;
|
class QLabel;
|
||||||
class QCloseEvent;
|
class QCloseEvent;
|
||||||
class QSpinBox;
|
class QSpinBox;
|
||||||
|
class QRadioButton;
|
||||||
|
|
||||||
class AbstractSettingsPage : public QWidget {
|
class AbstractSettingsPage : public QWidget {
|
||||||
public:
|
public:
|
||||||
|
|
@ -100,8 +101,13 @@ class DeckEditorSettingsPage : public AbstractSettingsPage {
|
||||||
public:
|
public:
|
||||||
DeckEditorSettingsPage();
|
DeckEditorSettingsPage();
|
||||||
void retranslateUi();
|
void retranslateUi();
|
||||||
|
private slots:
|
||||||
|
void radioPriceTagSourceClicked(bool checked);
|
||||||
|
signals:
|
||||||
|
void priceTagSourceChanged(int _priceTagSource);
|
||||||
private:
|
private:
|
||||||
QCheckBox *priceTagsCheckBox;
|
QCheckBox *priceTagsCheckBox;
|
||||||
|
QRadioButton *priceTagSource0, *priceTagSource1;
|
||||||
QGroupBox *generalGroupBox;
|
QGroupBox *generalGroupBox;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,10 +18,10 @@ public:
|
||||||
virtual void enable() { enabled = true; nodeChanged(); }
|
virtual void enable() { enabled = true; nodeChanged(); }
|
||||||
virtual void disable() { enabled = false; nodeChanged(); }
|
virtual void disable() { enabled = false; nodeChanged(); }
|
||||||
virtual FilterTreeNode *parent() const { return NULL; }
|
virtual FilterTreeNode *parent() const { return NULL; }
|
||||||
virtual FilterTreeNode *nodeAt(int i) const { return NULL; }
|
virtual FilterTreeNode *nodeAt(int /* i */) const { return NULL; }
|
||||||
virtual void deleteAt(int i) {}
|
virtual void deleteAt(int /* i */) {}
|
||||||
virtual int childCount() const { return 0; }
|
virtual int childCount() const { return 0; }
|
||||||
virtual int childIndex(const FilterTreeNode *node) const { return -1; }
|
virtual int childIndex(const FilterTreeNode * /* node */) const { return -1; }
|
||||||
virtual int index() const { return (parent() != NULL)? parent()->childIndex(this) : -1; }
|
virtual int index() const { return (parent() != NULL)? parent()->childIndex(this) : -1; }
|
||||||
virtual QString text() const { return QString(textCStr()); }
|
virtual QString text() const { return QString(textCStr()); }
|
||||||
virtual bool isLeaf() const { return false; }
|
virtual bool isLeaf() const { return false; }
|
||||||
|
|
@ -48,7 +48,7 @@ class FilterTreeBranch : public FilterTreeNode {
|
||||||
protected:
|
protected:
|
||||||
QList<T> childNodes;
|
QList<T> childNodes;
|
||||||
public:
|
public:
|
||||||
~FilterTreeBranch();
|
virtual ~FilterTreeBranch();
|
||||||
FilterTreeNode *nodeAt(int i) const;
|
FilterTreeNode *nodeAt(int i) const;
|
||||||
void deleteAt(int i);
|
void deleteAt(int i);
|
||||||
int childCount() const { return childNodes.size(); }
|
int childCount() const { return childNodes.size(); }
|
||||||
|
|
@ -102,6 +102,7 @@ public:
|
||||||
|
|
||||||
FilterItem(QString trm, FilterItemList *parent)
|
FilterItem(QString trm, FilterItemList *parent)
|
||||||
: p(parent), term(trm) {}
|
: p(parent), term(trm) {}
|
||||||
|
virtual ~FilterItem() {};
|
||||||
|
|
||||||
CardFilter::Attr attr() const { return p->attr(); }
|
CardFilter::Attr attr() const { return p->attr(); }
|
||||||
CardFilter::Type type() const { return p->type; }
|
CardFilter::Type type() const { return p->type; }
|
||||||
|
|
|
||||||
|
|
@ -84,12 +84,6 @@ void GameSelector::actSetFilter()
|
||||||
if (room)
|
if (room)
|
||||||
gameTypeMap = gameListModel->getGameTypes().value(room->getRoomId());
|
gameTypeMap = gameListModel->getGameTypes().value(room->getRoomId());
|
||||||
DlgFilterGames dlg(gameTypeMap, this);
|
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())
|
if (!dlg.exec())
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ ServerInfo_User LocalServer_DatabaseInterface::getUserData(const QString &name,
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
AuthenticationResult LocalServer_DatabaseInterface::checkUserPassword(Server_ProtocolHandler *handler, const QString &user, const QString &password, QString &reasonStr, int &secondsLeft)
|
AuthenticationResult LocalServer_DatabaseInterface::checkUserPassword(Server_ProtocolHandler * /* handler */, const QString & /* user */, const QString & /* password */, QString & /* reasonStr */, int & /* secondsLeft */)
|
||||||
{
|
{
|
||||||
return UnknownUser;
|
return UnknownUser;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@
|
||||||
#include <QIcon>
|
#include <QIcon>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QDesktopServices>
|
#include <QDesktopServices>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "window_main.h"
|
#include "window_main.h"
|
||||||
|
|
@ -158,6 +159,8 @@ int main(int argc, char *argv[])
|
||||||
QDir().mkpath(dataDir + "/pics");
|
QDir().mkpath(dataDir + "/pics");
|
||||||
settingsCache->setPicsPath(dataDir + "/pics");
|
settingsCache->setPicsPath(dataDir + "/pics");
|
||||||
}
|
}
|
||||||
|
if (!QDir().mkpath(settingsCache->getPicsPath() + "/CUSTOM"))
|
||||||
|
qDebug() << "Could not create " + settingsCache->getPicsPath().toUtf8() + "/CUSTOM. Will fall back on default card images.";
|
||||||
|
|
||||||
#ifdef Q_OS_MAC
|
#ifdef Q_OS_MAC
|
||||||
if(settingsCache->getHandBgPath().isEmpty() &&
|
if(settingsCache->getHandBgPath().isEmpty() &&
|
||||||
|
|
|
||||||
|
|
@ -959,6 +959,10 @@ void Player::actCreateToken()
|
||||||
return;
|
return;
|
||||||
|
|
||||||
lastTokenName = dlg.getName();
|
lastTokenName = dlg.getName();
|
||||||
|
if (CardInfo *correctedCard = db->getCardBySimpleName(lastTokenName, false)) {
|
||||||
|
lastTokenName = correctedCard->getName();
|
||||||
|
}
|
||||||
|
|
||||||
lastTokenColor = dlg.getColor();
|
lastTokenColor = dlg.getColor();
|
||||||
lastTokenPT = dlg.getPT();
|
lastTokenPT = dlg.getPT();
|
||||||
lastTokenAnnotation = dlg.getAnnotation();
|
lastTokenAnnotation = dlg.getAnnotation();
|
||||||
|
|
|
||||||
|
|
@ -178,5 +178,5 @@ void PlayerListWidget::showContextMenu(const QPoint &pos, const QModelIndex &ind
|
||||||
int playerId = index.sibling(index.row(), 4).data(Qt::UserRole + 1).toInt();
|
int playerId = index.sibling(index.row(), 4).data(Qt::UserRole + 1).toInt();
|
||||||
UserLevelFlags userLevel(index.sibling(index.row(), 3).data(Qt::UserRole).toInt());
|
UserLevelFlags userLevel(index.sibling(index.row(), 3).data(Qt::UserRole).toInt());
|
||||||
|
|
||||||
userContextMenu->showContextMenu(pos, userName, userLevel, playerId);
|
userContextMenu->showContextMenu(pos, userName, userLevel, true, playerId);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,25 +4,46 @@
|
||||||
*/
|
*/
|
||||||
#include <QNetworkAccessManager>
|
#include <QNetworkAccessManager>
|
||||||
#include <QNetworkReply>
|
#include <QNetworkReply>
|
||||||
|
#include <QMessageBox>
|
||||||
|
|
||||||
#include "qt-json/json.h"
|
#include "qt-json/json.h"
|
||||||
#include "priceupdater.h"
|
#include "priceupdater.h"
|
||||||
|
|
||||||
|
#include "main.h"
|
||||||
|
#include "carddatabase.h"
|
||||||
|
|
||||||
|
#if QT_VERSION < 0x050000
|
||||||
|
// for Qt::escape()
|
||||||
|
#include <QtGui/qtextdocument.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
* @param _deck deck.
|
* @param _deck deck.
|
||||||
*/
|
*/
|
||||||
PriceUpdater::PriceUpdater(const DeckList *_deck)
|
AbstractPriceUpdater::AbstractPriceUpdater(const DeckList *_deck)
|
||||||
{
|
{
|
||||||
nam = new QNetworkAccessManager(this);
|
nam = new QNetworkAccessManager(this);
|
||||||
deck = _deck;
|
deck = _deck;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// blacklotusproject.com
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param _deck deck.
|
||||||
|
*/
|
||||||
|
BLPPriceUpdater::BLPPriceUpdater(const DeckList *_deck)
|
||||||
|
: AbstractPriceUpdater(_deck)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the prices of the cards in deckList.
|
* Update the prices of the cards in deckList.
|
||||||
*/
|
*/
|
||||||
void PriceUpdater::updatePrices()
|
void BLPPriceUpdater::updatePrices()
|
||||||
{
|
{
|
||||||
QString q = "http://blacklotusproject.com/json/?cards=";
|
QString q = "http://blacklotusproject.com/json/?cards=";
|
||||||
QStringList cards = deck->getCardList();
|
QStringList cards = deck->getCardList();
|
||||||
|
|
@ -38,7 +59,7 @@ void PriceUpdater::updatePrices()
|
||||||
/**
|
/**
|
||||||
* Called when the download of the json file with the prices is finished.
|
* Called when the download of the json file with the prices is finished.
|
||||||
*/
|
*/
|
||||||
void PriceUpdater::downloadFinished()
|
void BLPPriceUpdater::downloadFinished()
|
||||||
{
|
{
|
||||||
QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
|
QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
|
||||||
bool ok;
|
bool ok;
|
||||||
|
|
@ -82,3 +103,188 @@ void PriceUpdater::downloadFinished()
|
||||||
deleteLater();
|
deleteLater();
|
||||||
emit finishedUpdate();
|
emit finishedUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// deckbrew.com
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param _deck deck.
|
||||||
|
*/
|
||||||
|
DBPriceUpdater::DBPriceUpdater(const DeckList *_deck)
|
||||||
|
: AbstractPriceUpdater(_deck)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the prices of the cards in deckList.
|
||||||
|
*/
|
||||||
|
void DBPriceUpdater::updatePrices()
|
||||||
|
{
|
||||||
|
QString base = "https://api.deckbrew.com/mtg/cards", q = "";
|
||||||
|
QStringList cards = deck->getCardList();
|
||||||
|
muidMap.clear();
|
||||||
|
urls.clear();
|
||||||
|
CardInfo * card;
|
||||||
|
int muid;
|
||||||
|
SetList sets;
|
||||||
|
bool bNotFirst=false;
|
||||||
|
|
||||||
|
for (int i = 0; i < cards.size(); ++i) {
|
||||||
|
card = db->getCard(cards[i], false);
|
||||||
|
sets = card->getSets();
|
||||||
|
for(int j = 0; j < sets.size(); ++j)
|
||||||
|
{
|
||||||
|
muid=card->getMuId(sets[j]->getShortName());
|
||||||
|
|
||||||
|
if (!muid) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//qDebug() << "muid " << muid << " card: " << cards[i] << endl;
|
||||||
|
if(bNotFirst)
|
||||||
|
{
|
||||||
|
q += QString("&m=%1").arg(muid);
|
||||||
|
} else {
|
||||||
|
q += QString("?m=%1").arg(muid);
|
||||||
|
bNotFirst = true;
|
||||||
|
}
|
||||||
|
muidMap.insert(muid, cards[i]);
|
||||||
|
|
||||||
|
if(q.length() > 240)
|
||||||
|
{
|
||||||
|
urls.append(base + q);
|
||||||
|
bNotFirst=false;
|
||||||
|
q = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(q.length() > 0)
|
||||||
|
urls.append(base + q);
|
||||||
|
|
||||||
|
requestNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DBPriceUpdater::requestNext()
|
||||||
|
{
|
||||||
|
if(urls.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
QUrl url(urls.takeFirst(), QUrl::TolerantMode);
|
||||||
|
//qDebug() << "request prices from: " << url.toString() << endl;
|
||||||
|
QNetworkReply *reply = nam->get(QNetworkRequest(url));
|
||||||
|
connect(reply, SIGNAL(finished()), this, SLOT(downloadFinished()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the download of the json file with the prices is finished.
|
||||||
|
*/
|
||||||
|
void DBPriceUpdater::downloadFinished()
|
||||||
|
{
|
||||||
|
QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
|
||||||
|
bool ok;
|
||||||
|
QString tmp = QString(reply->readAll());
|
||||||
|
|
||||||
|
// Errors are incapsulated in an object, check for them first
|
||||||
|
QVariantMap resultMap = QtJson::Json::parse(tmp, ok).toMap();
|
||||||
|
if (!ok) {
|
||||||
|
QMessageBox::critical(this, tr("Error"), tr("A problem has occured while fetching card prices."));
|
||||||
|
reply->deleteLater();
|
||||||
|
if(urls.isEmpty())
|
||||||
|
{
|
||||||
|
deleteLater();
|
||||||
|
emit finishedUpdate();
|
||||||
|
} else {
|
||||||
|
requestNext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(resultMap.contains("errors"))
|
||||||
|
{
|
||||||
|
QMessageBox::critical(this, tr("Error"), tr("A problem has occured while fetching card prices:") +
|
||||||
|
"<br/>" +
|
||||||
|
#if QT_VERSION < 0x050000
|
||||||
|
Qt::escape(resultMap["errors"].toList().first().toString())
|
||||||
|
#else
|
||||||
|
resultMap["errors"].toList().first().toString().toHtmlEscaped()
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
reply->deleteLater();
|
||||||
|
if(urls.isEmpty())
|
||||||
|
{
|
||||||
|
deleteLater();
|
||||||
|
emit finishedUpdate();
|
||||||
|
} else {
|
||||||
|
requestNext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Good results are a list
|
||||||
|
QVariantList resultList = QtJson::Json::parse(tmp, ok).toList();
|
||||||
|
if (!ok) {
|
||||||
|
QMessageBox::critical(this, tr("Error"), tr("A problem has occured while fetching card prices."));
|
||||||
|
reply->deleteLater();
|
||||||
|
if(urls.isEmpty())
|
||||||
|
{
|
||||||
|
deleteLater();
|
||||||
|
emit finishedUpdate();
|
||||||
|
} else {
|
||||||
|
requestNext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QMap<QString, float> cardsPrice;
|
||||||
|
QListIterator<QVariant> it(resultList);
|
||||||
|
while (it.hasNext()) {
|
||||||
|
QVariantMap cardMap = it.next().toMap();
|
||||||
|
|
||||||
|
|
||||||
|
// get sets list
|
||||||
|
QList<QVariant> editions = cardMap.value("editions").toList();
|
||||||
|
foreach (QVariant ed, editions)
|
||||||
|
{
|
||||||
|
// retrieve card name "as we know it" from the muid
|
||||||
|
QVariantMap edition = ed.toMap();
|
||||||
|
QString set = edition.value("set_id").toString();
|
||||||
|
|
||||||
|
int muid = edition.value("multiverse_id").toString().toInt();
|
||||||
|
if(!muidMap.contains(muid))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
QString name=muidMap.value(muid);
|
||||||
|
// Prices are in USD cents
|
||||||
|
float price = edition.value("price").toMap().value("median").toString().toFloat() / 100;
|
||||||
|
//qDebug() << "card " << name << " set " << set << " price " << price << endl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make sure Masters Edition (MED) isn't the set, as it doesn't
|
||||||
|
* physically exist. Also check the price to see that the cheapest set
|
||||||
|
* ends up as the final price.
|
||||||
|
*/
|
||||||
|
if (set != "MED" && price > 0 && (!cardsPrice.contains(name) || cardsPrice.value(name) > price))
|
||||||
|
cardsPrice.insert(name, price);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
InnerDecklistNode *listRoot = deck->getRoot();
|
||||||
|
for (int i = 0; i < listRoot->size(); i++) {
|
||||||
|
InnerDecklistNode *currentZone = dynamic_cast<InnerDecklistNode *>(listRoot->at(i));
|
||||||
|
for (int j = 0; j < currentZone->size(); j++) {
|
||||||
|
DecklistCardNode *currentCard = dynamic_cast<DecklistCardNode *>(currentZone->at(j));
|
||||||
|
if (!currentCard)
|
||||||
|
continue;
|
||||||
|
float price = cardsPrice[currentCard->getName()];
|
||||||
|
if(price > 0)
|
||||||
|
currentCard->setPrice(price);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
reply->deleteLater();
|
||||||
|
if(urls.isEmpty())
|
||||||
|
{
|
||||||
|
deleteLater();
|
||||||
|
emit finishedUpdate();
|
||||||
|
} else {
|
||||||
|
requestNext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,28 +1,57 @@
|
||||||
#ifndef PRICEUPDATER_H
|
#ifndef PRICEUPDATER_H
|
||||||
#define PRICEUPDATER_H
|
#define PRICEUPDATER_H
|
||||||
|
|
||||||
#include <QNetworkReply>
|
#include <QNetworkAccessManager>
|
||||||
#include "decklist.h"
|
#include "decklist.h"
|
||||||
|
|
||||||
class QNetworkAccessManager;
|
class QNetworkAccessManager;
|
||||||
|
|
||||||
|
// If we don't typedef this, won't compile on OS X < 10.9
|
||||||
|
typedef QMap<int, QString> MuidStringMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Price Updater.
|
* Price Updater.
|
||||||
*
|
*
|
||||||
* @author Marcio Ribeiro <mmr@b1n.org>
|
* @author Marcio Ribeiro <mmr@b1n.org>
|
||||||
*/
|
*/
|
||||||
class PriceUpdater : public QObject
|
class AbstractPriceUpdater : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
private:
|
public:
|
||||||
|
enum PriceSource { BLPPriceSource, DBPriceSource };
|
||||||
|
protected:
|
||||||
const DeckList *deck;
|
const DeckList *deck;
|
||||||
QNetworkAccessManager *nam;
|
QNetworkAccessManager *nam;
|
||||||
signals:
|
signals:
|
||||||
void finishedUpdate();
|
void finishedUpdate();
|
||||||
private slots:
|
protected slots:
|
||||||
void downloadFinished();
|
virtual void downloadFinished() = 0;
|
||||||
public:
|
public:
|
||||||
PriceUpdater(const DeckList *deck);
|
AbstractPriceUpdater(const DeckList *deck);
|
||||||
void updatePrices();
|
virtual void updatePrices() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class BLPPriceUpdater : public AbstractPriceUpdater
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
protected:
|
||||||
|
virtual void downloadFinished();
|
||||||
|
public:
|
||||||
|
BLPPriceUpdater(const DeckList *deck);
|
||||||
|
virtual void updatePrices();
|
||||||
|
};
|
||||||
|
|
||||||
|
class DBPriceUpdater : public AbstractPriceUpdater
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
protected:
|
||||||
|
MuidStringMap muidMap;
|
||||||
|
QList<QString> urls;
|
||||||
|
protected:
|
||||||
|
virtual void downloadFinished();
|
||||||
|
void requestNext();
|
||||||
|
public:
|
||||||
|
DBPriceUpdater(const DeckList *deck);
|
||||||
|
virtual void updatePrices();
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ void ReplayTimelineWidget::setTimeline(const QList<int> &_replayTimeline)
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReplayTimelineWidget::paintEvent(QPaintEvent *event)
|
void ReplayTimelineWidget::paintEvent(QPaintEvent * /* event */)
|
||||||
{
|
{
|
||||||
QPainter painter(this);
|
QPainter painter(this);
|
||||||
painter.drawRect(0, 0, width() - 1, height() - 1);
|
painter.drawRect(0, 0, width() - 1, height() - 1);
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,7 @@ SettingsCache::SettingsCache()
|
||||||
soundPath = settings->value("sound/path").toString();
|
soundPath = settings->value("sound/path").toString();
|
||||||
|
|
||||||
priceTagFeature = settings->value("deckeditor/pricetags", false).toBool();
|
priceTagFeature = settings->value("deckeditor/pricetags", false).toBool();
|
||||||
|
priceTagSource = settings->value("deckeditor/pricetagsource", 0).toInt();
|
||||||
|
|
||||||
ignoreUnregisteredUsers = settings->value("chat/ignore_unregistered", false).toBool();
|
ignoreUnregisteredUsers = settings->value("chat/ignore_unregistered", false).toBool();
|
||||||
}
|
}
|
||||||
|
|
@ -247,6 +248,12 @@ void SettingsCache::setPriceTagFeature(int _priceTagFeature)
|
||||||
emit priceTagFeatureChanged(priceTagFeature);
|
emit priceTagFeatureChanged(priceTagFeature);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SettingsCache::setPriceTagSource(int _priceTagSource)
|
||||||
|
{
|
||||||
|
priceTagSource = _priceTagSource;
|
||||||
|
settings->setValue("deckeditor/pricetagsource", priceTagSource);
|
||||||
|
}
|
||||||
|
|
||||||
void SettingsCache::setIgnoreUnregisteredUsers(bool _ignoreUnregisteredUsers)
|
void SettingsCache::setIgnoreUnregisteredUsers(bool _ignoreUnregisteredUsers)
|
||||||
{
|
{
|
||||||
ignoreUnregisteredUsers = _ignoreUnregisteredUsers;
|
ignoreUnregisteredUsers = _ignoreUnregisteredUsers;
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,7 @@ private:
|
||||||
bool soundEnabled;
|
bool soundEnabled;
|
||||||
QString soundPath;
|
QString soundPath;
|
||||||
bool priceTagFeature;
|
bool priceTagFeature;
|
||||||
|
int priceTagSource;
|
||||||
bool ignoreUnregisteredUsers;
|
bool ignoreUnregisteredUsers;
|
||||||
QString picUrl;
|
QString picUrl;
|
||||||
QString picUrlHq;
|
QString picUrlHq;
|
||||||
|
|
@ -87,6 +88,7 @@ public:
|
||||||
bool getSoundEnabled() const { return soundEnabled; }
|
bool getSoundEnabled() const { return soundEnabled; }
|
||||||
QString getSoundPath() const { return soundPath; }
|
QString getSoundPath() const { return soundPath; }
|
||||||
bool getPriceTagFeature() const { return priceTagFeature; }
|
bool getPriceTagFeature() const { return priceTagFeature; }
|
||||||
|
int getPriceTagSource() const { return priceTagSource; }
|
||||||
bool getIgnoreUnregisteredUsers() const { return ignoreUnregisteredUsers; }
|
bool getIgnoreUnregisteredUsers() const { return ignoreUnregisteredUsers; }
|
||||||
QString getPicUrl() const { return picUrl; }
|
QString getPicUrl() const { return picUrl; }
|
||||||
QString getPicUrlHq() const { return picUrlHq; }
|
QString getPicUrlHq() const { return picUrlHq; }
|
||||||
|
|
@ -121,6 +123,7 @@ public slots:
|
||||||
void setSoundEnabled(int _soundEnabled);
|
void setSoundEnabled(int _soundEnabled);
|
||||||
void setSoundPath(const QString &_soundPath);
|
void setSoundPath(const QString &_soundPath);
|
||||||
void setPriceTagFeature(int _priceTagFeature);
|
void setPriceTagFeature(int _priceTagFeature);
|
||||||
|
void setPriceTagSource(int _priceTagSource);
|
||||||
void setIgnoreUnregisteredUsers(bool _ignoreUnregisteredUsers);
|
void setIgnoreUnregisteredUsers(bool _ignoreUnregisteredUsers);
|
||||||
void setPicUrl(const QString &_picUrl);
|
void setPicUrl(const QString &_picUrl);
|
||||||
void setPicUrlHq(const QString &_picUrlHq);
|
void setPicUrlHq(const QString &_picUrlHq);
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ public:
|
||||||
virtual QString getTabText() const = 0;
|
virtual QString getTabText() const = 0;
|
||||||
virtual void retranslateUi() = 0;
|
virtual void retranslateUi() = 0;
|
||||||
virtual void closeRequest() { }
|
virtual void closeRequest() { }
|
||||||
|
virtual void tabActivated() { }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -512,7 +512,10 @@ void TabDeckEditor::actPrintDeck()
|
||||||
|
|
||||||
void TabDeckEditor::actAnalyzeDeck()
|
void TabDeckEditor::actAnalyzeDeck()
|
||||||
{
|
{
|
||||||
DeckStatsInterface *interface = new DeckStatsInterface(this); // it deletes itself when done
|
DeckStatsInterface *interface = new DeckStatsInterface(
|
||||||
|
*databaseModel->getDatabase(),
|
||||||
|
this
|
||||||
|
); // it deletes itself when done
|
||||||
interface->analyzeDeck(deckModel->getDeckList());
|
interface->analyzeDeck(deckModel->getDeckList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -643,12 +646,25 @@ void TabDeckEditor::actDecrement()
|
||||||
void TabDeckEditor::setPriceTagFeatureEnabled(int enabled)
|
void TabDeckEditor::setPriceTagFeatureEnabled(int enabled)
|
||||||
{
|
{
|
||||||
aUpdatePrices->setVisible(enabled);
|
aUpdatePrices->setVisible(enabled);
|
||||||
|
deckModel->pricesUpdated();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabDeckEditor::actUpdatePrices()
|
void TabDeckEditor::actUpdatePrices()
|
||||||
{
|
{
|
||||||
aUpdatePrices->setDisabled(true);
|
aUpdatePrices->setDisabled(true);
|
||||||
PriceUpdater *up = new PriceUpdater(deckModel->getDeckList());
|
AbstractPriceUpdater *up;
|
||||||
|
|
||||||
|
switch(settingsCache->getPriceTagSource())
|
||||||
|
{
|
||||||
|
case AbstractPriceUpdater::DBPriceSource:
|
||||||
|
up = new DBPriceUpdater(deckModel->getDeckList());
|
||||||
|
break;
|
||||||
|
case AbstractPriceUpdater::BLPPriceSource:
|
||||||
|
default:
|
||||||
|
up = new BLPPriceUpdater(deckModel->getDeckList());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
connect(up, SIGNAL(finishedUpdate()), this, SLOT(finishedUpdatingPrices()));
|
connect(up, SIGNAL(finishedUpdate()), this, SLOT(finishedUpdatingPrices()));
|
||||||
up->updatePrices();
|
up->updatePrices();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -255,7 +255,7 @@ TabGame::TabGame(TabSupervisor *_tabSupervisor, GameReplay *_replay)
|
||||||
|
|
||||||
// Create list: event number -> time [ms]
|
// Create list: event number -> time [ms]
|
||||||
// Distribute simultaneous events evenly across 1 second.
|
// Distribute simultaneous events evenly across 1 second.
|
||||||
int lastEventTimestamp = -1;
|
unsigned int lastEventTimestamp = 0;
|
||||||
const int eventCount = replay->event_list_size();
|
const int eventCount = replay->event_list_size();
|
||||||
for (int i = 0; i < eventCount; ++i) {
|
for (int i = 0; i < eventCount; ++i) {
|
||||||
int j = i + 1;
|
int j = i + 1;
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,12 @@ void TabMessage::retranslateUi()
|
||||||
aLeave->setText(tr("&Leave"));
|
aLeave->setText(tr("&Leave"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TabMessage::tabActivated()
|
||||||
|
{
|
||||||
|
if(!sayEdit->hasFocus())
|
||||||
|
sayEdit->setFocus();
|
||||||
|
}
|
||||||
|
|
||||||
QString TabMessage::getUserName() const
|
QString TabMessage::getUserName() const
|
||||||
{
|
{
|
||||||
return QString::fromStdString(otherUserInfo->name());
|
return QString::fromStdString(otherUserInfo->name());
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ public:
|
||||||
~TabMessage();
|
~TabMessage();
|
||||||
void retranslateUi();
|
void retranslateUi();
|
||||||
void closeRequest();
|
void closeRequest();
|
||||||
|
void tabActivated();
|
||||||
QString getUserName() const;
|
QString getUserName() const;
|
||||||
QString getTabText() const;
|
QString getTabText() const;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -202,7 +202,7 @@ void TabReplays::actDownload()
|
||||||
client->sendCommand(pend);
|
client->sendCommand(pend);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabReplays::downloadFinished(const Response &r, const CommandContainer &commandContainer, const QVariant &extraData)
|
void TabReplays::downloadFinished(const Response &r, const CommandContainer & /* commandContainer */, const QVariant &extraData)
|
||||||
{
|
{
|
||||||
if (r.response_code() != Response::RespOk)
|
if (r.response_code() != Response::RespOk)
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -121,6 +121,12 @@ void TabRoom::closeRequest()
|
||||||
actLeaveRoom();
|
actLeaveRoom();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TabRoom::tabActivated()
|
||||||
|
{
|
||||||
|
if(!sayEdit->hasFocus())
|
||||||
|
sayEdit->setFocus();
|
||||||
|
}
|
||||||
|
|
||||||
QString TabRoom::sanitizeHtml(QString dirty) const
|
QString TabRoom::sanitizeHtml(QString dirty) const
|
||||||
{
|
{
|
||||||
return dirty
|
return dirty
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,7 @@ public:
|
||||||
~TabRoom();
|
~TabRoom();
|
||||||
void retranslateUi();
|
void retranslateUi();
|
||||||
void closeRequest();
|
void closeRequest();
|
||||||
|
void tabActivated();
|
||||||
void processRoomEvent(const RoomEvent &event);
|
void processRoomEvent(const RoomEvent &event);
|
||||||
int getRoomId() const { return roomId; }
|
int getRoomId() const { return roomId; }
|
||||||
const QMap<int, QString> &getGameTypes() const { return gameTypes; }
|
const QMap<int, QString> &getGameTypes() const { return gameTypes; }
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,7 @@ void CloseButton::paintEvent(QPaintEvent * /*event*/)
|
||||||
}
|
}
|
||||||
|
|
||||||
TabSupervisor::TabSupervisor(AbstractClient *_client, QWidget *parent)
|
TabSupervisor::TabSupervisor(AbstractClient *_client, QWidget *parent)
|
||||||
: QTabWidget(parent), userInfo(0), client(_client), tabUserLists(0), tabServer(0), tabDeckStorage(0), tabAdmin(0), tabReplays(0)
|
: QTabWidget(parent), userInfo(0), client(_client), tabServer(0), tabUserLists(0), tabDeckStorage(0), tabReplays(0), tabAdmin(0)
|
||||||
{
|
{
|
||||||
tabChangedIcon = new QIcon(":/resources/icon_tab_changed.svg");
|
tabChangedIcon = new QIcon(":/resources/icon_tab_changed.svg");
|
||||||
setElideMode(Qt::ElideRight);
|
setElideMode(Qt::ElideRight);
|
||||||
|
|
@ -479,6 +479,7 @@ void TabSupervisor::updateCurrent(int index)
|
||||||
tab->setContentsChanged(false);
|
tab->setContentsChanged(false);
|
||||||
}
|
}
|
||||||
emit setMenu(static_cast<Tab *>(widget(index))->getTabMenus());
|
emit setMenu(static_cast<Tab *>(widget(index))->getTabMenus());
|
||||||
|
tab->tabActivated();
|
||||||
} else
|
} else
|
||||||
emit setMenu();
|
emit setMenu();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,7 @@ void UserContextMenu::banUser_dialogFinished()
|
||||||
client->sendCommand(client->prepareModeratorCommand(cmd));
|
client->sendCommand(client->prepareModeratorCommand(cmd));
|
||||||
}
|
}
|
||||||
|
|
||||||
void UserContextMenu::showContextMenu(const QPoint &pos, const QString &userName, UserLevelFlags userLevel, int playerId)
|
void UserContextMenu::showContextMenu(const QPoint &pos, const QString &userName, UserLevelFlags userLevel, bool online, int playerId)
|
||||||
{
|
{
|
||||||
aUserName->setText(userName);
|
aUserName->setText(userName);
|
||||||
|
|
||||||
|
|
@ -132,7 +132,8 @@ void UserContextMenu::showContextMenu(const QPoint &pos, const QString &userName
|
||||||
menu->addAction(aBan);
|
menu->addAction(aBan);
|
||||||
}
|
}
|
||||||
bool anotherUser = userName != QString::fromStdString(tabSupervisor->getUserInfo()->name());
|
bool anotherUser = userName != QString::fromStdString(tabSupervisor->getUserInfo()->name());
|
||||||
aChat->setEnabled(anotherUser);
|
aDetails->setEnabled(online);
|
||||||
|
aChat->setEnabled(anotherUser && online);
|
||||||
aShowGames->setEnabled(anotherUser);
|
aShowGames->setEnabled(anotherUser);
|
||||||
aAddToBuddyList->setEnabled(anotherUser);
|
aAddToBuddyList->setEnabled(anotherUser);
|
||||||
aRemoveFromBuddyList->setEnabled(anotherUser);
|
aRemoveFromBuddyList->setEnabled(anotherUser);
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ private slots:
|
||||||
public:
|
public:
|
||||||
UserContextMenu(const TabSupervisor *_tabSupervisor, QWidget *_parent, TabGame *_game = 0);
|
UserContextMenu(const TabSupervisor *_tabSupervisor, QWidget *_parent, TabGame *_game = 0);
|
||||||
void retranslateUi();
|
void retranslateUi();
|
||||||
void showContextMenu(const QPoint &pos, const QString &userName, UserLevelFlags userLevel, int playerId = -1);
|
void showContextMenu(const QPoint &pos, const QString &userName, UserLevelFlags userLevel, bool online = true, int playerId = -1);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -311,8 +311,9 @@ void UserList::userClicked(QTreeWidgetItem *item, int /*column*/)
|
||||||
void UserList::showContextMenu(const QPoint &pos, const QModelIndex &index)
|
void UserList::showContextMenu(const QPoint &pos, const QModelIndex &index)
|
||||||
{
|
{
|
||||||
const ServerInfo_User &userInfo = static_cast<UserListTWI *>(userTree->topLevelItem(index.row()))->getUserInfo();
|
const ServerInfo_User &userInfo = static_cast<UserListTWI *>(userTree->topLevelItem(index.row()))->getUserInfo();
|
||||||
|
bool online = index.sibling(index.row(), 0).data(Qt::UserRole + 1).toBool();
|
||||||
|
|
||||||
userContextMenu->showContextMenu(pos, QString::fromStdString(userInfo.name()), UserLevelFlags(userInfo.user_level()));
|
userContextMenu->showContextMenu(pos, QString::fromStdString(userInfo.name()), UserLevelFlags(userInfo.user_level()), online);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UserList::sortItems()
|
void UserList::sortItems()
|
||||||
|
|
|
||||||
|
|
@ -241,7 +241,7 @@ void MainWindow::loginError(Response::ResponseCode r, QString reasonStr, quint32
|
||||||
{
|
{
|
||||||
switch (r) {
|
switch (r) {
|
||||||
case Response::RespWrongPassword:
|
case Response::RespWrongPassword:
|
||||||
QMessageBox::critical(this, tr("Error"), tr("Invalid login data."));
|
QMessageBox::critical(this, tr("Error"), tr("Incorrect username or password. Please check your authentication information and try again."));
|
||||||
break;
|
break;
|
||||||
case Response::RespWouldOverwriteOldSession:
|
case Response::RespWouldOverwriteOldSession:
|
||||||
QMessageBox::critical(this, tr("Error"), tr("There is already an active session using this user name.\nPlease close that session first and re-login."));
|
QMessageBox::critical(this, tr("Error"), tr("There is already an active session using this user name.\nPlease close that session first and re-login."));
|
||||||
|
|
|
||||||
|
|
@ -10,26 +10,26 @@
|
||||||
#ifdef QT_GUI_LIB
|
#ifdef QT_GUI_LIB
|
||||||
inline QColor convertColorToQColor(const color &c)
|
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)
|
inline color convertQColorToColor(const QColor &c)
|
||||||
{
|
{
|
||||||
color result;
|
color result;
|
||||||
result.set_r(c.red());
|
result.set_r(c.red());
|
||||||
result.set_g(c.green());
|
result.set_g(c.green());
|
||||||
result.set_b(c.blue());
|
result.set_b(c.blue());
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
inline color makeColor(int r, int g, int b)
|
inline color makeColor(int r, int g, int b)
|
||||||
{
|
{
|
||||||
color result;
|
color result;
|
||||||
result.set_r(r);
|
result.set_r(r);
|
||||||
result.set_g(g);
|
result.set_g(g);
|
||||||
result.set_b(b);
|
result.set_b(b);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -23,152 +23,175 @@ class InnerDecklistNode;
|
||||||
|
|
||||||
class SideboardPlan {
|
class SideboardPlan {
|
||||||
private:
|
private:
|
||||||
QString name;
|
QString name;
|
||||||
QList<MoveCard_ToZone> moveList;
|
QList<MoveCard_ToZone> moveList;
|
||||||
public:
|
public:
|
||||||
SideboardPlan(const QString &_name = QString(), const QList<MoveCard_ToZone> &_moveList = QList<MoveCard_ToZone>());
|
SideboardPlan(const QString &_name = QString(), const QList<MoveCard_ToZone> &_moveList = QList<MoveCard_ToZone>());
|
||||||
bool readElement(QXmlStreamReader *xml);
|
bool readElement(QXmlStreamReader *xml);
|
||||||
void write(QXmlStreamWriter *xml);
|
void write(QXmlStreamWriter *xml);
|
||||||
|
|
||||||
QString getName() const { return name; }
|
QString getName() const { return name; }
|
||||||
const QList<MoveCard_ToZone> &getMoveList() const { return moveList; }
|
const QList<MoveCard_ToZone> &getMoveList() const { return moveList; }
|
||||||
void setMoveList(const QList<MoveCard_ToZone> &_moveList);
|
void setMoveList(const QList<MoveCard_ToZone> &_moveList);
|
||||||
};
|
};
|
||||||
|
|
||||||
enum DeckSortMethod { ByNumber, ByName, ByPrice };
|
enum DeckSortMethod { ByNumber, ByName, ByPrice };
|
||||||
|
|
||||||
class AbstractDecklistNode {
|
class AbstractDecklistNode {
|
||||||
protected:
|
protected:
|
||||||
InnerDecklistNode *parent;
|
InnerDecklistNode *parent;
|
||||||
DeckSortMethod sortMethod;
|
DeckSortMethod sortMethod;
|
||||||
public:
|
public:
|
||||||
AbstractDecklistNode(InnerDecklistNode *_parent = 0);
|
AbstractDecklistNode(InnerDecklistNode *_parent = 0);
|
||||||
virtual ~AbstractDecklistNode() { }
|
virtual ~AbstractDecklistNode() { }
|
||||||
virtual void setSortMethod(DeckSortMethod method) { sortMethod = method; }
|
virtual void setSortMethod(DeckSortMethod method) { sortMethod = method; }
|
||||||
virtual QString getName() const = 0;
|
virtual QString getName() const = 0;
|
||||||
InnerDecklistNode *getParent() const { return parent; }
|
InnerDecklistNode *getParent() const { return parent; }
|
||||||
int depth() const;
|
int depth() const;
|
||||||
virtual int height() const = 0;
|
virtual int height() const = 0;
|
||||||
virtual bool compare(AbstractDecklistNode *other) const = 0;
|
virtual bool compare(AbstractDecklistNode *other) const = 0;
|
||||||
|
|
||||||
virtual bool readElement(QXmlStreamReader *xml) = 0;
|
virtual bool readElement(QXmlStreamReader *xml) = 0;
|
||||||
virtual void writeElement(QXmlStreamWriter *xml) = 0;
|
virtual void writeElement(QXmlStreamWriter *xml) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class InnerDecklistNode : public AbstractDecklistNode, public QList<AbstractDecklistNode *> {
|
class InnerDecklistNode : public AbstractDecklistNode, public QList<AbstractDecklistNode *> {
|
||||||
private:
|
private:
|
||||||
QString name;
|
QString name;
|
||||||
class compareFunctor;
|
class compareFunctor;
|
||||||
public:
|
public:
|
||||||
InnerDecklistNode(const QString &_name = QString(), InnerDecklistNode *_parent = 0) : AbstractDecklistNode(_parent), name(_name) { }
|
InnerDecklistNode(const QString &_name = QString(), InnerDecklistNode *_parent = 0) : AbstractDecklistNode(_parent), name(_name) { }
|
||||||
InnerDecklistNode(InnerDecklistNode *other, InnerDecklistNode *_parent = 0);
|
InnerDecklistNode(InnerDecklistNode *other, InnerDecklistNode *_parent = 0);
|
||||||
virtual ~InnerDecklistNode();
|
virtual ~InnerDecklistNode();
|
||||||
void setSortMethod(DeckSortMethod method);
|
void setSortMethod(DeckSortMethod method);
|
||||||
QString getName() const { return name; }
|
QString getName() const { return name; }
|
||||||
void setName(const QString &_name) { name = _name; }
|
void setName(const QString &_name) { name = _name; }
|
||||||
static QString visibleNameFromName(const QString &_name);
|
static QString visibleNameFromName(const QString &_name);
|
||||||
virtual QString getVisibleName() const;
|
virtual QString getVisibleName() const;
|
||||||
void clearTree();
|
void clearTree();
|
||||||
AbstractDecklistNode *findChild(const QString &name);
|
AbstractDecklistNode *findChild(const QString &name);
|
||||||
int height() const;
|
int height() const;
|
||||||
int recursiveCount(bool countTotalCards = false) const;
|
int recursiveCount(bool countTotalCards = false) const;
|
||||||
float recursivePrice(bool countTotalCards = false) const;
|
float recursivePrice(bool countTotalCards = false) const;
|
||||||
bool compare(AbstractDecklistNode *other) const;
|
bool compare(AbstractDecklistNode *other) const;
|
||||||
bool compareNumber(AbstractDecklistNode *other) const;
|
bool compareNumber(AbstractDecklistNode *other) const;
|
||||||
bool compareName(AbstractDecklistNode *other) const;
|
bool compareName(AbstractDecklistNode *other) const;
|
||||||
bool comparePrice(AbstractDecklistNode *other) const;
|
bool comparePrice(AbstractDecklistNode *other) const;
|
||||||
QVector<QPair<int, int> > sort(Qt::SortOrder order = Qt::AscendingOrder);
|
QVector<QPair<int, int> > sort(Qt::SortOrder order = Qt::AscendingOrder);
|
||||||
|
|
||||||
bool readElement(QXmlStreamReader *xml);
|
bool readElement(QXmlStreamReader *xml);
|
||||||
void writeElement(QXmlStreamWriter *xml);
|
void writeElement(QXmlStreamWriter *xml);
|
||||||
};
|
};
|
||||||
|
|
||||||
class AbstractDecklistCardNode : public AbstractDecklistNode {
|
class AbstractDecklistCardNode : public AbstractDecklistNode {
|
||||||
public:
|
public:
|
||||||
AbstractDecklistCardNode(InnerDecklistNode *_parent = 0) : AbstractDecklistNode(_parent) { }
|
AbstractDecklistCardNode(InnerDecklistNode *_parent = 0) : AbstractDecklistNode(_parent) { }
|
||||||
virtual int getNumber() const = 0;
|
virtual int getNumber() const = 0;
|
||||||
virtual void setNumber(int _number) = 0;
|
virtual void setNumber(int _number) = 0;
|
||||||
virtual QString getName() const = 0;
|
virtual QString getName() const = 0;
|
||||||
virtual void setName(const QString &_name) = 0;
|
virtual void setName(const QString &_name) = 0;
|
||||||
virtual float getPrice() const = 0;
|
virtual float getPrice() const = 0;
|
||||||
virtual void setPrice(const float _price) = 0;
|
virtual void setPrice(const float _price) = 0;
|
||||||
float getTotalPrice() const { return getNumber() * getPrice(); }
|
float getTotalPrice() const { return getNumber() * getPrice(); }
|
||||||
int height() const { return 0; }
|
int height() const { return 0; }
|
||||||
bool compare(AbstractDecklistNode *other) const;
|
bool compare(AbstractDecklistNode *other) const;
|
||||||
bool compareNumber(AbstractDecklistNode *other) const;
|
bool compareNumber(AbstractDecklistNode *other) const;
|
||||||
bool compareName(AbstractDecklistNode *other) const;
|
bool compareName(AbstractDecklistNode *other) const;
|
||||||
bool compareTotalPrice(AbstractDecklistNode *other) const;
|
bool compareTotalPrice(AbstractDecklistNode *other) const;
|
||||||
|
|
||||||
bool readElement(QXmlStreamReader *xml);
|
bool readElement(QXmlStreamReader *xml);
|
||||||
void writeElement(QXmlStreamWriter *xml);
|
void writeElement(QXmlStreamWriter *xml);
|
||||||
};
|
};
|
||||||
|
|
||||||
class DecklistCardNode : public AbstractDecklistCardNode {
|
class DecklistCardNode : public AbstractDecklistCardNode {
|
||||||
private:
|
private:
|
||||||
QString name;
|
QString name;
|
||||||
int number;
|
int number;
|
||||||
float price;
|
float price;
|
||||||
public:
|
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, 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(const QString &_name = QString(), int _number = 1, InnerDecklistNode *_parent = 0) : AbstractDecklistCardNode(_parent), name(_name), number(_number), price(0) { }
|
||||||
DecklistCardNode(DecklistCardNode *other, InnerDecklistNode *_parent);
|
DecklistCardNode(DecklistCardNode *other, InnerDecklistNode *_parent);
|
||||||
int getNumber() const { return number; }
|
int getNumber() const { return number; }
|
||||||
void setNumber(int _number) { number = _number; }
|
void setNumber(int _number) { number = _number; }
|
||||||
QString getName() const { return name; }
|
QString getName() const { return name; }
|
||||||
void setName(const QString &_name) { name = _name; }
|
void setName(const QString &_name) { name = _name; }
|
||||||
float getPrice() const { return price; }
|
float getPrice() const { return price; }
|
||||||
|
|
||||||
void setPrice(const float _price) { price = _price; }
|
void setPrice(const float _price) { price = _price; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class DeckList : public QObject {
|
class DeckList : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
private:
|
private:
|
||||||
QString name, comments;
|
QString name, comments;
|
||||||
QString deckHash;
|
QString deckHash;
|
||||||
QMap<QString, SideboardPlan *> sideboardPlans;
|
QMap<QString, SideboardPlan *> sideboardPlans;
|
||||||
InnerDecklistNode *root;
|
InnerDecklistNode *root;
|
||||||
void getCardListHelper(InnerDecklistNode *node, QSet<QString> &result) const;
|
void getCardListHelper(InnerDecklistNode *node, QSet<QString> &result) const;
|
||||||
signals:
|
signals:
|
||||||
void deckHashChanged();
|
void deckHashChanged();
|
||||||
public slots:
|
public slots:
|
||||||
void setName(const QString &_name = QString()) { name = _name; }
|
void setName(const QString &_name = QString()) { name = _name; }
|
||||||
void setComments(const QString &_comments = QString()) { comments = _comments; }
|
void setComments(const QString &_comments = QString()) { comments = _comments; }
|
||||||
public:
|
public:
|
||||||
DeckList();
|
DeckList();
|
||||||
DeckList(const DeckList &other);
|
DeckList(const DeckList &other);
|
||||||
DeckList(const QString &nativeString);
|
DeckList(const QString &nativeString);
|
||||||
~DeckList();
|
~DeckList();
|
||||||
QString getName() const { return name; }
|
QString getName() const { return name; }
|
||||||
QString getComments() const { return comments; }
|
QString getComments() const { return comments; }
|
||||||
QList<MoveCard_ToZone> getCurrentSideboardPlan();
|
QList<MoveCard_ToZone> getCurrentSideboardPlan();
|
||||||
void setCurrentSideboardPlan(const QList<MoveCard_ToZone> &plan);
|
void setCurrentSideboardPlan(const QList<MoveCard_ToZone> &plan);
|
||||||
const QMap<QString, SideboardPlan *> &getSideboardPlans() const { return sideboardPlans; }
|
const QMap<QString, SideboardPlan *> &getSideboardPlans() const { return sideboardPlans; }
|
||||||
|
|
||||||
bool readElement(QXmlStreamReader *xml);
|
bool readElement(QXmlStreamReader *xml);
|
||||||
void write(QXmlStreamWriter *xml);
|
void write(QXmlStreamWriter *xml);
|
||||||
bool loadFromXml(QXmlStreamReader *xml);
|
bool loadFromXml(QXmlStreamReader *xml);
|
||||||
bool loadFromString_Native(const QString &nativeString);
|
bool loadFromString_Native(const QString &nativeString);
|
||||||
QString writeToString_Native();
|
QString writeToString_Native();
|
||||||
bool loadFromFile_Native(QIODevice *device);
|
bool loadFromFile_Native(QIODevice *device);
|
||||||
bool saveToFile_Native(QIODevice *device);
|
bool saveToFile_Native(QIODevice *device);
|
||||||
bool loadFromStream_Plain(QTextStream &stream);
|
bool loadFromStream_Plain(QTextStream &stream);
|
||||||
bool loadFromFile_Plain(QIODevice *device);
|
bool loadFromFile_Plain(QIODevice *device);
|
||||||
bool saveToStream_Plain(QTextStream &stream);
|
bool saveToStream_Plain(QTextStream &stream);
|
||||||
bool saveToFile_Plain(QIODevice *device);
|
bool saveToFile_Plain(QIODevice *device);
|
||||||
QString writeToString_Plain();
|
QString writeToString_Plain();
|
||||||
|
|
||||||
void cleanList();
|
void cleanList();
|
||||||
bool isEmpty() const { return root->isEmpty() && name.isEmpty() && comments.isEmpty() && sideboardPlans.isEmpty(); }
|
bool isEmpty() const { return root->isEmpty() && name.isEmpty() && comments.isEmpty() && sideboardPlans.isEmpty(); }
|
||||||
QStringList getCardList() const;
|
QStringList getCardList() const;
|
||||||
|
|
||||||
int getSideboardSize() const;
|
int getSideboardSize() const;
|
||||||
|
|
||||||
QString getDeckHash() const { return deckHash; }
|
QString getDeckHash() const { return deckHash; }
|
||||||
void updateDeckHash();
|
void updateDeckHash();
|
||||||
|
|
||||||
InnerDecklistNode *getRoot() const { return root; }
|
InnerDecklistNode *getRoot() const { return root; }
|
||||||
DecklistCardNode *addCard(const QString &cardName, const QString &zoneName);
|
DecklistCardNode *addCard(const QString &cardName, const QString &zoneName);
|
||||||
bool deleteNode(AbstractDecklistNode *node, InnerDecklistNode *rootNode = 0);
|
bool deleteNode(AbstractDecklistNode *node, InnerDecklistNode *rootNode = 0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calls a given function object for each card in the deck. It must
|
||||||
|
* take a InnerDecklistNode* as its first argument and a
|
||||||
|
* DecklistCardNode* as its second.
|
||||||
|
*/
|
||||||
|
template <typename Callback>
|
||||||
|
void forEachCard(Callback &callback) const {
|
||||||
|
// Support for this is only possible if the internal structure
|
||||||
|
// doesn't get more complicated.
|
||||||
|
for (int i = 0; i < root->size(); i++) {
|
||||||
|
const InnerDecklistNode *node =
|
||||||
|
dynamic_cast<InnerDecklistNode *>(root->at(i));
|
||||||
|
for (int j = 0; j < node->size(); j++) {
|
||||||
|
const DecklistCardNode *card =
|
||||||
|
dynamic_cast<DecklistCardNode *>(
|
||||||
|
node->at(j)
|
||||||
|
);
|
||||||
|
callback(node, card);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -4,10 +4,10 @@
|
||||||
|
|
||||||
int getPbExtension(const ::google::protobuf::Message &message)
|
int getPbExtension(const ::google::protobuf::Message &message)
|
||||||
{
|
{
|
||||||
std::vector< const ::google::protobuf::FieldDescriptor * > fieldList;
|
std::vector< const ::google::protobuf::FieldDescriptor * > fieldList;
|
||||||
message.GetReflection()->ListFields(message, &fieldList);
|
message.GetReflection()->ListFields(message, &fieldList);
|
||||||
for (unsigned int j = 0; j < fieldList.size(); ++j)
|
for (unsigned int j = 0; j < fieldList.size(); ++j)
|
||||||
if (fieldList[j]->is_extension())
|
if (fieldList[j]->is_extension())
|
||||||
return fieldList[j]->number();
|
return fieldList[j]->number();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,9 @@
|
||||||
#define GET_PB_EXTENSION_H
|
#define GET_PB_EXTENSION_H
|
||||||
|
|
||||||
namespace google {
|
namespace google {
|
||||||
namespace protobuf {
|
namespace protobuf {
|
||||||
class Message;
|
class Message;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int getPbExtension(const ::google::protobuf::Message &message);
|
int getPbExtension(const ::google::protobuf::Message &message);
|
||||||
|
|
|
||||||
|
|
@ -4,27 +4,27 @@
|
||||||
|
|
||||||
QVector<int> RNG_Abstract::makeNumbersVector(int n, int min, int max)
|
QVector<int> RNG_Abstract::makeNumbersVector(int n, int min, int max)
|
||||||
{
|
{
|
||||||
const int bins = max - min + 1;
|
const int bins = max - min + 1;
|
||||||
QVector<int> result(bins);
|
QVector<int> result(bins);
|
||||||
for (int i = 0; i < n; ++i) {
|
for (int i = 0; i < n; ++i) {
|
||||||
int number = rand(min, max);
|
int number = rand(min, max);
|
||||||
if ((number < min) || (number > max))
|
if ((number < min) || (number > max))
|
||||||
qDebug() << "rand(" << min << "," << max << ") returned " << number;
|
qDebug() << "rand(" << min << "," << max << ") returned " << number;
|
||||||
else
|
else
|
||||||
result[number - min]++;
|
result[number - min]++;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
double RNG_Abstract::testRandom(const QVector<int> &numbers) const
|
double RNG_Abstract::testRandom(const QVector<int> &numbers) const
|
||||||
{
|
{
|
||||||
int n = 0;
|
int n = 0;
|
||||||
for (int i = 0; i < numbers.size(); ++i)
|
for (int i = 0; i < numbers.size(); ++i)
|
||||||
n += numbers[i];
|
n += numbers[i];
|
||||||
double expected = (double) n / (double) numbers.size();
|
double expected = (double) n / (double) numbers.size();
|
||||||
double chisq = 0;
|
double chisq = 0;
|
||||||
for (int i = 0; i < numbers.size(); ++i)
|
for (int i = 0; i < numbers.size(); ++i)
|
||||||
chisq += ((double) numbers[i] - expected) * ((double) numbers[i] - expected) / expected;
|
chisq += ((double) numbers[i] - expected) * ((double) numbers[i] - expected) / expected;
|
||||||
|
|
||||||
return chisq;
|
return chisq;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,12 +5,12 @@
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
|
|
||||||
class RNG_Abstract : public QObject {
|
class RNG_Abstract : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
RNG_Abstract(QObject *parent = 0) : QObject(parent) { }
|
RNG_Abstract(QObject *parent = 0) : QObject(parent) { }
|
||||||
virtual unsigned int rand(int min, int max) = 0;
|
virtual unsigned int rand(int min, int max) = 0;
|
||||||
QVector<int> makeNumbersVector(int n, int min, int max);
|
QVector<int> makeNumbersVector(int n, int min, int max);
|
||||||
double testRandom(const QVector<int> &numbers) const;
|
double testRandom(const QVector<int> &numbers) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern RNG_Abstract *rng;
|
extern RNG_Abstract *rng;
|
||||||
|
|
|
||||||
|
|
@ -11,10 +11,10 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
RNG_SFMT::RNG_SFMT(QObject *parent)
|
RNG_SFMT::RNG_SFMT(QObject *parent)
|
||||||
: RNG_Abstract(parent)
|
: RNG_Abstract(parent)
|
||||||
{
|
{
|
||||||
// initialize the random number generator with a 32bit integer seed (timestamp)
|
// initialize the random number generator with a 32bit integer seed (timestamp)
|
||||||
sfmt_init_gen_rand(&sfmt, QDateTime::currentDateTime().toTime_t());
|
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.
|
* There has been no use for negative random numbers with rand() though, so it's treated as error.
|
||||||
*/
|
*/
|
||||||
if(min < 0) {
|
if(min < 0) {
|
||||||
throw std::invalid_argument(
|
throw std::invalid_argument(
|
||||||
QString("Invalid bounds for RNG: Got min " +
|
QString("Invalid bounds for RNG: Got min " +
|
||||||
QString::number(min) + " < 0!\n").toStdString());
|
QString::number(min) + " < 0!\n").toStdString());
|
||||||
// at this point, the method exits. No return value is needed, because
|
// at this point, the method exits. No return value is needed, because
|
||||||
// basically the exception itself is returned.
|
// basically the exception itself is returned.
|
||||||
}
|
}
|
||||||
|
|
||||||
// For complete fairness and equal timing, this should be a roll, but let's skip it anyway
|
// 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)
|
unsigned int RNG_SFMT::cdf(unsigned int min, unsigned int max)
|
||||||
{
|
{
|
||||||
// This all makes no sense if min > max, which should never happen.
|
// This all makes no sense if min > max, which should never happen.
|
||||||
if(min > max) {
|
if(min > max) {
|
||||||
throw std::invalid_argument(
|
throw std::invalid_argument(
|
||||||
QString("Invalid bounds for RNG: min > max! Values were: min = " +
|
QString("Invalid bounds for RNG: min > max! Values were: min = " +
|
||||||
QString::number(min) + ", max = " +
|
QString::number(min) + ", max = " +
|
||||||
QString::number(max)).toStdString());
|
QString::number(max)).toStdString());
|
||||||
// at this point, the method exits. No return value is needed, because
|
// at this point, the method exits. No return value is needed, because
|
||||||
// basically the exception itself is returned.
|
// basically the exception itself is returned.
|
||||||
}
|
}
|
||||||
|
|
||||||
// First compute the diameter (aka size, length) of the [min, max] interval
|
// First compute the diameter (aka size, length) of the [min, max] interval
|
||||||
const unsigned int diameter = max - min + 1;
|
const unsigned int diameter = max - min + 1;
|
||||||
|
|
||||||
// Compute how many buckets (each in size of the diameter) will fit into the
|
// Compute how many buckets (each in size of the diameter) will fit into the
|
||||||
// universe.
|
// universe.
|
||||||
// If the division has a remainder, the result is floored automatically.
|
// If the division has a remainder, the result is floored automatically.
|
||||||
const uint64_t buckets = UINT64_MAX / diameter;
|
const uint64_t buckets = UINT64_MAX / diameter;
|
||||||
|
|
||||||
// Compute the last valid random number. All numbers beyond have to be ignored.
|
// 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.
|
// If there was no remainder in the previous step, limit is equal to UINT64_MAX.
|
||||||
const uint64_t limit = diameter * buckets;
|
const uint64_t limit = diameter * buckets;
|
||||||
|
|
||||||
uint64_t rand;
|
uint64_t rand;
|
||||||
// To make the random number generation thread-safe, a mutex is created around
|
// 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.
|
// the generation. Outside of the loop of course, to avoid lock/unlock overhead.
|
||||||
mutex.lock();
|
mutex.lock();
|
||||||
do {
|
do {
|
||||||
rand = sfmt_genrand_uint64(&sfmt);
|
rand = sfmt_genrand_uint64(&sfmt);
|
||||||
} while (rand >= limit);
|
} while (rand >= limit);
|
||||||
mutex.unlock();
|
mutex.unlock();
|
||||||
|
|
||||||
// Now determine the bucket containing the SFMT() random number and after adding
|
// Now determine the bucket containing the SFMT() random number and after adding
|
||||||
// the lower bound, a random number from [min, max] can be returned.
|
// the lower bound, a random number from [min, max] can be returned.
|
||||||
return (unsigned int) (rand / buckets + min);
|
return (unsigned int) (rand / buckets + min);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,15 +26,15 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class RNG_SFMT : public RNG_Abstract {
|
class RNG_SFMT : public RNG_Abstract {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
private:
|
private:
|
||||||
QMutex mutex;
|
QMutex mutex;
|
||||||
sfmt_t sfmt;
|
sfmt_t sfmt;
|
||||||
// The discrete cumulative distribution function for the RNG
|
// The discrete cumulative distribution function for the RNG
|
||||||
unsigned int cdf(unsigned int min, unsigned int max);
|
unsigned int cdf(unsigned int min, unsigned int max);
|
||||||
public:
|
public:
|
||||||
RNG_SFMT(QObject *parent = 0);
|
RNG_SFMT(QObject *parent = 0);
|
||||||
unsigned int rand(int min, int max);
|
unsigned int rand(int min, int max);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -36,18 +36,18 @@
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
Server::Server(bool _threaded, QObject *parent)
|
Server::Server(bool _threaded, QObject *parent)
|
||||||
: QObject(parent), threaded(_threaded), nextLocalGameId(0)
|
: QObject(parent), threaded(_threaded), nextLocalGameId(0)
|
||||||
{
|
{
|
||||||
qRegisterMetaType<ServerInfo_Game>("ServerInfo_Game");
|
qRegisterMetaType<ServerInfo_Game>("ServerInfo_Game");
|
||||||
qRegisterMetaType<ServerInfo_Room>("ServerInfo_Room");
|
qRegisterMetaType<ServerInfo_Room>("ServerInfo_Room");
|
||||||
qRegisterMetaType<ServerInfo_User>("ServerInfo_User");
|
qRegisterMetaType<ServerInfo_User>("ServerInfo_User");
|
||||||
qRegisterMetaType<CommandContainer>("CommandContainer");
|
qRegisterMetaType<CommandContainer>("CommandContainer");
|
||||||
qRegisterMetaType<Response>("Response");
|
qRegisterMetaType<Response>("Response");
|
||||||
qRegisterMetaType<GameEventContainer>("GameEventContainer");
|
qRegisterMetaType<GameEventContainer>("GameEventContainer");
|
||||||
qRegisterMetaType<IslMessage>("IslMessage");
|
qRegisterMetaType<IslMessage>("IslMessage");
|
||||||
qRegisterMetaType<Command_JoinGame>("Command_JoinGame");
|
qRegisterMetaType<Command_JoinGame>("Command_JoinGame");
|
||||||
|
|
||||||
connect(this, SIGNAL(sigSendIslMessage(IslMessage, int)), this, SLOT(doSendIslMessage(IslMessage, int)), Qt::QueuedConnection);
|
connect(this, SIGNAL(sigSendIslMessage(IslMessage, int)), this, SLOT(doSendIslMessage(IslMessage, int)), Qt::QueuedConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
Server::~Server()
|
Server::~Server()
|
||||||
|
|
@ -56,532 +56,532 @@ Server::~Server()
|
||||||
|
|
||||||
void Server::prepareDestroy()
|
void Server::prepareDestroy()
|
||||||
{
|
{
|
||||||
// dirty :(
|
// dirty :(
|
||||||
if (threaded) {
|
if (threaded) {
|
||||||
clientsLock.lockForRead();
|
clientsLock.lockForRead();
|
||||||
for (int i = 0; i < clients.size(); ++i)
|
for (int i = 0; i < clients.size(); ++i)
|
||||||
QMetaObject::invokeMethod(clients.at(i), "prepareDestroy", Qt::QueuedConnection);
|
QMetaObject::invokeMethod(clients.at(i), "prepareDestroy", Qt::QueuedConnection);
|
||||||
clientsLock.unlock();
|
clientsLock.unlock();
|
||||||
|
|
||||||
bool done = false;
|
bool done = false;
|
||||||
|
|
||||||
class SleeperThread : public QThread
|
class SleeperThread : public QThread
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static void msleep(unsigned long msecs) { QThread::usleep(msecs); }
|
static void msleep(unsigned long msecs) { QThread::usleep(msecs); }
|
||||||
};
|
};
|
||||||
|
|
||||||
do {
|
do {
|
||||||
SleeperThread::msleep(10);
|
SleeperThread::msleep(10);
|
||||||
clientsLock.lockForRead();
|
clientsLock.lockForRead();
|
||||||
if (clients.isEmpty())
|
if (clients.isEmpty())
|
||||||
done = true;
|
done = true;
|
||||||
clientsLock.unlock();
|
clientsLock.unlock();
|
||||||
} while (!done);
|
} while (!done);
|
||||||
} else {
|
} else {
|
||||||
// no locking is needed in unthreaded mode
|
// no locking is needed in unthreaded mode
|
||||||
while (!clients.isEmpty())
|
while (!clients.isEmpty())
|
||||||
clients.first()->prepareDestroy();
|
clients.first()->prepareDestroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
roomsLock.lockForWrite();
|
roomsLock.lockForWrite();
|
||||||
QMapIterator<int, Server_Room *> roomIterator(rooms);
|
QMapIterator<int, Server_Room *> roomIterator(rooms);
|
||||||
while (roomIterator.hasNext())
|
while (roomIterator.hasNext())
|
||||||
delete roomIterator.next().value();
|
delete roomIterator.next().value();
|
||||||
rooms.clear();
|
rooms.clear();
|
||||||
roomsLock.unlock();
|
roomsLock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::setDatabaseInterface(Server_DatabaseInterface *_databaseInterface)
|
void Server::setDatabaseInterface(Server_DatabaseInterface *_databaseInterface)
|
||||||
{
|
{
|
||||||
connect(this, SIGNAL(endSession(qint64)), _databaseInterface, SLOT(endSession(qint64)));
|
connect(this, SIGNAL(endSession(qint64)), _databaseInterface, SLOT(endSession(qint64)));
|
||||||
databaseInterfaces.insert(QThread::currentThread(), _databaseInterface);
|
databaseInterfaces.insert(QThread::currentThread(), _databaseInterface);
|
||||||
}
|
}
|
||||||
|
|
||||||
Server_DatabaseInterface *Server::getDatabaseInterface() const
|
Server_DatabaseInterface *Server::getDatabaseInterface() const
|
||||||
{
|
{
|
||||||
return databaseInterfaces.value(QThread::currentThread());
|
return databaseInterfaces.value(QThread::currentThread());
|
||||||
}
|
}
|
||||||
|
|
||||||
AuthenticationResult Server::loginUser(Server_ProtocolHandler *session, QString &name, const QString &password, QString &reasonStr, int &secondsLeft)
|
AuthenticationResult Server::loginUser(Server_ProtocolHandler *session, QString &name, const QString &password, QString &reasonStr, int &secondsLeft)
|
||||||
{
|
{
|
||||||
if (name.size() > 35)
|
if (name.size() > 35)
|
||||||
name = name.left(35);
|
name = name.left(35);
|
||||||
|
|
||||||
Server_DatabaseInterface *databaseInterface = getDatabaseInterface();
|
Server_DatabaseInterface *databaseInterface = getDatabaseInterface();
|
||||||
|
|
||||||
QWriteLocker locker(&clientsLock);
|
QWriteLocker locker(&clientsLock);
|
||||||
|
|
||||||
AuthenticationResult authState = databaseInterface->checkUserPassword(session, name, password, reasonStr, secondsLeft);
|
AuthenticationResult authState = databaseInterface->checkUserPassword(session, name, password, reasonStr, secondsLeft);
|
||||||
if ((authState == NotLoggedIn) || (authState == UserIsBanned || authState == UsernameInvalid))
|
if ((authState == NotLoggedIn) || (authState == UserIsBanned || authState == UsernameInvalid))
|
||||||
return authState;
|
return authState;
|
||||||
|
|
||||||
ServerInfo_User data = databaseInterface->getUserData(name, true);
|
ServerInfo_User data = databaseInterface->getUserData(name, true);
|
||||||
data.set_address(session->getAddress().toStdString());
|
data.set_address(session->getAddress().toStdString());
|
||||||
name = QString::fromStdString(data.name()); // Compensate for case indifference
|
name = QString::fromStdString(data.name()); // Compensate for case indifference
|
||||||
|
|
||||||
databaseInterface->lockSessionTables();
|
databaseInterface->lockSessionTables();
|
||||||
|
|
||||||
if (authState == PasswordRight) {
|
if (authState == PasswordRight) {
|
||||||
if (users.contains(name) || databaseInterface->userSessionExists(name)) {
|
if (users.contains(name) || databaseInterface->userSessionExists(name)) {
|
||||||
qDebug("Login denied: would overwrite old session");
|
qDebug("Login denied: would overwrite old session");
|
||||||
databaseInterface->unlockSessionTables();
|
databaseInterface->unlockSessionTables();
|
||||||
return WouldOverwriteOldSession;
|
return WouldOverwriteOldSession;
|
||||||
}
|
}
|
||||||
} else if (authState == UnknownUser) {
|
} else if (authState == UnknownUser) {
|
||||||
// Change user name so that no two users have the same names,
|
// Change user name so that no two users have the same names,
|
||||||
// don't interfere with registered user names though.
|
// don't interfere with registered user names though.
|
||||||
QString tempName = name;
|
QString tempName = name;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (users.contains(tempName) || databaseInterface->userExists(tempName) || databaseInterface->userSessionExists(tempName))
|
while (users.contains(tempName) || databaseInterface->userExists(tempName) || databaseInterface->userSessionExists(tempName))
|
||||||
tempName = name + "_" + QString::number(++i);
|
tempName = name + "_" + QString::number(++i);
|
||||||
name = tempName;
|
name = tempName;
|
||||||
data.set_name(name.toStdString());
|
data.set_name(name.toStdString());
|
||||||
}
|
}
|
||||||
|
|
||||||
users.insert(name, session);
|
users.insert(name, session);
|
||||||
qDebug() << "Server::loginUser:" << session << "name=" << name;
|
qDebug() << "Server::loginUser:" << session << "name=" << name;
|
||||||
|
|
||||||
data.set_session_id(databaseInterface->startSession(name, session->getAddress()));
|
data.set_session_id(databaseInterface->startSession(name, session->getAddress()));
|
||||||
databaseInterface->unlockSessionTables();
|
databaseInterface->unlockSessionTables();
|
||||||
|
|
||||||
usersBySessionId.insert(data.session_id(), session);
|
usersBySessionId.insert(data.session_id(), session);
|
||||||
|
|
||||||
qDebug() << "session id:" << data.session_id();
|
qDebug() << "session id:" << data.session_id();
|
||||||
session->setUserInfo(data);
|
session->setUserInfo(data);
|
||||||
|
|
||||||
Event_UserJoined event;
|
Event_UserJoined event;
|
||||||
event.mutable_user_info()->CopyFrom(session->copyUserInfo(false));
|
event.mutable_user_info()->CopyFrom(session->copyUserInfo(false));
|
||||||
SessionEvent *se = Server_ProtocolHandler::prepareSessionEvent(event);
|
SessionEvent *se = Server_ProtocolHandler::prepareSessionEvent(event);
|
||||||
for (int i = 0; i < clients.size(); ++i)
|
for (int i = 0; i < clients.size(); ++i)
|
||||||
if (clients[i]->getAcceptsUserListChanges())
|
if (clients[i]->getAcceptsUserListChanges())
|
||||||
clients[i]->sendProtocolItem(*se);
|
clients[i]->sendProtocolItem(*se);
|
||||||
delete se;
|
delete se;
|
||||||
|
|
||||||
event.mutable_user_info()->CopyFrom(session->copyUserInfo(true, true, true));
|
event.mutable_user_info()->CopyFrom(session->copyUserInfo(true, true, true));
|
||||||
locker.unlock();
|
locker.unlock();
|
||||||
|
|
||||||
se = Server_ProtocolHandler::prepareSessionEvent(event);
|
se = Server_ProtocolHandler::prepareSessionEvent(event);
|
||||||
sendIsl_SessionEvent(*se);
|
sendIsl_SessionEvent(*se);
|
||||||
delete se;
|
delete se;
|
||||||
|
|
||||||
return authState;
|
return authState;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::addPersistentPlayer(const QString &userName, int roomId, int gameId, int playerId)
|
void Server::addPersistentPlayer(const QString &userName, int roomId, int gameId, int playerId)
|
||||||
{
|
{
|
||||||
QWriteLocker locker(&persistentPlayersLock);
|
QWriteLocker locker(&persistentPlayersLock);
|
||||||
persistentPlayers.insert(userName, PlayerReference(roomId, gameId, playerId));
|
persistentPlayers.insert(userName, PlayerReference(roomId, gameId, playerId));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::removePersistentPlayer(const QString &userName, int roomId, int gameId, int playerId)
|
void Server::removePersistentPlayer(const QString &userName, int roomId, int gameId, int playerId)
|
||||||
{
|
{
|
||||||
QWriteLocker locker(&persistentPlayersLock);
|
QWriteLocker locker(&persistentPlayersLock);
|
||||||
persistentPlayers.remove(userName, PlayerReference(roomId, gameId, playerId));
|
persistentPlayers.remove(userName, PlayerReference(roomId, gameId, playerId));
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<PlayerReference> Server::getPersistentPlayerReferences(const QString &userName) const
|
QList<PlayerReference> Server::getPersistentPlayerReferences(const QString &userName) const
|
||||||
{
|
{
|
||||||
QReadLocker locker(&persistentPlayersLock);
|
QReadLocker locker(&persistentPlayersLock);
|
||||||
return persistentPlayers.values(userName);
|
return persistentPlayers.values(userName);
|
||||||
}
|
}
|
||||||
|
|
||||||
Server_AbstractUserInterface *Server::findUser(const QString &userName) const
|
Server_AbstractUserInterface *Server::findUser(const QString &userName) const
|
||||||
{
|
{
|
||||||
// Call this only with clientsLock set.
|
// Call this only with clientsLock set.
|
||||||
|
|
||||||
Server_AbstractUserInterface *userHandler = users.value(userName);
|
Server_AbstractUserInterface *userHandler = users.value(userName);
|
||||||
if (userHandler)
|
if (userHandler)
|
||||||
return userHandler;
|
return userHandler;
|
||||||
else
|
else
|
||||||
return externalUsers.value(userName);
|
return externalUsers.value(userName);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::addClient(Server_ProtocolHandler *client)
|
void Server::addClient(Server_ProtocolHandler *client)
|
||||||
{
|
{
|
||||||
QWriteLocker locker(&clientsLock);
|
QWriteLocker locker(&clientsLock);
|
||||||
clients << client;
|
clients << client;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::removeClient(Server_ProtocolHandler *client)
|
void Server::removeClient(Server_ProtocolHandler *client)
|
||||||
{
|
{
|
||||||
QWriteLocker locker(&clientsLock);
|
QWriteLocker locker(&clientsLock);
|
||||||
clients.removeAt(clients.indexOf(client));
|
clients.removeAt(clients.indexOf(client));
|
||||||
ServerInfo_User *data = client->getUserInfo();
|
ServerInfo_User *data = client->getUserInfo();
|
||||||
if (data) {
|
if (data) {
|
||||||
Event_UserLeft event;
|
Event_UserLeft event;
|
||||||
event.set_name(data->name());
|
event.set_name(data->name());
|
||||||
SessionEvent *se = Server_ProtocolHandler::prepareSessionEvent(event);
|
SessionEvent *se = Server_ProtocolHandler::prepareSessionEvent(event);
|
||||||
for (int i = 0; i < clients.size(); ++i)
|
for (int i = 0; i < clients.size(); ++i)
|
||||||
if (clients[i]->getAcceptsUserListChanges())
|
if (clients[i]->getAcceptsUserListChanges())
|
||||||
clients[i]->sendProtocolItem(*se);
|
clients[i]->sendProtocolItem(*se);
|
||||||
sendIsl_SessionEvent(*se);
|
sendIsl_SessionEvent(*se);
|
||||||
delete se;
|
delete se;
|
||||||
|
|
||||||
users.remove(QString::fromStdString(data->name()));
|
users.remove(QString::fromStdString(data->name()));
|
||||||
qDebug() << "Server::removeClient: name=" << QString::fromStdString(data->name());
|
qDebug() << "Server::removeClient: name=" << QString::fromStdString(data->name());
|
||||||
|
|
||||||
if (data->has_session_id()) {
|
if (data->has_session_id()) {
|
||||||
const qint64 sessionId = data->session_id();
|
const qint64 sessionId = data->session_id();
|
||||||
usersBySessionId.remove(sessionId);
|
usersBySessionId.remove(sessionId);
|
||||||
emit endSession(sessionId);
|
emit endSession(sessionId);
|
||||||
qDebug() << "closed session id:" << sessionId;
|
qDebug() << "closed session id:" << sessionId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
qDebug() << "Server::removeClient: removed" << (void *) client << ";" << clients.size() << "clients; " << users.size() << "users left";
|
qDebug() << "Server::removeClient: removed" << (void *) client << ";" << clients.size() << "clients; " << users.size() << "users left";
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::externalUserJoined(const ServerInfo_User &userInfo)
|
void Server::externalUserJoined(const ServerInfo_User &userInfo)
|
||||||
{
|
{
|
||||||
// This function is always called from the main thread via signal/slot.
|
// This function is always called from the main thread via signal/slot.
|
||||||
clientsLock.lockForWrite();
|
clientsLock.lockForWrite();
|
||||||
|
|
||||||
Server_RemoteUserInterface *newUser = new Server_RemoteUserInterface(this, ServerInfo_User_Container(userInfo));
|
Server_RemoteUserInterface *newUser = new Server_RemoteUserInterface(this, ServerInfo_User_Container(userInfo));
|
||||||
externalUsers.insert(QString::fromStdString(userInfo.name()), newUser);
|
externalUsers.insert(QString::fromStdString(userInfo.name()), newUser);
|
||||||
externalUsersBySessionId.insert(userInfo.session_id(), newUser);
|
externalUsersBySessionId.insert(userInfo.session_id(), newUser);
|
||||||
|
|
||||||
Event_UserJoined event;
|
Event_UserJoined event;
|
||||||
event.mutable_user_info()->CopyFrom(userInfo);
|
event.mutable_user_info()->CopyFrom(userInfo);
|
||||||
|
|
||||||
SessionEvent *se = Server_ProtocolHandler::prepareSessionEvent(event);
|
SessionEvent *se = Server_ProtocolHandler::prepareSessionEvent(event);
|
||||||
for (int i = 0; i < clients.size(); ++i)
|
for (int i = 0; i < clients.size(); ++i)
|
||||||
if (clients[i]->getAcceptsUserListChanges())
|
if (clients[i]->getAcceptsUserListChanges())
|
||||||
clients[i]->sendProtocolItem(*se);
|
clients[i]->sendProtocolItem(*se);
|
||||||
delete se;
|
delete se;
|
||||||
clientsLock.unlock();
|
clientsLock.unlock();
|
||||||
|
|
||||||
ResponseContainer rc(-1);
|
ResponseContainer rc(-1);
|
||||||
newUser->joinPersistentGames(rc);
|
newUser->joinPersistentGames(rc);
|
||||||
newUser->sendResponseContainer(rc, Response::RespNothing);
|
newUser->sendResponseContainer(rc, Response::RespNothing);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::externalUserLeft(const QString &userName)
|
void Server::externalUserLeft(const QString &userName)
|
||||||
{
|
{
|
||||||
// This function is always called from the main thread via signal/slot.
|
// This function is always called from the main thread via signal/slot.
|
||||||
|
|
||||||
clientsLock.lockForWrite();
|
clientsLock.lockForWrite();
|
||||||
Server_AbstractUserInterface *user = externalUsers.take(userName);
|
Server_AbstractUserInterface *user = externalUsers.take(userName);
|
||||||
externalUsersBySessionId.remove(user->getUserInfo()->session_id());
|
externalUsersBySessionId.remove(user->getUserInfo()->session_id());
|
||||||
clientsLock.unlock();
|
clientsLock.unlock();
|
||||||
|
|
||||||
QMap<int, QPair<int, int> > userGames(user->getGames());
|
QMap<int, QPair<int, int> > userGames(user->getGames());
|
||||||
QMapIterator<int, QPair<int, int> > userGamesIterator(userGames);
|
QMapIterator<int, QPair<int, int> > userGamesIterator(userGames);
|
||||||
roomsLock.lockForRead();
|
roomsLock.lockForRead();
|
||||||
while (userGamesIterator.hasNext()) {
|
while (userGamesIterator.hasNext()) {
|
||||||
userGamesIterator.next();
|
userGamesIterator.next();
|
||||||
Server_Room *room = rooms.value(userGamesIterator.value().first);
|
Server_Room *room = rooms.value(userGamesIterator.value().first);
|
||||||
if (!room)
|
if (!room)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
QReadLocker roomGamesLocker(&room->gamesLock);
|
QReadLocker roomGamesLocker(&room->gamesLock);
|
||||||
Server_Game *game = room->getGames().value(userGamesIterator.key());
|
Server_Game *game = room->getGames().value(userGamesIterator.key());
|
||||||
if (!game)
|
if (!game)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
QMutexLocker gameLocker(&game->gameMutex);
|
QMutexLocker gameLocker(&game->gameMutex);
|
||||||
Server_Player *player = game->getPlayers().value(userGamesIterator.value().second);
|
Server_Player *player = game->getPlayers().value(userGamesIterator.value().second);
|
||||||
if (!player)
|
if (!player)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
player->disconnectClient();
|
player->disconnectClient();
|
||||||
}
|
}
|
||||||
roomsLock.unlock();
|
roomsLock.unlock();
|
||||||
|
|
||||||
delete user;
|
delete user;
|
||||||
|
|
||||||
Event_UserLeft event;
|
Event_UserLeft event;
|
||||||
event.set_name(userName.toStdString());
|
event.set_name(userName.toStdString());
|
||||||
|
|
||||||
SessionEvent *se = Server_ProtocolHandler::prepareSessionEvent(event);
|
SessionEvent *se = Server_ProtocolHandler::prepareSessionEvent(event);
|
||||||
clientsLock.lockForRead();
|
clientsLock.lockForRead();
|
||||||
for (int i = 0; i < clients.size(); ++i)
|
for (int i = 0; i < clients.size(); ++i)
|
||||||
if (clients[i]->getAcceptsUserListChanges())
|
if (clients[i]->getAcceptsUserListChanges())
|
||||||
clients[i]->sendProtocolItem(*se);
|
clients[i]->sendProtocolItem(*se);
|
||||||
clientsLock.unlock();
|
clientsLock.unlock();
|
||||||
delete se;
|
delete se;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::externalRoomUserJoined(int roomId, const ServerInfo_User &userInfo)
|
void Server::externalRoomUserJoined(int roomId, const ServerInfo_User &userInfo)
|
||||||
{
|
{
|
||||||
// This function is always called from the main thread via signal/slot.
|
// This function is always called from the main thread via signal/slot.
|
||||||
QReadLocker locker(&roomsLock);
|
QReadLocker locker(&roomsLock);
|
||||||
|
|
||||||
Server_Room *room = rooms.value(roomId);
|
Server_Room *room = rooms.value(roomId);
|
||||||
if (!room) {
|
if (!room) {
|
||||||
qDebug() << "externalRoomUserJoined: room id=" << roomId << "not found";
|
qDebug() << "externalRoomUserJoined: room id=" << roomId << "not found";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
room->addExternalUser(userInfo);
|
room->addExternalUser(userInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::externalRoomUserLeft(int roomId, const QString &userName)
|
void Server::externalRoomUserLeft(int roomId, const QString &userName)
|
||||||
{
|
{
|
||||||
// This function is always called from the main thread via signal/slot.
|
// This function is always called from the main thread via signal/slot.
|
||||||
QReadLocker locker(&roomsLock);
|
QReadLocker locker(&roomsLock);
|
||||||
|
|
||||||
Server_Room *room = rooms.value(roomId);
|
Server_Room *room = rooms.value(roomId);
|
||||||
if (!room) {
|
if (!room) {
|
||||||
qDebug() << "externalRoomUserLeft: room id=" << roomId << "not found";
|
qDebug() << "externalRoomUserLeft: room id=" << roomId << "not found";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
room->removeExternalUser(userName);
|
room->removeExternalUser(userName);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::externalRoomSay(int roomId, const QString &userName, const QString &message)
|
void Server::externalRoomSay(int roomId, const QString &userName, const QString &message)
|
||||||
{
|
{
|
||||||
// This function is always called from the main thread via signal/slot.
|
// This function is always called from the main thread via signal/slot.
|
||||||
QReadLocker locker(&roomsLock);
|
QReadLocker locker(&roomsLock);
|
||||||
|
|
||||||
Server_Room *room = rooms.value(roomId);
|
Server_Room *room = rooms.value(roomId);
|
||||||
if (!room) {
|
if (!room) {
|
||||||
qDebug() << "externalRoomSay: room id=" << roomId << "not found";
|
qDebug() << "externalRoomSay: room id=" << roomId << "not found";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
room->say(userName, message, false);
|
room->say(userName, message, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::externalRoomGameListChanged(int roomId, const ServerInfo_Game &gameInfo)
|
void Server::externalRoomGameListChanged(int roomId, const ServerInfo_Game &gameInfo)
|
||||||
{
|
{
|
||||||
// This function is always called from the main thread via signal/slot.
|
// This function is always called from the main thread via signal/slot.
|
||||||
QReadLocker locker(&roomsLock);
|
QReadLocker locker(&roomsLock);
|
||||||
|
|
||||||
Server_Room *room = rooms.value(roomId);
|
Server_Room *room = rooms.value(roomId);
|
||||||
if (!room) {
|
if (!room) {
|
||||||
qDebug() << "externalRoomGameListChanged: room id=" << roomId << "not found";
|
qDebug() << "externalRoomGameListChanged: room id=" << roomId << "not found";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
room->updateExternalGameList(gameInfo);
|
room->updateExternalGameList(gameInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::externalJoinGameCommandReceived(const Command_JoinGame &cmd, int cmdId, int roomId, int serverId, qint64 sessionId)
|
void Server::externalJoinGameCommandReceived(const Command_JoinGame &cmd, int cmdId, int roomId, int serverId, qint64 sessionId)
|
||||||
{
|
{
|
||||||
// This function is always called from the main thread via signal/slot.
|
// This function is always called from the main thread via signal/slot.
|
||||||
|
|
||||||
try {
|
try {
|
||||||
QReadLocker roomsLocker(&roomsLock);
|
QReadLocker roomsLocker(&roomsLock);
|
||||||
QReadLocker clientsLocker(&clientsLock);
|
QReadLocker clientsLocker(&clientsLock);
|
||||||
|
|
||||||
Server_Room *room = rooms.value(roomId);
|
Server_Room *room = rooms.value(roomId);
|
||||||
if (!room) {
|
if (!room) {
|
||||||
qDebug() << "externalJoinGameCommandReceived: room id=" << roomId << "not found";
|
qDebug() << "externalJoinGameCommandReceived: room id=" << roomId << "not found";
|
||||||
throw Response::RespNotInRoom;
|
throw Response::RespNotInRoom;
|
||||||
}
|
}
|
||||||
Server_AbstractUserInterface *userInterface = externalUsersBySessionId.value(sessionId);
|
Server_AbstractUserInterface *userInterface = externalUsersBySessionId.value(sessionId);
|
||||||
if (!userInterface) {
|
if (!userInterface) {
|
||||||
qDebug() << "externalJoinGameCommandReceived: session id=" << sessionId << "not found";
|
qDebug() << "externalJoinGameCommandReceived: session id=" << sessionId << "not found";
|
||||||
throw Response::RespNotInRoom;
|
throw Response::RespNotInRoom;
|
||||||
}
|
}
|
||||||
|
|
||||||
ResponseContainer responseContainer(cmdId);
|
ResponseContainer responseContainer(cmdId);
|
||||||
Response::ResponseCode responseCode = room->processJoinGameCommand(cmd, responseContainer, userInterface);
|
Response::ResponseCode responseCode = room->processJoinGameCommand(cmd, responseContainer, userInterface);
|
||||||
userInterface->sendResponseContainer(responseContainer, responseCode);
|
userInterface->sendResponseContainer(responseContainer, responseCode);
|
||||||
} catch (Response::ResponseCode code) {
|
} catch (Response::ResponseCode code) {
|
||||||
Response response;
|
Response response;
|
||||||
response.set_cmd_id(cmdId);
|
response.set_cmd_id(cmdId);
|
||||||
response.set_response_code(code);
|
response.set_response_code(code);
|
||||||
|
|
||||||
sendIsl_Response(response, serverId, sessionId);
|
sendIsl_Response(response, serverId, sessionId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::externalGameCommandContainerReceived(const CommandContainer &cont, int playerId, int serverId, qint64 sessionId)
|
void Server::externalGameCommandContainerReceived(const CommandContainer &cont, int playerId, int serverId, qint64 sessionId)
|
||||||
{
|
{
|
||||||
// This function is always called from the main thread via signal/slot.
|
// This function is always called from the main thread via signal/slot.
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ResponseContainer responseContainer(cont.cmd_id());
|
ResponseContainer responseContainer(cont.cmd_id());
|
||||||
Response::ResponseCode finalResponseCode = Response::RespOk;
|
Response::ResponseCode finalResponseCode = Response::RespOk;
|
||||||
|
|
||||||
QReadLocker roomsLocker(&roomsLock);
|
QReadLocker roomsLocker(&roomsLock);
|
||||||
Server_Room *room = rooms.value(cont.room_id());
|
Server_Room *room = rooms.value(cont.room_id());
|
||||||
if (!room) {
|
if (!room) {
|
||||||
qDebug() << "externalGameCommandContainerReceived: room id=" << cont.room_id() << "not found";
|
qDebug() << "externalGameCommandContainerReceived: room id=" << cont.room_id() << "not found";
|
||||||
throw Response::RespNotInRoom;
|
throw Response::RespNotInRoom;
|
||||||
}
|
}
|
||||||
|
|
||||||
QReadLocker roomGamesLocker(&room->gamesLock);
|
QReadLocker roomGamesLocker(&room->gamesLock);
|
||||||
Server_Game *game = room->getGames().value(cont.game_id());
|
Server_Game *game = room->getGames().value(cont.game_id());
|
||||||
if (!game) {
|
if (!game) {
|
||||||
qDebug() << "externalGameCommandContainerReceived: game id=" << cont.game_id() << "not found";
|
qDebug() << "externalGameCommandContainerReceived: game id=" << cont.game_id() << "not found";
|
||||||
throw Response::RespNotInRoom;
|
throw Response::RespNotInRoom;
|
||||||
}
|
}
|
||||||
|
|
||||||
QMutexLocker gameLocker(&game->gameMutex);
|
QMutexLocker gameLocker(&game->gameMutex);
|
||||||
Server_Player *player = game->getPlayers().value(playerId);
|
Server_Player *player = game->getPlayers().value(playerId);
|
||||||
if (!player) {
|
if (!player) {
|
||||||
qDebug() << "externalGameCommandContainerReceived: player id=" << playerId << "not found";
|
qDebug() << "externalGameCommandContainerReceived: player id=" << playerId << "not found";
|
||||||
throw Response::RespNotInRoom;
|
throw Response::RespNotInRoom;
|
||||||
}
|
}
|
||||||
|
|
||||||
GameEventStorage ges;
|
GameEventStorage ges;
|
||||||
for (int i = cont.game_command_size() - 1; i >= 0; --i) {
|
for (int i = cont.game_command_size() - 1; i >= 0; --i) {
|
||||||
const GameCommand &sc = cont.game_command(i);
|
const GameCommand &sc = cont.game_command(i);
|
||||||
qDebug() << "[ISL]" << QString::fromStdString(sc.ShortDebugString());
|
qDebug() << "[ISL]" << QString::fromStdString(sc.ShortDebugString());
|
||||||
|
|
||||||
Response::ResponseCode resp = player->processGameCommand(sc, responseContainer, ges);
|
Response::ResponseCode resp = player->processGameCommand(sc, responseContainer, ges);
|
||||||
|
|
||||||
if (resp != Response::RespOk)
|
if (resp != Response::RespOk)
|
||||||
finalResponseCode = resp;
|
finalResponseCode = resp;
|
||||||
}
|
}
|
||||||
ges.sendToGame(game);
|
ges.sendToGame(game);
|
||||||
|
|
||||||
if (finalResponseCode != Response::RespNothing) {
|
if (finalResponseCode != Response::RespNothing) {
|
||||||
player->playerMutex.lock();
|
player->playerMutex.lock();
|
||||||
player->getUserInterface()->sendResponseContainer(responseContainer, finalResponseCode);
|
player->getUserInterface()->sendResponseContainer(responseContainer, finalResponseCode);
|
||||||
player->playerMutex.unlock();
|
player->playerMutex.unlock();
|
||||||
}
|
}
|
||||||
} catch (Response::ResponseCode code) {
|
} catch (Response::ResponseCode code) {
|
||||||
Response response;
|
Response response;
|
||||||
response.set_cmd_id(cont.cmd_id());
|
response.set_cmd_id(cont.cmd_id());
|
||||||
response.set_response_code(code);
|
response.set_response_code(code);
|
||||||
|
|
||||||
sendIsl_Response(response, serverId, sessionId);
|
sendIsl_Response(response, serverId, sessionId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::externalGameEventContainerReceived(const GameEventContainer &cont, qint64 sessionId)
|
void Server::externalGameEventContainerReceived(const GameEventContainer &cont, qint64 sessionId)
|
||||||
{
|
{
|
||||||
// This function is always called from the main thread via signal/slot.
|
// This function is always called from the main thread via signal/slot.
|
||||||
|
|
||||||
QReadLocker usersLocker(&clientsLock);
|
QReadLocker usersLocker(&clientsLock);
|
||||||
|
|
||||||
Server_ProtocolHandler *client = usersBySessionId.value(sessionId);
|
Server_ProtocolHandler *client = usersBySessionId.value(sessionId);
|
||||||
if (!client) {
|
if (!client) {
|
||||||
qDebug() << "externalGameEventContainerReceived: session" << sessionId << "not found";
|
qDebug() << "externalGameEventContainerReceived: session" << sessionId << "not found";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
client->sendProtocolItem(cont);
|
client->sendProtocolItem(cont);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::externalResponseReceived(const Response &resp, qint64 sessionId)
|
void Server::externalResponseReceived(const Response &resp, qint64 sessionId)
|
||||||
{
|
{
|
||||||
// This function is always called from the main thread via signal/slot.
|
// This function is always called from the main thread via signal/slot.
|
||||||
|
|
||||||
QReadLocker usersLocker(&clientsLock);
|
QReadLocker usersLocker(&clientsLock);
|
||||||
|
|
||||||
Server_ProtocolHandler *client = usersBySessionId.value(sessionId);
|
Server_ProtocolHandler *client = usersBySessionId.value(sessionId);
|
||||||
if (!client) {
|
if (!client) {
|
||||||
qDebug() << "externalResponseReceived: session" << sessionId << "not found";
|
qDebug() << "externalResponseReceived: session" << sessionId << "not found";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
client->sendProtocolItem(resp);
|
client->sendProtocolItem(resp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::broadcastRoomUpdate(const ServerInfo_Room &roomInfo, bool sendToIsl)
|
void Server::broadcastRoomUpdate(const ServerInfo_Room &roomInfo, bool sendToIsl)
|
||||||
{
|
{
|
||||||
// This function is always called from the main thread via signal/slot.
|
// This function is always called from the main thread via signal/slot.
|
||||||
|
|
||||||
Event_ListRooms event;
|
Event_ListRooms event;
|
||||||
event.add_room_list()->CopyFrom(roomInfo);
|
event.add_room_list()->CopyFrom(roomInfo);
|
||||||
|
|
||||||
SessionEvent *se = Server_ProtocolHandler::prepareSessionEvent(event);
|
SessionEvent *se = Server_ProtocolHandler::prepareSessionEvent(event);
|
||||||
|
|
||||||
clientsLock.lockForRead();
|
clientsLock.lockForRead();
|
||||||
for (int i = 0; i < clients.size(); ++i)
|
for (int i = 0; i < clients.size(); ++i)
|
||||||
if (clients[i]->getAcceptsRoomListChanges())
|
if (clients[i]->getAcceptsRoomListChanges())
|
||||||
clients[i]->sendProtocolItem(*se);
|
clients[i]->sendProtocolItem(*se);
|
||||||
clientsLock.unlock();
|
clientsLock.unlock();
|
||||||
|
|
||||||
if (sendToIsl)
|
if (sendToIsl)
|
||||||
sendIsl_SessionEvent(*se);
|
sendIsl_SessionEvent(*se);
|
||||||
|
|
||||||
delete se;
|
delete se;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::addRoom(Server_Room *newRoom)
|
void Server::addRoom(Server_Room *newRoom)
|
||||||
{
|
{
|
||||||
QWriteLocker locker(&roomsLock);
|
QWriteLocker locker(&roomsLock);
|
||||||
qDebug() << "Adding room: ID=" << newRoom->getId() << "name=" << newRoom->getName();
|
qDebug() << "Adding room: ID=" << newRoom->getId() << "name=" << newRoom->getName();
|
||||||
rooms.insert(newRoom->getId(), newRoom);
|
rooms.insert(newRoom->getId(), newRoom);
|
||||||
connect(newRoom, SIGNAL(roomInfoChanged(ServerInfo_Room)), this, SLOT(broadcastRoomUpdate(const ServerInfo_Room &)), Qt::QueuedConnection);
|
connect(newRoom, SIGNAL(roomInfoChanged(ServerInfo_Room)), this, SLOT(broadcastRoomUpdate(const ServerInfo_Room &)), Qt::QueuedConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Server::getUsersCount() const
|
int Server::getUsersCount() const
|
||||||
{
|
{
|
||||||
QReadLocker locker(&clientsLock);
|
QReadLocker locker(&clientsLock);
|
||||||
return users.size();
|
return users.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
int Server::getGamesCount() const
|
int Server::getGamesCount() const
|
||||||
{
|
{
|
||||||
int result = 0;
|
int result = 0;
|
||||||
QReadLocker locker(&roomsLock);
|
QReadLocker locker(&roomsLock);
|
||||||
QMapIterator<int, Server_Room *> roomIterator(rooms);
|
QMapIterator<int, Server_Room *> roomIterator(rooms);
|
||||||
while (roomIterator.hasNext()) {
|
while (roomIterator.hasNext()) {
|
||||||
Server_Room *room = roomIterator.next().value();
|
Server_Room *room = roomIterator.next().value();
|
||||||
QReadLocker roomLocker(&room->gamesLock);
|
QReadLocker roomLocker(&room->gamesLock);
|
||||||
result += room->getGames().size();
|
result += room->getGames().size();
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::sendIsl_Response(const Response &item, int serverId, qint64 sessionId)
|
void Server::sendIsl_Response(const Response &item, int serverId, qint64 sessionId)
|
||||||
{
|
{
|
||||||
IslMessage msg;
|
IslMessage msg;
|
||||||
msg.set_message_type(IslMessage::RESPONSE);
|
msg.set_message_type(IslMessage::RESPONSE);
|
||||||
if (sessionId != -1)
|
if (sessionId != -1)
|
||||||
msg.set_session_id(sessionId);
|
msg.set_session_id(sessionId);
|
||||||
msg.mutable_response()->CopyFrom(item);
|
msg.mutable_response()->CopyFrom(item);
|
||||||
|
|
||||||
emit sigSendIslMessage(msg, serverId);
|
emit sigSendIslMessage(msg, serverId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::sendIsl_SessionEvent(const SessionEvent &item, int serverId, qint64 sessionId)
|
void Server::sendIsl_SessionEvent(const SessionEvent &item, int serverId, qint64 sessionId)
|
||||||
{
|
{
|
||||||
IslMessage msg;
|
IslMessage msg;
|
||||||
msg.set_message_type(IslMessage::SESSION_EVENT);
|
msg.set_message_type(IslMessage::SESSION_EVENT);
|
||||||
if (sessionId != -1)
|
if (sessionId != -1)
|
||||||
msg.set_session_id(sessionId);
|
msg.set_session_id(sessionId);
|
||||||
msg.mutable_session_event()->CopyFrom(item);
|
msg.mutable_session_event()->CopyFrom(item);
|
||||||
|
|
||||||
emit sigSendIslMessage(msg, serverId);
|
emit sigSendIslMessage(msg, serverId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::sendIsl_GameEventContainer(const GameEventContainer &item, int serverId, qint64 sessionId)
|
void Server::sendIsl_GameEventContainer(const GameEventContainer &item, int serverId, qint64 sessionId)
|
||||||
{
|
{
|
||||||
IslMessage msg;
|
IslMessage msg;
|
||||||
msg.set_message_type(IslMessage::GAME_EVENT_CONTAINER);
|
msg.set_message_type(IslMessage::GAME_EVENT_CONTAINER);
|
||||||
if (sessionId != -1)
|
if (sessionId != -1)
|
||||||
msg.set_session_id(sessionId);
|
msg.set_session_id(sessionId);
|
||||||
msg.mutable_game_event_container()->CopyFrom(item);
|
msg.mutable_game_event_container()->CopyFrom(item);
|
||||||
|
|
||||||
emit sigSendIslMessage(msg, serverId);
|
emit sigSendIslMessage(msg, serverId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::sendIsl_RoomEvent(const RoomEvent &item, int serverId, qint64 sessionId)
|
void Server::sendIsl_RoomEvent(const RoomEvent &item, int serverId, qint64 sessionId)
|
||||||
{
|
{
|
||||||
IslMessage msg;
|
IslMessage msg;
|
||||||
msg.set_message_type(IslMessage::ROOM_EVENT);
|
msg.set_message_type(IslMessage::ROOM_EVENT);
|
||||||
if (sessionId != -1)
|
if (sessionId != -1)
|
||||||
msg.set_session_id(sessionId);
|
msg.set_session_id(sessionId);
|
||||||
msg.mutable_room_event()->CopyFrom(item);
|
msg.mutable_room_event()->CopyFrom(item);
|
||||||
|
|
||||||
emit sigSendIslMessage(msg, serverId);
|
emit sigSendIslMessage(msg, serverId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::sendIsl_GameCommand(const CommandContainer &item, int serverId, qint64 sessionId, int roomId, int playerId)
|
void Server::sendIsl_GameCommand(const CommandContainer &item, int serverId, qint64 sessionId, int roomId, int playerId)
|
||||||
{
|
{
|
||||||
IslMessage msg;
|
IslMessage msg;
|
||||||
msg.set_message_type(IslMessage::GAME_COMMAND_CONTAINER);
|
msg.set_message_type(IslMessage::GAME_COMMAND_CONTAINER);
|
||||||
msg.set_session_id(sessionId);
|
msg.set_session_id(sessionId);
|
||||||
msg.set_player_id(playerId);
|
msg.set_player_id(playerId);
|
||||||
|
|
||||||
CommandContainer *cont = msg.mutable_game_command();
|
CommandContainer *cont = msg.mutable_game_command();
|
||||||
cont->CopyFrom(item);
|
cont->CopyFrom(item);
|
||||||
cont->set_room_id(roomId);
|
cont->set_room_id(roomId);
|
||||||
|
|
||||||
emit sigSendIslMessage(msg, serverId);
|
emit sigSendIslMessage(msg, serverId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::sendIsl_RoomCommand(const CommandContainer &item, int serverId, qint64 sessionId, int roomId)
|
void Server::sendIsl_RoomCommand(const CommandContainer &item, int serverId, qint64 sessionId, int roomId)
|
||||||
{
|
{
|
||||||
IslMessage msg;
|
IslMessage msg;
|
||||||
msg.set_message_type(IslMessage::ROOM_COMMAND_CONTAINER);
|
msg.set_message_type(IslMessage::ROOM_COMMAND_CONTAINER);
|
||||||
msg.set_session_id(sessionId);
|
msg.set_session_id(sessionId);
|
||||||
|
|
||||||
CommandContainer *cont = msg.mutable_room_command();
|
CommandContainer *cont = msg.mutable_room_command();
|
||||||
cont->CopyFrom(item);
|
cont->CopyFrom(item);
|
||||||
cont->set_room_id(roomId);
|
cont->set_room_id(roomId);
|
||||||
|
|
||||||
emit sigSendIslMessage(msg, serverId);
|
emit sigSendIslMessage(msg, serverId);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
134
common/server.h
134
common/server.h
|
|
@ -31,87 +31,87 @@ enum AuthenticationResult { NotLoggedIn = 0, PasswordRight = 1, UnknownUser = 2,
|
||||||
|
|
||||||
class Server : public QObject
|
class Server : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
signals:
|
signals:
|
||||||
void pingClockTimeout();
|
void pingClockTimeout();
|
||||||
void sigSendIslMessage(const IslMessage &message, int serverId);
|
void sigSendIslMessage(const IslMessage &message, int serverId);
|
||||||
void endSession(qint64 sessionId);
|
void endSession(qint64 sessionId);
|
||||||
private slots:
|
private slots:
|
||||||
void broadcastRoomUpdate(const ServerInfo_Room &roomInfo, bool sendToIsl = false);
|
void broadcastRoomUpdate(const ServerInfo_Room &roomInfo, bool sendToIsl = false);
|
||||||
public:
|
public:
|
||||||
mutable QReadWriteLock clientsLock, roomsLock; // locking order: roomsLock before clientsLock
|
mutable QReadWriteLock clientsLock, roomsLock; // locking order: roomsLock before clientsLock
|
||||||
Server(bool _threaded, QObject *parent = 0);
|
Server(bool _threaded, QObject *parent = 0);
|
||||||
~Server();
|
~Server();
|
||||||
void setThreaded(bool _threaded) { threaded = _threaded; }
|
void setThreaded(bool _threaded) { threaded = _threaded; }
|
||||||
AuthenticationResult loginUser(Server_ProtocolHandler *session, QString &name, const QString &password, QString &reason, int &secondsLeft);
|
AuthenticationResult loginUser(Server_ProtocolHandler *session, QString &name, const QString &password, QString &reason, int &secondsLeft);
|
||||||
const QMap<int, Server_Room *> &getRooms() { return rooms; }
|
const QMap<int, Server_Room *> &getRooms() { return rooms; }
|
||||||
|
|
||||||
Server_AbstractUserInterface *findUser(const QString &userName) const;
|
Server_AbstractUserInterface *findUser(const QString &userName) const;
|
||||||
const QMap<QString, Server_ProtocolHandler *> &getUsers() const { return users; }
|
const QMap<QString, Server_ProtocolHandler *> &getUsers() const { return users; }
|
||||||
const QMap<qint64, Server_ProtocolHandler *> &getUsersBySessionId() const { return usersBySessionId; }
|
const QMap<qint64, Server_ProtocolHandler *> &getUsersBySessionId() const { return usersBySessionId; }
|
||||||
void addClient(Server_ProtocolHandler *player);
|
void addClient(Server_ProtocolHandler *player);
|
||||||
void removeClient(Server_ProtocolHandler *player);
|
void removeClient(Server_ProtocolHandler *player);
|
||||||
virtual QString getLoginMessage() const { return QString(); }
|
virtual QString getLoginMessage() const { return QString(); }
|
||||||
|
|
||||||
virtual bool getGameShouldPing() const { return false; }
|
virtual bool getGameShouldPing() const { return false; }
|
||||||
virtual int getMaxGameInactivityTime() const { return 9999999; }
|
virtual int getMaxGameInactivityTime() const { return 9999999; }
|
||||||
virtual int getMaxPlayerInactivityTime() const { return 9999999; }
|
virtual int getMaxPlayerInactivityTime() const { return 9999999; }
|
||||||
virtual int getMessageCountingInterval() const { return 0; }
|
virtual int getMessageCountingInterval() const { return 0; }
|
||||||
virtual int getMaxMessageCountPerInterval() const { return 0; }
|
virtual int getMaxMessageCountPerInterval() const { return 0; }
|
||||||
virtual int getMaxMessageSizePerInterval() const { return 0; }
|
virtual int getMaxMessageSizePerInterval() const { return 0; }
|
||||||
virtual int getMaxGamesPerUser() const { return 0; }
|
virtual int getMaxGamesPerUser() const { return 0; }
|
||||||
virtual bool getThreaded() const { return false; }
|
virtual bool getThreaded() const { return false; }
|
||||||
|
|
||||||
Server_DatabaseInterface *getDatabaseInterface() const;
|
Server_DatabaseInterface *getDatabaseInterface() const;
|
||||||
int getNextLocalGameId() { QMutexLocker locker(&nextLocalGameIdMutex); return ++nextLocalGameId; }
|
int getNextLocalGameId() { QMutexLocker locker(&nextLocalGameIdMutex); return ++nextLocalGameId; }
|
||||||
|
|
||||||
void sendIsl_Response(const Response &item, int serverId = -1, qint64 sessionId = -1);
|
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_SessionEvent(const SessionEvent &item, int serverId = -1, qint64 sessionId = -1);
|
||||||
void sendIsl_GameEventContainer(const GameEventContainer &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_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_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 sendIsl_RoomCommand(const CommandContainer &item, int serverId, qint64 sessionId, int roomId);
|
||||||
|
|
||||||
void addExternalUser(const ServerInfo_User &userInfo);
|
void addExternalUser(const ServerInfo_User &userInfo);
|
||||||
void removeExternalUser(const QString &userName);
|
void removeExternalUser(const QString &userName);
|
||||||
const QMap<QString, Server_AbstractUserInterface *> &getExternalUsers() const { return externalUsers; }
|
const QMap<QString, Server_AbstractUserInterface *> &getExternalUsers() const { return externalUsers; }
|
||||||
|
|
||||||
void addPersistentPlayer(const QString &userName, int roomId, int gameId, int playerId);
|
void addPersistentPlayer(const QString &userName, int roomId, int gameId, int playerId);
|
||||||
void removePersistentPlayer(const QString &userName, int roomId, int gameId, int playerId);
|
void removePersistentPlayer(const QString &userName, int roomId, int gameId, int playerId);
|
||||||
QList<PlayerReference> getPersistentPlayerReferences(const QString &userName) const;
|
QList<PlayerReference> getPersistentPlayerReferences(const QString &userName) const;
|
||||||
private:
|
private:
|
||||||
bool threaded;
|
bool threaded;
|
||||||
QMultiMap<QString, PlayerReference> persistentPlayers;
|
QMultiMap<QString, PlayerReference> persistentPlayers;
|
||||||
mutable QReadWriteLock persistentPlayersLock;
|
mutable QReadWriteLock persistentPlayersLock;
|
||||||
int nextLocalGameId;
|
int nextLocalGameId;
|
||||||
QMutex nextLocalGameIdMutex;
|
QMutex nextLocalGameIdMutex;
|
||||||
protected slots:
|
protected slots:
|
||||||
void externalUserJoined(const ServerInfo_User &userInfo);
|
void externalUserJoined(const ServerInfo_User &userInfo);
|
||||||
void externalUserLeft(const QString &userName);
|
void externalUserLeft(const QString &userName);
|
||||||
void externalRoomUserJoined(int roomId, const ServerInfo_User &userInfo);
|
void externalRoomUserJoined(int roomId, const ServerInfo_User &userInfo);
|
||||||
void externalRoomUserLeft(int roomId, const QString &userName);
|
void externalRoomUserLeft(int roomId, const QString &userName);
|
||||||
void externalRoomSay(int roomId, const QString &userName, const QString &message);
|
void externalRoomSay(int roomId, const QString &userName, const QString &message);
|
||||||
void externalRoomGameListChanged(int roomId, const ServerInfo_Game &gameInfo);
|
void externalRoomGameListChanged(int roomId, const ServerInfo_Game &gameInfo);
|
||||||
void externalJoinGameCommandReceived(const Command_JoinGame &cmd, int cmdId, int roomId, int serverId, qint64 sessionId);
|
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 externalGameCommandContainerReceived(const CommandContainer &cont, int playerId, int serverId, qint64 sessionId);
|
||||||
void externalGameEventContainerReceived(const GameEventContainer &cont, qint64 sessionId);
|
void externalGameEventContainerReceived(const GameEventContainer &cont, qint64 sessionId);
|
||||||
void externalResponseReceived(const Response &resp, qint64 sessionId);
|
void externalResponseReceived(const Response &resp, qint64 sessionId);
|
||||||
|
|
||||||
virtual void doSendIslMessage(const IslMessage &msg, int serverId) { }
|
virtual void doSendIslMessage(const IslMessage & /* msg */, int /* serverId */) { }
|
||||||
protected:
|
protected:
|
||||||
void prepareDestroy();
|
void prepareDestroy();
|
||||||
void setDatabaseInterface(Server_DatabaseInterface *_databaseInterface);
|
void setDatabaseInterface(Server_DatabaseInterface *_databaseInterface);
|
||||||
QList<Server_ProtocolHandler *> clients;
|
QList<Server_ProtocolHandler *> clients;
|
||||||
QMap<qint64, Server_ProtocolHandler *> usersBySessionId;
|
QMap<qint64, Server_ProtocolHandler *> usersBySessionId;
|
||||||
QMap<QString, Server_ProtocolHandler *> users;
|
QMap<QString, Server_ProtocolHandler *> users;
|
||||||
QMap<qint64, Server_AbstractUserInterface *> externalUsersBySessionId;
|
QMap<qint64, Server_AbstractUserInterface *> externalUsersBySessionId;
|
||||||
QMap<QString, Server_AbstractUserInterface *> externalUsers;
|
QMap<QString, Server_AbstractUserInterface *> externalUsers;
|
||||||
QMap<int, Server_Room *> rooms;
|
QMap<int, Server_Room *> rooms;
|
||||||
QMap<QThread *, Server_DatabaseInterface *> databaseInterfaces;
|
QMap<QThread *, Server_DatabaseInterface *> databaseInterfaces;
|
||||||
|
|
||||||
int getUsersCount() const;
|
int getUsersCount() const;
|
||||||
int getGamesCount() const;
|
int getGamesCount() const;
|
||||||
void addRoom(Server_Room *newRoom);
|
void addRoom(Server_Room *newRoom);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -15,82 +15,82 @@
|
||||||
|
|
||||||
void Server_AbstractUserInterface::sendProtocolItemByType(ServerMessage::MessageType type, const ::google::protobuf::Message &item)
|
void Server_AbstractUserInterface::sendProtocolItemByType(ServerMessage::MessageType type, const ::google::protobuf::Message &item)
|
||||||
{
|
{
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case ServerMessage::RESPONSE: sendProtocolItem(static_cast<const Response &>(item)); break;
|
case ServerMessage::RESPONSE: sendProtocolItem(static_cast<const Response &>(item)); break;
|
||||||
case ServerMessage::SESSION_EVENT: sendProtocolItem(static_cast<const SessionEvent &>(item)); break;
|
case ServerMessage::SESSION_EVENT: sendProtocolItem(static_cast<const SessionEvent &>(item)); break;
|
||||||
case ServerMessage::GAME_EVENT_CONTAINER: sendProtocolItem(static_cast<const GameEventContainer &>(item)); break;
|
case ServerMessage::GAME_EVENT_CONTAINER: sendProtocolItem(static_cast<const GameEventContainer &>(item)); break;
|
||||||
case ServerMessage::ROOM_EVENT: sendProtocolItem(static_cast<const RoomEvent &>(item)); break;
|
case ServerMessage::ROOM_EVENT: sendProtocolItem(static_cast<const RoomEvent &>(item)); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SessionEvent *Server_AbstractUserInterface::prepareSessionEvent(const ::google::protobuf::Message &sessionEvent)
|
SessionEvent *Server_AbstractUserInterface::prepareSessionEvent(const ::google::protobuf::Message &sessionEvent)
|
||||||
{
|
{
|
||||||
SessionEvent *event = new SessionEvent;
|
SessionEvent *event = new SessionEvent;
|
||||||
event->GetReflection()->MutableMessage(event, sessionEvent.GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(sessionEvent);
|
event->GetReflection()->MutableMessage(event, sessionEvent.GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(sessionEvent);
|
||||||
return event;
|
return event;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server_AbstractUserInterface::sendResponseContainer(const ResponseContainer &responseContainer, Response::ResponseCode responseCode)
|
void Server_AbstractUserInterface::sendResponseContainer(const ResponseContainer &responseContainer, Response::ResponseCode responseCode)
|
||||||
{
|
{
|
||||||
const QList<QPair<ServerMessage::MessageType, ::google::protobuf::Message *> > &preResponseQueue = responseContainer.getPreResponseQueue();
|
const QList<QPair<ServerMessage::MessageType, ::google::protobuf::Message *> > &preResponseQueue = responseContainer.getPreResponseQueue();
|
||||||
for (int i = 0; i < preResponseQueue.size(); ++i)
|
for (int i = 0; i < preResponseQueue.size(); ++i)
|
||||||
sendProtocolItemByType(preResponseQueue[i].first, *preResponseQueue[i].second);
|
sendProtocolItemByType(preResponseQueue[i].first, *preResponseQueue[i].second);
|
||||||
|
|
||||||
if (responseCode != Response::RespNothing) {
|
if (responseCode != Response::RespNothing) {
|
||||||
Response response;
|
Response response;
|
||||||
response.set_cmd_id(responseContainer.getCmdId());
|
response.set_cmd_id(responseContainer.getCmdId());
|
||||||
response.set_response_code(responseCode);
|
response.set_response_code(responseCode);
|
||||||
::google::protobuf::Message *responseExtension = responseContainer.getResponseExtension();
|
::google::protobuf::Message *responseExtension = responseContainer.getResponseExtension();
|
||||||
if (responseExtension)
|
if (responseExtension)
|
||||||
response.GetReflection()->MutableMessage(&response, responseExtension->GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(*responseExtension);
|
response.GetReflection()->MutableMessage(&response, responseExtension->GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(*responseExtension);
|
||||||
sendProtocolItem(response);
|
sendProtocolItem(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
const QList<QPair<ServerMessage::MessageType, ::google::protobuf::Message *> > &postResponseQueue = responseContainer.getPostResponseQueue();
|
const QList<QPair<ServerMessage::MessageType, ::google::protobuf::Message *> > &postResponseQueue = responseContainer.getPostResponseQueue();
|
||||||
for (int i = 0; i < postResponseQueue.size(); ++i)
|
for (int i = 0; i < postResponseQueue.size(); ++i)
|
||||||
sendProtocolItemByType(postResponseQueue[i].first, *postResponseQueue[i].second);
|
sendProtocolItemByType(postResponseQueue[i].first, *postResponseQueue[i].second);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server_AbstractUserInterface::playerRemovedFromGame(Server_Game *game)
|
void Server_AbstractUserInterface::playerRemovedFromGame(Server_Game *game)
|
||||||
{
|
{
|
||||||
qDebug() << "Server_AbstractUserInterface::playerRemovedFromGame(): gameId =" << game->getGameId();
|
qDebug() << "Server_AbstractUserInterface::playerRemovedFromGame(): gameId =" << game->getGameId();
|
||||||
|
|
||||||
QMutexLocker locker(&gameListMutex);
|
QMutexLocker locker(&gameListMutex);
|
||||||
games.remove(game->getGameId());
|
games.remove(game->getGameId());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server_AbstractUserInterface::playerAddedToGame(int gameId, int roomId, int playerId)
|
void Server_AbstractUserInterface::playerAddedToGame(int gameId, int roomId, int playerId)
|
||||||
{
|
{
|
||||||
qDebug() << "Server_AbstractUserInterface::playerAddedToGame(): gameId =" << gameId;
|
qDebug() << "Server_AbstractUserInterface::playerAddedToGame(): gameId =" << gameId;
|
||||||
|
|
||||||
QMutexLocker locker(&gameListMutex);
|
QMutexLocker locker(&gameListMutex);
|
||||||
games.insert(gameId, QPair<int, int>(roomId, playerId));
|
games.insert(gameId, QPair<int, int>(roomId, playerId));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server_AbstractUserInterface::joinPersistentGames(ResponseContainer &rc)
|
void Server_AbstractUserInterface::joinPersistentGames(ResponseContainer &rc)
|
||||||
{
|
{
|
||||||
QList<PlayerReference> gamesToJoin = server->getPersistentPlayerReferences(QString::fromStdString(userInfo->name()));
|
QList<PlayerReference> gamesToJoin = server->getPersistentPlayerReferences(QString::fromStdString(userInfo->name()));
|
||||||
|
|
||||||
server->roomsLock.lockForRead();
|
server->roomsLock.lockForRead();
|
||||||
for (int i = 0; i < gamesToJoin.size(); ++i) {
|
for (int i = 0; i < gamesToJoin.size(); ++i) {
|
||||||
const PlayerReference &pr = gamesToJoin.at(i);
|
const PlayerReference &pr = gamesToJoin.at(i);
|
||||||
|
|
||||||
Server_Room *room = server->getRooms().value(pr.getRoomId());
|
Server_Room *room = server->getRooms().value(pr.getRoomId());
|
||||||
if (!room)
|
if (!room)
|
||||||
continue;
|
continue;
|
||||||
QReadLocker roomGamesLocker(&room->gamesLock);
|
QReadLocker roomGamesLocker(&room->gamesLock);
|
||||||
|
|
||||||
Server_Game *game = room->getGames().value(pr.getGameId());
|
Server_Game *game = room->getGames().value(pr.getGameId());
|
||||||
if (!game)
|
if (!game)
|
||||||
continue;
|
continue;
|
||||||
QMutexLocker gameLocker(&game->gameMutex);
|
QMutexLocker gameLocker(&game->gameMutex);
|
||||||
|
|
||||||
Server_Player *player = game->getPlayers().value(pr.getPlayerId());
|
Server_Player *player = game->getPlayers().value(pr.getPlayerId());
|
||||||
|
|
||||||
player->setUserInterface(this);
|
player->setUserInterface(this);
|
||||||
playerAddedToGame(game->getGameId(), room->getId(), player->getPlayerId());
|
playerAddedToGame(game->getGameId(), room->getId(), player->getPlayerId());
|
||||||
|
|
||||||
game->createGameJoinedEvent(player, rc, true);
|
game->createGameJoinedEvent(player, rc, true);
|
||||||
}
|
}
|
||||||
server->roomsLock.unlock();
|
server->roomsLock.unlock();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,31 +18,31 @@ class Server_Game;
|
||||||
|
|
||||||
class Server_AbstractUserInterface : public ServerInfo_User_Container {
|
class Server_AbstractUserInterface : public ServerInfo_User_Container {
|
||||||
private:
|
private:
|
||||||
mutable QMutex gameListMutex;
|
mutable QMutex gameListMutex;
|
||||||
QMap<int, QPair<int, int> > games; // gameId -> (roomId, playerId)
|
QMap<int, QPair<int, int> > games; // gameId -> (roomId, playerId)
|
||||||
protected:
|
protected:
|
||||||
Server *server;
|
Server *server;
|
||||||
public:
|
public:
|
||||||
Server_AbstractUserInterface(Server *_server) : server(_server) { }
|
Server_AbstractUserInterface(Server *_server) : server(_server) { }
|
||||||
Server_AbstractUserInterface(Server *_server, const ServerInfo_User_Container &other) : ServerInfo_User_Container(other), server(_server) { }
|
Server_AbstractUserInterface(Server *_server, const ServerInfo_User_Container &other) : ServerInfo_User_Container(other), server(_server) { }
|
||||||
virtual ~Server_AbstractUserInterface() { }
|
virtual ~Server_AbstractUserInterface() { }
|
||||||
|
|
||||||
virtual int getLastCommandTime() const = 0;
|
virtual int getLastCommandTime() const = 0;
|
||||||
|
|
||||||
void playerRemovedFromGame(Server_Game *game);
|
void playerRemovedFromGame(Server_Game *game);
|
||||||
void playerAddedToGame(int gameId, int roomId, int playerId);
|
void playerAddedToGame(int gameId, int roomId, int playerId);
|
||||||
void joinPersistentGames(ResponseContainer &rc);
|
void joinPersistentGames(ResponseContainer &rc);
|
||||||
|
|
||||||
QMap<int, QPair<int, int> > getGames() const { QMutexLocker locker(&gameListMutex); return games; }
|
QMap<int, QPair<int, int> > getGames() const { QMutexLocker locker(&gameListMutex); return games; }
|
||||||
|
|
||||||
virtual void sendProtocolItem(const Response &item) = 0;
|
virtual void sendProtocolItem(const Response &item) = 0;
|
||||||
virtual void sendProtocolItem(const SessionEvent &item) = 0;
|
virtual void sendProtocolItem(const SessionEvent &item) = 0;
|
||||||
virtual void sendProtocolItem(const GameEventContainer &item) = 0;
|
virtual void sendProtocolItem(const GameEventContainer &item) = 0;
|
||||||
virtual void sendProtocolItem(const RoomEvent &item) = 0;
|
virtual void sendProtocolItem(const RoomEvent &item) = 0;
|
||||||
void sendProtocolItemByType(ServerMessage::MessageType type, const ::google::protobuf::Message &item);
|
void sendProtocolItemByType(ServerMessage::MessageType type, const ::google::protobuf::Message &item);
|
||||||
|
|
||||||
static SessionEvent *prepareSessionEvent(const ::google::protobuf::Message &sessionEvent);
|
static SessionEvent *prepareSessionEvent(const ::google::protobuf::Message &sessionEvent);
|
||||||
void sendResponseContainer(const ResponseContainer &responseContainer, Response::ResponseCode responseCode);
|
void sendResponseContainer(const ResponseContainer &responseContainer, Response::ResponseCode responseCode);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -14,17 +14,17 @@ Server_Arrow::Server_Arrow(int _id, Server_Card *_startCard, Server_ArrowTarget
|
||||||
|
|
||||||
void Server_Arrow::getInfo(ServerInfo_Arrow *info)
|
void Server_Arrow::getInfo(ServerInfo_Arrow *info)
|
||||||
{
|
{
|
||||||
info->set_id(id);
|
info->set_id(id);
|
||||||
info->set_start_player_id(startCard->getZone()->getPlayer()->getPlayerId());
|
info->set_start_player_id(startCard->getZone()->getPlayer()->getPlayerId());
|
||||||
info->set_start_zone(startCard->getZone()->getName().toStdString());
|
info->set_start_zone(startCard->getZone()->getName().toStdString());
|
||||||
info->set_start_card_id(startCard->getId());
|
info->set_start_card_id(startCard->getId());
|
||||||
info->mutable_arrow_color()->CopyFrom(arrowColor);
|
info->mutable_arrow_color()->CopyFrom(arrowColor);
|
||||||
|
|
||||||
Server_Card *targetCard = qobject_cast<Server_Card *>(targetItem);
|
Server_Card *targetCard = qobject_cast<Server_Card *>(targetItem);
|
||||||
if (targetCard) {
|
if (targetCard) {
|
||||||
info->set_target_player_id(targetCard->getZone()->getPlayer()->getPlayerId());
|
info->set_target_player_id(targetCard->getZone()->getPlayer()->getPlayerId());
|
||||||
info->set_target_zone(targetCard->getZone()->getName().toStdString());
|
info->set_target_zone(targetCard->getZone()->getName().toStdString());
|
||||||
info->set_target_card_id(targetCard->getId());
|
info->set_target_card_id(targetCard->getId());
|
||||||
} else
|
} else
|
||||||
info->set_target_player_id(static_cast<Server_Player *>(targetItem)->getPlayerId());
|
info->set_target_player_id(static_cast<Server_Player *>(targetItem)->getPlayerId());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,18 +9,18 @@ class ServerInfo_Arrow;
|
||||||
|
|
||||||
class Server_Arrow {
|
class Server_Arrow {
|
||||||
private:
|
private:
|
||||||
int id;
|
int id;
|
||||||
Server_Card *startCard;
|
Server_Card *startCard;
|
||||||
Server_ArrowTarget *targetItem;
|
Server_ArrowTarget *targetItem;
|
||||||
color arrowColor;
|
color arrowColor;
|
||||||
public:
|
public:
|
||||||
Server_Arrow(int _id, Server_Card *_startCard, Server_ArrowTarget *_targetItem, const color &_arrowColor);
|
Server_Arrow(int _id, Server_Card *_startCard, Server_ArrowTarget *_targetItem, const color &_arrowColor);
|
||||||
int getId() const { return id; }
|
int getId() const { return id; }
|
||||||
Server_Card *getStartCard() const { return startCard; }
|
Server_Card *getStartCard() const { return startCard; }
|
||||||
Server_ArrowTarget *getTargetItem() const { return targetItem; }
|
Server_ArrowTarget *getTargetItem() const { return targetItem; }
|
||||||
const color &getColor() const { return arrowColor; }
|
const color &getColor() const { return arrowColor; }
|
||||||
|
|
||||||
void getInfo(ServerInfo_Arrow *info);
|
void getInfo(ServerInfo_Arrow *info);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
class Server_ArrowTarget : public QObject {
|
class Server_ArrowTarget : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -23,138 +23,138 @@
|
||||||
#include "pb/serverinfo_card.pb.h"
|
#include "pb/serverinfo_card.pb.h"
|
||||||
|
|
||||||
Server_Card::Server_Card(QString _name, int _id, int _coord_x, int _coord_y, Server_CardZone *_zone)
|
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()
|
Server_Card::~Server_Card()
|
||||||
{
|
{
|
||||||
// setParentCard(0) leads to the item being removed from our list, so we can't iterate properly
|
// setParentCard(0) leads to the item being removed from our list, so we can't iterate properly
|
||||||
while (!attachedCards.isEmpty())
|
while (!attachedCards.isEmpty())
|
||||||
attachedCards.first()->setParentCard(0);
|
attachedCards.first()->setParentCard(0);
|
||||||
|
|
||||||
if (parentCard)
|
if (parentCard)
|
||||||
parentCard->removeAttachedCard(this);
|
parentCard->removeAttachedCard(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server_Card::resetState()
|
void Server_Card::resetState()
|
||||||
{
|
{
|
||||||
counters.clear();
|
counters.clear();
|
||||||
setTapped(false);
|
setTapped(false);
|
||||||
setAttacking(false);
|
setAttacking(false);
|
||||||
power = -1;
|
power = -1;
|
||||||
toughness = -1;
|
toughness = -1;
|
||||||
setAnnotation(QString());
|
setAnnotation(QString());
|
||||||
setDoesntUntap(false);
|
setDoesntUntap(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Server_Card::setAttribute(CardAttribute attribute, const QString &avalue, bool allCards)
|
QString Server_Card::setAttribute(CardAttribute attribute, const QString &avalue, bool allCards)
|
||||||
{
|
{
|
||||||
switch (attribute) {
|
switch (attribute) {
|
||||||
case AttrTapped: {
|
case AttrTapped: {
|
||||||
bool value = avalue == "1";
|
bool value = avalue == "1";
|
||||||
if (!(!value && allCards && doesntUntap))
|
if (!(!value && allCards && doesntUntap))
|
||||||
setTapped(value);
|
setTapped(value);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case AttrAttacking: setAttacking(avalue == "1"); break;
|
case AttrAttacking: setAttacking(avalue == "1"); break;
|
||||||
case AttrFaceDown: setFaceDown(avalue == "1"); break;
|
case AttrFaceDown: setFaceDown(avalue == "1"); break;
|
||||||
case AttrColor: setColor(avalue); break;
|
case AttrColor: setColor(avalue); break;
|
||||||
case AttrPT: setPT(avalue); return getPT();
|
case AttrPT: setPT(avalue); return getPT();
|
||||||
case AttrAnnotation: setAnnotation(avalue); break;
|
case AttrAnnotation: setAnnotation(avalue); break;
|
||||||
case AttrDoesntUntap: setDoesntUntap(avalue == "1"); break;
|
case AttrDoesntUntap: setDoesntUntap(avalue == "1"); break;
|
||||||
}
|
}
|
||||||
return avalue;
|
return avalue;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server_Card::setCounter(int id, int value)
|
void Server_Card::setCounter(int id, int value)
|
||||||
{
|
{
|
||||||
if (value)
|
if (value)
|
||||||
counters.insert(id, value);
|
counters.insert(id, value);
|
||||||
else
|
else
|
||||||
counters.remove(id);
|
counters.remove(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server_Card::setPT(const QString &_pt)
|
void Server_Card::setPT(const QString &_pt)
|
||||||
{
|
{
|
||||||
if (_pt.isEmpty()) {
|
if (_pt.isEmpty()) {
|
||||||
power = 0;
|
power = 0;
|
||||||
toughness = -1;
|
toughness = -1;
|
||||||
} else {
|
} else {
|
||||||
int sep = _pt.indexOf('/');
|
int sep = _pt.indexOf('/');
|
||||||
QString p1 = _pt.left(sep);
|
QString p1 = _pt.left(sep);
|
||||||
QString p2 = _pt.mid(sep + 1);
|
QString p2 = _pt.mid(sep + 1);
|
||||||
if (p1.isEmpty() || p2.isEmpty())
|
if (p1.isEmpty() || p2.isEmpty())
|
||||||
return;
|
return;
|
||||||
if ((p1[0] == '+') || (p2[0] == '+')) {
|
if ((p1[0] == '+') || (p2[0] == '+')) {
|
||||||
if (power < 0)
|
if (power < 0)
|
||||||
power = 0;
|
power = 0;
|
||||||
if (toughness < 0)
|
if (toughness < 0)
|
||||||
toughness = 0;
|
toughness = 0;
|
||||||
}
|
}
|
||||||
if (p1[0] == '+')
|
if (p1[0] == '+')
|
||||||
power += p1.mid(1).toInt();
|
power += p1.mid(1).toInt();
|
||||||
else
|
else
|
||||||
power = p1.toInt();
|
power = p1.toInt();
|
||||||
if (p2[0] == '+')
|
if (p2[0] == '+')
|
||||||
toughness += p2.mid(1).toInt();
|
toughness += p2.mid(1).toInt();
|
||||||
else
|
else
|
||||||
toughness = p2.toInt();
|
toughness = p2.toInt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Server_Card::getPT() const
|
QString Server_Card::getPT() const
|
||||||
{
|
{
|
||||||
if (toughness < 0)
|
if (toughness < 0)
|
||||||
return QString("");
|
return QString("");
|
||||||
return QString::number(power) + "/" + QString::number(toughness);
|
return QString::number(power) + "/" + QString::number(toughness);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server_Card::setParentCard(Server_Card *_parentCard)
|
void Server_Card::setParentCard(Server_Card *_parentCard)
|
||||||
{
|
{
|
||||||
if (parentCard)
|
if (parentCard)
|
||||||
parentCard->removeAttachedCard(this);
|
parentCard->removeAttachedCard(this);
|
||||||
parentCard = _parentCard;
|
parentCard = _parentCard;
|
||||||
if (parentCard)
|
if (parentCard)
|
||||||
parentCard->addAttachedCard(this);
|
parentCard->addAttachedCard(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server_Card::getInfo(ServerInfo_Card *info)
|
void Server_Card::getInfo(ServerInfo_Card *info)
|
||||||
{
|
{
|
||||||
QString displayedName = facedown ? QString() : name;
|
QString displayedName = facedown ? QString() : name;
|
||||||
|
|
||||||
info->set_id(id);
|
info->set_id(id);
|
||||||
info->set_name(displayedName.toStdString());
|
info->set_name(displayedName.toStdString());
|
||||||
info->set_x(coord_x);
|
info->set_x(coord_x);
|
||||||
info->set_y(coord_y);
|
info->set_y(coord_y);
|
||||||
if (facedown)
|
if (facedown)
|
||||||
info->set_face_down(true);
|
info->set_face_down(true);
|
||||||
info->set_tapped(tapped);
|
info->set_tapped(tapped);
|
||||||
if (attacking)
|
if (attacking)
|
||||||
info->set_attacking(true);
|
info->set_attacking(true);
|
||||||
if (!color.isEmpty())
|
if (!color.isEmpty())
|
||||||
info->set_color(color.toStdString());
|
info->set_color(color.toStdString());
|
||||||
const QString ptStr = getPT();
|
const QString ptStr = getPT();
|
||||||
if (!ptStr.isEmpty())
|
if (!ptStr.isEmpty())
|
||||||
info->set_pt(ptStr.toStdString());
|
info->set_pt(ptStr.toStdString());
|
||||||
if (!annotation.isEmpty())
|
if (!annotation.isEmpty())
|
||||||
info->set_annotation(annotation.toStdString());
|
info->set_annotation(annotation.toStdString());
|
||||||
if (destroyOnZoneChange)
|
if (destroyOnZoneChange)
|
||||||
info->set_destroy_on_zone_change(true);
|
info->set_destroy_on_zone_change(true);
|
||||||
if (doesntUntap)
|
if (doesntUntap)
|
||||||
info->set_doesnt_untap(true);
|
info->set_doesnt_untap(true);
|
||||||
|
|
||||||
QMapIterator<int, int> cardCounterIterator(counters);
|
QMapIterator<int, int> cardCounterIterator(counters);
|
||||||
while (cardCounterIterator.hasNext()) {
|
while (cardCounterIterator.hasNext()) {
|
||||||
cardCounterIterator.next();
|
cardCounterIterator.next();
|
||||||
ServerInfo_CardCounter *counterInfo = info->add_counter_list();
|
ServerInfo_CardCounter *counterInfo = info->add_counter_list();
|
||||||
counterInfo->set_id(cardCounterIterator.key());
|
counterInfo->set_id(cardCounterIterator.key());
|
||||||
counterInfo->set_value(cardCounterIterator.value());
|
counterInfo->set_value(cardCounterIterator.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parentCard) {
|
if (parentCard) {
|
||||||
info->set_attach_player_id(parentCard->getZone()->getPlayer()->getPlayerId());
|
info->set_attach_player_id(parentCard->getZone()->getPlayer()->getPlayerId());
|
||||||
info->set_attach_zone(parentCard->getZone()->getName().toStdString());
|
info->set_attach_zone(parentCard->getZone()->getName().toStdString());
|
||||||
info->set_attach_card_id(parentCard->getId());
|
info->set_attach_card_id(parentCard->getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,68 +29,68 @@ class Server_CardZone;
|
||||||
class ServerInfo_Card;
|
class ServerInfo_Card;
|
||||||
|
|
||||||
class Server_Card : public Server_ArrowTarget {
|
class Server_Card : public Server_ArrowTarget {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
private:
|
private:
|
||||||
Server_CardZone *zone;
|
Server_CardZone *zone;
|
||||||
int id;
|
int id;
|
||||||
int coord_x, coord_y;
|
int coord_x, coord_y;
|
||||||
QString name;
|
QString name;
|
||||||
QMap<int, int> counters;
|
QMap<int, int> counters;
|
||||||
bool tapped;
|
bool tapped;
|
||||||
bool attacking;
|
bool attacking;
|
||||||
bool facedown;
|
bool facedown;
|
||||||
QString color;
|
QString color;
|
||||||
int power, toughness;
|
int power, toughness;
|
||||||
QString annotation;
|
QString annotation;
|
||||||
bool destroyOnZoneChange;
|
bool destroyOnZoneChange;
|
||||||
bool doesntUntap;
|
bool doesntUntap;
|
||||||
|
|
||||||
Server_Card *parentCard;
|
Server_Card *parentCard;
|
||||||
QList<Server_Card *> attachedCards;
|
QList<Server_Card *> attachedCards;
|
||||||
public:
|
public:
|
||||||
Server_Card(QString _name, int _id, int _coord_x, int _coord_y, Server_CardZone *_zone = 0);
|
Server_Card(QString _name, int _id, int _coord_x, int _coord_y, Server_CardZone *_zone = 0);
|
||||||
~Server_Card();
|
~Server_Card();
|
||||||
|
|
||||||
Server_CardZone *getZone() const { return zone; }
|
Server_CardZone *getZone() const { return zone; }
|
||||||
void setZone(Server_CardZone *_zone) { zone = _zone; }
|
void setZone(Server_CardZone *_zone) { zone = _zone; }
|
||||||
|
|
||||||
int getId() const { return id; }
|
int getId() const { return id; }
|
||||||
int getX() const { return coord_x; }
|
int getX() const { return coord_x; }
|
||||||
int getY() const { return coord_y; }
|
int getY() const { return coord_y; }
|
||||||
QString getName() const { return name; }
|
QString getName() const { return name; }
|
||||||
const QMap<int, int> &getCounters() const { return counters; }
|
const QMap<int, int> &getCounters() const { return counters; }
|
||||||
int getCounter(int id) const { return counters.value(id, 0); }
|
int getCounter(int id) const { return counters.value(id, 0); }
|
||||||
bool getTapped() const { return tapped; }
|
bool getTapped() const { return tapped; }
|
||||||
bool getAttacking() const { return attacking; }
|
bool getAttacking() const { return attacking; }
|
||||||
bool getFaceDown() const { return facedown; }
|
bool getFaceDown() const { return facedown; }
|
||||||
QString getColor() const { return color; }
|
QString getColor() const { return color; }
|
||||||
QString getPT() const;
|
QString getPT() const;
|
||||||
QString getAnnotation() const { return annotation; }
|
QString getAnnotation() const { return annotation; }
|
||||||
bool getDoesntUntap() const { return doesntUntap; }
|
bool getDoesntUntap() const { return doesntUntap; }
|
||||||
bool getDestroyOnZoneChange() const { return destroyOnZoneChange; }
|
bool getDestroyOnZoneChange() const { return destroyOnZoneChange; }
|
||||||
Server_Card *getParentCard() const { return parentCard; }
|
Server_Card *getParentCard() const { return parentCard; }
|
||||||
const QList<Server_Card *> &getAttachedCards() const { return attachedCards; }
|
const QList<Server_Card *> &getAttachedCards() const { return attachedCards; }
|
||||||
|
|
||||||
void setId(int _id) { id = _id; }
|
void setId(int _id) { id = _id; }
|
||||||
void setCoords(int x, int y) { coord_x = x; coord_y = y; }
|
void setCoords(int x, int y) { coord_x = x; coord_y = y; }
|
||||||
void setName(const QString &_name) { name = _name; }
|
void setName(const QString &_name) { name = _name; }
|
||||||
void setCounter(int id, int value);
|
void setCounter(int id, int value);
|
||||||
void setTapped(bool _tapped) { tapped = _tapped; }
|
void setTapped(bool _tapped) { tapped = _tapped; }
|
||||||
void setAttacking(bool _attacking) { attacking = _attacking; }
|
void setAttacking(bool _attacking) { attacking = _attacking; }
|
||||||
void setFaceDown(bool _facedown) { facedown = _facedown; }
|
void setFaceDown(bool _facedown) { facedown = _facedown; }
|
||||||
void setColor(const QString &_color) { color = _color; }
|
void setColor(const QString &_color) { color = _color; }
|
||||||
void setPT(const QString &_pt);
|
void setPT(const QString &_pt);
|
||||||
void setAnnotation(const QString &_annotation) { annotation = _annotation; }
|
void setAnnotation(const QString &_annotation) { annotation = _annotation; }
|
||||||
void setDestroyOnZoneChange(bool _destroy) { destroyOnZoneChange = _destroy; }
|
void setDestroyOnZoneChange(bool _destroy) { destroyOnZoneChange = _destroy; }
|
||||||
void setDoesntUntap(bool _doesntUntap) { doesntUntap = _doesntUntap; }
|
void setDoesntUntap(bool _doesntUntap) { doesntUntap = _doesntUntap; }
|
||||||
void setParentCard(Server_Card *_parentCard);
|
void setParentCard(Server_Card *_parentCard);
|
||||||
void addAttachedCard(Server_Card *card) { attachedCards.append(card); }
|
void addAttachedCard(Server_Card *card) { attachedCards.append(card); }
|
||||||
void removeAttachedCard(Server_Card *card) { attachedCards.removeAt(attachedCards.indexOf(card)); }
|
void removeAttachedCard(Server_Card *card) { attachedCards.removeAt(attachedCards.indexOf(card)); }
|
||||||
|
|
||||||
void resetState();
|
void resetState();
|
||||||
QString setAttribute(CardAttribute attribute, const QString &avalue, bool allCards);
|
QString setAttribute(CardAttribute attribute, const QString &avalue, bool allCards);
|
||||||
|
|
||||||
void getInfo(ServerInfo_Card *info);
|
void getInfo(ServerInfo_Card *info);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -33,48 +33,48 @@ class GameEventStorage;
|
||||||
|
|
||||||
class Server_CardZone {
|
class Server_CardZone {
|
||||||
private:
|
private:
|
||||||
Server_Player *player;
|
Server_Player *player;
|
||||||
QString name;
|
QString name;
|
||||||
bool has_coords;
|
bool has_coords;
|
||||||
ServerInfo_Zone::ZoneType type;
|
ServerInfo_Zone::ZoneType type;
|
||||||
int cardsBeingLookedAt;
|
int cardsBeingLookedAt;
|
||||||
QSet<int> playersWithWritePermission;
|
QSet<int> playersWithWritePermission;
|
||||||
bool alwaysRevealTopCard;
|
bool alwaysRevealTopCard;
|
||||||
QList<Server_Card *> cards;
|
QList<Server_Card *> cards;
|
||||||
QMap<int, QMap<int, Server_Card *> > coordinateMap; // y -> (x -> card)
|
QMap<int, QMap<int, Server_Card *> > coordinateMap; // y -> (x -> card)
|
||||||
QMap<int, QMultiMap<QString, int> > freePilesMap; // y -> (cardName -> x)
|
QMap<int, QMultiMap<QString, int> > freePilesMap; // y -> (cardName -> x)
|
||||||
QMap<int, int> freeSpaceMap; // y -> x
|
QMap<int, int> freeSpaceMap; // y -> x
|
||||||
void removeCardFromCoordMap(Server_Card *card, int oldX, int oldY);
|
void removeCardFromCoordMap(Server_Card *card, int oldX, int oldY);
|
||||||
void insertCardIntoCoordMap(Server_Card *card, int x, int y);
|
void insertCardIntoCoordMap(Server_Card *card, int x, int y);
|
||||||
public:
|
public:
|
||||||
Server_CardZone(Server_Player *_player, const QString &_name, bool _has_coords, ServerInfo_Zone::ZoneType _type);
|
Server_CardZone(Server_Player *_player, const QString &_name, bool _has_coords, ServerInfo_Zone::ZoneType _type);
|
||||||
~Server_CardZone();
|
~Server_CardZone();
|
||||||
|
|
||||||
const QList<Server_Card *> &getCards() const { return cards; }
|
const QList<Server_Card *> &getCards() const { return cards; }
|
||||||
int removeCard(Server_Card *card);
|
int removeCard(Server_Card *card);
|
||||||
Server_Card *getCard(int id, int *position = NULL, bool remove = false);
|
Server_Card *getCard(int id, int *position = NULL, bool remove = false);
|
||||||
|
|
||||||
int getCardsBeingLookedAt() const { return cardsBeingLookedAt; }
|
int getCardsBeingLookedAt() const { return cardsBeingLookedAt; }
|
||||||
void setCardsBeingLookedAt(int _cardsBeingLookedAt) { cardsBeingLookedAt = _cardsBeingLookedAt; }
|
void setCardsBeingLookedAt(int _cardsBeingLookedAt) { cardsBeingLookedAt = _cardsBeingLookedAt; }
|
||||||
bool hasCoords() const { return has_coords; }
|
bool hasCoords() const { return has_coords; }
|
||||||
ServerInfo_Zone::ZoneType getType() const { return type; }
|
ServerInfo_Zone::ZoneType getType() const { return type; }
|
||||||
QString getName() const { return name; }
|
QString getName() const { return name; }
|
||||||
Server_Player *getPlayer() const { return player; }
|
Server_Player *getPlayer() const { return player; }
|
||||||
void getInfo(ServerInfo_Zone *info, Server_Player *playerWhosAsking, bool omniscient);
|
void getInfo(ServerInfo_Zone *info, Server_Player *playerWhosAsking, bool omniscient);
|
||||||
|
|
||||||
int getFreeGridColumn(int x, int y, const QString &cardName) const;
|
int getFreeGridColumn(int x, int y, const QString &cardName) const;
|
||||||
bool isColumnEmpty(int x, int y) const;
|
bool isColumnEmpty(int x, int y) const;
|
||||||
bool isColumnStacked(int x, int y) const;
|
bool isColumnStacked(int x, int y) const;
|
||||||
void fixFreeSpaces(GameEventStorage &ges);
|
void fixFreeSpaces(GameEventStorage &ges);
|
||||||
void moveCardInRow(GameEventStorage &ges, Server_Card *card, int x, int y);
|
void moveCardInRow(GameEventStorage &ges, Server_Card *card, int x, int y);
|
||||||
void insertCard(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 updateCardCoordinates(Server_Card *card, int oldX, int oldY);
|
||||||
void shuffle();
|
void shuffle();
|
||||||
void clear();
|
void clear();
|
||||||
void addWritePermission(int playerId);
|
void addWritePermission(int playerId);
|
||||||
const QSet<int> &getPlayersWithWritePermission() const { return playersWithWritePermission; }
|
const QSet<int> &getPlayersWithWritePermission() const { return playersWithWritePermission; }
|
||||||
bool getAlwaysRevealTopCard() const { return alwaysRevealTopCard; }
|
bool getAlwaysRevealTopCard() const { return alwaysRevealTopCard; }
|
||||||
void setAlwaysRevealTopCard(bool _alwaysRevealTopCard) { alwaysRevealTopCard = _alwaysRevealTopCard; }
|
void setAlwaysRevealTopCard(bool _alwaysRevealTopCard) { alwaysRevealTopCard = _alwaysRevealTopCard; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -12,9 +12,9 @@ Server_Counter::Server_Counter(int _id, const QString &_name, const color &_coun
|
||||||
|
|
||||||
void Server_Counter::getInfo(ServerInfo_Counter *info)
|
void Server_Counter::getInfo(ServerInfo_Counter *info)
|
||||||
{
|
{
|
||||||
info->set_id(id);
|
info->set_id(id);
|
||||||
info->set_name(name.toStdString());
|
info->set_name(name.toStdString());
|
||||||
info->mutable_counter_color()->CopyFrom(counterColor);
|
info->mutable_counter_color()->CopyFrom(counterColor);
|
||||||
info->set_radius(radius);
|
info->set_radius(radius);
|
||||||
info->set_count(count);
|
info->set_count(count);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,22 +27,22 @@ class ServerInfo_Counter;
|
||||||
|
|
||||||
class Server_Counter {
|
class Server_Counter {
|
||||||
protected:
|
protected:
|
||||||
int id;
|
int id;
|
||||||
QString name;
|
QString name;
|
||||||
color counterColor;
|
color counterColor;
|
||||||
int radius;
|
int radius;
|
||||||
int count;
|
int count;
|
||||||
public:
|
public:
|
||||||
Server_Counter(int _id, const QString &_name, const color &_counterColor, int _radius, int _count = 0);
|
Server_Counter(int _id, const QString &_name, const color &_counterColor, int _radius, int _count = 0);
|
||||||
~Server_Counter() { }
|
~Server_Counter() { }
|
||||||
int getId() const { return id; }
|
int getId() const { return id; }
|
||||||
QString getName() const { return name; }
|
QString getName() const { return name; }
|
||||||
const color &getColor() const { return counterColor; }
|
const color &getColor() const { return counterColor; }
|
||||||
int getRadius() const { return radius; }
|
int getRadius() const { return radius; }
|
||||||
int getCount() const { return count; }
|
int getCount() const { return count; }
|
||||||
void setCount(int _count) { count = _count; }
|
void setCount(int _count) { count = _count; }
|
||||||
|
|
||||||
void getInfo(ServerInfo_Counter *info);
|
void getInfo(ServerInfo_Counter *info);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -6,32 +6,32 @@
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
|
|
||||||
class Server_DatabaseInterface : public QObject {
|
class Server_DatabaseInterface : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
Server_DatabaseInterface(QObject *parent = 0)
|
Server_DatabaseInterface(QObject *parent = 0)
|
||||||
: QObject(parent) { }
|
: QObject(parent) { }
|
||||||
|
|
||||||
virtual AuthenticationResult checkUserPassword(Server_ProtocolHandler *handler, const QString &user, const QString &password, QString &reasonStr, int &secondsLeft) = 0;
|
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 bool userExists(const QString & /* user */) { return false; }
|
||||||
virtual QMap<QString, ServerInfo_User> getBuddyList(const QString &name) { return QMap<QString, ServerInfo_User>(); }
|
virtual QMap<QString, ServerInfo_User> getBuddyList(const QString & /* name */) { return QMap<QString, ServerInfo_User>(); }
|
||||||
virtual QMap<QString, ServerInfo_User> getIgnoreList(const QString &name) { return QMap<QString, ServerInfo_User>(); }
|
virtual QMap<QString, ServerInfo_User> getIgnoreList(const QString & /* name */) { return QMap<QString, ServerInfo_User>(); }
|
||||||
virtual bool isInBuddyList(const QString &whoseList, const QString &who) { return false; }
|
virtual bool isInBuddyList(const QString & /* whoseList */, const QString & /* who */) { return false; }
|
||||||
virtual bool isInIgnoreList(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 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<QString> &allPlayersEver, const QSet<QString> &allSpectatorsEver, const QList<GameReplay *> &replayList) { }
|
virtual void storeGameInformation(const QString & /* roomName */, const QStringList & /* roomGameTypes */, const ServerInfo_Game & /* gameInfo */, const QSet<QString> & /* allPlayersEver */, const QSet<QString> & /* allSpectatorsEver */, const QList<GameReplay *> & /* replayList */) { }
|
||||||
virtual DeckList *getDeckFromDatabase(int deckId, int userId) { return 0; }
|
virtual DeckList *getDeckFromDatabase(int /* deckId */, int /* userId */) { return 0; }
|
||||||
|
|
||||||
virtual qint64 startSession(const QString &userName, const QString &address) { return 0; }
|
virtual qint64 startSession(const QString & /* userName */, const QString & /* address */) { return 0; }
|
||||||
public slots:
|
public slots:
|
||||||
virtual void endSession(qint64 sessionId) { }
|
virtual void endSession(qint64 /* sessionId */ ) { }
|
||||||
public:
|
public:
|
||||||
virtual int getNextGameId() = 0;
|
virtual int getNextGameId() = 0;
|
||||||
virtual int getNextReplayId() = 0;
|
virtual int getNextReplayId() = 0;
|
||||||
|
|
||||||
virtual void clearSessionTables() { }
|
virtual void clearSessionTables() { }
|
||||||
virtual void lockSessionTables() { }
|
virtual void lockSessionTables() { }
|
||||||
virtual void unlockSessionTables() { }
|
virtual void unlockSessionTables() { }
|
||||||
virtual bool userSessionExists(const QString &userName) { return false; }
|
virtual bool userSessionExists(const QString & /* userName */) { return false; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -42,86 +42,86 @@ class Server_AbstractUserInterface;
|
||||||
class Event_GameStateChanged;
|
class Event_GameStateChanged;
|
||||||
|
|
||||||
class Server_Game : public QObject {
|
class Server_Game : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
private:
|
private:
|
||||||
Server_Room *room;
|
Server_Room *room;
|
||||||
int nextPlayerId;
|
int nextPlayerId;
|
||||||
int hostId;
|
int hostId;
|
||||||
ServerInfo_User *creatorInfo;
|
ServerInfo_User *creatorInfo;
|
||||||
QMap<int, Server_Player *> players;
|
QMap<int, Server_Player *> players;
|
||||||
QSet<QString> allPlayersEver, allSpectatorsEver;
|
QSet<QString> allPlayersEver, allSpectatorsEver;
|
||||||
bool gameStarted;
|
bool gameStarted;
|
||||||
bool gameClosed;
|
bool gameClosed;
|
||||||
int gameId;
|
int gameId;
|
||||||
QString description;
|
QString description;
|
||||||
QString password;
|
QString password;
|
||||||
int maxPlayers;
|
int maxPlayers;
|
||||||
QList<int> gameTypes;
|
QList<int> gameTypes;
|
||||||
int activePlayer, activePhase;
|
int activePlayer, activePhase;
|
||||||
bool onlyBuddies, onlyRegistered;
|
bool onlyBuddies, onlyRegistered;
|
||||||
bool spectatorsAllowed;
|
bool spectatorsAllowed;
|
||||||
bool spectatorsNeedPassword;
|
bool spectatorsNeedPassword;
|
||||||
bool spectatorsCanTalk;
|
bool spectatorsCanTalk;
|
||||||
bool spectatorsSeeEverything;
|
bool spectatorsSeeEverything;
|
||||||
int inactivityCounter;
|
int inactivityCounter;
|
||||||
int startTimeOfThisGame, secondsElapsed;
|
int startTimeOfThisGame, secondsElapsed;
|
||||||
bool firstGameStarted;
|
bool firstGameStarted;
|
||||||
QDateTime startTime;
|
QDateTime startTime;
|
||||||
QTimer *pingClock;
|
QTimer *pingClock;
|
||||||
QList<GameReplay *> replayList;
|
QList<GameReplay *> replayList;
|
||||||
GameReplay *currentReplay;
|
GameReplay *currentReplay;
|
||||||
|
|
||||||
void createGameStateChangedEvent(Event_GameStateChanged *event, Server_Player *playerWhosAsking, bool omniscient, bool withUserInfo);
|
void createGameStateChangedEvent(Event_GameStateChanged *event, Server_Player *playerWhosAsking, bool omniscient, bool withUserInfo);
|
||||||
void sendGameStateToPlayers();
|
void sendGameStateToPlayers();
|
||||||
void storeGameInformation();
|
void storeGameInformation();
|
||||||
signals:
|
signals:
|
||||||
void sigStartGameIfReady();
|
void sigStartGameIfReady();
|
||||||
void gameInfoChanged(ServerInfo_Game gameInfo);
|
void gameInfoChanged(ServerInfo_Game gameInfo);
|
||||||
private slots:
|
private slots:
|
||||||
void pingClockTimeout();
|
void pingClockTimeout();
|
||||||
void doStartGameIfReady();
|
void doStartGameIfReady();
|
||||||
public:
|
public:
|
||||||
mutable QMutex gameMutex;
|
mutable QMutex gameMutex;
|
||||||
Server_Game(const ServerInfo_User &_creatorInfo, int _gameId, const QString &_description, const QString &_password, int _maxPlayers, const QList<int> &_gameTypes, bool _onlyBuddies, bool _onlyRegistered, bool _spectatorsAllowed, bool _spectatorsNeedPassword, bool _spectatorsCanTalk, bool _spectatorsSeeEverything, Server_Room *parent);
|
Server_Game(const ServerInfo_User &_creatorInfo, int _gameId, const QString &_description, const QString &_password, int _maxPlayers, const QList<int> &_gameTypes, bool _onlyBuddies, bool _onlyRegistered, bool _spectatorsAllowed, bool _spectatorsNeedPassword, bool _spectatorsCanTalk, bool _spectatorsSeeEverything, Server_Room *parent);
|
||||||
~Server_Game();
|
~Server_Game();
|
||||||
Server_Room *getRoom() const { return room; }
|
Server_Room *getRoom() const { return room; }
|
||||||
void getInfo(ServerInfo_Game &result) const;
|
void getInfo(ServerInfo_Game &result) const;
|
||||||
int getHostId() const { return hostId; }
|
int getHostId() const { return hostId; }
|
||||||
ServerInfo_User *getCreatorInfo() const { return creatorInfo; }
|
ServerInfo_User *getCreatorInfo() const { return creatorInfo; }
|
||||||
bool getGameStarted() const { return gameStarted; }
|
bool getGameStarted() const { return gameStarted; }
|
||||||
int getPlayerCount() const;
|
int getPlayerCount() const;
|
||||||
int getSpectatorCount() const;
|
int getSpectatorCount() const;
|
||||||
const QMap<int, Server_Player *> &getPlayers() const { return players; }
|
const QMap<int, Server_Player *> &getPlayers() const { return players; }
|
||||||
int getGameId() const { return gameId; }
|
int getGameId() const { return gameId; }
|
||||||
QString getDescription() const { return description; }
|
QString getDescription() const { return description; }
|
||||||
QString getPassword() const { return password; }
|
QString getPassword() const { return password; }
|
||||||
int getMaxPlayers() const { return maxPlayers; }
|
int getMaxPlayers() const { return maxPlayers; }
|
||||||
bool getSpectatorsAllowed() const { return spectatorsAllowed; }
|
bool getSpectatorsAllowed() const { return spectatorsAllowed; }
|
||||||
bool getSpectatorsNeedPassword() const { return spectatorsNeedPassword; }
|
bool getSpectatorsNeedPassword() const { return spectatorsNeedPassword; }
|
||||||
bool getSpectatorsCanTalk() const { return spectatorsCanTalk; }
|
bool getSpectatorsCanTalk() const { return spectatorsCanTalk; }
|
||||||
bool getSpectatorsSeeEverything() const { return spectatorsSeeEverything; }
|
bool getSpectatorsSeeEverything() const { return spectatorsSeeEverything; }
|
||||||
Response::ResponseCode checkJoin(ServerInfo_User *user, const QString &_password, bool spectator, bool overrideRestrictions);
|
Response::ResponseCode checkJoin(ServerInfo_User *user, const QString &_password, bool spectator, bool overrideRestrictions);
|
||||||
bool containsUser(const QString &userName) const;
|
bool containsUser(const QString &userName) const;
|
||||||
void addPlayer(Server_AbstractUserInterface *userInterface, ResponseContainer &rc, bool spectator, bool broadcastUpdate = true);
|
void addPlayer(Server_AbstractUserInterface *userInterface, ResponseContainer &rc, bool spectator, bool broadcastUpdate = true);
|
||||||
void removePlayer(Server_Player *player);
|
void removePlayer(Server_Player *player);
|
||||||
void removeArrowsRelatedToPlayer(GameEventStorage &ges, Server_Player *player);
|
void removeArrowsRelatedToPlayer(GameEventStorage &ges, Server_Player *player);
|
||||||
void unattachCards(GameEventStorage &ges, Server_Player *player);
|
void unattachCards(GameEventStorage &ges, Server_Player *player);
|
||||||
bool kickPlayer(int playerId);
|
bool kickPlayer(int playerId);
|
||||||
void startGameIfReady();
|
void startGameIfReady();
|
||||||
void stopGameIfFinished();
|
void stopGameIfFinished();
|
||||||
int getActivePlayer() const { return activePlayer; }
|
int getActivePlayer() const { return activePlayer; }
|
||||||
int getActivePhase() const { return activePhase; }
|
int getActivePhase() const { return activePhase; }
|
||||||
void setActivePlayer(int _activePlayer);
|
void setActivePlayer(int _activePlayer);
|
||||||
void setActivePhase(int _activePhase);
|
void setActivePhase(int _activePhase);
|
||||||
void nextTurn();
|
void nextTurn();
|
||||||
int getSecondsElapsed() const { return secondsElapsed; }
|
int getSecondsElapsed() const { return secondsElapsed; }
|
||||||
|
|
||||||
void createGameJoinedEvent(Server_Player *player, ResponseContainer &rc, bool resuming);
|
void createGameJoinedEvent(Server_Player *player, ResponseContainer &rc, bool resuming);
|
||||||
|
|
||||||
GameEventContainer *prepareGameEvent(const ::google::protobuf::Message &gameEvent, int playerId, GameEventContext *context = 0);
|
GameEventContainer *prepareGameEvent(const ::google::protobuf::Message &gameEvent, int playerId, GameEventContext *context = 0);
|
||||||
GameEventContext prepareGameEventContext(const ::google::protobuf::Message &gameEventContext);
|
GameEventContext prepareGameEventContext(const ::google::protobuf::Message &gameEventContext);
|
||||||
|
|
||||||
void sendGameEventContainer(GameEventContainer *cont, GameEventStorageItem::EventRecipients recipients = GameEventStorageItem::SendToPrivate | GameEventStorageItem::SendToOthers, int privatePlayerId = -1);
|
void sendGameEventContainer(GameEventContainer *cont, GameEventStorageItem::EventRecipients recipients = GameEventStorageItem::SendToPrivate | GameEventStorageItem::SendToOthers, int privatePlayerId = -1);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -62,104 +62,104 @@ class Command_SetSideboardLock;
|
||||||
class Command_ChangeZoneProperties;
|
class Command_ChangeZoneProperties;
|
||||||
|
|
||||||
class Server_Player : public Server_ArrowTarget, public ServerInfo_User_Container {
|
class Server_Player : public Server_ArrowTarget, public ServerInfo_User_Container {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
private:
|
private:
|
||||||
class MoveCardCompareFunctor;
|
class MoveCardCompareFunctor;
|
||||||
Server_Game *game;
|
Server_Game *game;
|
||||||
Server_AbstractUserInterface *userInterface;
|
Server_AbstractUserInterface *userInterface;
|
||||||
DeckList *deck;
|
DeckList *deck;
|
||||||
QMap<QString, Server_CardZone *> zones;
|
QMap<QString, Server_CardZone *> zones;
|
||||||
QMap<int, Server_Counter *> counters;
|
QMap<int, Server_Counter *> counters;
|
||||||
QMap<int, Server_Arrow *> arrows;
|
QMap<int, Server_Arrow *> arrows;
|
||||||
QList<int> lastDrawList;
|
QList<int> lastDrawList;
|
||||||
int pingTime;
|
int pingTime;
|
||||||
int playerId;
|
int playerId;
|
||||||
bool spectator;
|
bool spectator;
|
||||||
int initialCards;
|
int initialCards;
|
||||||
int nextCardId;
|
int nextCardId;
|
||||||
bool readyStart;
|
bool readyStart;
|
||||||
bool conceded;
|
bool conceded;
|
||||||
bool sideboardLocked;
|
bool sideboardLocked;
|
||||||
public:
|
public:
|
||||||
mutable QMutex playerMutex;
|
mutable QMutex playerMutex;
|
||||||
Server_Player(Server_Game *_game, int _playerId, const ServerInfo_User &_userInfo, bool _spectator, Server_AbstractUserInterface *_handler);
|
Server_Player(Server_Game *_game, int _playerId, const ServerInfo_User &_userInfo, bool _spectator, Server_AbstractUserInterface *_handler);
|
||||||
~Server_Player();
|
~Server_Player();
|
||||||
void prepareDestroy();
|
void prepareDestroy();
|
||||||
Server_AbstractUserInterface *getUserInterface() const { return userInterface; }
|
Server_AbstractUserInterface *getUserInterface() const { return userInterface; }
|
||||||
void setUserInterface(Server_AbstractUserInterface *_userInterface);
|
void setUserInterface(Server_AbstractUserInterface *_userInterface);
|
||||||
void disconnectClient();
|
void disconnectClient();
|
||||||
|
|
||||||
void setPlayerId(int _id) { playerId = _id; }
|
void setPlayerId(int _id) { playerId = _id; }
|
||||||
bool getReadyStart() const { return readyStart; }
|
bool getReadyStart() const { return readyStart; }
|
||||||
void setReadyStart(bool _readyStart) { readyStart = _readyStart; }
|
void setReadyStart(bool _readyStart) { readyStart = _readyStart; }
|
||||||
int getPlayerId() const { return playerId; }
|
int getPlayerId() const { return playerId; }
|
||||||
bool getSpectator() const { return spectator; }
|
bool getSpectator() const { return spectator; }
|
||||||
bool getConceded() const { return conceded; }
|
bool getConceded() const { return conceded; }
|
||||||
void setConceded(bool _conceded) { conceded = _conceded; }
|
void setConceded(bool _conceded) { conceded = _conceded; }
|
||||||
DeckList *getDeck() const { return deck; }
|
DeckList *getDeck() const { return deck; }
|
||||||
Server_Game *getGame() const { return game; }
|
Server_Game *getGame() const { return game; }
|
||||||
const QMap<QString, Server_CardZone *> &getZones() const { return zones; }
|
const QMap<QString, Server_CardZone *> &getZones() const { return zones; }
|
||||||
const QMap<int, Server_Counter *> &getCounters() const { return counters; }
|
const QMap<int, Server_Counter *> &getCounters() const { return counters; }
|
||||||
const QMap<int, Server_Arrow *> &getArrows() const { return arrows; }
|
const QMap<int, Server_Arrow *> &getArrows() const { return arrows; }
|
||||||
|
|
||||||
int getPingTime() const { return pingTime; }
|
int getPingTime() const { return pingTime; }
|
||||||
void setPingTime(int _pingTime) { pingTime = _pingTime; }
|
void setPingTime(int _pingTime) { pingTime = _pingTime; }
|
||||||
void getProperties(ServerInfo_PlayerProperties &result, bool withUserInfo);
|
void getProperties(ServerInfo_PlayerProperties &result, bool withUserInfo);
|
||||||
|
|
||||||
int newCardId();
|
int newCardId();
|
||||||
int newCounterId() const;
|
int newCounterId() const;
|
||||||
int newArrowId() const;
|
int newArrowId() const;
|
||||||
|
|
||||||
void addZone(Server_CardZone *zone);
|
void addZone(Server_CardZone *zone);
|
||||||
void addArrow(Server_Arrow *arrow);
|
void addArrow(Server_Arrow *arrow);
|
||||||
bool deleteArrow(int arrowId);
|
bool deleteArrow(int arrowId);
|
||||||
void addCounter(Server_Counter *counter);
|
void addCounter(Server_Counter *counter);
|
||||||
|
|
||||||
void clearZones();
|
void clearZones();
|
||||||
void setupZones();
|
void setupZones();
|
||||||
|
|
||||||
Response::ResponseCode drawCards(GameEventStorage &ges, int number);
|
Response::ResponseCode drawCards(GameEventStorage &ges, int number);
|
||||||
Response::ResponseCode moveCard(GameEventStorage &ges, Server_CardZone *startzone, const QList<const CardToMove *> &_cards, Server_CardZone *targetzone, int x, int y, bool fixFreeSpaces = true, bool undoingDraw = false);
|
Response::ResponseCode moveCard(GameEventStorage &ges, Server_CardZone *startzone, const QList<const CardToMove *> &_cards, Server_CardZone *targetzone, int x, int y, bool fixFreeSpaces = true, bool undoingDraw = false);
|
||||||
void unattachCard(GameEventStorage &ges, Server_Card *card);
|
void unattachCard(GameEventStorage &ges, Server_Card *card);
|
||||||
Response::ResponseCode setCardAttrHelper(GameEventStorage &ges, const QString &zone, int cardId, CardAttribute attribute, const QString &attrValue);
|
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 cmdLeaveGame(const Command_LeaveGame &cmd, ResponseContainer &rc, GameEventStorage &ges);
|
||||||
Response::ResponseCode cmdKickFromGame(const Command_KickFromGame &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 cmdConcede(const Command_Concede &cmd, ResponseContainer &rc, GameEventStorage &ges);
|
||||||
Response::ResponseCode cmdReadyStart(const Command_ReadyStart &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 cmdDeckSelect(const Command_DeckSelect &cmd, ResponseContainer &rc, GameEventStorage &ges);
|
||||||
Response::ResponseCode cmdSetSideboardPlan(const Command_SetSideboardPlan &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 cmdSetSideboardLock(const Command_SetSideboardLock &cmd, ResponseContainer &rc, GameEventStorage &ges);
|
||||||
Response::ResponseCode cmdGameSay(const Command_GameSay &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 cmdShuffle(const Command_Shuffle &cmd, ResponseContainer &rc, GameEventStorage &ges);
|
||||||
Response::ResponseCode cmdMulligan(const Command_Mulligan &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 cmdRollDie(const Command_RollDie &cmd, ResponseContainer &rc, GameEventStorage &ges);
|
||||||
Response::ResponseCode cmdDrawCards(const Command_DrawCards &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 cmdUndoDraw(const Command_UndoDraw &cmd, ResponseContainer &rc, GameEventStorage &ges);
|
||||||
Response::ResponseCode cmdMoveCard(const Command_MoveCard &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 cmdFlipCard(const Command_FlipCard &cmd, ResponseContainer &rc, GameEventStorage &ges);
|
||||||
Response::ResponseCode cmdAttachCard(const Command_AttachCard &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 cmdCreateToken(const Command_CreateToken &cmd, ResponseContainer &rc, GameEventStorage &ges);
|
||||||
Response::ResponseCode cmdCreateArrow(const Command_CreateArrow &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 cmdDeleteArrow(const Command_DeleteArrow &cmd, ResponseContainer &rc, GameEventStorage &ges);
|
||||||
Response::ResponseCode cmdSetCardAttr(const Command_SetCardAttr &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 cmdSetCardCounter(const Command_SetCardCounter &cmd, ResponseContainer &rc, GameEventStorage &ges);
|
||||||
Response::ResponseCode cmdIncCardCounter(const Command_IncCardCounter &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 cmdIncCounter(const Command_IncCounter &cmd, ResponseContainer &rc, GameEventStorage &ges);
|
||||||
Response::ResponseCode cmdCreateCounter(const Command_CreateCounter &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 cmdSetCounter(const Command_SetCounter &cmd, ResponseContainer &rc, GameEventStorage &ges);
|
||||||
Response::ResponseCode cmdDelCounter(const Command_DelCounter &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 cmdNextTurn(const Command_NextTurn &cmd, ResponseContainer &rc, GameEventStorage &ges);
|
||||||
Response::ResponseCode cmdSetActivePhase(const Command_SetActivePhase &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 cmdDumpZone(const Command_DumpZone &cmd, ResponseContainer &rc, GameEventStorage &ges);
|
||||||
Response::ResponseCode cmdStopDumpZone(const Command_StopDumpZone &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 cmdRevealCards(const Command_RevealCards &cmd, ResponseContainer &rc, GameEventStorage &ges);
|
||||||
Response::ResponseCode cmdChangeZoneProperties(const Command_ChangeZoneProperties &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);
|
Response::ResponseCode processGameCommand(const GameCommand &command, ResponseContainer &rc, GameEventStorage &ges);
|
||||||
void sendGameEvent(const GameEventContainer &event);
|
void sendGameEvent(const GameEventContainer &event);
|
||||||
|
|
||||||
void getInfo(ServerInfo_Player *info, Server_Player *playerWhosAsking, bool omniscient, bool withUserInfo);
|
void getInfo(ServerInfo_Player *info, Server_Player *playerWhosAsking, bool omniscient, bool withUserInfo);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -3,15 +3,15 @@
|
||||||
|
|
||||||
class PlayerReference {
|
class PlayerReference {
|
||||||
private:
|
private:
|
||||||
int roomId;
|
int roomId;
|
||||||
int gameId;
|
int gameId;
|
||||||
int playerId;
|
int playerId;
|
||||||
public:
|
public:
|
||||||
PlayerReference(int _roomId, int _gameId, int _playerId) : roomId(_roomId), gameId(_gameId), playerId(_playerId) { }
|
PlayerReference(int _roomId, int _gameId, int _playerId) : roomId(_roomId), gameId(_gameId), playerId(_playerId) { }
|
||||||
int getRoomId() const { return roomId; }
|
int getRoomId() const { return roomId; }
|
||||||
int getGameId() const { return gameId; }
|
int getGameId() const { return gameId; }
|
||||||
int getPlayerId() const { return playerId; }
|
int getPlayerId() const { return playerId; }
|
||||||
bool operator==(const PlayerReference &other) { return ((roomId == other.roomId) && (gameId == other.gameId) && (playerId == other.playerId)); }
|
bool operator==(const PlayerReference &other) { return ((roomId == other.roomId) && (gameId == other.gameId) && (playerId == other.playerId)); }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -21,17 +21,17 @@
|
||||||
#include <google/protobuf/descriptor.h>
|
#include <google/protobuf/descriptor.h>
|
||||||
|
|
||||||
Server_ProtocolHandler::Server_ProtocolHandler(Server *_server, Server_DatabaseInterface *_databaseInterface, QObject *parent)
|
Server_ProtocolHandler::Server_ProtocolHandler(Server *_server, Server_DatabaseInterface *_databaseInterface, QObject *parent)
|
||||||
: QObject(parent),
|
: QObject(parent),
|
||||||
Server_AbstractUserInterface(_server),
|
Server_AbstractUserInterface(_server),
|
||||||
deleted(false),
|
deleted(false),
|
||||||
databaseInterface(_databaseInterface),
|
databaseInterface(_databaseInterface),
|
||||||
authState(NotLoggedIn),
|
authState(NotLoggedIn),
|
||||||
acceptsUserListChanges(false),
|
acceptsUserListChanges(false),
|
||||||
acceptsRoomListChanges(false),
|
acceptsRoomListChanges(false),
|
||||||
timeRunning(0),
|
timeRunning(0),
|
||||||
lastDataReceived(0)
|
lastDataReceived(0)
|
||||||
{
|
{
|
||||||
connect(server, SIGNAL(pingClockTimeout()), this, SLOT(pingClockTimeout()));
|
connect(server, SIGNAL(pingClockTimeout()), this, SLOT(pingClockTimeout()));
|
||||||
}
|
}
|
||||||
|
|
||||||
Server_ProtocolHandler::~Server_ProtocolHandler()
|
Server_ProtocolHandler::~Server_ProtocolHandler()
|
||||||
|
|
@ -42,540 +42,540 @@ Server_ProtocolHandler::~Server_ProtocolHandler()
|
||||||
// The thread must not hold any server locks when calling this (e.g. clientsLock, roomsLock).
|
// The thread must not hold any server locks when calling this (e.g. clientsLock, roomsLock).
|
||||||
void Server_ProtocolHandler::prepareDestroy()
|
void Server_ProtocolHandler::prepareDestroy()
|
||||||
{
|
{
|
||||||
if (deleted)
|
if (deleted)
|
||||||
return;
|
return;
|
||||||
deleted = true;
|
deleted = true;
|
||||||
|
|
||||||
QMapIterator<int, Server_Room *> roomIterator(rooms);
|
QMapIterator<int, Server_Room *> roomIterator(rooms);
|
||||||
while (roomIterator.hasNext())
|
while (roomIterator.hasNext())
|
||||||
roomIterator.next().value()->removeClient(this);
|
roomIterator.next().value()->removeClient(this);
|
||||||
|
|
||||||
QMap<int, QPair<int, int> > tempGames(getGames());
|
QMap<int, QPair<int, int> > tempGames(getGames());
|
||||||
|
|
||||||
server->roomsLock.lockForRead();
|
server->roomsLock.lockForRead();
|
||||||
QMapIterator<int, QPair<int, int> > gameIterator(tempGames);
|
QMapIterator<int, QPair<int, int> > gameIterator(tempGames);
|
||||||
while (gameIterator.hasNext()) {
|
while (gameIterator.hasNext()) {
|
||||||
gameIterator.next();
|
gameIterator.next();
|
||||||
|
|
||||||
Server_Room *r = server->getRooms().value(gameIterator.value().first);
|
Server_Room *r = server->getRooms().value(gameIterator.value().first);
|
||||||
if (!r)
|
if (!r)
|
||||||
continue;
|
continue;
|
||||||
r->gamesLock.lockForRead();
|
r->gamesLock.lockForRead();
|
||||||
Server_Game *g = r->getGames().value(gameIterator.key());
|
Server_Game *g = r->getGames().value(gameIterator.key());
|
||||||
if (!g) {
|
if (!g) {
|
||||||
r->gamesLock.unlock();
|
r->gamesLock.unlock();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
g->gameMutex.lock();
|
g->gameMutex.lock();
|
||||||
Server_Player *p = g->getPlayers().value(gameIterator.value().second);
|
Server_Player *p = g->getPlayers().value(gameIterator.value().second);
|
||||||
if (!p) {
|
if (!p) {
|
||||||
g->gameMutex.unlock();
|
g->gameMutex.unlock();
|
||||||
r->gamesLock.unlock();
|
r->gamesLock.unlock();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
p->disconnectClient();
|
p->disconnectClient();
|
||||||
|
|
||||||
g->gameMutex.unlock();
|
g->gameMutex.unlock();
|
||||||
r->gamesLock.unlock();
|
r->gamesLock.unlock();
|
||||||
}
|
}
|
||||||
server->roomsLock.unlock();
|
server->roomsLock.unlock();
|
||||||
|
|
||||||
server->removeClient(this);
|
server->removeClient(this);
|
||||||
|
|
||||||
deleteLater();
|
deleteLater();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server_ProtocolHandler::sendProtocolItem(const Response &item)
|
void Server_ProtocolHandler::sendProtocolItem(const Response &item)
|
||||||
{
|
{
|
||||||
ServerMessage msg;
|
ServerMessage msg;
|
||||||
msg.mutable_response()->CopyFrom(item);
|
msg.mutable_response()->CopyFrom(item);
|
||||||
msg.set_message_type(ServerMessage::RESPONSE);
|
msg.set_message_type(ServerMessage::RESPONSE);
|
||||||
|
|
||||||
transmitProtocolItem(msg);
|
transmitProtocolItem(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server_ProtocolHandler::sendProtocolItem(const SessionEvent &item)
|
void Server_ProtocolHandler::sendProtocolItem(const SessionEvent &item)
|
||||||
{
|
{
|
||||||
ServerMessage msg;
|
ServerMessage msg;
|
||||||
msg.mutable_session_event()->CopyFrom(item);
|
msg.mutable_session_event()->CopyFrom(item);
|
||||||
msg.set_message_type(ServerMessage::SESSION_EVENT);
|
msg.set_message_type(ServerMessage::SESSION_EVENT);
|
||||||
|
|
||||||
transmitProtocolItem(msg);
|
transmitProtocolItem(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server_ProtocolHandler::sendProtocolItem(const GameEventContainer &item)
|
void Server_ProtocolHandler::sendProtocolItem(const GameEventContainer &item)
|
||||||
{
|
{
|
||||||
ServerMessage msg;
|
ServerMessage msg;
|
||||||
msg.mutable_game_event_container()->CopyFrom(item);
|
msg.mutable_game_event_container()->CopyFrom(item);
|
||||||
msg.set_message_type(ServerMessage::GAME_EVENT_CONTAINER);
|
msg.set_message_type(ServerMessage::GAME_EVENT_CONTAINER);
|
||||||
|
|
||||||
transmitProtocolItem(msg);
|
transmitProtocolItem(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server_ProtocolHandler::sendProtocolItem(const RoomEvent &item)
|
void Server_ProtocolHandler::sendProtocolItem(const RoomEvent &item)
|
||||||
{
|
{
|
||||||
ServerMessage msg;
|
ServerMessage msg;
|
||||||
msg.mutable_room_event()->CopyFrom(item);
|
msg.mutable_room_event()->CopyFrom(item);
|
||||||
msg.set_message_type(ServerMessage::ROOM_EVENT);
|
msg.set_message_type(ServerMessage::ROOM_EVENT);
|
||||||
|
|
||||||
transmitProtocolItem(msg);
|
transmitProtocolItem(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
Response::ResponseCode Server_ProtocolHandler::processSessionCommandContainer(const CommandContainer &cont, ResponseContainer &rc)
|
Response::ResponseCode Server_ProtocolHandler::processSessionCommandContainer(const CommandContainer &cont, ResponseContainer &rc)
|
||||||
{
|
{
|
||||||
Response::ResponseCode finalResponseCode = Response::RespOk;
|
Response::ResponseCode finalResponseCode = Response::RespOk;
|
||||||
for (int i = cont.session_command_size() - 1; i >= 0; --i) {
|
for (int i = cont.session_command_size() - 1; i >= 0; --i) {
|
||||||
Response::ResponseCode resp = Response::RespInvalidCommand;
|
Response::ResponseCode resp = Response::RespInvalidCommand;
|
||||||
const SessionCommand &sc = cont.session_command(i);
|
const SessionCommand &sc = cont.session_command(i);
|
||||||
const int num = getPbExtension(sc);
|
const int num = getPbExtension(sc);
|
||||||
if (num != SessionCommand::PING) { // don't log ping commands
|
if (num != SessionCommand::PING) { // don't log ping commands
|
||||||
if (num == SessionCommand::LOGIN) { // log login commands, but hide passwords
|
if (num == SessionCommand::LOGIN) { // log login commands, but hide passwords
|
||||||
SessionCommand debugSc(sc);
|
SessionCommand debugSc(sc);
|
||||||
debugSc.MutableExtension(Command_Login::ext)->clear_password();
|
debugSc.MutableExtension(Command_Login::ext)->clear_password();
|
||||||
logDebugMessage(QString::fromStdString(debugSc.ShortDebugString()));
|
logDebugMessage(QString::fromStdString(debugSc.ShortDebugString()));
|
||||||
} else
|
} else
|
||||||
logDebugMessage(QString::fromStdString(sc.ShortDebugString()));
|
logDebugMessage(QString::fromStdString(sc.ShortDebugString()));
|
||||||
}
|
}
|
||||||
switch ((SessionCommand::SessionCommandType) num) {
|
switch ((SessionCommand::SessionCommandType) num) {
|
||||||
case SessionCommand::PING: resp = cmdPing(sc.GetExtension(Command_Ping::ext), rc); break;
|
case SessionCommand::PING: resp = cmdPing(sc.GetExtension(Command_Ping::ext), rc); break;
|
||||||
case SessionCommand::LOGIN: resp = cmdLogin(sc.GetExtension(Command_Login::ext), rc); break;
|
case SessionCommand::LOGIN: resp = cmdLogin(sc.GetExtension(Command_Login::ext), rc); break;
|
||||||
case SessionCommand::MESSAGE: resp = cmdMessage(sc.GetExtension(Command_Message::ext), rc); break;
|
case SessionCommand::MESSAGE: resp = cmdMessage(sc.GetExtension(Command_Message::ext), rc); break;
|
||||||
case SessionCommand::GET_GAMES_OF_USER: resp = cmdGetGamesOfUser(sc.GetExtension(Command_GetGamesOfUser::ext), rc); break;
|
case SessionCommand::GET_GAMES_OF_USER: resp = cmdGetGamesOfUser(sc.GetExtension(Command_GetGamesOfUser::ext), rc); break;
|
||||||
case SessionCommand::GET_USER_INFO: resp = cmdGetUserInfo(sc.GetExtension(Command_GetUserInfo::ext), rc); break;
|
case SessionCommand::GET_USER_INFO: resp = cmdGetUserInfo(sc.GetExtension(Command_GetUserInfo::ext), rc); break;
|
||||||
case SessionCommand::LIST_ROOMS: resp = cmdListRooms(sc.GetExtension(Command_ListRooms::ext), rc); break;
|
case SessionCommand::LIST_ROOMS: resp = cmdListRooms(sc.GetExtension(Command_ListRooms::ext), rc); break;
|
||||||
case SessionCommand::JOIN_ROOM: resp = cmdJoinRoom(sc.GetExtension(Command_JoinRoom::ext), rc); break;
|
case SessionCommand::JOIN_ROOM: resp = cmdJoinRoom(sc.GetExtension(Command_JoinRoom::ext), rc); break;
|
||||||
case SessionCommand::LIST_USERS: resp = cmdListUsers(sc.GetExtension(Command_ListUsers::ext), rc); break;
|
case SessionCommand::LIST_USERS: resp = cmdListUsers(sc.GetExtension(Command_ListUsers::ext), rc); break;
|
||||||
default: resp = processExtendedSessionCommand(num, sc, rc);
|
default: resp = processExtendedSessionCommand(num, sc, rc);
|
||||||
}
|
}
|
||||||
if (resp != Response::RespOk)
|
if (resp != Response::RespOk)
|
||||||
finalResponseCode = resp;
|
finalResponseCode = resp;
|
||||||
}
|
}
|
||||||
return finalResponseCode;
|
return finalResponseCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
Response::ResponseCode Server_ProtocolHandler::processRoomCommandContainer(const CommandContainer &cont, ResponseContainer &rc)
|
Response::ResponseCode Server_ProtocolHandler::processRoomCommandContainer(const CommandContainer &cont, ResponseContainer &rc)
|
||||||
{
|
{
|
||||||
if (authState == NotLoggedIn)
|
if (authState == NotLoggedIn)
|
||||||
return Response::RespLoginNeeded;
|
return Response::RespLoginNeeded;
|
||||||
|
|
||||||
QReadLocker locker(&server->roomsLock);
|
QReadLocker locker(&server->roomsLock);
|
||||||
Server_Room *room = rooms.value(cont.room_id(), 0);
|
Server_Room *room = rooms.value(cont.room_id(), 0);
|
||||||
if (!room)
|
if (!room)
|
||||||
return Response::RespNotInRoom;
|
return Response::RespNotInRoom;
|
||||||
|
|
||||||
Response::ResponseCode finalResponseCode = Response::RespOk;
|
Response::ResponseCode finalResponseCode = Response::RespOk;
|
||||||
for (int i = cont.room_command_size() - 1; i >= 0; --i) {
|
for (int i = cont.room_command_size() - 1; i >= 0; --i) {
|
||||||
Response::ResponseCode resp = Response::RespInvalidCommand;
|
Response::ResponseCode resp = Response::RespInvalidCommand;
|
||||||
const RoomCommand &sc = cont.room_command(i);
|
const RoomCommand &sc = cont.room_command(i);
|
||||||
const int num = getPbExtension(sc);
|
const int num = getPbExtension(sc);
|
||||||
logDebugMessage(QString::fromStdString(sc.ShortDebugString()));
|
logDebugMessage(QString::fromStdString(sc.ShortDebugString()));
|
||||||
switch ((RoomCommand::RoomCommandType) num) {
|
switch ((RoomCommand::RoomCommandType) num) {
|
||||||
case RoomCommand::LEAVE_ROOM: resp = cmdLeaveRoom(sc.GetExtension(Command_LeaveRoom::ext), room, rc); break;
|
case RoomCommand::LEAVE_ROOM: resp = cmdLeaveRoom(sc.GetExtension(Command_LeaveRoom::ext), room, rc); break;
|
||||||
case RoomCommand::ROOM_SAY: resp = cmdRoomSay(sc.GetExtension(Command_RoomSay::ext), room, rc); break;
|
case RoomCommand::ROOM_SAY: resp = cmdRoomSay(sc.GetExtension(Command_RoomSay::ext), room, rc); break;
|
||||||
case RoomCommand::CREATE_GAME: resp = cmdCreateGame(sc.GetExtension(Command_CreateGame::ext), room, rc); break;
|
case RoomCommand::CREATE_GAME: resp = cmdCreateGame(sc.GetExtension(Command_CreateGame::ext), room, rc); break;
|
||||||
case RoomCommand::JOIN_GAME: resp = cmdJoinGame(sc.GetExtension(Command_JoinGame::ext), room, rc); break;
|
case RoomCommand::JOIN_GAME: resp = cmdJoinGame(sc.GetExtension(Command_JoinGame::ext), room, rc); break;
|
||||||
}
|
}
|
||||||
if (resp != Response::RespOk)
|
if (resp != Response::RespOk)
|
||||||
finalResponseCode = resp;
|
finalResponseCode = resp;
|
||||||
}
|
}
|
||||||
return finalResponseCode;
|
return finalResponseCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
Response::ResponseCode Server_ProtocolHandler::processGameCommandContainer(const CommandContainer &cont, ResponseContainer &rc)
|
Response::ResponseCode Server_ProtocolHandler::processGameCommandContainer(const CommandContainer &cont, ResponseContainer &rc)
|
||||||
{
|
{
|
||||||
if (authState == NotLoggedIn)
|
if (authState == NotLoggedIn)
|
||||||
return Response::RespLoginNeeded;
|
return Response::RespLoginNeeded;
|
||||||
|
|
||||||
QMap<int, QPair<int, int> > gameMap = getGames();
|
QMap<int, QPair<int, int> > gameMap = getGames();
|
||||||
if (!gameMap.contains(cont.game_id()))
|
if (!gameMap.contains(cont.game_id()))
|
||||||
return Response::RespNotInRoom;
|
return Response::RespNotInRoom;
|
||||||
const QPair<int, int> roomIdAndPlayerId = gameMap.value(cont.game_id());
|
const QPair<int, int> roomIdAndPlayerId = gameMap.value(cont.game_id());
|
||||||
|
|
||||||
QReadLocker roomsLocker(&server->roomsLock);
|
QReadLocker roomsLocker(&server->roomsLock);
|
||||||
Server_Room *room = server->getRooms().value(roomIdAndPlayerId.first);
|
Server_Room *room = server->getRooms().value(roomIdAndPlayerId.first);
|
||||||
if (!room)
|
if (!room)
|
||||||
return Response::RespNotInRoom;
|
return Response::RespNotInRoom;
|
||||||
|
|
||||||
QReadLocker roomGamesLocker(&room->gamesLock);
|
QReadLocker roomGamesLocker(&room->gamesLock);
|
||||||
Server_Game *game = room->getGames().value(cont.game_id());
|
Server_Game *game = room->getGames().value(cont.game_id());
|
||||||
if (!game) {
|
if (!game) {
|
||||||
if (room->getExternalGames().contains(cont.game_id())) {
|
if (room->getExternalGames().contains(cont.game_id())) {
|
||||||
server->sendIsl_GameCommand(cont,
|
server->sendIsl_GameCommand(cont,
|
||||||
room->getExternalGames().value(cont.game_id()).server_id(),
|
room->getExternalGames().value(cont.game_id()).server_id(),
|
||||||
userInfo->session_id(),
|
userInfo->session_id(),
|
||||||
roomIdAndPlayerId.first,
|
roomIdAndPlayerId.first,
|
||||||
roomIdAndPlayerId.second
|
roomIdAndPlayerId.second
|
||||||
);
|
);
|
||||||
return Response::RespNothing;
|
return Response::RespNothing;
|
||||||
}
|
}
|
||||||
return Response::RespNotInRoom;
|
return Response::RespNotInRoom;
|
||||||
}
|
}
|
||||||
|
|
||||||
QMutexLocker gameLocker(&game->gameMutex);
|
QMutexLocker gameLocker(&game->gameMutex);
|
||||||
Server_Player *player = game->getPlayers().value(roomIdAndPlayerId.second);
|
Server_Player *player = game->getPlayers().value(roomIdAndPlayerId.second);
|
||||||
if (!player)
|
if (!player)
|
||||||
return Response::RespNotInRoom;
|
return Response::RespNotInRoom;
|
||||||
|
|
||||||
GameEventStorage ges;
|
GameEventStorage ges;
|
||||||
Response::ResponseCode finalResponseCode = Response::RespOk;
|
Response::ResponseCode finalResponseCode = Response::RespOk;
|
||||||
for (int i = cont.game_command_size() - 1; i >= 0; --i) {
|
for (int i = cont.game_command_size() - 1; i >= 0; --i) {
|
||||||
const GameCommand &sc = cont.game_command(i);
|
const GameCommand &sc = cont.game_command(i);
|
||||||
logDebugMessage(QString("game %1 player %2: ").arg(cont.game_id()).arg(roomIdAndPlayerId.second) + QString::fromStdString(sc.ShortDebugString()));
|
logDebugMessage(QString("game %1 player %2: ").arg(cont.game_id()).arg(roomIdAndPlayerId.second) + QString::fromStdString(sc.ShortDebugString()));
|
||||||
|
|
||||||
Response::ResponseCode resp = player->processGameCommand(sc, rc, ges);
|
Response::ResponseCode resp = player->processGameCommand(sc, rc, ges);
|
||||||
|
|
||||||
if (resp != Response::RespOk)
|
if (resp != Response::RespOk)
|
||||||
finalResponseCode = resp;
|
finalResponseCode = resp;
|
||||||
}
|
}
|
||||||
ges.sendToGame(game);
|
ges.sendToGame(game);
|
||||||
|
|
||||||
return finalResponseCode;
|
return finalResponseCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
Response::ResponseCode Server_ProtocolHandler::processModeratorCommandContainer(const CommandContainer &cont, ResponseContainer &rc)
|
Response::ResponseCode Server_ProtocolHandler::processModeratorCommandContainer(const CommandContainer &cont, ResponseContainer &rc)
|
||||||
{
|
{
|
||||||
if (!userInfo)
|
if (!userInfo)
|
||||||
return Response::RespLoginNeeded;
|
return Response::RespLoginNeeded;
|
||||||
if (!(userInfo->user_level() & ServerInfo_User::IsModerator))
|
if (!(userInfo->user_level() & ServerInfo_User::IsModerator))
|
||||||
return Response::RespLoginNeeded;
|
return Response::RespLoginNeeded;
|
||||||
|
|
||||||
Response::ResponseCode finalResponseCode = Response::RespOk;
|
Response::ResponseCode finalResponseCode = Response::RespOk;
|
||||||
for (int i = cont.moderator_command_size() - 1; i >= 0; --i) {
|
for (int i = cont.moderator_command_size() - 1; i >= 0; --i) {
|
||||||
Response::ResponseCode resp = Response::RespInvalidCommand;
|
Response::ResponseCode resp = Response::RespInvalidCommand;
|
||||||
const ModeratorCommand &sc = cont.moderator_command(i);
|
const ModeratorCommand &sc = cont.moderator_command(i);
|
||||||
const int num = getPbExtension(sc);
|
const int num = getPbExtension(sc);
|
||||||
logDebugMessage(QString::fromStdString(sc.ShortDebugString()));
|
logDebugMessage(QString::fromStdString(sc.ShortDebugString()));
|
||||||
|
|
||||||
resp = processExtendedModeratorCommand(num, sc, rc);
|
resp = processExtendedModeratorCommand(num, sc, rc);
|
||||||
if (resp != Response::RespOk)
|
if (resp != Response::RespOk)
|
||||||
finalResponseCode = resp;
|
finalResponseCode = resp;
|
||||||
}
|
}
|
||||||
return finalResponseCode;
|
return finalResponseCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
Response::ResponseCode Server_ProtocolHandler::processAdminCommandContainer(const CommandContainer &cont, ResponseContainer &rc)
|
Response::ResponseCode Server_ProtocolHandler::processAdminCommandContainer(const CommandContainer &cont, ResponseContainer &rc)
|
||||||
{
|
{
|
||||||
if (!userInfo)
|
if (!userInfo)
|
||||||
return Response::RespLoginNeeded;
|
return Response::RespLoginNeeded;
|
||||||
if (!(userInfo->user_level() & ServerInfo_User::IsAdmin))
|
if (!(userInfo->user_level() & ServerInfo_User::IsAdmin))
|
||||||
return Response::RespLoginNeeded;
|
return Response::RespLoginNeeded;
|
||||||
|
|
||||||
Response::ResponseCode finalResponseCode = Response::RespOk;
|
Response::ResponseCode finalResponseCode = Response::RespOk;
|
||||||
for (int i = cont.admin_command_size() - 1; i >= 0; --i) {
|
for (int i = cont.admin_command_size() - 1; i >= 0; --i) {
|
||||||
Response::ResponseCode resp = Response::RespInvalidCommand;
|
Response::ResponseCode resp = Response::RespInvalidCommand;
|
||||||
const AdminCommand &sc = cont.admin_command(i);
|
const AdminCommand &sc = cont.admin_command(i);
|
||||||
const int num = getPbExtension(sc);
|
const int num = getPbExtension(sc);
|
||||||
logDebugMessage(QString::fromStdString(sc.ShortDebugString()));
|
logDebugMessage(QString::fromStdString(sc.ShortDebugString()));
|
||||||
|
|
||||||
resp = processExtendedAdminCommand(num, sc, rc);
|
resp = processExtendedAdminCommand(num, sc, rc);
|
||||||
if (resp != Response::RespOk)
|
if (resp != Response::RespOk)
|
||||||
finalResponseCode = resp;
|
finalResponseCode = resp;
|
||||||
}
|
}
|
||||||
return finalResponseCode;
|
return finalResponseCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server_ProtocolHandler::processCommandContainer(const CommandContainer &cont)
|
void Server_ProtocolHandler::processCommandContainer(const CommandContainer &cont)
|
||||||
{
|
{
|
||||||
// Command processing must be disabled after prepareDestroy() has been called.
|
// Command processing must be disabled after prepareDestroy() has been called.
|
||||||
if (deleted)
|
if (deleted)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
lastDataReceived = timeRunning;
|
lastDataReceived = timeRunning;
|
||||||
|
|
||||||
ResponseContainer responseContainer(cont.has_cmd_id() ? cont.cmd_id() : -1);
|
ResponseContainer responseContainer(cont.has_cmd_id() ? cont.cmd_id() : -1);
|
||||||
Response::ResponseCode finalResponseCode;
|
Response::ResponseCode finalResponseCode;
|
||||||
|
|
||||||
if (cont.game_command_size())
|
if (cont.game_command_size())
|
||||||
finalResponseCode = processGameCommandContainer(cont, responseContainer);
|
finalResponseCode = processGameCommandContainer(cont, responseContainer);
|
||||||
else if (cont.room_command_size())
|
else if (cont.room_command_size())
|
||||||
finalResponseCode = processRoomCommandContainer(cont, responseContainer);
|
finalResponseCode = processRoomCommandContainer(cont, responseContainer);
|
||||||
else if (cont.session_command_size())
|
else if (cont.session_command_size())
|
||||||
finalResponseCode = processSessionCommandContainer(cont, responseContainer);
|
finalResponseCode = processSessionCommandContainer(cont, responseContainer);
|
||||||
else if (cont.moderator_command_size())
|
else if (cont.moderator_command_size())
|
||||||
finalResponseCode = processModeratorCommandContainer(cont, responseContainer);
|
finalResponseCode = processModeratorCommandContainer(cont, responseContainer);
|
||||||
else if (cont.admin_command_size())
|
else if (cont.admin_command_size())
|
||||||
finalResponseCode = processAdminCommandContainer(cont, responseContainer);
|
finalResponseCode = processAdminCommandContainer(cont, responseContainer);
|
||||||
else
|
else
|
||||||
finalResponseCode = Response::RespInvalidCommand;
|
finalResponseCode = Response::RespInvalidCommand;
|
||||||
|
|
||||||
if ((finalResponseCode != Response::RespNothing))
|
if ((finalResponseCode != Response::RespNothing))
|
||||||
sendResponseContainer(responseContainer, finalResponseCode);
|
sendResponseContainer(responseContainer, finalResponseCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server_ProtocolHandler::pingClockTimeout()
|
void Server_ProtocolHandler::pingClockTimeout()
|
||||||
{
|
{
|
||||||
int interval = server->getMessageCountingInterval();
|
int interval = server->getMessageCountingInterval();
|
||||||
if (interval > 0) {
|
if (interval > 0) {
|
||||||
messageSizeOverTime.prepend(0);
|
messageSizeOverTime.prepend(0);
|
||||||
if (messageSizeOverTime.size() > server->getMessageCountingInterval())
|
if (messageSizeOverTime.size() > server->getMessageCountingInterval())
|
||||||
messageSizeOverTime.removeLast();
|
messageSizeOverTime.removeLast();
|
||||||
messageCountOverTime.prepend(0);
|
messageCountOverTime.prepend(0);
|
||||||
if (messageCountOverTime.size() > server->getMessageCountingInterval())
|
if (messageCountOverTime.size() > server->getMessageCountingInterval())
|
||||||
messageCountOverTime.removeLast();
|
messageCountOverTime.removeLast();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (timeRunning - lastDataReceived > server->getMaxPlayerInactivityTime())
|
if (timeRunning - lastDataReceived > server->getMaxPlayerInactivityTime())
|
||||||
prepareDestroy();
|
prepareDestroy();
|
||||||
++timeRunning;
|
++timeRunning;
|
||||||
}
|
}
|
||||||
|
|
||||||
Response::ResponseCode Server_ProtocolHandler::cmdPing(const Command_Ping & /*cmd*/, ResponseContainer & /*rc*/)
|
Response::ResponseCode Server_ProtocolHandler::cmdPing(const Command_Ping & /*cmd*/, ResponseContainer & /*rc*/)
|
||||||
{
|
{
|
||||||
return Response::RespOk;
|
return Response::RespOk;
|
||||||
}
|
}
|
||||||
|
|
||||||
Response::ResponseCode Server_ProtocolHandler::cmdLogin(const Command_Login &cmd, ResponseContainer &rc)
|
Response::ResponseCode Server_ProtocolHandler::cmdLogin(const Command_Login &cmd, ResponseContainer &rc)
|
||||||
{
|
{
|
||||||
QString userName = QString::fromStdString(cmd.user_name()).simplified();
|
QString userName = QString::fromStdString(cmd.user_name()).simplified();
|
||||||
if (userName.isEmpty() || (userInfo != 0))
|
if (userName.isEmpty() || (userInfo != 0))
|
||||||
return Response::RespContextError;
|
return Response::RespContextError;
|
||||||
QString reasonStr;
|
QString reasonStr;
|
||||||
int banSecondsLeft = 0;
|
int banSecondsLeft = 0;
|
||||||
AuthenticationResult res = server->loginUser(this, userName, QString::fromStdString(cmd.password()), reasonStr, banSecondsLeft);
|
AuthenticationResult res = server->loginUser(this, userName, QString::fromStdString(cmd.password()), reasonStr, banSecondsLeft);
|
||||||
switch (res) {
|
switch (res) {
|
||||||
case UserIsBanned: {
|
case UserIsBanned: {
|
||||||
Response_Login *re = new Response_Login;
|
Response_Login *re = new Response_Login;
|
||||||
re->set_denied_reason_str(reasonStr.toStdString());
|
re->set_denied_reason_str(reasonStr.toStdString());
|
||||||
if (banSecondsLeft != 0)
|
if (banSecondsLeft != 0)
|
||||||
re->set_denied_end_time(QDateTime::currentDateTime().addSecs(banSecondsLeft).toTime_t());
|
re->set_denied_end_time(QDateTime::currentDateTime().addSecs(banSecondsLeft).toTime_t());
|
||||||
rc.setResponseExtension(re);
|
rc.setResponseExtension(re);
|
||||||
return Response::RespUserIsBanned;
|
return Response::RespUserIsBanned;
|
||||||
}
|
}
|
||||||
case NotLoggedIn: return Response::RespWrongPassword;
|
case NotLoggedIn: return Response::RespWrongPassword;
|
||||||
case WouldOverwriteOldSession: return Response::RespWouldOverwriteOldSession;
|
case WouldOverwriteOldSession: return Response::RespWouldOverwriteOldSession;
|
||||||
case UsernameInvalid: return Response::RespUsernameInvalid;
|
case UsernameInvalid: return Response::RespUsernameInvalid;
|
||||||
default: authState = res;
|
default: authState = res;
|
||||||
}
|
}
|
||||||
|
|
||||||
userName = QString::fromStdString(userInfo->name());
|
userName = QString::fromStdString(userInfo->name());
|
||||||
Event_ServerMessage event;
|
Event_ServerMessage event;
|
||||||
event.set_message(server->getLoginMessage().toStdString());
|
event.set_message(server->getLoginMessage().toStdString());
|
||||||
rc.enqueuePostResponseItem(ServerMessage::SESSION_EVENT, prepareSessionEvent(event));
|
rc.enqueuePostResponseItem(ServerMessage::SESSION_EVENT, prepareSessionEvent(event));
|
||||||
|
|
||||||
Response_Login *re = new Response_Login;
|
Response_Login *re = new Response_Login;
|
||||||
re->mutable_user_info()->CopyFrom(copyUserInfo(true));
|
re->mutable_user_info()->CopyFrom(copyUserInfo(true));
|
||||||
|
|
||||||
if (authState == PasswordRight) {
|
if (authState == PasswordRight) {
|
||||||
QMapIterator<QString, ServerInfo_User> buddyIterator(databaseInterface->getBuddyList(userName));
|
QMapIterator<QString, ServerInfo_User> buddyIterator(databaseInterface->getBuddyList(userName));
|
||||||
while (buddyIterator.hasNext())
|
while (buddyIterator.hasNext())
|
||||||
re->add_buddy_list()->CopyFrom(buddyIterator.next().value());
|
re->add_buddy_list()->CopyFrom(buddyIterator.next().value());
|
||||||
|
|
||||||
QMapIterator<QString, ServerInfo_User> ignoreIterator(databaseInterface->getIgnoreList(userName));
|
QMapIterator<QString, ServerInfo_User> ignoreIterator(databaseInterface->getIgnoreList(userName));
|
||||||
while (ignoreIterator.hasNext())
|
while (ignoreIterator.hasNext())
|
||||||
re->add_ignore_list()->CopyFrom(ignoreIterator.next().value());
|
re->add_ignore_list()->CopyFrom(ignoreIterator.next().value());
|
||||||
}
|
}
|
||||||
|
|
||||||
joinPersistentGames(rc);
|
joinPersistentGames(rc);
|
||||||
|
|
||||||
rc.setResponseExtension(re);
|
rc.setResponseExtension(re);
|
||||||
return Response::RespOk;
|
return Response::RespOk;
|
||||||
}
|
}
|
||||||
|
|
||||||
Response::ResponseCode Server_ProtocolHandler::cmdMessage(const Command_Message &cmd, ResponseContainer &rc)
|
Response::ResponseCode Server_ProtocolHandler::cmdMessage(const Command_Message &cmd, ResponseContainer &rc)
|
||||||
{
|
{
|
||||||
if (authState == NotLoggedIn)
|
if (authState == NotLoggedIn)
|
||||||
return Response::RespLoginNeeded;
|
return Response::RespLoginNeeded;
|
||||||
|
|
||||||
QReadLocker locker(&server->clientsLock);
|
QReadLocker locker(&server->clientsLock);
|
||||||
|
|
||||||
QString receiver = QString::fromStdString(cmd.user_name());
|
QString receiver = QString::fromStdString(cmd.user_name());
|
||||||
Server_AbstractUserInterface *userInterface = server->findUser(receiver);
|
Server_AbstractUserInterface *userInterface = server->findUser(receiver);
|
||||||
if (!userInterface)
|
if (!userInterface)
|
||||||
return Response::RespNameNotFound;
|
return Response::RespNameNotFound;
|
||||||
if (databaseInterface->isInIgnoreList(receiver, QString::fromStdString(userInfo->name())))
|
if (databaseInterface->isInIgnoreList(receiver, QString::fromStdString(userInfo->name())))
|
||||||
return Response::RespInIgnoreList;
|
return Response::RespInIgnoreList;
|
||||||
|
|
||||||
Event_UserMessage event;
|
Event_UserMessage event;
|
||||||
event.set_sender_name(userInfo->name());
|
event.set_sender_name(userInfo->name());
|
||||||
event.set_receiver_name(cmd.user_name());
|
event.set_receiver_name(cmd.user_name());
|
||||||
event.set_message(cmd.message());
|
event.set_message(cmd.message());
|
||||||
|
|
||||||
SessionEvent *se = prepareSessionEvent(event);
|
SessionEvent *se = prepareSessionEvent(event);
|
||||||
userInterface->sendProtocolItem(*se);
|
userInterface->sendProtocolItem(*se);
|
||||||
rc.enqueuePreResponseItem(ServerMessage::SESSION_EVENT, se);
|
rc.enqueuePreResponseItem(ServerMessage::SESSION_EVENT, se);
|
||||||
|
|
||||||
return Response::RespOk;
|
return Response::RespOk;
|
||||||
}
|
}
|
||||||
|
|
||||||
Response::ResponseCode Server_ProtocolHandler::cmdGetGamesOfUser(const Command_GetGamesOfUser &cmd, ResponseContainer &rc)
|
Response::ResponseCode Server_ProtocolHandler::cmdGetGamesOfUser(const Command_GetGamesOfUser &cmd, ResponseContainer &rc)
|
||||||
{
|
{
|
||||||
if (authState == NotLoggedIn)
|
if (authState == NotLoggedIn)
|
||||||
return Response::RespLoginNeeded;
|
return Response::RespLoginNeeded;
|
||||||
|
|
||||||
// We don't need to check whether the user is logged in; persistent games should also work.
|
// We don't need to check whether the user is logged in; persistent games should also work.
|
||||||
// The client needs to deal with an empty result list.
|
// The client needs to deal with an empty result list.
|
||||||
|
|
||||||
Response_GetGamesOfUser *re = new Response_GetGamesOfUser;
|
Response_GetGamesOfUser *re = new Response_GetGamesOfUser;
|
||||||
server->roomsLock.lockForRead();
|
server->roomsLock.lockForRead();
|
||||||
QMapIterator<int, Server_Room *> roomIterator(server->getRooms());
|
QMapIterator<int, Server_Room *> roomIterator(server->getRooms());
|
||||||
while (roomIterator.hasNext()) {
|
while (roomIterator.hasNext()) {
|
||||||
Server_Room *room = roomIterator.next().value();
|
Server_Room *room = roomIterator.next().value();
|
||||||
room->gamesLock.lockForRead();
|
room->gamesLock.lockForRead();
|
||||||
room->getInfo(*re->add_room_list(), false, true);
|
room->getInfo(*re->add_room_list(), false, true);
|
||||||
QListIterator<ServerInfo_Game> gameIterator(room->getGamesOfUser(QString::fromStdString(cmd.user_name())));
|
QListIterator<ServerInfo_Game> gameIterator(room->getGamesOfUser(QString::fromStdString(cmd.user_name())));
|
||||||
while (gameIterator.hasNext())
|
while (gameIterator.hasNext())
|
||||||
re->add_game_list()->CopyFrom(gameIterator.next());
|
re->add_game_list()->CopyFrom(gameIterator.next());
|
||||||
room->gamesLock.unlock();
|
room->gamesLock.unlock();
|
||||||
}
|
}
|
||||||
server->roomsLock.unlock();
|
server->roomsLock.unlock();
|
||||||
|
|
||||||
rc.setResponseExtension(re);
|
rc.setResponseExtension(re);
|
||||||
return Response::RespOk;
|
return Response::RespOk;
|
||||||
}
|
}
|
||||||
|
|
||||||
Response::ResponseCode Server_ProtocolHandler::cmdGetUserInfo(const Command_GetUserInfo &cmd, ResponseContainer &rc)
|
Response::ResponseCode Server_ProtocolHandler::cmdGetUserInfo(const Command_GetUserInfo &cmd, ResponseContainer &rc)
|
||||||
{
|
{
|
||||||
if (authState == NotLoggedIn)
|
if (authState == NotLoggedIn)
|
||||||
return Response::RespLoginNeeded;
|
return Response::RespLoginNeeded;
|
||||||
|
|
||||||
QString userName = QString::fromStdString(cmd.user_name());
|
QString userName = QString::fromStdString(cmd.user_name());
|
||||||
Response_GetUserInfo *re = new Response_GetUserInfo;
|
Response_GetUserInfo *re = new Response_GetUserInfo;
|
||||||
if (userName.isEmpty())
|
if (userName.isEmpty())
|
||||||
re->mutable_user_info()->CopyFrom(*userInfo);
|
re->mutable_user_info()->CopyFrom(*userInfo);
|
||||||
else {
|
else {
|
||||||
|
|
||||||
QReadLocker locker(&server->clientsLock);
|
QReadLocker locker(&server->clientsLock);
|
||||||
|
|
||||||
ServerInfo_User_Container *infoSource = server->findUser(userName);
|
ServerInfo_User_Container *infoSource = server->findUser(userName);
|
||||||
if (!infoSource)
|
if (!infoSource)
|
||||||
return Response::RespNameNotFound;
|
return Response::RespNameNotFound;
|
||||||
|
|
||||||
re->mutable_user_info()->CopyFrom(infoSource->copyUserInfo(true, false, userInfo->user_level() & ServerInfo_User::IsModerator));
|
re->mutable_user_info()->CopyFrom(infoSource->copyUserInfo(true, false, userInfo->user_level() & ServerInfo_User::IsModerator));
|
||||||
}
|
}
|
||||||
|
|
||||||
rc.setResponseExtension(re);
|
rc.setResponseExtension(re);
|
||||||
return Response::RespOk;
|
return Response::RespOk;
|
||||||
}
|
}
|
||||||
|
|
||||||
Response::ResponseCode Server_ProtocolHandler::cmdListRooms(const Command_ListRooms & /*cmd*/, ResponseContainer &rc)
|
Response::ResponseCode Server_ProtocolHandler::cmdListRooms(const Command_ListRooms & /*cmd*/, ResponseContainer &rc)
|
||||||
{
|
{
|
||||||
if (authState == NotLoggedIn)
|
if (authState == NotLoggedIn)
|
||||||
return Response::RespLoginNeeded;
|
return Response::RespLoginNeeded;
|
||||||
|
|
||||||
Event_ListRooms event;
|
Event_ListRooms event;
|
||||||
QMapIterator<int, Server_Room *> roomIterator(server->getRooms());
|
QMapIterator<int, Server_Room *> roomIterator(server->getRooms());
|
||||||
while (roomIterator.hasNext())
|
while (roomIterator.hasNext())
|
||||||
roomIterator.next().value()->getInfo(*event.add_room_list(), false);
|
roomIterator.next().value()->getInfo(*event.add_room_list(), false);
|
||||||
rc.enqueuePreResponseItem(ServerMessage::SESSION_EVENT, prepareSessionEvent(event));
|
rc.enqueuePreResponseItem(ServerMessage::SESSION_EVENT, prepareSessionEvent(event));
|
||||||
|
|
||||||
acceptsRoomListChanges = true;
|
acceptsRoomListChanges = true;
|
||||||
return Response::RespOk;
|
return Response::RespOk;
|
||||||
}
|
}
|
||||||
|
|
||||||
Response::ResponseCode Server_ProtocolHandler::cmdJoinRoom(const Command_JoinRoom &cmd, ResponseContainer &rc)
|
Response::ResponseCode Server_ProtocolHandler::cmdJoinRoom(const Command_JoinRoom &cmd, ResponseContainer &rc)
|
||||||
{
|
{
|
||||||
if (authState == NotLoggedIn)
|
if (authState == NotLoggedIn)
|
||||||
return Response::RespLoginNeeded;
|
return Response::RespLoginNeeded;
|
||||||
|
|
||||||
if (rooms.contains(cmd.room_id()))
|
if (rooms.contains(cmd.room_id()))
|
||||||
return Response::RespContextError;
|
return Response::RespContextError;
|
||||||
|
|
||||||
QReadLocker serverLocker(&server->roomsLock);
|
QReadLocker serverLocker(&server->roomsLock);
|
||||||
Server_Room *r = server->getRooms().value(cmd.room_id(), 0);
|
Server_Room *r = server->getRooms().value(cmd.room_id(), 0);
|
||||||
if (!r)
|
if (!r)
|
||||||
return Response::RespNameNotFound;
|
return Response::RespNameNotFound;
|
||||||
|
|
||||||
r->addClient(this);
|
r->addClient(this);
|
||||||
rooms.insert(r->getId(), r);
|
rooms.insert(r->getId(), r);
|
||||||
|
|
||||||
Event_RoomSay joinMessageEvent;
|
Event_RoomSay joinMessageEvent;
|
||||||
joinMessageEvent.set_message(r->getJoinMessage().toStdString());
|
joinMessageEvent.set_message(r->getJoinMessage().toStdString());
|
||||||
rc.enqueuePostResponseItem(ServerMessage::ROOM_EVENT, r->prepareRoomEvent(joinMessageEvent));
|
rc.enqueuePostResponseItem(ServerMessage::ROOM_EVENT, r->prepareRoomEvent(joinMessageEvent));
|
||||||
|
|
||||||
Response_JoinRoom *re = new Response_JoinRoom;
|
Response_JoinRoom *re = new Response_JoinRoom;
|
||||||
r->getInfo(*re->mutable_room_info(), true);
|
r->getInfo(*re->mutable_room_info(), true);
|
||||||
|
|
||||||
rc.setResponseExtension(re);
|
rc.setResponseExtension(re);
|
||||||
return Response::RespOk;
|
return Response::RespOk;
|
||||||
}
|
}
|
||||||
|
|
||||||
Response::ResponseCode Server_ProtocolHandler::cmdListUsers(const Command_ListUsers & /*cmd*/, ResponseContainer &rc)
|
Response::ResponseCode Server_ProtocolHandler::cmdListUsers(const Command_ListUsers & /*cmd*/, ResponseContainer &rc)
|
||||||
{
|
{
|
||||||
if (authState == NotLoggedIn)
|
if (authState == NotLoggedIn)
|
||||||
return Response::RespLoginNeeded;
|
return Response::RespLoginNeeded;
|
||||||
|
|
||||||
Response_ListUsers *re = new Response_ListUsers;
|
Response_ListUsers *re = new Response_ListUsers;
|
||||||
server->clientsLock.lockForRead();
|
server->clientsLock.lockForRead();
|
||||||
QMapIterator<QString, Server_ProtocolHandler *> userIterator = server->getUsers();
|
QMapIterator<QString, Server_ProtocolHandler *> userIterator = server->getUsers();
|
||||||
while (userIterator.hasNext())
|
while (userIterator.hasNext())
|
||||||
re->add_user_list()->CopyFrom(userIterator.next().value()->copyUserInfo(false));
|
re->add_user_list()->CopyFrom(userIterator.next().value()->copyUserInfo(false));
|
||||||
QMapIterator<QString, Server_AbstractUserInterface *> extIterator = server->getExternalUsers();
|
QMapIterator<QString, Server_AbstractUserInterface *> extIterator = server->getExternalUsers();
|
||||||
while (extIterator.hasNext())
|
while (extIterator.hasNext())
|
||||||
re->add_user_list()->CopyFrom(extIterator.next().value()->copyUserInfo(false));
|
re->add_user_list()->CopyFrom(extIterator.next().value()->copyUserInfo(false));
|
||||||
|
|
||||||
acceptsUserListChanges = true;
|
acceptsUserListChanges = true;
|
||||||
server->clientsLock.unlock();
|
server->clientsLock.unlock();
|
||||||
|
|
||||||
rc.setResponseExtension(re);
|
rc.setResponseExtension(re);
|
||||||
return Response::RespOk;
|
return Response::RespOk;
|
||||||
}
|
}
|
||||||
|
|
||||||
Response::ResponseCode Server_ProtocolHandler::cmdLeaveRoom(const Command_LeaveRoom & /*cmd*/, Server_Room *room, ResponseContainer & /*rc*/)
|
Response::ResponseCode Server_ProtocolHandler::cmdLeaveRoom(const Command_LeaveRoom & /*cmd*/, Server_Room *room, ResponseContainer & /*rc*/)
|
||||||
{
|
{
|
||||||
rooms.remove(room->getId());
|
rooms.remove(room->getId());
|
||||||
room->removeClient(this);
|
room->removeClient(this);
|
||||||
return Response::RespOk;
|
return Response::RespOk;
|
||||||
}
|
}
|
||||||
|
|
||||||
Response::ResponseCode Server_ProtocolHandler::cmdRoomSay(const Command_RoomSay &cmd, Server_Room *room, ResponseContainer & /*rc*/)
|
Response::ResponseCode Server_ProtocolHandler::cmdRoomSay(const Command_RoomSay &cmd, Server_Room *room, ResponseContainer & /*rc*/)
|
||||||
{
|
{
|
||||||
QString msg = QString::fromStdString(cmd.message());
|
QString msg = QString::fromStdString(cmd.message());
|
||||||
|
|
||||||
if (server->getMessageCountingInterval() > 0) {
|
if (server->getMessageCountingInterval() > 0) {
|
||||||
int totalSize = 0, totalCount = 0;
|
int totalSize = 0, totalCount = 0;
|
||||||
if (messageSizeOverTime.isEmpty())
|
if (messageSizeOverTime.isEmpty())
|
||||||
messageSizeOverTime.prepend(0);
|
messageSizeOverTime.prepend(0);
|
||||||
messageSizeOverTime[0] += msg.size();
|
messageSizeOverTime[0] += msg.size();
|
||||||
for (int i = 0; i < messageSizeOverTime.size(); ++i)
|
for (int i = 0; i < messageSizeOverTime.size(); ++i)
|
||||||
totalSize += messageSizeOverTime[i];
|
totalSize += messageSizeOverTime[i];
|
||||||
|
|
||||||
if (messageCountOverTime.isEmpty())
|
if (messageCountOverTime.isEmpty())
|
||||||
messageCountOverTime.prepend(0);
|
messageCountOverTime.prepend(0);
|
||||||
++messageCountOverTime[0];
|
++messageCountOverTime[0];
|
||||||
for (int i = 0; i < messageCountOverTime.size(); ++i)
|
for (int i = 0; i < messageCountOverTime.size(); ++i)
|
||||||
totalCount += messageCountOverTime[i];
|
totalCount += messageCountOverTime[i];
|
||||||
|
|
||||||
if ((totalSize > server->getMaxMessageSizePerInterval()) || (totalCount > server->getMaxMessageCountPerInterval()))
|
if ((totalSize > server->getMaxMessageSizePerInterval()) || (totalCount > server->getMaxMessageCountPerInterval()))
|
||||||
return Response::RespChatFlood;
|
return Response::RespChatFlood;
|
||||||
}
|
}
|
||||||
msg.replace(QChar('\n'), QChar(' '));
|
msg.replace(QChar('\n'), QChar(' '));
|
||||||
|
|
||||||
room->say(QString::fromStdString(userInfo->name()), msg);
|
room->say(QString::fromStdString(userInfo->name()), msg);
|
||||||
return Response::RespOk;
|
return Response::RespOk;
|
||||||
}
|
}
|
||||||
|
|
||||||
Response::ResponseCode Server_ProtocolHandler::cmdCreateGame(const Command_CreateGame &cmd, Server_Room *room, ResponseContainer &rc)
|
Response::ResponseCode Server_ProtocolHandler::cmdCreateGame(const Command_CreateGame &cmd, Server_Room *room, ResponseContainer &rc)
|
||||||
{
|
{
|
||||||
if (authState == NotLoggedIn)
|
if (authState == NotLoggedIn)
|
||||||
return Response::RespLoginNeeded;
|
return Response::RespLoginNeeded;
|
||||||
const int gameId = databaseInterface->getNextGameId();
|
const int gameId = databaseInterface->getNextGameId();
|
||||||
if (gameId == -1)
|
if (gameId == -1)
|
||||||
return Response::RespInternalError;
|
return Response::RespInternalError;
|
||||||
|
|
||||||
if (server->getMaxGamesPerUser() > 0)
|
if (server->getMaxGamesPerUser() > 0)
|
||||||
if (room->getGamesCreatedByUser(QString::fromStdString(userInfo->name())) >= server->getMaxGamesPerUser())
|
if (room->getGamesCreatedByUser(QString::fromStdString(userInfo->name())) >= server->getMaxGamesPerUser())
|
||||||
return Response::RespContextError;
|
return Response::RespContextError;
|
||||||
|
|
||||||
QList<int> gameTypes;
|
QList<int> gameTypes;
|
||||||
for (int i = cmd.game_type_ids_size() - 1; i >= 0; --i)
|
for (int i = cmd.game_type_ids_size() - 1; i >= 0; --i)
|
||||||
gameTypes.append(cmd.game_type_ids(i));
|
gameTypes.append(cmd.game_type_ids(i));
|
||||||
|
|
||||||
QString description = QString::fromStdString(cmd.description());
|
QString description = QString::fromStdString(cmd.description());
|
||||||
if (description.size() > 60)
|
if (description.size() > 60)
|
||||||
description = description.left(60);
|
description = description.left(60);
|
||||||
|
|
||||||
Server_Game *game = new Server_Game(copyUserInfo(false), gameId, description, QString::fromStdString(cmd.password()), cmd.max_players(), gameTypes, cmd.only_buddies(), cmd.only_registered(), cmd.spectators_allowed(), cmd.spectators_need_password(), cmd.spectators_can_talk(), cmd.spectators_see_everything(), room);
|
Server_Game *game = new Server_Game(copyUserInfo(false), gameId, description, QString::fromStdString(cmd.password()), cmd.max_players(), gameTypes, cmd.only_buddies(), cmd.only_registered(), cmd.spectators_allowed(), cmd.spectators_need_password(), cmd.spectators_can_talk(), cmd.spectators_see_everything(), room);
|
||||||
game->addPlayer(this, rc, false, false);
|
game->addPlayer(this, rc, false, false);
|
||||||
room->addGame(game);
|
room->addGame(game);
|
||||||
|
|
||||||
return Response::RespOk;
|
return Response::RespOk;
|
||||||
}
|
}
|
||||||
|
|
||||||
Response::ResponseCode Server_ProtocolHandler::cmdJoinGame(const Command_JoinGame &cmd, Server_Room *room, ResponseContainer &rc)
|
Response::ResponseCode Server_ProtocolHandler::cmdJoinGame(const Command_JoinGame &cmd, Server_Room *room, ResponseContainer &rc)
|
||||||
{
|
{
|
||||||
if (authState == NotLoggedIn)
|
if (authState == NotLoggedIn)
|
||||||
return Response::RespLoginNeeded;
|
return Response::RespLoginNeeded;
|
||||||
|
|
||||||
return room->processJoinGameCommand(cmd, rc, this);
|
return room->processJoinGameCommand(cmd, rc, this);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,64 +40,64 @@ class Command_CreateGame;
|
||||||
class Command_JoinGame;
|
class Command_JoinGame;
|
||||||
|
|
||||||
class Server_ProtocolHandler : public QObject, public Server_AbstractUserInterface {
|
class Server_ProtocolHandler : public QObject, public Server_AbstractUserInterface {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
protected:
|
protected:
|
||||||
QMap<int, Server_Room *> rooms;
|
QMap<int, Server_Room *> rooms;
|
||||||
|
|
||||||
bool deleted;
|
bool deleted;
|
||||||
Server_DatabaseInterface *databaseInterface;
|
Server_DatabaseInterface *databaseInterface;
|
||||||
AuthenticationResult authState;
|
AuthenticationResult authState;
|
||||||
bool acceptsUserListChanges;
|
bool acceptsUserListChanges;
|
||||||
bool acceptsRoomListChanges;
|
bool acceptsRoomListChanges;
|
||||||
virtual void logDebugMessage(const QString &message) { }
|
virtual void logDebugMessage(const QString & /* message */) { }
|
||||||
private:
|
private:
|
||||||
QList<int> messageSizeOverTime, messageCountOverTime;
|
QList<int> messageSizeOverTime, messageCountOverTime;
|
||||||
int timeRunning, lastDataReceived;
|
int timeRunning, lastDataReceived;
|
||||||
QTimer *pingClock;
|
QTimer *pingClock;
|
||||||
|
|
||||||
virtual void transmitProtocolItem(const ServerMessage &item) = 0;
|
virtual void transmitProtocolItem(const ServerMessage &item) = 0;
|
||||||
|
|
||||||
Response::ResponseCode cmdPing(const Command_Ping &cmd, ResponseContainer &rc);
|
Response::ResponseCode cmdPing(const Command_Ping &cmd, ResponseContainer &rc);
|
||||||
Response::ResponseCode cmdLogin(const Command_Login &cmd, ResponseContainer &rc);
|
Response::ResponseCode cmdLogin(const Command_Login &cmd, ResponseContainer &rc);
|
||||||
Response::ResponseCode cmdMessage(const Command_Message &cmd, ResponseContainer &rc);
|
Response::ResponseCode cmdMessage(const Command_Message &cmd, ResponseContainer &rc);
|
||||||
Response::ResponseCode cmdGetGamesOfUser(const Command_GetGamesOfUser &cmd, ResponseContainer &rc);
|
Response::ResponseCode cmdGetGamesOfUser(const Command_GetGamesOfUser &cmd, ResponseContainer &rc);
|
||||||
Response::ResponseCode cmdGetUserInfo(const Command_GetUserInfo &cmd, ResponseContainer &rc);
|
Response::ResponseCode cmdGetUserInfo(const Command_GetUserInfo &cmd, ResponseContainer &rc);
|
||||||
Response::ResponseCode cmdListRooms(const Command_ListRooms &cmd, ResponseContainer &rc);
|
Response::ResponseCode cmdListRooms(const Command_ListRooms &cmd, ResponseContainer &rc);
|
||||||
Response::ResponseCode cmdJoinRoom(const Command_JoinRoom &cmd, ResponseContainer &rc);
|
Response::ResponseCode cmdJoinRoom(const Command_JoinRoom &cmd, ResponseContainer &rc);
|
||||||
Response::ResponseCode cmdListUsers(const Command_ListUsers &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 cmdLeaveRoom(const Command_LeaveRoom &cmd, Server_Room *room, ResponseContainer &rc);
|
||||||
Response::ResponseCode cmdRoomSay(const Command_RoomSay &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 cmdCreateGame(const Command_CreateGame &cmd, Server_Room *room, ResponseContainer &rc);
|
||||||
Response::ResponseCode cmdJoinGame(const Command_JoinGame &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);
|
Response::ResponseCode processSessionCommandContainer(const CommandContainer &cont, ResponseContainer &rc);
|
||||||
virtual Response::ResponseCode processExtendedSessionCommand(int cmdType, const SessionCommand &cmd, ResponseContainer &rc) { return Response::RespFunctionNotAllowed; }
|
virtual Response::ResponseCode processExtendedSessionCommand(int /* cmdType */, const SessionCommand & /* cmd */, ResponseContainer & /* rc */) { return Response::RespFunctionNotAllowed; }
|
||||||
Response::ResponseCode processRoomCommandContainer(const CommandContainer &cont, ResponseContainer &rc);
|
Response::ResponseCode processRoomCommandContainer(const CommandContainer &cont, ResponseContainer &rc);
|
||||||
Response::ResponseCode processGameCommandContainer(const CommandContainer &cont, ResponseContainer &rc);
|
Response::ResponseCode processGameCommandContainer(const CommandContainer &cont, ResponseContainer &rc);
|
||||||
Response::ResponseCode processModeratorCommandContainer(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; }
|
virtual Response::ResponseCode processExtendedModeratorCommand(int /* cmdType */, const ModeratorCommand & /* cmd */, ResponseContainer & /* rc */) { return Response::RespFunctionNotAllowed; }
|
||||||
Response::ResponseCode processAdminCommandContainer(const CommandContainer &cont, ResponseContainer &rc);
|
Response::ResponseCode processAdminCommandContainer(const CommandContainer &cont, ResponseContainer &rc);
|
||||||
virtual Response::ResponseCode processExtendedAdminCommand(int cmdType, const AdminCommand &cmd, ResponseContainer &rc) { return Response::RespFunctionNotAllowed; }
|
virtual Response::ResponseCode processExtendedAdminCommand(int /* cmdType */, const AdminCommand & /* cmd */, ResponseContainer & /* rc */) { return Response::RespFunctionNotAllowed; }
|
||||||
private slots:
|
private slots:
|
||||||
void pingClockTimeout();
|
void pingClockTimeout();
|
||||||
public slots:
|
public slots:
|
||||||
void prepareDestroy();
|
void prepareDestroy();
|
||||||
public:
|
public:
|
||||||
Server_ProtocolHandler(Server *_server, Server_DatabaseInterface *_databaseInterface, QObject *parent = 0);
|
Server_ProtocolHandler(Server *_server, Server_DatabaseInterface *_databaseInterface, QObject *parent = 0);
|
||||||
~Server_ProtocolHandler();
|
~Server_ProtocolHandler();
|
||||||
|
|
||||||
bool getAcceptsUserListChanges() const { return acceptsUserListChanges; }
|
bool getAcceptsUserListChanges() const { return acceptsUserListChanges; }
|
||||||
bool getAcceptsRoomListChanges() const { return acceptsRoomListChanges; }
|
bool getAcceptsRoomListChanges() const { return acceptsRoomListChanges; }
|
||||||
virtual QString getAddress() const = 0;
|
virtual QString getAddress() const = 0;
|
||||||
Server_DatabaseInterface *getDatabaseInterface() const { return databaseInterface; }
|
Server_DatabaseInterface *getDatabaseInterface() const { return databaseInterface; }
|
||||||
|
|
||||||
int getLastCommandTime() const { return timeRunning - lastDataReceived; }
|
int getLastCommandTime() const { return timeRunning - lastDataReceived; }
|
||||||
void processCommandContainer(const CommandContainer &cont);
|
void processCommandContainer(const CommandContainer &cont);
|
||||||
|
|
||||||
void sendProtocolItem(const Response &item);
|
void sendProtocolItem(const Response &item);
|
||||||
void sendProtocolItem(const SessionEvent &item);
|
void sendProtocolItem(const SessionEvent &item);
|
||||||
void sendProtocolItem(const GameEventContainer &item);
|
void sendProtocolItem(const GameEventContainer &item);
|
||||||
void sendProtocolItem(const RoomEvent &item);
|
void sendProtocolItem(const RoomEvent &item);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -4,20 +4,20 @@
|
||||||
|
|
||||||
void Server_RemoteUserInterface::sendProtocolItem(const Response &item)
|
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)
|
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)
|
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)
|
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());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,14 +5,14 @@
|
||||||
|
|
||||||
class Server_RemoteUserInterface : public Server_AbstractUserInterface {
|
class Server_RemoteUserInterface : public Server_AbstractUserInterface {
|
||||||
public:
|
public:
|
||||||
Server_RemoteUserInterface(Server *_server, const ServerInfo_User_Container &_userInfoContainer) : Server_AbstractUserInterface(_server, _userInfoContainer) { }
|
Server_RemoteUserInterface(Server *_server, const ServerInfo_User_Container &_userInfoContainer) : Server_AbstractUserInterface(_server, _userInfoContainer) { }
|
||||||
|
|
||||||
int getLastCommandTime() const { return 0; }
|
int getLastCommandTime() const { return 0; }
|
||||||
|
|
||||||
void sendProtocolItem(const Response &item);
|
void sendProtocolItem(const Response &item);
|
||||||
void sendProtocolItem(const SessionEvent &item);
|
void sendProtocolItem(const SessionEvent &item);
|
||||||
void sendProtocolItem(const GameEventContainer &item);
|
void sendProtocolItem(const GameEventContainer &item);
|
||||||
void sendProtocolItem(const RoomEvent &item);
|
void sendProtocolItem(const RoomEvent &item);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -3,64 +3,64 @@
|
||||||
#include "server_game.h"
|
#include "server_game.h"
|
||||||
|
|
||||||
GameEventStorageItem::GameEventStorageItem(const ::google::protobuf::Message &_event, int _playerId, EventRecipients _recipients)
|
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->GetReflection()->MutableMessage(event, _event.GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(_event);
|
||||||
event->set_player_id(_playerId);
|
event->set_player_id(_playerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
GameEventStorageItem::~GameEventStorageItem()
|
GameEventStorageItem::~GameEventStorageItem()
|
||||||
{
|
{
|
||||||
delete event;
|
delete event;
|
||||||
}
|
}
|
||||||
|
|
||||||
GameEventStorage::GameEventStorage()
|
GameEventStorage::GameEventStorage()
|
||||||
: gameEventContext(0)
|
: gameEventContext(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
GameEventStorage::~GameEventStorage()
|
GameEventStorage::~GameEventStorage()
|
||||||
{
|
{
|
||||||
delete gameEventContext;
|
delete gameEventContext;
|
||||||
for (int i = 0; i < gameEventList.size(); ++i)
|
for (int i = 0; i < gameEventList.size(); ++i)
|
||||||
delete gameEventList[i];
|
delete gameEventList[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameEventStorage::setGameEventContext(const ::google::protobuf::Message &_gameEventContext)
|
void GameEventStorage::setGameEventContext(const ::google::protobuf::Message &_gameEventContext)
|
||||||
{
|
{
|
||||||
delete gameEventContext;
|
delete gameEventContext;
|
||||||
gameEventContext = new GameEventContext;
|
gameEventContext = new GameEventContext;
|
||||||
gameEventContext->GetReflection()->MutableMessage(gameEventContext, _gameEventContext.GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(_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)
|
void GameEventStorage::enqueueGameEvent(const ::google::protobuf::Message &event, int playerId, GameEventStorageItem::EventRecipients recipients, int _privatePlayerId)
|
||||||
{
|
{
|
||||||
gameEventList.append(new GameEventStorageItem(event, playerId, recipients));
|
gameEventList.append(new GameEventStorageItem(event, playerId, recipients));
|
||||||
if (_privatePlayerId != -1)
|
if (_privatePlayerId != -1)
|
||||||
privatePlayerId = _privatePlayerId;
|
privatePlayerId = _privatePlayerId;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameEventStorage::sendToGame(Server_Game *game)
|
void GameEventStorage::sendToGame(Server_Game *game)
|
||||||
{
|
{
|
||||||
if (gameEventList.isEmpty())
|
if (gameEventList.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
GameEventContainer *contPrivate = new GameEventContainer;
|
GameEventContainer *contPrivate = new GameEventContainer;
|
||||||
GameEventContainer *contOthers = new GameEventContainer;
|
GameEventContainer *contOthers = new GameEventContainer;
|
||||||
for (int i = 0; i < gameEventList.size(); ++i) {
|
for (int i = 0; i < gameEventList.size(); ++i) {
|
||||||
const GameEvent &event = gameEventList[i]->getGameEvent();
|
const GameEvent &event = gameEventList[i]->getGameEvent();
|
||||||
const GameEventStorageItem::EventRecipients recipients = gameEventList[i]->getRecipients();
|
const GameEventStorageItem::EventRecipients recipients = gameEventList[i]->getRecipients();
|
||||||
if (recipients.testFlag(GameEventStorageItem::SendToPrivate))
|
if (recipients.testFlag(GameEventStorageItem::SendToPrivate))
|
||||||
contPrivate->add_event_list()->CopyFrom(event);
|
contPrivate->add_event_list()->CopyFrom(event);
|
||||||
if (recipients.testFlag(GameEventStorageItem::SendToOthers))
|
if (recipients.testFlag(GameEventStorageItem::SendToOthers))
|
||||||
contOthers->add_event_list()->CopyFrom(event);
|
contOthers->add_event_list()->CopyFrom(event);
|
||||||
}
|
}
|
||||||
if (gameEventContext) {
|
if (gameEventContext) {
|
||||||
contPrivate->mutable_context()->CopyFrom(*gameEventContext);
|
contPrivate->mutable_context()->CopyFrom(*gameEventContext);
|
||||||
contOthers->mutable_context()->CopyFrom(*gameEventContext);
|
contOthers->mutable_context()->CopyFrom(*gameEventContext);
|
||||||
}
|
}
|
||||||
game->sendGameEventContainer(contPrivate, GameEventStorageItem::SendToPrivate, privatePlayerId);
|
game->sendGameEventContainer(contPrivate, GameEventStorageItem::SendToPrivate, privatePlayerId);
|
||||||
game->sendGameEventContainer(contOthers, GameEventStorageItem::SendToOthers, privatePlayerId);
|
game->sendGameEventContainer(contOthers, GameEventStorageItem::SendToOthers, privatePlayerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
ResponseContainer::ResponseContainer(int _cmdId)
|
ResponseContainer::ResponseContainer(int _cmdId)
|
||||||
|
|
@ -70,9 +70,9 @@ ResponseContainer::ResponseContainer(int _cmdId)
|
||||||
|
|
||||||
ResponseContainer::~ResponseContainer()
|
ResponseContainer::~ResponseContainer()
|
||||||
{
|
{
|
||||||
delete responseExtension;
|
delete responseExtension;
|
||||||
for (int i = 0; i < preResponseQueue.size(); ++i)
|
for (int i = 0; i < preResponseQueue.size(); ++i)
|
||||||
delete preResponseQueue[i].second;
|
delete preResponseQueue[i].second;
|
||||||
for (int i = 0; i < postResponseQueue.size(); ++i)
|
for (int i = 0; i < postResponseQueue.size(); ++i)
|
||||||
delete postResponseQueue[i].second;
|
delete postResponseQueue[i].second;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,54 +10,54 @@ class Server_Game;
|
||||||
|
|
||||||
class GameEventStorageItem {
|
class GameEventStorageItem {
|
||||||
public:
|
public:
|
||||||
enum EventRecipient { SendToPrivate = 0x01, SendToOthers = 0x02};
|
enum EventRecipient { SendToPrivate = 0x01, SendToOthers = 0x02};
|
||||||
Q_DECLARE_FLAGS(EventRecipients, EventRecipient)
|
Q_DECLARE_FLAGS(EventRecipients, EventRecipient)
|
||||||
private:
|
private:
|
||||||
GameEvent *event;
|
GameEvent *event;
|
||||||
EventRecipients recipients;
|
EventRecipients recipients;
|
||||||
public:
|
public:
|
||||||
GameEventStorageItem(const ::google::protobuf::Message &_event, int _playerId, EventRecipients _recipients);
|
GameEventStorageItem(const ::google::protobuf::Message &_event, int _playerId, EventRecipients _recipients);
|
||||||
~GameEventStorageItem();
|
~GameEventStorageItem();
|
||||||
|
|
||||||
const GameEvent &getGameEvent() const { return *event; }
|
const GameEvent &getGameEvent() const { return *event; }
|
||||||
EventRecipients getRecipients() const { return recipients; }
|
EventRecipients getRecipients() const { return recipients; }
|
||||||
};
|
};
|
||||||
Q_DECLARE_OPERATORS_FOR_FLAGS(GameEventStorageItem::EventRecipients)
|
Q_DECLARE_OPERATORS_FOR_FLAGS(GameEventStorageItem::EventRecipients)
|
||||||
|
|
||||||
class GameEventStorage {
|
class GameEventStorage {
|
||||||
private:
|
private:
|
||||||
::google::protobuf::Message *gameEventContext;
|
::google::protobuf::Message *gameEventContext;
|
||||||
QList<GameEventStorageItem *> gameEventList;
|
QList<GameEventStorageItem *> gameEventList;
|
||||||
int privatePlayerId;
|
int privatePlayerId;
|
||||||
public:
|
public:
|
||||||
GameEventStorage();
|
GameEventStorage();
|
||||||
~GameEventStorage();
|
~GameEventStorage();
|
||||||
|
|
||||||
void setGameEventContext(const ::google::protobuf::Message &_gameEventContext);
|
void setGameEventContext(const ::google::protobuf::Message &_gameEventContext);
|
||||||
::google::protobuf::Message *getGameEventContext() const { return gameEventContext; }
|
::google::protobuf::Message *getGameEventContext() const { return gameEventContext; }
|
||||||
const QList<GameEventStorageItem *> &getGameEventList() const { return gameEventList; }
|
const QList<GameEventStorageItem *> &getGameEventList() const { return gameEventList; }
|
||||||
int getPrivatePlayerId() const { return privatePlayerId; }
|
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 enqueueGameEvent(const ::google::protobuf::Message &event, int playerId, GameEventStorageItem::EventRecipients recipients = GameEventStorageItem::SendToPrivate | GameEventStorageItem::SendToOthers, int _privatePlayerId = -1);
|
||||||
void sendToGame(Server_Game *game);
|
void sendToGame(Server_Game *game);
|
||||||
};
|
};
|
||||||
|
|
||||||
class ResponseContainer {
|
class ResponseContainer {
|
||||||
private:
|
private:
|
||||||
int cmdId;
|
int cmdId;
|
||||||
::google::protobuf::Message *responseExtension;
|
::google::protobuf::Message *responseExtension;
|
||||||
QList<QPair<ServerMessage::MessageType, ::google::protobuf::Message *> > preResponseQueue, postResponseQueue;
|
QList<QPair<ServerMessage::MessageType, ::google::protobuf::Message *> > preResponseQueue, postResponseQueue;
|
||||||
public:
|
public:
|
||||||
ResponseContainer(int _cmdId);
|
ResponseContainer(int _cmdId);
|
||||||
~ResponseContainer();
|
~ResponseContainer();
|
||||||
|
|
||||||
int getCmdId() const { return cmdId; }
|
int getCmdId() const { return cmdId; }
|
||||||
void setResponseExtension(::google::protobuf::Message *_responseExtension) { responseExtension = _responseExtension; }
|
void setResponseExtension(::google::protobuf::Message *_responseExtension) { responseExtension = _responseExtension; }
|
||||||
::google::protobuf::Message *getResponseExtension() const { return responseExtension; }
|
::google::protobuf::Message *getResponseExtension() const { return responseExtension; }
|
||||||
void enqueuePreResponseItem(ServerMessage::MessageType type, ::google::protobuf::Message *item) { preResponseQueue.append(qMakePair(type, item)); }
|
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)); }
|
void enqueuePostResponseItem(ServerMessage::MessageType type, ::google::protobuf::Message *item) { postResponseQueue.append(qMakePair(type, item)); }
|
||||||
const QList<QPair<ServerMessage::MessageType, ::google::protobuf::Message *> > &getPreResponseQueue() const { return preResponseQueue; }
|
const QList<QPair<ServerMessage::MessageType, ::google::protobuf::Message *> > &getPreResponseQueue() const { return preResponseQueue; }
|
||||||
const QList<QPair<ServerMessage::MessageType, ::google::protobuf::Message *> > &getPostResponseQueue() const { return postResponseQueue; }
|
const QList<QPair<ServerMessage::MessageType, ::google::protobuf::Message *> > &getPostResponseQueue() const { return postResponseQueue; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -13,326 +13,326 @@
|
||||||
#include <google/protobuf/descriptor.h>
|
#include <google/protobuf/descriptor.h>
|
||||||
|
|
||||||
Server_Room::Server_Room(int _id, const QString &_name, const QString &_description, bool _autoJoin, const QString &_joinMessage, const QStringList &_gameTypes, Server *parent)
|
Server_Room::Server_Room(int _id, const QString &_name, const QString &_description, bool _autoJoin, const QString &_joinMessage, const QStringList &_gameTypes, Server *parent)
|
||||||
: QObject(parent), id(_id), name(_name), description(_description), autoJoin(_autoJoin), joinMessage(_joinMessage), gameTypes(_gameTypes), 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()
|
Server_Room::~Server_Room()
|
||||||
{
|
{
|
||||||
qDebug("Server_Room destructor");
|
qDebug("Server_Room destructor");
|
||||||
|
|
||||||
gamesLock.lockForWrite();
|
gamesLock.lockForWrite();
|
||||||
const QList<Server_Game *> gameList = games.values();
|
const QList<Server_Game *> gameList = games.values();
|
||||||
for (int i = 0; i < gameList.size(); ++i)
|
for (int i = 0; i < gameList.size(); ++i)
|
||||||
delete gameList[i];
|
delete gameList[i];
|
||||||
games.clear();
|
games.clear();
|
||||||
gamesLock.unlock();
|
gamesLock.unlock();
|
||||||
|
|
||||||
usersLock.lockForWrite();
|
usersLock.lockForWrite();
|
||||||
users.clear();
|
users.clear();
|
||||||
usersLock.unlock();
|
usersLock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
Server *Server_Room::getServer() const
|
Server *Server_Room::getServer() const
|
||||||
{
|
{
|
||||||
return static_cast<Server *>(parent());
|
return static_cast<Server *>(parent());
|
||||||
}
|
}
|
||||||
|
|
||||||
const ServerInfo_Room &Server_Room::getInfo(ServerInfo_Room &result, bool complete, bool showGameTypes, bool includeExternalData) const
|
const ServerInfo_Room &Server_Room::getInfo(ServerInfo_Room &result, bool complete, bool showGameTypes, bool includeExternalData) const
|
||||||
{
|
{
|
||||||
result.set_room_id(id);
|
result.set_room_id(id);
|
||||||
|
|
||||||
result.set_name(name.toStdString());
|
result.set_name(name.toStdString());
|
||||||
result.set_description(description.toStdString());
|
result.set_description(description.toStdString());
|
||||||
result.set_auto_join(autoJoin);
|
result.set_auto_join(autoJoin);
|
||||||
|
|
||||||
gamesLock.lockForRead();
|
gamesLock.lockForRead();
|
||||||
result.set_game_count(games.size() + externalGames.size());
|
result.set_game_count(games.size() + externalGames.size());
|
||||||
if (complete) {
|
if (complete) {
|
||||||
QMapIterator<int, Server_Game *> gameIterator(games);
|
QMapIterator<int, Server_Game *> gameIterator(games);
|
||||||
while (gameIterator.hasNext())
|
while (gameIterator.hasNext())
|
||||||
gameIterator.next().value()->getInfo(*result.add_game_list());
|
gameIterator.next().value()->getInfo(*result.add_game_list());
|
||||||
if (includeExternalData) {
|
if (includeExternalData) {
|
||||||
QMapIterator<int, ServerInfo_Game> externalGameIterator(externalGames);
|
QMapIterator<int, ServerInfo_Game> externalGameIterator(externalGames);
|
||||||
while (externalGameIterator.hasNext())
|
while (externalGameIterator.hasNext())
|
||||||
result.add_game_list()->CopyFrom(externalGameIterator.next().value());
|
result.add_game_list()->CopyFrom(externalGameIterator.next().value());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gamesLock.unlock();
|
gamesLock.unlock();
|
||||||
|
|
||||||
usersLock.lockForRead();
|
usersLock.lockForRead();
|
||||||
result.set_player_count(users.size() + externalUsers.size());
|
result.set_player_count(users.size() + externalUsers.size());
|
||||||
if (complete) {
|
if (complete) {
|
||||||
QMapIterator<QString, Server_ProtocolHandler *> userIterator(users);
|
QMapIterator<QString, Server_ProtocolHandler *> userIterator(users);
|
||||||
while (userIterator.hasNext())
|
while (userIterator.hasNext())
|
||||||
result.add_user_list()->CopyFrom(userIterator.next().value()->copyUserInfo(false));
|
result.add_user_list()->CopyFrom(userIterator.next().value()->copyUserInfo(false));
|
||||||
if (includeExternalData) {
|
if (includeExternalData) {
|
||||||
QMapIterator<QString, ServerInfo_User_Container> externalUserIterator(externalUsers);
|
QMapIterator<QString, ServerInfo_User_Container> externalUserIterator(externalUsers);
|
||||||
while (externalUserIterator.hasNext())
|
while (externalUserIterator.hasNext())
|
||||||
result.add_user_list()->CopyFrom(externalUserIterator.next().value().copyUserInfo(false));
|
result.add_user_list()->CopyFrom(externalUserIterator.next().value().copyUserInfo(false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
usersLock.unlock();
|
usersLock.unlock();
|
||||||
|
|
||||||
if (complete || showGameTypes)
|
if (complete || showGameTypes)
|
||||||
for (int i = 0; i < gameTypes.size(); ++i) {
|
for (int i = 0; i < gameTypes.size(); ++i) {
|
||||||
ServerInfo_GameType *gameTypeInfo = result.add_gametype_list();
|
ServerInfo_GameType *gameTypeInfo = result.add_gametype_list();
|
||||||
gameTypeInfo->set_game_type_id(i);
|
gameTypeInfo->set_game_type_id(i);
|
||||||
gameTypeInfo->set_description(gameTypes[i].toStdString());
|
gameTypeInfo->set_description(gameTypes[i].toStdString());
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
RoomEvent *Server_Room::prepareRoomEvent(const ::google::protobuf::Message &roomEvent)
|
RoomEvent *Server_Room::prepareRoomEvent(const ::google::protobuf::Message &roomEvent)
|
||||||
{
|
{
|
||||||
RoomEvent *event = new RoomEvent;
|
RoomEvent *event = new RoomEvent;
|
||||||
event->set_room_id(id);
|
event->set_room_id(id);
|
||||||
event->GetReflection()->MutableMessage(event, roomEvent.GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(roomEvent);
|
event->GetReflection()->MutableMessage(event, roomEvent.GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(roomEvent);
|
||||||
return event;
|
return event;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server_Room::addClient(Server_ProtocolHandler *client)
|
void Server_Room::addClient(Server_ProtocolHandler *client)
|
||||||
{
|
{
|
||||||
Event_JoinRoom event;
|
Event_JoinRoom event;
|
||||||
event.mutable_user_info()->CopyFrom(client->copyUserInfo(false));
|
event.mutable_user_info()->CopyFrom(client->copyUserInfo(false));
|
||||||
sendRoomEvent(prepareRoomEvent(event));
|
sendRoomEvent(prepareRoomEvent(event));
|
||||||
|
|
||||||
ServerInfo_Room roomInfo;
|
ServerInfo_Room roomInfo;
|
||||||
roomInfo.set_room_id(id);
|
roomInfo.set_room_id(id);
|
||||||
|
|
||||||
usersLock.lockForWrite();
|
usersLock.lockForWrite();
|
||||||
users.insert(QString::fromStdString(client->getUserInfo()->name()), client);
|
users.insert(QString::fromStdString(client->getUserInfo()->name()), client);
|
||||||
roomInfo.set_player_count(users.size() + externalUsers.size());
|
roomInfo.set_player_count(users.size() + externalUsers.size());
|
||||||
usersLock.unlock();
|
usersLock.unlock();
|
||||||
|
|
||||||
// XXX This can be removed during the next client update.
|
// XXX This can be removed during the next client update.
|
||||||
gamesLock.lockForRead();
|
gamesLock.lockForRead();
|
||||||
roomInfo.set_game_count(games.size() + externalGames.size());
|
roomInfo.set_game_count(games.size() + externalGames.size());
|
||||||
gamesLock.unlock();
|
gamesLock.unlock();
|
||||||
// -----------
|
// -----------
|
||||||
|
|
||||||
emit roomInfoChanged(roomInfo);
|
emit roomInfoChanged(roomInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server_Room::removeClient(Server_ProtocolHandler *client)
|
void Server_Room::removeClient(Server_ProtocolHandler *client)
|
||||||
{
|
{
|
||||||
usersLock.lockForWrite();
|
usersLock.lockForWrite();
|
||||||
users.remove(QString::fromStdString(client->getUserInfo()->name()));
|
users.remove(QString::fromStdString(client->getUserInfo()->name()));
|
||||||
|
|
||||||
ServerInfo_Room roomInfo;
|
ServerInfo_Room roomInfo;
|
||||||
roomInfo.set_room_id(id);
|
roomInfo.set_room_id(id);
|
||||||
roomInfo.set_player_count(users.size() + externalUsers.size());
|
roomInfo.set_player_count(users.size() + externalUsers.size());
|
||||||
usersLock.unlock();
|
usersLock.unlock();
|
||||||
|
|
||||||
Event_LeaveRoom event;
|
Event_LeaveRoom event;
|
||||||
event.set_name(client->getUserInfo()->name());
|
event.set_name(client->getUserInfo()->name());
|
||||||
sendRoomEvent(prepareRoomEvent(event));
|
sendRoomEvent(prepareRoomEvent(event));
|
||||||
|
|
||||||
// XXX This can be removed during the next client update.
|
// XXX This can be removed during the next client update.
|
||||||
gamesLock.lockForRead();
|
gamesLock.lockForRead();
|
||||||
roomInfo.set_game_count(games.size() + externalGames.size());
|
roomInfo.set_game_count(games.size() + externalGames.size());
|
||||||
gamesLock.unlock();
|
gamesLock.unlock();
|
||||||
// -----------
|
// -----------
|
||||||
|
|
||||||
emit roomInfoChanged(roomInfo);
|
emit roomInfoChanged(roomInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server_Room::addExternalUser(const ServerInfo_User &userInfo)
|
void Server_Room::addExternalUser(const ServerInfo_User &userInfo)
|
||||||
{
|
{
|
||||||
// This function is always called from the Server thread with server->roomsMutex locked.
|
// This function is always called from the Server thread with server->roomsMutex locked.
|
||||||
ServerInfo_User_Container userInfoContainer(userInfo);
|
ServerInfo_User_Container userInfoContainer(userInfo);
|
||||||
Event_JoinRoom event;
|
Event_JoinRoom event;
|
||||||
event.mutable_user_info()->CopyFrom(userInfoContainer.copyUserInfo(false));
|
event.mutable_user_info()->CopyFrom(userInfoContainer.copyUserInfo(false));
|
||||||
sendRoomEvent(prepareRoomEvent(event), false);
|
sendRoomEvent(prepareRoomEvent(event), false);
|
||||||
|
|
||||||
ServerInfo_Room roomInfo;
|
ServerInfo_Room roomInfo;
|
||||||
roomInfo.set_room_id(id);
|
roomInfo.set_room_id(id);
|
||||||
|
|
||||||
usersLock.lockForWrite();
|
usersLock.lockForWrite();
|
||||||
externalUsers.insert(QString::fromStdString(userInfo.name()), userInfoContainer);
|
externalUsers.insert(QString::fromStdString(userInfo.name()), userInfoContainer);
|
||||||
roomInfo.set_player_count(users.size() + externalUsers.size());
|
roomInfo.set_player_count(users.size() + externalUsers.size());
|
||||||
usersLock.unlock();
|
usersLock.unlock();
|
||||||
|
|
||||||
emit roomInfoChanged(roomInfo);
|
emit roomInfoChanged(roomInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server_Room::removeExternalUser(const QString &name)
|
void Server_Room::removeExternalUser(const QString &name)
|
||||||
{
|
{
|
||||||
// This function is always called from the Server thread with server->roomsMutex locked.
|
// This function is always called from the Server thread with server->roomsMutex locked.
|
||||||
ServerInfo_Room roomInfo;
|
ServerInfo_Room roomInfo;
|
||||||
roomInfo.set_room_id(id);
|
roomInfo.set_room_id(id);
|
||||||
|
|
||||||
usersLock.lockForWrite();
|
usersLock.lockForWrite();
|
||||||
if (externalUsers.contains(name))
|
if (externalUsers.contains(name))
|
||||||
externalUsers.remove(name);
|
externalUsers.remove(name);
|
||||||
roomInfo.set_player_count(users.size() + externalUsers.size());
|
roomInfo.set_player_count(users.size() + externalUsers.size());
|
||||||
usersLock.unlock();
|
usersLock.unlock();
|
||||||
|
|
||||||
Event_LeaveRoom event;
|
Event_LeaveRoom event;
|
||||||
event.set_name(name.toStdString());
|
event.set_name(name.toStdString());
|
||||||
sendRoomEvent(prepareRoomEvent(event), false);
|
sendRoomEvent(prepareRoomEvent(event), false);
|
||||||
|
|
||||||
emit roomInfoChanged(roomInfo);
|
emit roomInfoChanged(roomInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server_Room::updateExternalGameList(const ServerInfo_Game &gameInfo)
|
void Server_Room::updateExternalGameList(const ServerInfo_Game &gameInfo)
|
||||||
{
|
{
|
||||||
// This function is always called from the Server thread with server->roomsMutex locked.
|
// This function is always called from the Server thread with server->roomsMutex locked.
|
||||||
ServerInfo_Room roomInfo;
|
ServerInfo_Room roomInfo;
|
||||||
roomInfo.set_room_id(id);
|
roomInfo.set_room_id(id);
|
||||||
|
|
||||||
gamesLock.lockForWrite();
|
gamesLock.lockForWrite();
|
||||||
if (!gameInfo.has_player_count() && externalGames.contains(gameInfo.game_id()))
|
if (!gameInfo.has_player_count() && externalGames.contains(gameInfo.game_id()))
|
||||||
externalGames.remove(gameInfo.game_id());
|
externalGames.remove(gameInfo.game_id());
|
||||||
else
|
else
|
||||||
externalGames.insert(gameInfo.game_id(), gameInfo);
|
externalGames.insert(gameInfo.game_id(), gameInfo);
|
||||||
roomInfo.set_game_count(games.size() + externalGames.size());
|
roomInfo.set_game_count(games.size() + externalGames.size());
|
||||||
gamesLock.unlock();
|
gamesLock.unlock();
|
||||||
|
|
||||||
broadcastGameListUpdate(gameInfo, false);
|
broadcastGameListUpdate(gameInfo, false);
|
||||||
emit roomInfoChanged(roomInfo);
|
emit roomInfoChanged(roomInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
Response::ResponseCode Server_Room::processJoinGameCommand(const Command_JoinGame &cmd, ResponseContainer &rc, Server_AbstractUserInterface *userInterface)
|
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.
|
// This function is called from the Server thread and from the S_PH thread.
|
||||||
// server->roomsMutex is always locked.
|
// server->roomsMutex is always locked.
|
||||||
|
|
||||||
QReadLocker roomGamesLocker(&gamesLock);
|
QReadLocker roomGamesLocker(&gamesLock);
|
||||||
Server_Game *g = games.value(cmd.game_id());
|
Server_Game *g = games.value(cmd.game_id());
|
||||||
if (!g) {
|
if (!g) {
|
||||||
if (externalGames.contains(cmd.game_id())) {
|
if (externalGames.contains(cmd.game_id())) {
|
||||||
CommandContainer cont;
|
CommandContainer cont;
|
||||||
cont.set_cmd_id(rc.getCmdId());
|
cont.set_cmd_id(rc.getCmdId());
|
||||||
RoomCommand *roomCommand = cont.add_room_command();
|
RoomCommand *roomCommand = cont.add_room_command();
|
||||||
roomCommand->GetReflection()->MutableMessage(roomCommand, cmd.GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(cmd);
|
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);
|
getServer()->sendIsl_RoomCommand(cont, externalGames.value(cmd.game_id()).server_id(), userInterface->getUserInfo()->session_id(), id);
|
||||||
|
|
||||||
return Response::RespNothing;
|
return Response::RespNothing;
|
||||||
} else
|
} else
|
||||||
return Response::RespNameNotFound;
|
return Response::RespNameNotFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
QMutexLocker gameLocker(&g->gameMutex);
|
QMutexLocker gameLocker(&g->gameMutex);
|
||||||
|
|
||||||
Response::ResponseCode result = g->checkJoin(userInterface->getUserInfo(), QString::fromStdString(cmd.password()), cmd.spectator(), cmd.override_restrictions());
|
Response::ResponseCode result = g->checkJoin(userInterface->getUserInfo(), QString::fromStdString(cmd.password()), cmd.spectator(), cmd.override_restrictions());
|
||||||
if (result == Response::RespOk)
|
if (result == Response::RespOk)
|
||||||
g->addPlayer(userInterface, rc, cmd.spectator());
|
g->addPlayer(userInterface, rc, cmd.spectator());
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Server_Room::say(const QString &userName, const QString &s, bool sendToIsl)
|
void Server_Room::say(const QString &userName, const QString &s, bool sendToIsl)
|
||||||
{
|
{
|
||||||
Event_RoomSay event;
|
Event_RoomSay event;
|
||||||
event.set_name(userName.toStdString());
|
event.set_name(userName.toStdString());
|
||||||
event.set_message(s.toStdString());
|
event.set_message(s.toStdString());
|
||||||
sendRoomEvent(prepareRoomEvent(event), sendToIsl);
|
sendRoomEvent(prepareRoomEvent(event), sendToIsl);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server_Room::sendRoomEvent(RoomEvent *event, bool sendToIsl)
|
void Server_Room::sendRoomEvent(RoomEvent *event, bool sendToIsl)
|
||||||
{
|
{
|
||||||
usersLock.lockForRead();
|
usersLock.lockForRead();
|
||||||
{
|
{
|
||||||
QMapIterator<QString, Server_ProtocolHandler *> userIterator(users);
|
QMapIterator<QString, Server_ProtocolHandler *> userIterator(users);
|
||||||
while (userIterator.hasNext())
|
while (userIterator.hasNext())
|
||||||
userIterator.next().value()->sendProtocolItem(*event);
|
userIterator.next().value()->sendProtocolItem(*event);
|
||||||
}
|
}
|
||||||
usersLock.unlock();
|
usersLock.unlock();
|
||||||
|
|
||||||
if (sendToIsl)
|
if (sendToIsl)
|
||||||
static_cast<Server *>(parent())->sendIsl_RoomEvent(*event);
|
static_cast<Server *>(parent())->sendIsl_RoomEvent(*event);
|
||||||
|
|
||||||
delete event;
|
delete event;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server_Room::broadcastGameListUpdate(const ServerInfo_Game &gameInfo, bool sendToIsl)
|
void Server_Room::broadcastGameListUpdate(const ServerInfo_Game &gameInfo, bool sendToIsl)
|
||||||
{
|
{
|
||||||
Event_ListGames event;
|
Event_ListGames event;
|
||||||
event.add_game_list()->CopyFrom(gameInfo);
|
event.add_game_list()->CopyFrom(gameInfo);
|
||||||
sendRoomEvent(prepareRoomEvent(event), sendToIsl);
|
sendRoomEvent(prepareRoomEvent(event), sendToIsl);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server_Room::addGame(Server_Game *game)
|
void Server_Room::addGame(Server_Game *game)
|
||||||
{
|
{
|
||||||
ServerInfo_Room roomInfo;
|
ServerInfo_Room roomInfo;
|
||||||
roomInfo.set_room_id(id);
|
roomInfo.set_room_id(id);
|
||||||
|
|
||||||
gamesLock.lockForWrite();
|
gamesLock.lockForWrite();
|
||||||
connect(game, SIGNAL(gameInfoChanged(ServerInfo_Game)), this, SLOT(broadcastGameListUpdate(ServerInfo_Game)));
|
connect(game, SIGNAL(gameInfoChanged(ServerInfo_Game)), this, SLOT(broadcastGameListUpdate(ServerInfo_Game)));
|
||||||
|
|
||||||
game->gameMutex.lock();
|
game->gameMutex.lock();
|
||||||
games.insert(game->getGameId(), game);
|
games.insert(game->getGameId(), game);
|
||||||
ServerInfo_Game gameInfo;
|
ServerInfo_Game gameInfo;
|
||||||
game->getInfo(gameInfo);
|
game->getInfo(gameInfo);
|
||||||
roomInfo.set_game_count(games.size() + externalGames.size());
|
roomInfo.set_game_count(games.size() + externalGames.size());
|
||||||
game->gameMutex.unlock();
|
game->gameMutex.unlock();
|
||||||
gamesLock.unlock();
|
gamesLock.unlock();
|
||||||
|
|
||||||
// XXX This can be removed during the next client update.
|
// XXX This can be removed during the next client update.
|
||||||
usersLock.lockForRead();
|
usersLock.lockForRead();
|
||||||
roomInfo.set_player_count(users.size() + externalUsers.size());
|
roomInfo.set_player_count(users.size() + externalUsers.size());
|
||||||
usersLock.unlock();
|
usersLock.unlock();
|
||||||
// -----------
|
// -----------
|
||||||
|
|
||||||
emit gameListChanged(gameInfo);
|
emit gameListChanged(gameInfo);
|
||||||
emit roomInfoChanged(roomInfo);
|
emit roomInfoChanged(roomInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server_Room::removeGame(Server_Game *game)
|
void Server_Room::removeGame(Server_Game *game)
|
||||||
{
|
{
|
||||||
// No need to lock gamesLock or gameMutex. This method is only
|
// No need to lock gamesLock or gameMutex. This method is only
|
||||||
// called from ~Server_Game, which locks both mutexes anyway beforehand.
|
// called from ~Server_Game, which locks both mutexes anyway beforehand.
|
||||||
|
|
||||||
disconnect(game, 0, this, 0);
|
disconnect(game, 0, this, 0);
|
||||||
|
|
||||||
ServerInfo_Game gameInfo;
|
ServerInfo_Game gameInfo;
|
||||||
game->getInfo(gameInfo);
|
game->getInfo(gameInfo);
|
||||||
emit gameListChanged(gameInfo);
|
emit gameListChanged(gameInfo);
|
||||||
|
|
||||||
games.remove(game->getGameId());
|
games.remove(game->getGameId());
|
||||||
|
|
||||||
ServerInfo_Room roomInfo;
|
ServerInfo_Room roomInfo;
|
||||||
roomInfo.set_room_id(id);
|
roomInfo.set_room_id(id);
|
||||||
roomInfo.set_game_count(games.size() + externalGames.size());
|
roomInfo.set_game_count(games.size() + externalGames.size());
|
||||||
|
|
||||||
// XXX This can be removed during the next client update.
|
// XXX This can be removed during the next client update.
|
||||||
usersLock.lockForRead();
|
usersLock.lockForRead();
|
||||||
roomInfo.set_player_count(users.size() + externalUsers.size());
|
roomInfo.set_player_count(users.size() + externalUsers.size());
|
||||||
usersLock.unlock();
|
usersLock.unlock();
|
||||||
// -----------
|
// -----------
|
||||||
|
|
||||||
emit roomInfoChanged(roomInfo);
|
emit roomInfoChanged(roomInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Server_Room::getGamesCreatedByUser(const QString &userName) const
|
int Server_Room::getGamesCreatedByUser(const QString &userName) const
|
||||||
{
|
{
|
||||||
QReadLocker locker(&gamesLock);
|
QReadLocker locker(&gamesLock);
|
||||||
|
|
||||||
QMapIterator<int, Server_Game *> gamesIterator(games);
|
QMapIterator<int, Server_Game *> gamesIterator(games);
|
||||||
int result = 0;
|
int result = 0;
|
||||||
while (gamesIterator.hasNext())
|
while (gamesIterator.hasNext())
|
||||||
if (gamesIterator.next().value()->getCreatorInfo()->name() == userName.toStdString())
|
if (gamesIterator.next().value()->getCreatorInfo()->name() == userName.toStdString())
|
||||||
++result;
|
++result;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<ServerInfo_Game> Server_Room::getGamesOfUser(const QString &userName) const
|
QList<ServerInfo_Game> Server_Room::getGamesOfUser(const QString &userName) const
|
||||||
{
|
{
|
||||||
QReadLocker locker(&gamesLock);
|
QReadLocker locker(&gamesLock);
|
||||||
|
|
||||||
QList<ServerInfo_Game> result;
|
QList<ServerInfo_Game> result;
|
||||||
QMapIterator<int, Server_Game *> gamesIterator(games);
|
QMapIterator<int, Server_Game *> gamesIterator(games);
|
||||||
while (gamesIterator.hasNext()) {
|
while (gamesIterator.hasNext()) {
|
||||||
Server_Game *game = gamesIterator.next().value();
|
Server_Game *game = gamesIterator.next().value();
|
||||||
if (game->containsUser(userName)) {
|
if (game->containsUser(userName)) {
|
||||||
ServerInfo_Game gameInfo;
|
ServerInfo_Game gameInfo;
|
||||||
game->getInfo(gameInfo);
|
game->getInfo(gameInfo);
|
||||||
result.append(gameInfo);
|
result.append(gameInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,58 +24,58 @@ class ResponseContainer;
|
||||||
class Server_AbstractUserInterface;
|
class Server_AbstractUserInterface;
|
||||||
|
|
||||||
class Server_Room : public QObject {
|
class Server_Room : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
signals:
|
signals:
|
||||||
void roomInfoChanged(const ServerInfo_Room &roomInfo);
|
void roomInfoChanged(const ServerInfo_Room &roomInfo);
|
||||||
void gameListChanged(const ServerInfo_Game &gameInfo);
|
void gameListChanged(const ServerInfo_Game &gameInfo);
|
||||||
private:
|
private:
|
||||||
int id;
|
int id;
|
||||||
QString name;
|
QString name;
|
||||||
QString description;
|
QString description;
|
||||||
bool autoJoin;
|
bool autoJoin;
|
||||||
QString joinMessage;
|
QString joinMessage;
|
||||||
QStringList gameTypes;
|
QStringList gameTypes;
|
||||||
QMap<int, Server_Game *> games;
|
QMap<int, Server_Game *> games;
|
||||||
QMap<int, ServerInfo_Game> externalGames;
|
QMap<int, ServerInfo_Game> externalGames;
|
||||||
QMap<QString, Server_ProtocolHandler *> users;
|
QMap<QString, Server_ProtocolHandler *> users;
|
||||||
QMap<QString, ServerInfo_User_Container> externalUsers;
|
QMap<QString, ServerInfo_User_Container> externalUsers;
|
||||||
private slots:
|
private slots:
|
||||||
void broadcastGameListUpdate(const ServerInfo_Game &gameInfo, bool sendToIsl = true);
|
void broadcastGameListUpdate(const ServerInfo_Game &gameInfo, bool sendToIsl = true);
|
||||||
public:
|
public:
|
||||||
mutable QReadWriteLock usersLock;
|
mutable QReadWriteLock usersLock;
|
||||||
mutable QReadWriteLock gamesLock;
|
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 _id, const QString &_name, const QString &_description, bool _autoJoin, const QString &_joinMessage, const QStringList &_gameTypes, Server *parent);
|
||||||
~Server_Room();
|
~Server_Room();
|
||||||
int getId() const { return id; }
|
int getId() const { return id; }
|
||||||
QString getName() const { return name; }
|
QString getName() const { return name; }
|
||||||
QString getDescription() const { return description; }
|
QString getDescription() const { return description; }
|
||||||
bool getAutoJoin() const { return autoJoin; }
|
bool getAutoJoin() const { return autoJoin; }
|
||||||
QString getJoinMessage() const { return joinMessage; }
|
QString getJoinMessage() const { return joinMessage; }
|
||||||
const QStringList &getGameTypes() const { return gameTypes; }
|
const QStringList &getGameTypes() const { return gameTypes; }
|
||||||
const QMap<int, Server_Game *> &getGames() const { return games; }
|
const QMap<int, Server_Game *> &getGames() const { return games; }
|
||||||
const QMap<int, ServerInfo_Game> &getExternalGames() const { return externalGames; }
|
const QMap<int, ServerInfo_Game> &getExternalGames() const { return externalGames; }
|
||||||
Server *getServer() const;
|
Server *getServer() const;
|
||||||
const ServerInfo_Room &getInfo(ServerInfo_Room &result, bool complete, bool showGameTypes = false, bool includeExternalData = true) const;
|
const ServerInfo_Room &getInfo(ServerInfo_Room &result, bool complete, bool showGameTypes = false, bool includeExternalData = true) const;
|
||||||
int getGamesCreatedByUser(const QString &name) const;
|
int getGamesCreatedByUser(const QString &name) const;
|
||||||
QList<ServerInfo_Game> getGamesOfUser(const QString &name) const;
|
QList<ServerInfo_Game> getGamesOfUser(const QString &name) const;
|
||||||
|
|
||||||
void addClient(Server_ProtocolHandler *client);
|
void addClient(Server_ProtocolHandler *client);
|
||||||
void removeClient(Server_ProtocolHandler *client);
|
void removeClient(Server_ProtocolHandler *client);
|
||||||
|
|
||||||
void addExternalUser(const ServerInfo_User &userInfo);
|
void addExternalUser(const ServerInfo_User &userInfo);
|
||||||
void removeExternalUser(const QString &name);
|
void removeExternalUser(const QString &name);
|
||||||
const QMap<QString, ServerInfo_User_Container> &getExternalUsers() const { return externalUsers; }
|
const QMap<QString, ServerInfo_User_Container> &getExternalUsers() const { return externalUsers; }
|
||||||
void updateExternalGameList(const ServerInfo_Game &gameInfo);
|
void updateExternalGameList(const ServerInfo_Game &gameInfo);
|
||||||
|
|
||||||
Response::ResponseCode processJoinGameCommand(const Command_JoinGame &cmd, ResponseContainer &rc, Server_AbstractUserInterface *userInterface);
|
Response::ResponseCode processJoinGameCommand(const Command_JoinGame &cmd, ResponseContainer &rc, Server_AbstractUserInterface *userInterface);
|
||||||
|
|
||||||
void say(const QString &userName, const QString &s, bool sendToIsl = true);
|
void say(const QString &userName, const QString &s, bool sendToIsl = true);
|
||||||
|
|
||||||
void addGame(Server_Game *game);
|
void addGame(Server_Game *game);
|
||||||
void removeGame(Server_Game *game);
|
void removeGame(Server_Game *game);
|
||||||
|
|
||||||
void sendRoomEvent(RoomEvent *event, bool sendToIsl = true);
|
void sendRoomEvent(RoomEvent *event, bool sendToIsl = true);
|
||||||
RoomEvent *prepareRoomEvent(const ::google::protobuf::Message &roomEvent);
|
RoomEvent *prepareRoomEvent(const ::google::protobuf::Message &roomEvent);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -7,46 +7,46 @@ ServerInfo_User_Container::ServerInfo_User_Container(ServerInfo_User *_userInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
ServerInfo_User_Container::ServerInfo_User_Container(const 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)
|
ServerInfo_User_Container::ServerInfo_User_Container(const ServerInfo_User_Container &other)
|
||||||
{
|
{
|
||||||
if (other.userInfo)
|
if (other.userInfo)
|
||||||
userInfo = new ServerInfo_User(*other.userInfo);
|
userInfo = new ServerInfo_User(*other.userInfo);
|
||||||
else
|
else
|
||||||
userInfo = 0;
|
userInfo = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ServerInfo_User_Container::~ServerInfo_User_Container()
|
ServerInfo_User_Container::~ServerInfo_User_Container()
|
||||||
{
|
{
|
||||||
delete userInfo;
|
delete userInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServerInfo_User_Container::setUserInfo(const ServerInfo_User &_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
|
ServerInfo_User &ServerInfo_User_Container::copyUserInfo(ServerInfo_User &result, bool complete, bool internalInfo, bool sessionInfo) const
|
||||||
{
|
{
|
||||||
if (userInfo) {
|
if (userInfo) {
|
||||||
result.CopyFrom(*userInfo);
|
result.CopyFrom(*userInfo);
|
||||||
if (!sessionInfo) {
|
if (!sessionInfo) {
|
||||||
result.clear_session_id();
|
result.clear_session_id();
|
||||||
result.clear_address();
|
result.clear_address();
|
||||||
}
|
}
|
||||||
if (!internalInfo)
|
if (!internalInfo)
|
||||||
result.clear_id();
|
result.clear_id();
|
||||||
if (!complete)
|
if (!complete)
|
||||||
result.clear_avatar_bmp();
|
result.clear_avatar_bmp();
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
ServerInfo_User ServerInfo_User_Container::copyUserInfo(bool complete, bool internalInfo, bool sessionInfo) const
|
ServerInfo_User ServerInfo_User_Container::copyUserInfo(bool complete, bool internalInfo, bool sessionInfo) const
|
||||||
{
|
{
|
||||||
ServerInfo_User result;
|
ServerInfo_User result;
|
||||||
return copyUserInfo(result, complete, internalInfo, sessionInfo);
|
return copyUserInfo(result, complete, internalInfo, sessionInfo);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,16 +5,16 @@ class ServerInfo_User;
|
||||||
|
|
||||||
class ServerInfo_User_Container {
|
class ServerInfo_User_Container {
|
||||||
protected:
|
protected:
|
||||||
ServerInfo_User *userInfo;
|
ServerInfo_User *userInfo;
|
||||||
public:
|
public:
|
||||||
ServerInfo_User_Container(ServerInfo_User *_userInfo = 0);
|
ServerInfo_User_Container(ServerInfo_User *_userInfo = 0);
|
||||||
ServerInfo_User_Container(const ServerInfo_User &_userInfo);
|
ServerInfo_User_Container(const ServerInfo_User &_userInfo);
|
||||||
ServerInfo_User_Container(const ServerInfo_User_Container &other);
|
ServerInfo_User_Container(const ServerInfo_User_Container &other);
|
||||||
virtual ~ServerInfo_User_Container();
|
virtual ~ServerInfo_User_Container();
|
||||||
ServerInfo_User *getUserInfo() const { return userInfo; }
|
ServerInfo_User *getUserInfo() const { return userInfo; }
|
||||||
void setUserInfo(const ServerInfo_User &_userInfo);
|
void setUserInfo(const ServerInfo_User &_userInfo);
|
||||||
ServerInfo_User ©UserInfo(ServerInfo_User &result, bool complete, bool internalInfo = false, bool sessionInfo = false) const;
|
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 copyUserInfo(bool complete, bool internalInfo = false, bool sessionInfo = false) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
56
doc/cards.xsd
Normal file
56
doc/cards.xsd
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||||
|
<xs:element name="cockatrice_carddatabase">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:sequence>
|
||||||
|
<xs:element name="sets">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:sequence>
|
||||||
|
<xs:element name="set" maxOccurs="unbounded" minOccurs="0">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:sequence>
|
||||||
|
<xs:element type="xs:string" name="name"/>
|
||||||
|
<xs:element type="xs:string" name="longname"/>
|
||||||
|
</xs:sequence>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
</xs:sequence>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element name="cards">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:sequence>
|
||||||
|
<xs:element name="card" maxOccurs="unbounded" minOccurs="0">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:sequence>
|
||||||
|
<xs:element type="xs:string" name="name"/>
|
||||||
|
<xs:element name="set" maxOccurs="unbounded" minOccurs="0">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:simpleContent>
|
||||||
|
<xs:extension base="xs:string">
|
||||||
|
<xs:attribute type="xs:int" name="muId" use="optional"/>
|
||||||
|
<xs:attribute type="xs:anyURI" name="picUrl" use="optional"/>
|
||||||
|
<xs:attribute type="xs:anyURI" name="picUrlHq" use="optional"/>
|
||||||
|
</xs:extension>
|
||||||
|
</xs:simpleContent>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element type="xs:string" name="color" minOccurs="0" maxOccurs="unbounded"/>
|
||||||
|
<xs:element type="xs:string" name="manacost"/>
|
||||||
|
<xs:element type="xs:string" name="type"/>
|
||||||
|
<xs:element type="xs:string" name="pt" minOccurs="0"/>
|
||||||
|
<xs:element type="xs:integer" name="tablerow"/>
|
||||||
|
<xs:element type="xs:string" name="text"/>
|
||||||
|
<xs:element type="xs:boolean" name="cipt" minOccurs="0"/>
|
||||||
|
<xs:element type="xs:integer" name="loyalty" minOccurs="0"/>
|
||||||
|
<xs:element type="xs:boolean" name="token" minOccurs="0"/>
|
||||||
|
</xs:sequence>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
</xs:sequence>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
</xs:sequence>
|
||||||
|
<xs:attribute type="xs:integer" name="version"/>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
</xs:schema>
|
||||||
|
|
@ -16,6 +16,19 @@ SET(oracle_SOURCES
|
||||||
../cockatrice/src/qt-json/json.cpp
|
../cockatrice/src/qt-json/json.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
set(oracle_RESOURCES oracle.qrc)
|
||||||
|
|
||||||
|
if(WIN32)
|
||||||
|
set(oracle_SOURCES ${oracle_SOURCES} oracle.rc)
|
||||||
|
endif(WIN32)
|
||||||
|
|
||||||
|
|
||||||
|
if(APPLE)
|
||||||
|
set(MACOSX_BUNDLE_ICON_FILE appicon.icns)
|
||||||
|
set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/resources/appicon.icns PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
|
||||||
|
set(oracle_SOURCES ${oracle_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/resources/appicon.icns)
|
||||||
|
ENDIF(APPLE)
|
||||||
|
|
||||||
set(ORACLE_LIBS)
|
set(ORACLE_LIBS)
|
||||||
|
|
||||||
# Qt4 stuff
|
# Qt4 stuff
|
||||||
|
|
@ -29,6 +42,10 @@ if(Qt4_FOUND)
|
||||||
include_directories(${QT_INCLUDES})
|
include_directories(${QT_INCLUDES})
|
||||||
LIST(APPEND ORACLE_LIBS ${QT_QTMAIN_LIBRARY})
|
LIST(APPEND ORACLE_LIBS ${QT_QTMAIN_LIBRARY})
|
||||||
LIST(APPEND ORACLE_LIBS ${QT_LIBRARIES})
|
LIST(APPEND ORACLE_LIBS ${QT_LIBRARIES})
|
||||||
|
|
||||||
|
# Let cmake chew Qt4's translations and resource files
|
||||||
|
# Note: header files are MOC-ed automatically by cmake
|
||||||
|
QT4_ADD_RESOURCES(oracle_RESOURCES_RCC ${oracle_RESOURCES})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# qt5 stuff
|
# qt5 stuff
|
||||||
|
|
@ -64,6 +81,10 @@ if(Qt5Widgets_FOUND)
|
||||||
list(APPEND ORACLE_LIBS Svg)
|
list(APPEND ORACLE_LIBS Svg)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# Let cmake chew Qt5's translations and resource files
|
||||||
|
# Note: header files are MOC-ed automatically by cmake
|
||||||
|
QT5_ADD_RESOURCES(oracle_RESOURCES_RCC ${oracle_RESOURCES})
|
||||||
|
|
||||||
# guess plugins and libraries directory
|
# guess plugins and libraries directory
|
||||||
set(QT_PLUGINS_DIR "${Qt5Widgets_DIR}/../../../plugins")
|
set(QT_PLUGINS_DIR "${Qt5Widgets_DIR}/../../../plugins")
|
||||||
get_target_property(QT_LIBRARY_DIR Qt5::Core LOCATION)
|
get_target_property(QT_LIBRARY_DIR Qt5::Core LOCATION)
|
||||||
|
|
@ -73,7 +94,7 @@ endif()
|
||||||
INCLUDE_DIRECTORIES(../cockatrice/src)
|
INCLUDE_DIRECTORIES(../cockatrice/src)
|
||||||
|
|
||||||
# Build oracle binary and link it
|
# Build oracle binary and link it
|
||||||
ADD_EXECUTABLE(oracle WIN32 MACOSX_BUNDLE ${oracle_SOURCES} ${oracle_MOC_SRCS})
|
ADD_EXECUTABLE(oracle WIN32 MACOSX_BUNDLE ${oracle_SOURCES} ${oracle_RESOURCES_RCC} ${oracle_MOC_SRCS})
|
||||||
|
|
||||||
if(Qt4_FOUND)
|
if(Qt4_FOUND)
|
||||||
if(MSVC)
|
if(MSVC)
|
||||||
|
|
@ -94,6 +115,8 @@ if(UNIX)
|
||||||
else()
|
else()
|
||||||
# Assume linux
|
# Assume linux
|
||||||
INSTALL(TARGETS oracle RUNTIME DESTINATION bin/)
|
INSTALL(TARGETS oracle RUNTIME DESTINATION bin/)
|
||||||
|
INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/resources/oracle.png DESTINATION ${ICONDIR}/hicolor/48x48/apps)
|
||||||
|
INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/resources/oracle.svg DESTINATION ${ICONDIR}/hicolor/scalable/apps)
|
||||||
endif()
|
endif()
|
||||||
elseif(WIN32)
|
elseif(WIN32)
|
||||||
INSTALL(TARGETS oracle RUNTIME DESTINATION ./)
|
INSTALL(TARGETS oracle RUNTIME DESTINATION ./)
|
||||||
|
|
|
||||||
|
|
@ -4,5 +4,5 @@ Version=1.0
|
||||||
Type=Application
|
Type=Application
|
||||||
Name=Cockatrice Oracle downloader
|
Name=Cockatrice Oracle downloader
|
||||||
Exec=oracle
|
Exec=oracle
|
||||||
Icon=cockatrice
|
Icon=oracle
|
||||||
Categories=Game;CardGame;
|
Categories=Game;CardGame;
|
||||||
|
|
|
||||||
5
oracle/oracle.qrc
Normal file
5
oracle/oracle.qrc
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
<RCC>
|
||||||
|
<qresource prefix="/" >
|
||||||
|
<file alias="resources/appicon.svg">resources/oracle.svg</file>
|
||||||
|
</qresource>
|
||||||
|
</RCC>
|
||||||
1
oracle/oracle.rc
Normal file
1
oracle/oracle.rc
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
ID1_ICON1 ICON DISCARDABLE "resources/appicon.ico"
|
||||||
BIN
oracle/resources/appicon.icns
Normal file
BIN
oracle/resources/appicon.icns
Normal file
Binary file not shown.
BIN
oracle/resources/appicon.ico
Normal file
BIN
oracle/resources/appicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 118 KiB |
BIN
oracle/resources/oracle.png
Normal file
BIN
oracle/resources/oracle.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.5 KiB |
228
oracle/resources/oracle.svg
Normal file
228
oracle/resources/oracle.svg
Normal file
|
|
@ -0,0 +1,228 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="300.0036"
|
||||||
|
height="300"
|
||||||
|
id="svg2"
|
||||||
|
sodipodi:version="0.32"
|
||||||
|
inkscape:version="0.48.2 r9819"
|
||||||
|
sodipodi:docname="back.svg"
|
||||||
|
inkscape:output_extension="org.inkscape.output.svg.inkscape"
|
||||||
|
version="1.0"
|
||||||
|
inkscape:export-xdpi="96"
|
||||||
|
inkscape:export-ydpi="96">
|
||||||
|
<defs
|
||||||
|
id="defs4">
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient3169">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#0000ff;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop3171" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#000067;stop-opacity:1;"
|
||||||
|
offset="1"
|
||||||
|
id="stop3173" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient4766">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#784421;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop4768" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#3d2210;stop-opacity:0;"
|
||||||
|
offset="1"
|
||||||
|
id="stop4770" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient4758">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#a05a2c;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop4760" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#3d2210;stop-opacity:1;"
|
||||||
|
offset="1"
|
||||||
|
id="stop4762" />
|
||||||
|
</linearGradient>
|
||||||
|
<inkscape:perspective
|
||||||
|
sodipodi:type="inkscape:persp3d"
|
||||||
|
inkscape:vp_x="0 : 526.18109 : 1"
|
||||||
|
inkscape:vp_y="0 : 1000 : 0"
|
||||||
|
inkscape:vp_z="744.09448 : 526.18109 : 1"
|
||||||
|
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
|
||||||
|
id="perspective10" />
|
||||||
|
<inkscape:perspective
|
||||||
|
id="perspective2484"
|
||||||
|
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
|
||||||
|
inkscape:vp_z="744.09448 : 526.18109 : 1"
|
||||||
|
inkscape:vp_y="0 : 1000 : 0"
|
||||||
|
inkscape:vp_x="0 : 526.18109 : 1"
|
||||||
|
sodipodi:type="inkscape:persp3d" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient4758"
|
||||||
|
id="linearGradient4764"
|
||||||
|
x1="466.09601"
|
||||||
|
y1="485.96021"
|
||||||
|
x2="715.14801"
|
||||||
|
y2="485.96021"
|
||||||
|
gradientUnits="userSpaceOnUse" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient4766"
|
||||||
|
id="linearGradient4772"
|
||||||
|
x1="496.548"
|
||||||
|
y1="485.26816"
|
||||||
|
x2="683.31201"
|
||||||
|
y2="485.26816"
|
||||||
|
gradientUnits="userSpaceOnUse" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient4766"
|
||||||
|
id="linearGradient2396"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
x1="661.24402"
|
||||||
|
y1="602.90814"
|
||||||
|
x2="431.5"
|
||||||
|
y2="201.5482"
|
||||||
|
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient4758"
|
||||||
|
id="linearGradient2399"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
x1="590.62201"
|
||||||
|
y1="434.7522"
|
||||||
|
x2="698.54004"
|
||||||
|
y2="517.79218"
|
||||||
|
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)" />
|
||||||
|
<filter
|
||||||
|
inkscape:collect="always"
|
||||||
|
id="filter3287"
|
||||||
|
color-interpolation-filters="sRGB">
|
||||||
|
<feGaussianBlur
|
||||||
|
inkscape:collect="always"
|
||||||
|
stdDeviation="0.88403668"
|
||||||
|
id="feGaussianBlur3289" />
|
||||||
|
</filter>
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient4766"
|
||||||
|
id="linearGradient3057"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(0.84875138,0,0,0.874988,-395.5345,-274.89225)"
|
||||||
|
x1="661.24402"
|
||||||
|
y1="602.90814"
|
||||||
|
x2="431.5"
|
||||||
|
y2="201.5482" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient4758"
|
||||||
|
id="linearGradient3059"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(0.84875138,0,0,0.874988,-395.5345,-274.89225)"
|
||||||
|
x1="590.62201"
|
||||||
|
y1="434.7522"
|
||||||
|
x2="698.54004"
|
||||||
|
y2="517.79218" />
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="1.4911765"
|
||||||
|
inkscape:cx="164.24505"
|
||||||
|
inkscape:cy="113.77996"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:window-width="1280"
|
||||||
|
inkscape:window-height="725"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="25"
|
||||||
|
fit-margin-left="44.18"
|
||||||
|
fit-margin-right="44.18"
|
||||||
|
fit-margin-top="0"
|
||||||
|
fit-margin-bottom="0"
|
||||||
|
inkscape:window-maximized="0" />
|
||||||
|
<metadata
|
||||||
|
id="metadata7">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Ebene 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(44.245053,-0.31708717)">
|
||||||
|
<rect
|
||||||
|
style="fill:url(#linearGradient3059);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:17.23539734;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||||
|
id="rect2490"
|
||||||
|
width="194.4082"
|
||||||
|
height="282.76462"
|
||||||
|
x="8.5526457"
|
||||||
|
y="8.9347858"
|
||||||
|
inkscape:export-xdpi="969.46002"
|
||||||
|
inkscape:export-ydpi="969.46002" />
|
||||||
|
<rect
|
||||||
|
style="fill:url(#linearGradient3057);fill-opacity:1;stroke:#000000;stroke-width:1.72353971;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||||
|
id="rect3302"
|
||||||
|
width="156.81871"
|
||||||
|
height="244.01315"
|
||||||
|
x="26.760056"
|
||||||
|
y="27.704998" />
|
||||||
|
<path
|
||||||
|
sodipodi:type="arc"
|
||||||
|
style="opacity:0.39208954;fill:#a05a2c;stroke:#000000;stroke-width:2.00029755;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;filter:url(#filter3287)"
|
||||||
|
id="path3304"
|
||||||
|
sodipodi:cx="589.58398"
|
||||||
|
sodipodi:cy="489.76617"
|
||||||
|
sodipodi:rx="71.968002"
|
||||||
|
sodipodi:ry="128.71201"
|
||||||
|
d="m 661.55199,489.76617 c 0,71.08568 -32.22118,128.71201 -71.96801,128.71201 -39.74683,0 -71.968,-57.62633 -71.968,-128.71201 0,-71.08567 32.22117,-128.712 71.968,-128.712 39.74683,0 71.96801,57.62633 71.96801,128.712 z"
|
||||||
|
transform="matrix(1.0026379,0,0,0.89548037,-485.67617,-289.46994)" />
|
||||||
|
<flowRoot
|
||||||
|
xml:space="preserve"
|
||||||
|
id="flowRoot3021"
|
||||||
|
style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"><flowRegion
|
||||||
|
id="flowRegion3023"><rect
|
||||||
|
id="rect3025"
|
||||||
|
width="151.92514"
|
||||||
|
height="235.58012"
|
||||||
|
x="50.000679"
|
||||||
|
y="60.188515" /></flowRegion><flowPara
|
||||||
|
id="flowPara3027"></flowPara></flowRoot> <text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:35.18093872px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Songti SC;-inkscape-font-specification:Songti SC"
|
||||||
|
x="-14.38486"
|
||||||
|
y="244.29784"
|
||||||
|
id="text3029"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3031"
|
||||||
|
x="-14.38486"
|
||||||
|
y="244.29784"
|
||||||
|
style="font-size:390.50842285px;font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;fill:#ffffff;font-family:STKaiti;-inkscape-font-specification:STKaiti Bold Italic">o</tspan></text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 7.9 KiB |
|
|
@ -1,5 +1,6 @@
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QTextCodec>
|
#include <QTextCodec>
|
||||||
|
#include <QIcon>
|
||||||
#include "oraclewizard.h"
|
#include "oraclewizard.h"
|
||||||
#include "settingscache.h"
|
#include "settingscache.h"
|
||||||
|
|
||||||
|
|
@ -22,6 +23,10 @@ int main(int argc, char *argv[])
|
||||||
settingsCache = new SettingsCache;
|
settingsCache = new SettingsCache;
|
||||||
|
|
||||||
OracleWizard wizard;
|
OracleWizard wizard;
|
||||||
|
|
||||||
|
QIcon icon(":/resources/appicon.svg");
|
||||||
|
wizard.setWindowIcon(icon);
|
||||||
|
|
||||||
wizard.show();
|
wizard.show();
|
||||||
|
|
||||||
return app.exec();
|
return app.exec();
|
||||||
|
|
|
||||||
|
|
@ -80,8 +80,8 @@ CardInfo *OracleImporter::addCard(const QString &setName,
|
||||||
cardCost.remove(QChar('}'));
|
cardCost.remove(QChar('}'));
|
||||||
|
|
||||||
CardInfo *card;
|
CardInfo *card;
|
||||||
if (cardHash.contains(cardName)) {
|
if (cards.contains(cardName)) {
|
||||||
card = cardHash.value(cardName);
|
card = cards.value(cardName);
|
||||||
if (splitCard && !card->getText().contains(fullCardText))
|
if (splitCard && !card->getText().contains(fullCardText))
|
||||||
card->setText(card->getText() + "\n---\n" + fullCardText);
|
card->setText(card->getText() + "\n---\n" + fullCardText);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -121,7 +121,7 @@ CardInfo *OracleImporter::addCard(const QString &setName,
|
||||||
tableRow = 2;
|
tableRow = 2;
|
||||||
card->setTableRow(tableRow);
|
card->setTableRow(tableRow);
|
||||||
|
|
||||||
cardHash.insert(cardName, card);
|
cards.insert(cardName, card);
|
||||||
}
|
}
|
||||||
card->setMuId(setName, cardId);
|
card->setMuId(setName, cardId);
|
||||||
|
|
||||||
|
|
@ -141,6 +141,7 @@ int OracleImporter::importTextSpoiler(CardSet *set, const QVariant &data)
|
||||||
QString cardText;
|
QString cardText;
|
||||||
int cardId;
|
int cardId;
|
||||||
int cardLoyalty;
|
int cardLoyalty;
|
||||||
|
bool cardIsToken = false;
|
||||||
QMap<int, QVariantMap> splitCards;
|
QMap<int, QVariantMap> splitCards;
|
||||||
|
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
|
|
@ -201,9 +202,15 @@ int OracleImporter::importTextSpoiler(CardSet *set, const QVariant &data)
|
||||||
cardText = map.contains("text") ? map.value("text").toString() : QString("");
|
cardText = map.contains("text") ? map.value("text").toString() : QString("");
|
||||||
cardId = map.contains("multiverseid") ? map.value("multiverseid").toInt() : 0;
|
cardId = map.contains("multiverseid") ? map.value("multiverseid").toInt() : 0;
|
||||||
cardLoyalty = map.contains("loyalty") ? map.value("loyalty").toInt() : 0;
|
cardLoyalty = map.contains("loyalty") ? map.value("loyalty").toInt() : 0;
|
||||||
|
cardIsToken = map.value("layout") == "token";
|
||||||
|
|
||||||
|
// Distinguish Vanguard cards from regular cards of the same name.
|
||||||
|
if (map.value("layout") == "vanguard") {
|
||||||
|
cardName += " Avatar";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CardInfo *card = addCard(set->getShortName(), cardName, false, cardId, cardCost, cardType, cardPT, cardLoyalty, cardText.split("\n"));
|
CardInfo *card = addCard(set->getShortName(), cardName, cardIsToken, cardId, cardCost, cardType, cardPT, cardLoyalty, cardText.split("\n"));
|
||||||
|
|
||||||
if (!set->contains(card)) {
|
if (!set->contains(card)) {
|
||||||
card->addToSet(set);
|
card->addToSet(set);
|
||||||
|
|
@ -229,8 +236,8 @@ int OracleImporter::startImport()
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
CardSet *set = new CardSet(curSet->getShortName(), curSet->getLongName());
|
CardSet *set = new CardSet(curSet->getShortName(), curSet->getLongName());
|
||||||
if (!setHash.contains(set->getShortName()))
|
if (!sets.contains(set->getShortName()))
|
||||||
setHash.insert(set->getShortName(), set);
|
sets.insert(set->getShortName(), set);
|
||||||
|
|
||||||
int setCards = importTextSpoiler(set, curSet->getCards());
|
int setCards = importTextSpoiler(set, curSet->getCards());
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -383,7 +383,7 @@ void SaveSetsPage::initializePage()
|
||||||
QMessageBox::critical(this, tr("Error"), tr("No set has been imported."));
|
QMessageBox::critical(this, tr("Error"), tr("No set has been imported."));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SaveSetsPage::updateTotalProgress(int cardsImported, int setIndex, const QString &setName)
|
void SaveSetsPage::updateTotalProgress(int cardsImported, int /* setIndex */, const QString &setName)
|
||||||
{
|
{
|
||||||
if (setName.isEmpty()) {
|
if (setName.isEmpty()) {
|
||||||
messageLog->append("<b>" + tr("Import finished: %1 cards.").arg(wizard()->importer->getCardList().size()) + "</b>");
|
messageLog->append("<b>" + tr("Import finished: %1 cards.").arg(wizard()->importer->getCardList().size()) + "</b>");
|
||||||
|
|
@ -418,9 +418,12 @@ bool SaveSetsPage::validatePage()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (wizard()->importer->saveToFile(fileName))
|
if (wizard()->importer->saveToFile(fileName))
|
||||||
|
{
|
||||||
ok = true;
|
ok = true;
|
||||||
else
|
QMessageBox::information(this, tr("Success"), tr("The card database has been saved successfully."));
|
||||||
|
} else {
|
||||||
QMessageBox::critical(this, tr("Error"), tr("The file could not be saved to the desired location."));
|
QMessageBox::critical(this, tr("Error"), tr("The file could not be saved to the desired location."));
|
||||||
|
}
|
||||||
} while (!ok);
|
} while (!ok);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
3
servatrice/scripts/maint_replays
Normal file
3
servatrice/scripts/maint_replays
Normal file
|
|
@ -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'
|
||||||
3
servatrice/scripts/maint_sessions
Normal file
3
servatrice/scripts/maint_sessions
Normal file
|
|
@ -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)"
|
||||||
3
servatrice/scripts/mysql.cnf.example
Normal file
3
servatrice/scripts/mysql.cnf.example
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
[client]
|
||||||
|
user={db_username}
|
||||||
|
password={db_password}
|
||||||
|
|
@ -29,6 +29,7 @@
|
||||||
#include "server_logger.h"
|
#include "server_logger.h"
|
||||||
#include "rng_sfmt.h"
|
#include "rng_sfmt.h"
|
||||||
#include "version_string.h"
|
#include "version_string.h"
|
||||||
|
#include <google/protobuf/stubs/common.h>
|
||||||
#ifdef Q_OS_UNIX
|
#ifdef Q_OS_UNIX
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -37,6 +38,23 @@ RNG_Abstract *rng;
|
||||||
ServerLogger *logger;
|
ServerLogger *logger;
|
||||||
QThread *loggerThread;
|
QThread *loggerThread;
|
||||||
|
|
||||||
|
/* Prototypes */
|
||||||
|
|
||||||
|
void testRNG();
|
||||||
|
void testHash();
|
||||||
|
#if QT_VERSION < 0x050000
|
||||||
|
void myMessageOutput(QtMsgType type, const char *msg);
|
||||||
|
void myMessageOutput2(QtMsgType type, const char *msg);
|
||||||
|
#else
|
||||||
|
void myMessageOutput(QtMsgType type, const QMessageLogContext &, const QString &msg);
|
||||||
|
void myMessageOutput2(QtMsgType type, const QMessageLogContext &, const QString &msg);
|
||||||
|
#endif
|
||||||
|
#ifdef Q_OS_UNIX
|
||||||
|
void sigSegvHandler(int sig);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Implementations */
|
||||||
|
|
||||||
void testRNG()
|
void testRNG()
|
||||||
{
|
{
|
||||||
const int n = 500000;
|
const int n = 500000;
|
||||||
|
|
@ -216,5 +234,8 @@ int main(int argc, char *argv[])
|
||||||
loggerThread->wait();
|
loggerThread->wait();
|
||||||
delete loggerThread;
|
delete loggerThread;
|
||||||
|
|
||||||
|
// Delete all global objects allocated by libprotobuf.
|
||||||
|
google::protobuf::ShutdownProtobufLibrary();
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,12 +18,15 @@ QString PasswordHasher::computeHash(const QString &password, const QString &salt
|
||||||
|
|
||||||
QByteArray passwordBuffer = (salt + password).toUtf8();
|
QByteArray passwordBuffer = (salt + password).toUtf8();
|
||||||
int hashLen = gcry_md_get_algo_dlen(algo);
|
int hashLen = gcry_md_get_algo_dlen(algo);
|
||||||
char hash[hashLen], tmp[hashLen];
|
char *hash = new char[hashLen], *tmp = new char[hashLen];
|
||||||
gcry_md_hash_buffer(algo, hash, passwordBuffer.data(), passwordBuffer.size());
|
gcry_md_hash_buffer(algo, hash, passwordBuffer.data(), passwordBuffer.size());
|
||||||
for (int i = 1; i < rounds; ++i) {
|
for (int i = 1; i < rounds; ++i) {
|
||||||
memcpy(tmp, hash, hashLen);
|
memcpy(tmp, hash, hashLen);
|
||||||
gcry_md_hash_buffer(algo, hash, tmp, hashLen);
|
gcry_md_hash_buffer(algo, hash, tmp, hashLen);
|
||||||
}
|
}
|
||||||
return salt + QString(QByteArray(hash, hashLen).toBase64());
|
QString hashedPass = salt + QString(QByteArray(hash, hashLen).toBase64());
|
||||||
|
delete[] tmp;
|
||||||
|
delete[] hash;
|
||||||
|
return hashedPass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,11 @@ Servatrice_GameServer::~Servatrice_GameServer()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if QT_VERSION < 0x050000
|
||||||
void Servatrice_GameServer::incomingConnection(int socketDescriptor)
|
void Servatrice_GameServer::incomingConnection(int socketDescriptor)
|
||||||
|
#else
|
||||||
|
void Servatrice_GameServer::incomingConnection(qintptr socketDescriptor)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
// Determine connection pool with smallest client count
|
// Determine connection pool with smallest client count
|
||||||
int minClientCount = -1;
|
int minClientCount = -1;
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue