Merge branch 'master' into cmake_qt5

Conflicts:
	cockatrice/src/main.cpp
This commit is contained in:
Daenyth 2014-06-28 09:13:10 -04:00
commit 09d6d26fb2
22 changed files with 156 additions and 93 deletions

View file

@ -5,6 +5,6 @@ os:
compiler:
- gcc
- clang
script: mkdir build && cd build && cmake .. && make
script: mkdir build && cd build && cmake .. -DWITH_SERVER=1 && make
install: ./travis-dependencies.sh
cache: apt

View file

@ -71,7 +71,7 @@ IF(MSVC)
ELSEIF (CMAKE_COMPILER_IS_GNUCXX)
# linux/gcc, bsd/gcc, windows/mingw
set(CMAKE_CXX_FLAGS_RELEASE "-s -O2")
set(CMAKE_CXX_FLAGS_DEBUG "-ggdb -O0")
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 -W-noerror=sign-compare -Wno-error=reorder -Wno-error=missing-declarations")
ELSE()
# other: osx/llvm, bsd/llvm
set(CMAKE_CXX_FLAGS_RELEASE "-O2")

View file

@ -31,7 +31,7 @@ enum ClientStatus {
StatusConnecting,
StatusAwaitingWelcome,
StatusLoggingIn,
StatusLoggedIn,
StatusLoggedIn
};
class AbstractClient : public QObject {

View file

@ -16,7 +16,7 @@
const int CardDatabase::versionNeeded = 3;
QXmlStreamWriter &operator<<(QXmlStreamWriter &xml, const CardSet *set)
static QXmlStreamWriter &operator<<(QXmlStreamWriter &xml, const CardSet *set)
{
xml.writeStartElement("set");
xml.writeTextElement("name", set->getShortName());
@ -275,18 +275,18 @@ CardInfo::CardInfo(CardDatabase *_db,
bool _cipt,
int _tableRow,
const SetList &_sets,
QMap<QString, int> _muIds)
MuidMap _muIds)
: db(_db),
name(_name),
isToken(_isToken),
sets(_sets),
muIds(_muIds),
manacost(_manacost),
cardtype(_cardtype),
powtough(_powtough),
text(_text),
colors(_colors),
loyalty(_loyalty),
muIds(_muIds),
cipt(_cipt),
tableRow(_tableRow),
pixmap(NULL)
@ -434,7 +434,7 @@ int CardInfo::getPreferredMuId()
return muIds[getPreferredSet()->getShortName()];
}
QXmlStreamWriter &operator<<(QXmlStreamWriter &xml, const CardInfo *info)
static QXmlStreamWriter &operator<<(QXmlStreamWriter &xml, const CardInfo *info)
{
xml.writeStartElement("card");
xml.writeTextElement("name", info->getName());
@ -473,7 +473,7 @@ QXmlStreamWriter &operator<<(QXmlStreamWriter &xml, const CardInfo *info)
}
CardDatabase::CardDatabase(QObject *parent)
: QObject(parent), loadStatus(NotLoaded), noCard(0)
: QObject(parent), noCard(0), loadStatus(NotLoaded)
{
connect(settingsCache, SIGNAL(picsPathChanged()), this, SLOT(picsPathChanged()));
connect(settingsCache, SIGNAL(cardDatabasePathChanged()), this, SLOT(loadCardDatabase()));
@ -610,7 +610,7 @@ void CardDatabase::loadCardsFromXml(QXmlStreamReader &xml)
if (xml.name() == "card") {
QString name, manacost, type, pt, text;
QStringList colors;
QMap<QString, int> muids;
MuidMap muids;
SetList sets;
int tableRow = 0;
int loyalty = 0;

View file

@ -20,6 +20,9 @@ class QNetworkRequest;
typedef QMap<QString, QString> QStringMap;
// If we don't typedef this, CardInfo::CardInfo will refuse to compile on OS X < 10.9
typedef QMap<QString, int> MuidMap;
class CardSet : public QList<CardInfo *> {
private:
QString shortName, longName;
@ -100,7 +103,7 @@ private:
QString text;
QStringList colors;
int loyalty;
QMap<QString, int> muIds;
MuidMap muIds;
bool cipt;
int tableRow;
QPixmap *pixmap;
@ -118,7 +121,7 @@ public:
bool _cipt = false,
int _tableRow = 0,
const SetList &_sets = SetList(),
QMap<QString, int> muids = QMap<QString, int>());
MuidMap muids = MuidMap());
~CardInfo();
const QString &getName() const { return name; }
bool getIsToken() const { return isToken; }

View file

@ -26,9 +26,9 @@ public:
};
private:
QString trm;
enum Type t;
enum Attr a;
QString trm;
public:
CardFilter(QString term, Type type, Attr attr) : trm(term), t(type), a(attr) {};

View file

@ -342,6 +342,9 @@ void DeckListModel::sort(int column, Qt::SortOrder order)
break;
case 2:
sortMethod = ByPrice;
break;
default:
sortMethod = ByName;
}
root->setSortMethod(sortMethod);
sortHelper(root, order);

View file

@ -66,7 +66,7 @@ public:
const CardFilter::Attr attr;
LogicMap(CardFilter::Attr a, FilterTree *parent)
: attr(a), p(parent) {}
: p(parent), attr(a) {}
const FilterItemList *findTypeList(CardFilter::Type type) const;
FilterItemList *typeList(CardFilter::Type type);
FilterTreeNode *parent() const;
@ -81,7 +81,7 @@ public:
const CardFilter::Type type;
FilterItemList(CardFilter::Type t, LogicMap *parent)
: type(t), p(parent) {}
: p(parent), type(t) {}
CardFilter::Attr attr() const { return p->attr; }
FilterTreeNode *parent() const { return p; }
int termIndex(const QString &term) const;

View file

@ -56,7 +56,7 @@ QString translationPath = QString();
#endif
#if QT_VERSION < 0x050000
void myMessageOutput(QtMsgType /*type*/, const char *msg)
static void myMessageOutput(QtMsgType /*type*/, const char *msg)
{
QFile file("qdebug.txt");
file.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text);
@ -65,7 +65,7 @@ void myMessageOutput(QtMsgType /*type*/, const char *msg)
file.close();
}
#else
void myMessageOutput(QtMsgType /*type*/, const QMessageLogContext &, const QString &msg)
static void myMessageOutput(QtMsgType /*type*/, const QMessageLogContext &, const QString &msg)
{
QFile file("qdebug.txt");
file.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text);

View file

@ -13,4 +13,6 @@ extern QString translationPath;
void installNewTranslator();
bool settingsValid();
#endif

View file

@ -86,12 +86,16 @@ void MessageLogWidget::logLeaveSpectator(QString name)
appendHtml(tr("%1 is not watching the game any more.").arg(sanitizeHtml(name)));
}
void MessageLogWidget::logDeckSelect(Player *player, QString deckHash)
void MessageLogWidget::logDeckSelect(Player *player, QString deckHash, int sideboardSize)
{
if (isFemale(player))
appendHtml(tr("%1 has loaded a deck (%2).", "female").arg(sanitizeHtml(player->getName())).arg(deckHash));
const char* gender = isFemale(player) ? "female" : "male";
if (sideboardSize < 0)
appendHtml(tr("%1 has loaded a deck (%2).", gender).arg(sanitizeHtml(player->getName())).arg(deckHash));
else
appendHtml(tr("%1 has loaded a deck (%2).", "male").arg(sanitizeHtml(player->getName())).arg(deckHash));
appendHtml(tr("%1 has loaded a deck with %2 sideboard cards (%3).", gender).
arg(sanitizeHtml(player->getName())).
arg(sideboardSize).
arg(deckHash));
}
void MessageLogWidget::logReadyStart(Player *player)

View file

@ -48,7 +48,7 @@ public slots:
void logKicked();
void logJoinSpectator(QString name);
void logLeaveSpectator(QString name);
void logDeckSelect(Player *player, QString deckHash);
void logDeckSelect(Player *player, QString deckHash, int sideboardSize);
void logReadyStart(Player *player);
void logNotReadyStart(Player *player);
void logSetSideboardLock(Player *player, bool locked);

View file

@ -1012,7 +1012,10 @@ void TabGame::eventPlayerPropertiesChanged(const Event_PlayerPropertiesChanged &
break;
}
case GameEventContext::DECK_SELECT: {
messageLog->logDeckSelect(player, QString::fromStdString(context.GetExtension(Context_DeckSelect::ext).deck_hash()));
Context_DeckSelect deckSelect = context.GetExtension(Context_DeckSelect::ext);
messageLog->logDeckSelect(player,
QString::fromStdString(deckSelect.deck_hash()),
deckSelect.sideboard_size());
break;
}
case GameEventContext::SET_SIDEBOARD_LOCK: {

View file

@ -180,6 +180,7 @@ bool InnerDecklistNode::compare(AbstractDecklistNode *other) const
case 2:
return comparePrice(other);
}
return 0;
}
bool InnerDecklistNode::compareNumber(AbstractDecklistNode *other) const
@ -226,6 +227,7 @@ bool AbstractDecklistCardNode::compare(AbstractDecklistNode *other) const
case ByPrice:
return compareTotalPrice(other);
}
return 0;
}
bool AbstractDecklistCardNode::compareNumber(AbstractDecklistNode *other) const
@ -351,6 +353,7 @@ DeckList::DeckList()
root = new InnerDecklistNode;
}
// TODO: http://qt-project.org/doc/qt-4.8/qobject.html#no-copy-constructor-or-assignment-operator
DeckList::DeckList(const DeckList &other)
: name(other.name),
comments(other.comments),
@ -630,12 +633,27 @@ QStringList DeckList::getCardList() const
return result.toList();
}
int DeckList::getSideboardSize() const
{
int size = 0;
for (int i = 0; i < root->size(); ++i) {
InnerDecklistNode *node = dynamic_cast<InnerDecklistNode *>(root->at(i));
if (node->getName() != "side")
continue;
for (int j = 0; j < node->size(); j++) {
DecklistCardNode *card = dynamic_cast<DecklistCardNode *>(node->at(j));
size += card->getNumber();
}
}
return size;
}
DecklistCardNode *DeckList::addCard(const QString &cardName, const QString &zoneName)
{
InnerDecklistNode *zoneNode = dynamic_cast<InnerDecklistNode *>(root->findChild(zoneName));
if (!zoneNode)
zoneNode = new InnerDecklistNode(zoneName, root);
DecklistCardNode *node = new DecklistCardNode(cardName, 1, zoneNode);
updateDeckHash();
return node;

View file

@ -160,7 +160,9 @@ public:
void cleanList();
bool isEmpty() const { return root->isEmpty() && name.isEmpty() && comments.isEmpty() && sideboardPlans.isEmpty(); }
QStringList getCardList() const;
int getSideboardSize() const;
QString getDeckHash() const { return deckHash; }
void updateDeckHash();

View file

@ -1,8 +1,9 @@
import "game_event_context.proto";
message Context_DeckSelect {
extend GameEventContext {
optional Context_DeckSelect ext = 1002;
}
optional string deck_hash = 1;
extend GameEventContext {
optional Context_DeckSelect ext = 1002;
}
optional string deck_hash = 1;
optional int32 sideboard_size = 2 [default = -1];
}

View file

@ -657,6 +657,7 @@ Response::ResponseCode Server_Player::cmdDeckSelect(const Command_DeckSelect &cm
Context_DeckSelect context;
context.set_deck_hash(deck->getDeckHash().toStdString());
context.set_sideboard_size(deck->getSideboardSize());
ges.setGameEventContext(context);
Response_DeckDownload *re = new Response_DeckDownload;

View file

@ -64,7 +64,7 @@ void GameEventStorage::sendToGame(Server_Game *game)
}
ResponseContainer::ResponseContainer(int _cmdId)
: responseExtension(0), cmdId(_cmdId)
: cmdId(_cmdId), responseExtension(0)
{
}

View file

@ -17,7 +17,7 @@ public:
bool getImport() const { return import; }
void setImport(bool _import) { import = _import; }
SetToDownload(const QString &_shortName, const QString &_longName, const QVariant &_cards, bool _import)
: shortName(_shortName), longName(_longName), cards(_cards), import(_import) { }
: shortName(_shortName), longName(_longName), import(_import), cards(_cards) { }
bool operator<(const SetToDownload &set) const { return longName.compare(set.longName, Qt::CaseInsensitive) < 0; }
};

View file

@ -5,6 +5,8 @@ logfile=server.log
name="My Cockatrice server"
id=1
number_pools=1
writelog=1
logfilters=""
[servernetwork]
active=0

View file

@ -3,6 +3,7 @@
#include <QFile>
#include <QTextStream>
#include <QDateTime>
#include <QSettings>
#include <iostream>
#ifdef Q_OS_UNIX
# include <sys/types.h>
@ -11,99 +12,122 @@
#endif
ServerLogger::ServerLogger(bool _logToConsole, QObject *parent)
: QObject(parent), logToConsole(_logToConsole), flushRunning(false)
: QObject(parent), logToConsole(_logToConsole), flushRunning(false)
{
}
ServerLogger::~ServerLogger()
{
flushBuffer();
// This does not work with the destroyed() signal as this destructor is called after the main event loop is done.
thread()->quit();
flushBuffer();
// This does not work with the destroyed() signal as this destructor is called after the main event loop is done.
thread()->quit();
}
void ServerLogger::startLog(const QString &logFileName)
{
if (!logFileName.isEmpty()) {
logFile = new QFile("server.log", this);
logFile->open(QIODevice::Append);
if (!logFileName.isEmpty()) {
logFile = new QFile("server.log", this);
logFile->open(QIODevice::Append);
#ifdef Q_OS_UNIX
::socketpair(AF_UNIX, SOCK_STREAM, 0, sigHupFD);
::socketpair(AF_UNIX, SOCK_STREAM, 0, sigHupFD);
snHup = new QSocketNotifier(sigHupFD[1], QSocketNotifier::Read, this);
connect(snHup, SIGNAL(activated(int)), this, SLOT(handleSigHup()));
snHup = new QSocketNotifier(sigHupFD[1], QSocketNotifier::Read, this);
connect(snHup, SIGNAL(activated(int)), this, SLOT(handleSigHup()));
#endif
} else
logFile = 0;
connect(this, SIGNAL(sigFlushBuffer()), this, SLOT(flushBuffer()), Qt::QueuedConnection);
} else
logFile = 0;
connect(this, SIGNAL(sigFlushBuffer()), this, SLOT(flushBuffer()), Qt::QueuedConnection);
}
void ServerLogger::logMessage(QString message, void *caller)
{
if (!logFile)
return;
bufferMutex.lock();
QString callerString;
if (caller)
callerString = QString::number((qulonglong) caller, 16) + " ";
buffer.append(QDateTime::currentDateTime().toString() + " " + callerString + message);
bufferMutex.unlock();
emit sigFlushBuffer();
if (!logFile)
return;
QString callerString;
if (caller)
callerString = QString::number((qulonglong) caller, 16) + " ";
//filter out all log entries based on values in configuration file
QSettings *settings = new QSettings("servatrice.ini", QSettings::IniFormat);
bool shouldWeWriteLog = settings->value("server/writelog").toBool();
QString logFilters = settings->value("server/logfilters").toString();
QStringList listlogFilters = logFilters.split(",", QString::SkipEmptyParts);
bool shouldWeSkipLine = false;
if (!shouldWeWriteLog)
return;
if (!logFilters.trimmed().isEmpty()){
shouldWeSkipLine = true;
foreach(QString logFilter, listlogFilters){
if (message.contains(logFilter, Qt::CaseInsensitive)){
shouldWeSkipLine = false;
break;
}
}
}
if (shouldWeSkipLine)
return;
bufferMutex.lock();
buffer.append(QDateTime::currentDateTime().toString() + " " + callerString + message);
bufferMutex.unlock();
emit sigFlushBuffer();
}
void ServerLogger::flushBuffer()
{
if (flushRunning)
return;
flushRunning = true;
QTextStream stream(logFile);
forever {
bufferMutex.lock();
if (buffer.isEmpty()) {
bufferMutex.unlock();
flushRunning = false;
return;
}
QString message = buffer.takeFirst();
bufferMutex.unlock();
stream << message << "\n";
stream.flush();
if (logToConsole)
std::cout << message.toStdString() << std::endl;
}
if (flushRunning)
return;
flushRunning = true;
QTextStream stream(logFile);
forever {
bufferMutex.lock();
if (buffer.isEmpty()) {
bufferMutex.unlock();
flushRunning = false;
return;
}
QString message = buffer.takeFirst();
bufferMutex.unlock();
stream << message << "\n";
stream.flush();
if (logToConsole)
std::cout << message.toStdString() << std::endl;
}
}
void ServerLogger::hupSignalHandler(int /*unused*/)
{
#ifdef Q_OS_UNIX
if (!logFile)
return;
char a = 1;
::write(sigHupFD[0], &a, sizeof(a));
if (!logFile)
return;
char a = 1;
::write(sigHupFD[0], &a, sizeof(a));
#endif
}
void ServerLogger::handleSigHup()
{
#ifdef Q_OS_UNIX
if (!logFile)
return;
snHup->setEnabled(false);
char tmp;
::read(sigHupFD[1], &tmp, sizeof(tmp));
logFile->close();
logFile->open(QIODevice::Append);
snHup->setEnabled(true);
if (!logFile)
return;
snHup->setEnabled(false);
char tmp;
::read(sigHupFD[1], &tmp, sizeof(tmp));
logFile->close();
logFile->open(QIODevice::Append);
snHup->setEnabled(true);
#endif
}

View file

@ -2,7 +2,7 @@
if [[ $TRAVIS_OS_NAME == "osx" ]] ; then
brew update
brew install qt cmake protobuf
brew install qt cmake protobuf libgcrypt
else
sudo apt-get update -qq
sudo apt-get install -y qtmobility-dev libprotobuf-dev protobuf-compiler libqt4-dev