diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..74f6feff6 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,10 @@ +language: cpp +os: + - linux + - osx +compiler: + - gcc + - clang +script: mkdir build && cd build && cmake .. -DWITH_SERVER=1 && make +install: ./travis-dependencies.sh +cache: apt diff --git a/CMakeLists.txt b/CMakeLists.txt index e820c5efb..400eb161d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -59,7 +59,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 -Wno-error=sign-compare -Wno-error=reorder -Wno-error=missing-declarations") ELSE() # other: osx/llvm, bsd/llvm set(CMAKE_CXX_FLAGS_RELEASE "-O2") @@ -79,11 +79,51 @@ set(CMAKE_AUTOMOC TRUE) # Find other needed libraries FIND_PACKAGE(Protobuf REQUIRED) +# Package builder +set(CPACK_PACKAGE_CONTACT "Daenyth+github@gmail.com") +set(CPACK_PACKAGE_DESCRIPTION_SUMMARY ${PROJECT_NAME}) +set(CPACK_PACKAGE_VENDOR "Cockatrice Development Team") +set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README.md") +set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/COPYING") +set(CPACK_PACKAGE_VERSION_MAJOR "${PROJECT_VERSION_MAJOR}") +set(CPACK_PACKAGE_VERSION_MINOR "${PROJECT_VERSION_MINOR}") +set(CPACK_PACKAGE_VERSION_PATCH "${PROJECT_VERSION_PATCH}") + +if(UNIX) + if(APPLE) + set(CPACK_GENERATOR DragNDrop ${CPACK_GENERATOR}) + set(CPACK_GENERATOR "DragNDrop") + set(CPACK_DMG_FORMAT "UDBZ") + set(CPACK_DMG_VOLUME_NAME "${PROJECT_NAME}") + set(CPACK_SYSTEM_NAME "OSX") + set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${PROJECT_VERSION}") + set(CPACK_PACKAGE_ICON "${CMAKE_CURRENT_SOURCE_DIR}/cockatrice/resources/appicon.icns") + else() + # linux + set(CPACK_GENERATOR DEB ${CPACK_GENERATOR}) + set(CPACK_PACKAGE_INSTALL_DIRECTORY "${PROJECT_NAME}/${PROJECT_VERSION}") + set(CPACK_STRIP_FILES "bin/${PROJECT_NAME}") + set(CPACK_SOURCE_STRIP_FILES "") + endif() +elseif(WIN32) + set(CPACK_GENERATOR NSIS ${CPACK_GENERATOR}) + set(CPACK_PACKAGE_INSTALL_DIRECTORY "${PROJECT_NAME}\\\\${PROJECT_VERSION}") + set(CPACK_NSIS_INSTALLED_ICON_NAME "bin\\\\${PROJECT_NAME}.exe") + set(CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY} ${PROJECT_NAME}") + set(CPACK_NSIS_HELP_LINK "https://github.com/Daenyth/Cockatrice") + set(CPACK_NSIS_URL_INFO_ABOUT "https://github.com/Daenyth/Cockatrice") + set(CPACK_NSIS_CONTACT "Daenyth+github@gmail.com") + set(CPACK_NSIS_MODIFY_PATH ON) +endif() + +include(CPack) + # Compile servatrice (default off) option(WITH_SERVER "build servatrice" OFF) add_subdirectory(common) if(WITH_SERVER) add_subdirectory(servatrice) + SET(CPACK_INSTALL_CMAKE_PROJECTS "servatrice;servatrice;ALL;/" ${CPACK_INSTALL_CMAKE_PROJECTS}) endif() # Compile cockatrice (default on) @@ -92,10 +132,12 @@ if(WITH_CLIENT) add_subdirectory(cockatrice) add_subdirectory(sounds) add_subdirectory(zonebg) + SET(CPACK_INSTALL_CMAKE_PROJECTS "cockatrice;cockatrice;ALL;/" ${CPACK_INSTALL_CMAKE_PROJECTS}) endif() # Compile oracle (default on) option(WITH_ORACLE "build oracle" ON) if(WITH_ORACLE) add_subdirectory(oracle) + SET(CPACK_INSTALL_CMAKE_PROJECTS "release/oracle.app;oracle;ALL;/" ${CPACK_INSTALL_CMAKE_PROJECTS}) endif() diff --git a/README.md b/README.md index 957a0249d..ca8796b4f 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # Cockatrice +[![Build Status](https://travis-ci.org/Daenyth/Cockatrice.svg?branch=master)](https://travis-ci.org/Daenyth/Cockatrice) + Cockatrice is an open-source multiplatform software for playing card games, such as Magic: The Gathering, over a network. It is fully client-server based to prevent any kind of cheating, though it supports single-player games without diff --git a/cockatrice/CMakeLists.txt b/cockatrice/CMakeLists.txt index 499836dd1..b4de656a6 100644 --- a/cockatrice/CMakeLists.txt +++ b/cockatrice/CMakeLists.txt @@ -126,6 +126,7 @@ if(APPLE) ENDIF(APPLE) if (NOT QT_QTMULTIMEDIA_FOUND) + SET(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}) FIND_PACKAGE(QtMobility REQUIRED) endif (NOT QT_QTMULTIMEDIA_FOUND) @@ -183,8 +184,9 @@ add_custom_command( ) if(APPLE) - set(plugin_dest_dir ./cockatrice.app/Contents/Plugins) - set(qtconf_dest_dir ./cockatrice.app/Contents/Resources) + # these needs to be relative to CMAKE_INSTALL_PREFIX + set(plugin_dest_dir cockatrice.app/Contents/Plugins) + set(qtconf_dest_dir cockatrice.app/Contents/Resources) # note: no codecs in qt5 # note: phonon_backend => mediaservice @@ -199,13 +201,16 @@ if(APPLE) endif() install(CODE " - file(WRITE \"${qtconf_dest_dir}/qt.conf\" \"[Paths] -Plugins = Plugins\") - " COMPONENT Runtime) + file(WRITE \"\${CMAKE_INSTALL_PREFIX}/${qtconf_dest_dir}/qt.conf\" \"[Paths] +Plugins = Plugins +Translations = Resources/translations +Data = Resources\") + " COMPONENT Runtime) install(CODE " file(GLOB_RECURSE QTPLUGINS - \"${plugin_dest_dir}/*.dylib\") + \"\${CMAKE_INSTALL_PREFIX}/${plugin_dest_dir}/*.dylib\") + set(BU_CHMOD_BUNDLE_ITEMS ON) include(BundleUtilities) fixup_bundle(\"\${CMAKE_INSTALL_PREFIX}/cockatrice.app\" \"\${QTPLUGINS}\" \"${QT_LIBRARY_DIR}\") " COMPONENT Runtime) diff --git a/cockatrice/src/abstractclient.h b/cockatrice/src/abstractclient.h index 130c85b52..4dc9af2bf 100644 --- a/cockatrice/src/abstractclient.h +++ b/cockatrice/src/abstractclient.h @@ -31,7 +31,7 @@ enum ClientStatus { StatusConnecting, StatusAwaitingWelcome, StatusLoggingIn, - StatusLoggedIn, + StatusLoggedIn }; class AbstractClient : public QObject { diff --git a/cockatrice/src/abstractgraphicsitem.h b/cockatrice/src/abstractgraphicsitem.h index 83cbf0db7..f838dcd3b 100644 --- a/cockatrice/src/abstractgraphicsitem.h +++ b/cockatrice/src/abstractgraphicsitem.h @@ -14,6 +14,7 @@ enum GraphicsItemType { class AbstractGraphicsItem : public QObject, public QGraphicsItem { Q_OBJECT + Q_INTERFACES(QGraphicsItem) protected: void paintNumberEllipse(int number, int radius, const QColor &color, int position, int count, QPainter *painter); public: diff --git a/cockatrice/src/carddatabase.cpp b/cockatrice/src/carddatabase.cpp index c9c3756fb..eff101f94 100644 --- a/cockatrice/src/carddatabase.cpp +++ b/cockatrice/src/carddatabase.cpp @@ -16,13 +16,7 @@ const int CardDatabase::versionNeeded = 3; -CardSet::CardSet(const QString &_shortName, const QString &_longName) - : shortName(_shortName), longName(_longName) -{ - updateSortKey(); -} - -QXmlStreamWriter &operator<<(QXmlStreamWriter &xml, const CardSet *set) +static QXmlStreamWriter &operator<<(QXmlStreamWriter &xml, const CardSet *set) { xml.writeStartElement("set"); xml.writeTextElement("name", set->getShortName()); @@ -32,6 +26,24 @@ QXmlStreamWriter &operator<<(QXmlStreamWriter &xml, const CardSet *set) return xml; } +CardSet::CardSet(const QString &_shortName, const QString &_longName) + : shortName(_shortName), longName(_longName) +{ + updateSortKey(); +} + +QString CardSet::getCorrectedShortName() const +{ + // Because windows is horrible. + QSet invalidFileNames; + invalidFileNames << "CON" << "PRN" << "AUX" << "NUL" << "COM1" << "COM2" << + "COM3" << "COM4" << "COM5" << "COM6" << "COM7" << "COM8" << "COM9" << + "LPT1" << "LPT2" << "LPT3" << "LPT4" << "LPT5" << "LPT6" << "LPT7" << + "LPT8" << "LPT9"; + + return invalidFileNames.contains(shortName) ? shortName + "_" : shortName; +} + void CardSet::setSortKey(unsigned int _sortKey) { sortKey = _sortKey; @@ -132,7 +144,7 @@ void PictureLoader::processLoadQueue() } continue; } - + emit imageLoaded(ptl.getCard(), image); } } @@ -169,13 +181,17 @@ void PictureLoader::startNextPicDownload() QUrl url(picUrl); QNetworkRequest req(url); - qDebug() << "starting picture download:" << req.url(); + qDebug() << "starting picture download:" << cardBeingDownloaded.getCard()->getName() << "Url:" << req.url(); networkManager->get(req); } void PictureLoader::picDownloadFinished(QNetworkReply *reply) { QString picsPath = _picsPath; + if (reply->error()) { + qDebug() << "Download failed:" << reply->errorString(); + } + const QByteArray &picData = reply->readAll(); QImage testImage; if (testImage.loadFromData(picData)) { @@ -189,17 +205,17 @@ void PictureLoader::picDownloadFinished(QNetworkReply *reply) QDir dir(QString(picsPath + "/downloadedPics")); dir.mkdir(cardBeingDownloaded.getSetName()); } - + QString suffix; if (!cardBeingDownloaded.getStripped()) suffix = ".full"; - + QFile newPic(picsPath + "/downloadedPics/" + cardBeingDownloaded.getSetName() + "/" + cardBeingDownloaded.getCard()->getCorrectedName() + suffix + ".jpg"); if (!newPic.open(QIODevice::WriteOnly)) return; newPic.write(picData); newPic.close(); - + emit imageLoaded(cardBeingDownloaded.getCard(), testImage); } else if (cardBeingDownloaded.getHq()) { qDebug() << "HQ: received invalid picture. URL:" << reply->request().url(); @@ -216,7 +232,7 @@ void PictureLoader::picDownloadFinished(QNetworkReply *reply) } else emit imageLoaded(cardBeingDownloaded.getCard(), QImage()); } - + reply->deleteLater(); startNextPicDownload(); } @@ -224,7 +240,7 @@ void PictureLoader::picDownloadFinished(QNetworkReply *reply) void PictureLoader::loadImage(CardInfo *card, bool stripped) { QMutexLocker locker(&mutex); - + loadQueue.append(PictureToLoad(card, stripped)); emit startLoadQueue(); } @@ -259,18 +275,18 @@ CardInfo::CardInfo(CardDatabase *_db, bool _cipt, int _tableRow, const SetList &_sets, - QMap _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) @@ -418,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()); @@ -457,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())); @@ -594,7 +610,7 @@ void CardDatabase::loadCardsFromXml(QXmlStreamReader &xml) if (xml.name() == "card") { QString name, manacost, type, pt, text; QStringList colors; - QMap muids; + MuidMap muids; SetList sets; int tableRow = 0; int loyalty = 0; diff --git a/cockatrice/src/carddatabase.h b/cockatrice/src/carddatabase.h index bd3fd419e..09edeff4a 100644 --- a/cockatrice/src/carddatabase.h +++ b/cockatrice/src/carddatabase.h @@ -20,12 +20,16 @@ class QNetworkRequest; typedef QMap QStringMap; +// If we don't typedef this, CardInfo::CardInfo will refuse to compile on OS X < 10.9 +typedef QMap MuidMap; + class CardSet : public QList { private: QString shortName, longName; unsigned int sortKey; public: CardSet(const QString &_shortName = QString(), const QString &_longName = QString()); + QString getCorrectedShortName() const; QString getShortName() const { return shortName; } QString getLongName() const { return longName; } int getSortKey() const { return sortKey; } @@ -51,12 +55,10 @@ public: PictureToLoad(CardInfo *_card = 0, bool _stripped = false, bool _hq = true); CardInfo *getCard() const { return card; } bool getStripped() const { return stripped; } - QString getSetName() const { return sortedSets[setIndex]->getShortName(); } + QString getSetName() const { return sortedSets[setIndex]->getCorrectedShortName(); } bool nextSet(); - bool getHq() const { return hq; } void setHq(bool _hq) { hq = _hq; } - }; class PictureLoader : public QObject { @@ -101,7 +103,7 @@ private: QString text; QStringList colors; int loyalty; - QMap muIds; + MuidMap muIds; bool cipt; int tableRow; QPixmap *pixmap; @@ -119,7 +121,7 @@ public: bool _cipt = false, int _tableRow = 0, const SetList &_sets = SetList(), - QMap muids = QMap()); + MuidMap muids = MuidMap()); ~CardInfo(); const QString &getName() const { return name; } bool getIsToken() const { return isToken; } diff --git a/cockatrice/src/cardfilter.h b/cockatrice/src/cardfilter.h index 47a85ea61..e5f881233 100644 --- a/cockatrice/src/cardfilter.h +++ b/cockatrice/src/cardfilter.h @@ -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) {}; diff --git a/cockatrice/src/deck_loader.cpp b/cockatrice/src/deck_loader.cpp index 6a907ed75..4443b43b3 100644 --- a/cockatrice/src/deck_loader.cpp +++ b/cockatrice/src/deck_loader.cpp @@ -1,5 +1,6 @@ #include #include +#include #include "deck_loader.h" #include "decklist.h" @@ -44,18 +45,28 @@ bool DeckLoader::loadFromFile(const QString &fileName, FileFormat fmt) QFile file(fileName); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) return false; - + bool result = false; switch (fmt) { case PlainTextFormat: result = loadFromFile_Plain(&file); break; - case CockatriceFormat: result = loadFromFile_Native(&file); break; + case CockatriceFormat: + result = loadFromFile_Native(&file); + qDebug() << "Loaded from" << fileName << "-" << result; + if (!result) { + qDebug() << "Retying as plain format"; + file.seek(0); + result = loadFromFile_Plain(&file); + fmt = PlainTextFormat; + } + break; } if (result) { lastFileName = fileName; lastFileFormat = fmt; - + emit deckLoaded(); } + qDebug() << "Deck was loaded -" << result; return result; } @@ -66,7 +77,7 @@ bool DeckLoader::loadFromRemote(const QString &nativeString, int remoteDeckId) lastFileName = QString(); lastFileFormat = CockatriceFormat; lastRemoteDeckId = remoteDeckId; - + emit deckLoaded(); } return result; diff --git a/cockatrice/src/decklistmodel.cpp b/cockatrice/src/decklistmodel.cpp index 00d92faea..a98ee261e 100644 --- a/cockatrice/src/decklistmodel.cpp +++ b/cockatrice/src/decklistmodel.cpp @@ -340,6 +340,9 @@ void DeckListModel::sort(int column, Qt::SortOrder order) break; case 2: sortMethod = ByPrice; + break; + default: + sortMethod = ByName; } root->setSortMethod(sortMethod); sortHelper(root, order); diff --git a/cockatrice/src/filtertree.h b/cockatrice/src/filtertree.h index 9a5fc5313..a6c4536d6 100644 --- a/cockatrice/src/filtertree.h +++ b/cockatrice/src/filtertree.h @@ -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; diff --git a/cockatrice/src/main.cpp b/cockatrice/src/main.cpp index d0664bf94..22e1fe129 100644 --- a/cockatrice/src/main.cpp +++ b/cockatrice/src/main.cpp @@ -55,7 +55,7 @@ QString translationPath = TRANSLATION_PATH; QString translationPath = QString(); #endif -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); @@ -88,15 +88,6 @@ int main(int argc, char *argv[]) if (app.arguments().contains("--debug-output")) qInstallMsgHandler(myMessageOutput); -#ifdef Q_OS_MAC - QDir baseDir(app.applicationDirPath()); - baseDir.cdUp(); - baseDir.cdUp(); - baseDir.cdUp(); - QDir pluginsDir = baseDir; - pluginsDir.cd("PlugIns"); - app.addLibraryPath(pluginsDir.absolutePath()); -#endif #ifdef Q_OS_WIN app.addLibraryPath(app.applicationDirPath() + "/plugins"); #endif @@ -108,11 +99,8 @@ int main(int argc, char *argv[]) if (translationPath.isEmpty()) { #ifdef Q_OS_MAC - QDir translationsDir = baseDir; - translationsDir.cd("translations"); - translationPath = translationsDir.absolutePath(); -#endif -#ifdef Q_OS_WIN + translationPath = QLibraryInfo::location(QLibraryInfo::TranslationsPath); +#elif defined(Q_OS_WIN) translationPath = app.applicationDirPath() + "/translations"; #endif } @@ -145,6 +133,43 @@ int main(int argc, char *argv[]) QDir().mkpath(dataDir + "/pics"); settingsCache->setPicsPath(dataDir + "/pics"); } + +#ifdef Q_OS_MAC + if(settingsCache->getHandBgPath().isEmpty() && + settingsCache->getStackBgPath().isEmpty() && + settingsCache->getTableBgPath().isEmpty() && + settingsCache->getPlayerBgPath().isEmpty()) + { + QString srcDir = QLibraryInfo::location(QLibraryInfo::DataPath); + QString destDir = dataDir + "/zonebg"; + QDir tmpDir(destDir); + if(!tmpDir.exists()) + { + // try to install the default images for the current user and set the settigs value + settingsCache->copyPath(srcDir + "/zonebg", destDir); + + settingsCache->setHandBgPath(destDir + "/fabric_green.png"); + settingsCache->setStackBgPath(destDir + "/fabric_red.png"); + settingsCache->setTableBgPath(destDir + "/fabric_blue.png"); + settingsCache->setPlayerBgPath(destDir + "/fabric_gray.png"); + } + } + + if(settingsCache->getSoundPath().isEmpty()) + { + QString srcDir = QLibraryInfo::location(QLibraryInfo::DataPath); + QString destDir = dataDir + "/sounds"; + QDir tmpDir(destDir); + if(!tmpDir.exists()) + { + // try to install the default sounds for the current user and set the settigs value + settingsCache->copyPath(srcDir + "/sounds", destDir); + + settingsCache->setSoundPath(destDir); + } + } +#endif + if (!settingsValid() || db->getLoadStatus() != Ok) { qDebug("main(): invalid settings or load status"); DlgSettings dlgSettings; diff --git a/cockatrice/src/main.h b/cockatrice/src/main.h index 4a1d234f0..9237f23cb 100644 --- a/cockatrice/src/main.h +++ b/cockatrice/src/main.h @@ -13,4 +13,6 @@ extern QString translationPath; void installNewTranslator(); +bool settingsValid(); + #endif diff --git a/cockatrice/src/messagelogwidget.cpp b/cockatrice/src/messagelogwidget.cpp index ec9b90cb2..d40b10682 100644 --- a/cockatrice/src/messagelogwidget.cpp +++ b/cockatrice/src/messagelogwidget.cpp @@ -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) diff --git a/cockatrice/src/messagelogwidget.h b/cockatrice/src/messagelogwidget.h index 1747a3389..2b12b3c50 100644 --- a/cockatrice/src/messagelogwidget.h +++ b/cockatrice/src/messagelogwidget.h @@ -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); diff --git a/cockatrice/src/remoteclient.cpp b/cockatrice/src/remoteclient.cpp index 0eae13abe..e0d3d8604 100644 --- a/cockatrice/src/remoteclient.cpp +++ b/cockatrice/src/remoteclient.cpp @@ -15,7 +15,7 @@ RemoteClient::RemoteClient(QObject *parent) : AbstractClient(parent), timeRunning(0), lastDataReceived(0), messageInProgress(false), handshakeStarted(false), messageLength(0) { timer = new QTimer(this); - timer->setInterval(1000); + timer->setInterval(9000); connect(timer, SIGNAL(timeout()), this, SLOT(ping())); socket = new QTcpSocket(this); @@ -23,7 +23,7 @@ RemoteClient::RemoteClient(QObject *parent) connect(socket, SIGNAL(connected()), this, SLOT(slotConnected())); connect(socket, SIGNAL(readyRead()), this, SLOT(readData())); connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(slotSocketError(QAbstractSocket::SocketError))); - + connect(this, SIGNAL(serverIdentificationEventReceived(const Event_ServerIdentification &)), this, SLOT(processServerIdentificationEvent(const Event_ServerIdentification &))); connect(this, SIGNAL(connectionClosedEventReceived(Event_ConnectionClosed)), this, SLOT(processConnectionClosedEvent(Event_ConnectionClosed))); connect(this, SIGNAL(sigConnectToServer(QString, unsigned int, QString, QString)), this, SLOT(doConnectToServer(QString, unsigned int, QString, QString))); @@ -47,12 +47,12 @@ void RemoteClient::slotConnected() { timeRunning = lastDataReceived = 0; timer->start(); - + // dirty hack to be compatible with v14 server sendCommandContainer(CommandContainer()); getNewCmdId(); // end of hack - + setStatus(StatusAwaitingWelcome); } @@ -208,7 +208,7 @@ void RemoteClient::ping() pend->deleteLater(); } } - + int maxTime = timeRunning - lastDataReceived; emit maxPingTime(maxTime, maxTimeout); if (maxTime >= maxTimeout) { diff --git a/cockatrice/src/settingscache.cpp b/cockatrice/src/settingscache.cpp index 10dad8c92..892630f53 100644 --- a/cockatrice/src/settingscache.cpp +++ b/cockatrice/src/settingscache.cpp @@ -1,5 +1,7 @@ #include "settingscache.h" #include +#include +#include SettingsCache::SettingsCache() { @@ -257,3 +259,31 @@ void SettingsCache::setMainWindowGeometry(const QByteArray &_mainWindowGeometry) mainWindowGeometry = _mainWindowGeometry; settings->setValue("interface/main_window_geometry", mainWindowGeometry); } + +void SettingsCache::copyPath(const QString &src, const QString &dst) +{ + // test source && return if inexistent + QDir dir(src); + if (! dir.exists()) + return; + // test destination && create if inexistent + QDir tmpDir(dst); + if (!tmpDir.exists()) + { + tmpDir.setPath(QDir::rootPath()); + if (!tmpDir.mkdir(dst) && !tmpDir.exists()) { + // TODO: this is probably not good. + qDebug() << "copyPath(): Failed to create dir: " << dst; + } + } + + foreach (QString d, dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) { + QString dst_path = dst + QDir::separator() + d; + dir.mkpath(dst_path); + copyPath(src+ QDir::separator() + d, dst_path); + } + + foreach (QString f, dir.entryList(QDir::Files)) { + QFile::copy(src + QDir::separator() + f, dst + QDir::separator() + f); + } +} diff --git a/cockatrice/src/settingscache.h b/cockatrice/src/settingscache.h index a9b9ce49a..68b5129e6 100644 --- a/cockatrice/src/settingscache.h +++ b/cockatrice/src/settingscache.h @@ -90,6 +90,7 @@ public: bool getIgnoreUnregisteredUsers() const { return ignoreUnregisteredUsers; } QString getPicUrl() const { return picUrl; } QString getPicUrlHq() const { return picUrlHq; } + void copyPath(const QString &src, const QString &dst); public slots: void setMainWindowGeometry(const QByteArray &_mainWindowGeometry); void setLang(const QString &_lang); diff --git a/cockatrice/src/tab_game.cpp b/cockatrice/src/tab_game.cpp index cee000374..b99fff020 100644 --- a/cockatrice/src/tab_game.cpp +++ b/cockatrice/src/tab_game.cpp @@ -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: { diff --git a/common/decklist.cpp b/common/decklist.cpp index 8ba9378e9..90b5cb7e6 100644 --- a/common/decklist.cpp +++ b/common/decklist.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include "decklist.h" SideboardPlan::SideboardPlan(const QString &_name, const QList &_moveList) @@ -179,6 +180,7 @@ bool InnerDecklistNode::compare(AbstractDecklistNode *other) const case 2: return comparePrice(other); } + return 0; } bool InnerDecklistNode::compareNumber(AbstractDecklistNode *other) const @@ -225,6 +227,7 @@ bool AbstractDecklistCardNode::compare(AbstractDecklistNode *other) const case ByPrice: return compareTotalPrice(other); } + return 0; } bool AbstractDecklistCardNode::compareNumber(AbstractDecklistNode *other) const @@ -350,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), @@ -441,6 +445,11 @@ void DeckList::write(QXmlStreamWriter *xml) bool DeckList::loadFromXml(QXmlStreamReader *xml) { + if (xml->error()) { + qDebug() << "Error loading deck from xml: " << xml->errorString(); + return false; + } + cleanList(); while (!xml->atEnd()) { xml->readNext(); @@ -455,6 +464,10 @@ bool DeckList::loadFromXml(QXmlStreamReader *xml) } } updateDeckHash(); + if (xml->error()) { + qDebug() << "Error loading deck from xml: " << xml->errorString(); + return false; + } return true; } @@ -477,8 +490,7 @@ QString DeckList::writeToString_Native() bool DeckList::loadFromFile_Native(QIODevice *device) { QXmlStreamReader xml(device); - loadFromXml(&xml); - return true; + return loadFromXml(&xml); } bool DeckList::saveToFile_Native(QIODevice *device) @@ -496,7 +508,7 @@ bool DeckList::saveToFile_Native(QIODevice *device) bool DeckList::loadFromStream_Plain(QTextStream &in) { cleanList(); - + InnerDecklistNode *main = 0, *side = 0; bool inSideboard = false; @@ -530,7 +542,7 @@ bool DeckList::loadFromStream_Plain(QTextStream &in) line.remove(rx); rx.setPattern("\\(.*\\)"); line.remove(rx); - //Filter out post card name editions + //Filter out post card name editions rx.setPattern("\\|.*$"); line.remove(rx); line = line.simplified(); @@ -543,10 +555,10 @@ bool DeckList::loadFromStream_Plain(QTextStream &in) continue; QString cardName = line.mid(i + 1); - // Common differences between cockatrice's card names - // and what's commonly used in decklists + // Common differences between cockatrice's card names + // and what's commonly used in decklists rx.setPattern("’"); - cardName.replace(rx, "'"); + cardName.replace(rx, "'"); rx.setPattern("Æ"); cardName.replace(rx, "AE"); rx.setPattern("^Aether"); @@ -621,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(root->at(i)); + if (node->getName() != "side") + continue; + for (int j = 0; j < node->size(); j++) { + DecklistCardNode *card = dynamic_cast(node->at(j)); + size += card->getNumber(); + } + } + return size; +} + DecklistCardNode *DeckList::addCard(const QString &cardName, const QString &zoneName) { InnerDecklistNode *zoneNode = dynamic_cast(root->findChild(zoneName)); if (!zoneNode) zoneNode = new InnerDecklistNode(zoneName, root); - + DecklistCardNode *node = new DecklistCardNode(cardName, 1, zoneNode); updateDeckHash(); return node; diff --git a/common/decklist.h b/common/decklist.h index 94df407a7..2eed52fc6 100644 --- a/common/decklist.h +++ b/common/decklist.h @@ -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(); diff --git a/common/pb/context_deck_select.proto b/common/pb/context_deck_select.proto index df4a95b56..f36c8b6c2 100644 --- a/common/pb/context_deck_select.proto +++ b/common/pb/context_deck_select.proto @@ -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]; } diff --git a/common/server_player.cpp b/common/server_player.cpp index a029abed2..76cd260d0 100644 --- a/common/server_player.cpp +++ b/common/server_player.cpp @@ -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; diff --git a/common/server_response_containers.cpp b/common/server_response_containers.cpp index 8b6d27300..bc36222ef 100644 --- a/common/server_response_containers.cpp +++ b/common/server_response_containers.cpp @@ -64,7 +64,7 @@ void GameEventStorage::sendToGame(Server_Game *game) } ResponseContainer::ResponseContainer(int _cmdId) - : responseExtension(0), cmdId(_cmdId) + : cmdId(_cmdId), responseExtension(0) { } diff --git a/doc/usermanual/Usermanual.pdf b/doc/usermanual/Usermanual.pdf index 3d279df38..3d2d562da 100644 Binary files a/doc/usermanual/Usermanual.pdf and b/doc/usermanual/Usermanual.pdf differ diff --git a/nsis/cockatrice.nsi b/nsis/cockatrice.nsi index 33cc496b2..27f55ce30 100644 --- a/nsis/cockatrice.nsi +++ b/nsis/cockatrice.nsi @@ -1,7 +1,7 @@ !include "MUI2.nsh" !include "FileFunc.nsh" -!define /date TIMESTAMP "%Y%m%d" +!define /date TIMESTAMP "%Y%m%d" !searchparse /file ../build/cockatrice/version_string.cpp '= "' VERSION '";' Name "Cockatrice" @@ -52,7 +52,7 @@ Section "Application" SecApplication SetOutPath "$INSTDIR\zonebg" File /r ..\zonebg\*.* - + SetOutPath "$INSTDIR\plugins" SetOutPath "$INSTDIR\plugins\codecs" File "${QTDIR}\plugins\codecs\qcncodecs4.dll" @@ -67,7 +67,7 @@ Section "Application" SecApplication SetOutPath "$INSTDIR\sounds" File /r ..\sounds\*.* - + SetOutPath "$INSTDIR\translations" File /r ..\build\cockatrice\*.qm @@ -83,15 +83,15 @@ Section "Application" SecApplication SectionEnd Section "Update configuration" SecUpdateConfig - WriteRegStr HKCU "Software\Cockatrice\Cockatrice\paths" "carddatabase" "$INSTDIR\cards.xml" - WriteRegStr HKCU "Software\Cockatrice\Cockatrice\paths" "decks" "$INSTDIR\decks" - WriteRegStr HKCU "Software\Cockatrice\Cockatrice\paths" "pics" "$INSTDIR\pics" - WriteRegStr HKCU "Software\Cockatrice\Cockatrice\sound" "path" "$INSTDIR\sounds" + WriteRegStr HKCU "Software\Cockatrice\Cockatrice\paths" "carddatabase" "$APPDATA\Cockatrice\cards.xml" + WriteRegStr HKCU "Software\Cockatrice\Cockatrice\paths" "decks" "$APPDATA\Cockatrice\decks" + WriteRegStr HKCU "Software\Cockatrice\Cockatrice\paths" "pics" "$APPDATA\Cockatrice\pics" + WriteRegStr HKCU "Software\Cockatrice\Cockatrice\sound" "path" "$APPDATA\Cockatrice\sounds" SectionEnd Section "Start menu item" SecStartMenu createDirectory "$SMPROGRAMS\Cockatrice" - createShortCut "$SMPROGRAMS\Cockatrice\Cockatrice.lnk" "$INSTDIR\cockatrice.exe" + createShortCut "$SMPROGRAMS\Cockatrice\Cockatrice.lnk" "$INSTDIR\cockatrice.exe" '--debug-output' createShortCut "$SMPROGRAMS\Cockatrice\Oracle.lnk" "$INSTDIR\oracle.exe" createShortCut "$SMPROGRAMS\Cockatrice\Usermanual.lnk" "$INSTDIR\Usermanual.pdf" SectionEnd @@ -115,7 +115,7 @@ SetShellVarContext all Delete "$INSTDIR\QtMultimedia4.dll" RMDir "$INSTDIR" - RMDir /r "$SMPROGRAMS\Cockatrice" + RMDir "$SMPROGRAMS\Cockatrice" DeleteRegKey HKCU "Software\Cockatrice" DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Cockatrice" diff --git a/oracle/CMakeLists.txt b/oracle/CMakeLists.txt index 2eada38cf..05bcd494b 100644 --- a/oracle/CMakeLists.txt +++ b/oracle/CMakeLists.txt @@ -48,8 +48,9 @@ IF (NOT WIN32 AND NOT APPLE) ENDIF (NOT WIN32 AND NOT APPLE) if(APPLE) - set(plugin_dest_dir ./oracle.app/Contents/Plugins) - set(qtconf_dest_dir ./oracle.app/Contents/Resources) + # these needs to be relative to CMAKE_INSTALL_PREFIX + set(plugin_dest_dir oracle.app/Contents/Plugins) + set(qtconf_dest_dir oracle.app/Contents/Resources) # note: no codecs in qt5 # note: phonon_backend => mediaservice @@ -64,13 +65,15 @@ if(APPLE) endif() install(CODE " - file(WRITE \"${qtconf_dest_dir}/qt.conf\" \"[Paths] -Plugins = Plugins\") - " COMPONENT Runtime) + file(WRITE \"\${CMAKE_INSTALL_PREFIX}/${qtconf_dest_dir}/qt.conf\" \"[Paths] +Plugins = Plugins +Translations = Resources/translations\") + " COMPONENT Runtime) install(CODE " file(GLOB_RECURSE QTPLUGINS - \"${plugin_dest_dir}/*.dylib\") + \"\${CMAKE_INSTALL_PREFIX}/${plugin_dest_dir}/*.dylib\") + set(BU_CHMOD_BUNDLE_ITEMS ON) include(BundleUtilities) fixup_bundle(\"\${CMAKE_INSTALL_PREFIX}/oracle.app\" \"\${QTPLUGINS}\" \"${QT_LIBRARY_DIR}\") " COMPONENT Runtime) diff --git a/oracle/src/oracleimporter.cpp b/oracle/src/oracleimporter.cpp index 70972d92d..241924e3b 100644 --- a/oracle/src/oracleimporter.cpp +++ b/oracle/src/oracleimporter.cpp @@ -197,6 +197,11 @@ int OracleImporter::importTextSpoiler(CardSet *set, const QVariant &data) cardText = map.contains("text") ? map.value("text").toString() : QString(""); cardId = map.contains("multiverseid") ? map.value("multiverseid").toInt() : 0; cardLoyalty = map.contains("loyalty") ? map.value("loyalty").toInt() : 0; + + // Distinguish Vanguard cards from regular cards of the same name. + if (map.value("layout") == "vanguard") { + cardName += " Avatar"; + } } CardInfo *card = addCard(set->getShortName(), cardName, false, cardId, cardCost, cardType, cardPT, cardLoyalty, cardText.split("\n")); diff --git a/oracle/src/oracleimporter.h b/oracle/src/oracleimporter.h index 1f705eeb2..4c36a211c 100644 --- a/oracle/src/oracleimporter.h +++ b/oracle/src/oracleimporter.h @@ -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; } }; diff --git a/prepareMacRelease.sh b/prepareMacRelease.sh deleted file mode 100644 index d1f58e26d..000000000 --- a/prepareMacRelease.sh +++ /dev/null @@ -1,67 +0,0 @@ -#!/bin/sh - -FRAMEWORKS="Core Gui Multimedia Network Svg Xml" -DATE=`date '+%Y%m%d'` -#QTDIR="/Users/brukie/QtSDK/Desktop/Qt/474/gcc" -QTLIB="/Users/brukie/qt_leopard/lib" -QTPLUGINS="/Users/brukie/qt_leopard/plugins" -PROTOBUF="/Users/brukie/protobuf_leopard" -DIR=cockatrice_mac_$DATE -if [ -d $DIR ]; then echo "delete old dir first"; exit 1; fi - -mkdir $DIR - -cp -R build/cockatrice/cockatrice.app $DIR -cp -R build/oracle/oracle.app $DIR -mkdir $DIR/Frameworks -cp -R sounds zonebg $DIR -mkdir $DIR/translations -cp build/cockatrice/*.qm $DIR/translations -cp -R $QTPLUGINS $DIR/PlugIns -for f in $FRAMEWORKS; do - cp -R $QTLIB/Qt"$f".framework $DIR/Frameworks -done -find $DIR/Frameworks -name '*debug*'|xargs -n 1 rm -f -find $DIR/Frameworks -name 'Headers'|xargs -n 1 rm -rf -find $DIR/PlugIns -name '*debug*'|xargs -n 1 rm -f -cp $PROTOBUF/lib/libprotobuf.7.dylib $DIR/Frameworks - -cd $DIR -for f in $FRAMEWORKS; do - echo "Framework $f" - echo "step 1" - install_name_tool -id @executable_path/../../../Frameworks/Qt"$f".framework/Versions/4/Qt"$f" Frameworks/Qt"$f".framework/Versions/4/Qt"$f" - for g in $FRAMEWORKS; do - install_name_tool -change $QTLIB/Qt"$f".framework/Versions/4/Qt"$f" @executable_path/../../../Frameworks/Qt"$f".framework/Versions/4/Qt"$f" Frameworks/Qt"$g".framework/Versions/4/Qt"$g" - done - echo "step 2" - for g in cockatrice oracle; do - install_name_tool -change $QTLIB/Qt"$f".framework/Versions/4/Qt"$f" @executable_path/../../../Frameworks/Qt"$f".framework/Versions/4/Qt"$f" "$g".app/Contents/MacOS/$g - done - echo "step 3" - for g in `find . -name '*.dylib'`; do - install_name_tool -change $QTLIB/Qt"$f".framework/Versions/4/Qt"$f" @executable_path/../../../Frameworks/Qt"$f".framework/Versions/4/Qt"$f" "$g" - done -done - -install_name_tool -id @executable_path/../../../libprotobuf.7.dylib Frameworks/libprotobuf.7.dylib -install_name_tool -change $PROTOBUF/lib/libprotobuf.7.dylib @executable_path/../../../Frameworks/libprotobuf.7.dylib cockatrice.app/Contents/MacOS/cockatrice - -cd .. - -VOL=cockatrice_mac_${DATE} -DMG="tmp-$VOL.dmg" - -SIZE=`du -sk $DIR | cut -f1` -SIZE=$((${SIZE}/1000+10)) -hdiutil create "$DMG" -megabytes ${SIZE} -ov -type UDIF -fs HFS+ -volname "$VOL" - -hdid "$DMG" -cp -R "${DIR}" "/Volumes/$VOL" -hdiutil detach "/Volumes/$VOL" -#osascript -e "tell application "Finder" to eject disk "$VOL"" && - -# convert to compressed image, delete temp image -rm -f "${VOL}.dmg" -hdiutil convert "$DMG" -format UDZO -o "${VOL}.dmg" -rm -f "$DMG" diff --git a/servatrice/CMakeLists.txt b/servatrice/CMakeLists.txt index 799cecbd8..c1aefed1c 100644 --- a/servatrice/CMakeLists.txt +++ b/servatrice/CMakeLists.txt @@ -55,8 +55,9 @@ elseif(WIN32) endif() if(APPLE) - set(plugin_dest_dir ./servatrice.app/Contents/Plugins) - set(qtconf_dest_dir ./servatrice.app/Contents/Resources) + # these needs to be relative to CMAKE_INSTALL_PREFIX + set(plugin_dest_dir servatrice.app/Contents/Plugins) + set(qtconf_dest_dir servatrice.app/Contents/Resources) # note: no codecs in qt5 # note: phonon_backend => mediaservice @@ -71,13 +72,15 @@ if(APPLE) endif() install(CODE " - file(WRITE \"${qtconf_dest_dir}/qt.conf\" \"[Paths] -Plugins = Plugins\") + file(WRITE \"\${CMAKE_INSTALL_PREFIX}/${qtconf_dest_dir}/qt.conf\" \"[Paths] +Plugins = Plugins +Translations = Resources/translations\") " COMPONENT Runtime) install(CODE " file(GLOB_RECURSE QTPLUGINS - \"${plugin_dest_dir}/*.dylib\") + \"\${CMAKE_INSTALL_PREFIX}/${plugin_dest_dir}/*.dylib\") + set(BU_CHMOD_BUNDLE_ITEMS ON) include(BundleUtilities) fixup_bundle(\"\${CMAKE_INSTALL_PREFIX}/servatrice.app\" \"\${QTPLUGINS}\" \"${QT_LIBRARY_DIR}\") " COMPONENT Runtime) diff --git a/sounds/CMakeLists.txt b/sounds/CMakeLists.txt index e38c9090b..cd9f6c331 100644 --- a/sounds/CMakeLists.txt +++ b/sounds/CMakeLists.txt @@ -6,7 +6,7 @@ FILE(GLOB sounds "${CMAKE_CURRENT_SOURCE_DIR}/*.raw") if(UNIX) if(APPLE) - INSTALL(FILES ${sounds} DESTINATION sounds/) + INSTALL(FILES ${sounds} DESTINATION cockatrice.app/Contents/Resources/sounds/) else() # Assume linux INSTALL(FILES ${sounds} DESTINATION share/cockatrice/sounds/) diff --git a/travis-dependencies.sh b/travis-dependencies.sh new file mode 100755 index 000000000..0c6c62e65 --- /dev/null +++ b/travis-dependencies.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +if [[ $TRAVIS_OS_NAME == "osx" ]] ; then + brew update + 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 +fi diff --git a/zonebg/CMakeLists.txt b/zonebg/CMakeLists.txt index 961c4e12a..b250a44b0 100644 --- a/zonebg/CMakeLists.txt +++ b/zonebg/CMakeLists.txt @@ -2,11 +2,11 @@ # # Installs default "zone background" files -FILE(GLOB zonebg "${CMAKE_CURRENT_SOURCE_DIR}/*.*") +FILE(GLOB zonebg "${CMAKE_CURRENT_SOURCE_DIR}/*.png" "${CMAKE_CURRENT_SOURCE_DIR}/*.jpg") if(UNIX) if(APPLE) - INSTALL(FILES ${zonebg} DESTINATION zonebg/) + INSTALL(FILES ${zonebg} DESTINATION cockatrice.app/Contents/Resources/zonebg/) else() # Assume linux INSTALL(FILES ${zonebg} DESTINATION share/cockatrice/zonebg/)