diff --git a/CMakeLists.txt b/CMakeLists.txt index d0e688e1c..b95a13568 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -742,6 +742,19 @@ if(MINGW) endif() +# Find LibGamerzilla library or build it if missing +if (NOT APPLE) + include(FindPkgConfig) + pkg_search_module(GAMERZILLA OPTIONAL gamerzilla) + + if (GAMERZILLA_LIBRARIES) + message(STATUS "Gamerzilla found") + include_directories(${GAMERZILLA_INCLUDE_DIRS}) + target_link_libraries(supertuxkart ${GAMERZILLA_LIBRARIES}) + add_definitions(-DGAMERZILLA) + endif() +endif() + # ==== Checking if data folder exists ==== if(NOT IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/data) message( FATAL_ERROR "${CMAKE_CURRENT_SOURCE_DIR}/data folder doesn't exist" ) diff --git a/data/achievements.xml b/data/achievements.xml index d9684e6b1..c611e56f5 100644 --- a/data/achievements.xml +++ b/data/achievements.xml @@ -137,7 +137,7 @@ egg-hunt-started-all egg-hunt-finished-all --> - + diff --git a/data/gamerzilla/achievement0.png b/data/gamerzilla/achievement0.png new file mode 100644 index 000000000..484d7e40f Binary files /dev/null and b/data/gamerzilla/achievement0.png differ diff --git a/data/gamerzilla/achievement1.png b/data/gamerzilla/achievement1.png new file mode 100644 index 000000000..3c5b8e5d0 Binary files /dev/null and b/data/gamerzilla/achievement1.png differ diff --git a/data/gamerzilla/supertuxkart.png b/data/gamerzilla/supertuxkart.png new file mode 100644 index 000000000..e8af83069 Binary files /dev/null and b/data/gamerzilla/supertuxkart.png differ diff --git a/src/achievements/achievement.cpp b/src/achievements/achievement.cpp index c6930b8f7..411d953d2 100644 --- a/src/achievements/achievement.cpp +++ b/src/achievements/achievement.cpp @@ -396,4 +396,8 @@ void Achievement::onCompletion() request->addParameter("achievementid", getID()); request->queue(); } + if (PlayerManager::getCurrentPlayer()->getUniqueID() == 1) + { + AchievementsManager::get()->getWebAchievementStatus()->achieved(m_achievement_info); + } } // onCompletion diff --git a/src/achievements/achievement_info.hpp b/src/achievements/achievement_info.hpp index acae76e95..5cb8929e4 100644 --- a/src/achievements/achievement_info.hpp +++ b/src/achievements/achievement_info.hpp @@ -93,6 +93,8 @@ public: uint32_t getID() const { return m_id; } irr::core::stringw getDescription() const; irr::core::stringw getName() const; + std::string getRawName() const { return m_name; } + std::string getRawDescription() const { return m_description; } bool isSecret() const { return m_is_secret; } // This function should not be called if copy already has children diff --git a/src/achievements/achievements_manager.cpp b/src/achievements/achievements_manager.cpp index 5e5039a1c..a13078f2e 100644 --- a/src/achievements/achievements_manager.cpp +++ b/src/achievements/achievements_manager.cpp @@ -43,6 +43,8 @@ AchievementsManager::AchievementsManager() const std::string file_name = file_manager->getAsset("achievements.xml"); const XMLNode *root = file_manager->createXMLTree(file_name); unsigned int num_nodes = root->getNumNodes(); + uint32_t version = 1; + root->get("version", &version); for (unsigned int i = 0; i < num_nodes; i++) { const XMLNode *node = root->getNode(i); @@ -54,6 +56,7 @@ AchievementsManager::AchievementsManager() "Multiple achievements with the same id!"); delete root; + m_web = new WebAchievementsStatus(version, m_achievements_info); } // AchievementsManager // ---------------------------------------------------------------------------- @@ -64,6 +67,7 @@ AchievementsManager::~AchievementsManager() delete it->second; } m_achievements_info.clear(); + delete m_web; } // ~AchievementsManager // ---------------------------------------------------------------------------- @@ -72,7 +76,7 @@ AchievementsManager::~AchievementsManager() * \param node The XML of saved data, or NULL if no saved data exists. */ AchievementsStatus* - AchievementsManager::createAchievementsStatus(const XMLNode *node) + AchievementsManager::createAchievementsStatus(const XMLNode *node, bool updateWeb) { AchievementsStatus *status = new AchievementsStatus(); @@ -90,6 +94,8 @@ AchievementsStatus* if (node) status->load(node); + if (updateWeb) + m_web->updateAchievementsProgress(status); return status; } // createAchievementStatus diff --git a/src/achievements/achievements_manager.hpp b/src/achievements/achievements_manager.hpp index ba4b82b6c..baa96e1fa 100644 --- a/src/achievements/achievements_manager.hpp +++ b/src/achievements/achievements_manager.hpp @@ -20,6 +20,7 @@ #define HEADER_ACHIEVEMENTS_MANAGER_HPP #include "achievements/achievements_status.hpp" +#include "achievements/web_achievements_status.hpp" #include "utils/types.hpp" #include "utils/ptr_vector.hpp" @@ -43,6 +44,7 @@ private: static AchievementsManager* m_achievements_manager; std::map m_achievements_info; + WebAchievementsStatus *m_web; AchievementsManager (); ~AchievementsManager (); @@ -71,13 +73,14 @@ public: // ======================================================================== AchievementInfo* getAchievementInfo(uint32_t id) const; - AchievementsStatus* createAchievementsStatus(const XMLNode *node=NULL); + AchievementsStatus* createAchievementsStatus(const XMLNode *node=NULL, bool updateWeb = false); // ------------------------------------------------------------------------ const std::map & getAllInfo() { return m_achievements_info; } // getAllInfo + WebAchievementsStatus* getWebAchievementStatus() { return m_web; } }; // class AchievementsManager #endif diff --git a/src/achievements/web_achievements_status.cpp b/src/achievements/web_achievements_status.cpp new file mode 100644 index 000000000..1f3519cff --- /dev/null +++ b/src/achievements/web_achievements_status.cpp @@ -0,0 +1,93 @@ +// +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2013-2015 Glenn De Jonghe +// (C) 2014-2015 Joerg Henrichs +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 3 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +#include "achievements/web_achievements_status.hpp" + +#include "achievements/achievement.hpp" +#include "achievements/achievement_info.hpp" +#include "achievements/achievements_status.hpp" +#include "io/file_manager.hpp" + +#ifdef GAMERZILLA +#include "gamerzilla.h" +#endif + +/** Constructur, initialises this object with the data from the + * corresponding AchievementInfo. + */ +WebAchievementsStatus::WebAchievementsStatus(int version, std::map &info) +{ +#ifdef GAMERZILLA + GamerzillaStart(false, (file_manager->getUserConfigDir() + "gamerzilla/").c_str()); + Gamerzilla g; + std::string path = file_manager->getAsset("gamerzilla/"); + std::string main_image = path + "supertuxkart.png"; + std::string true_image = path + "achievement1.png"; + std::string false_image = path + "achievement0.png"; + GamerzillaInitGame(&g); + g.version = version; + g.short_name = strdup("supertuxkart"); + g.name = strdup("SuperTuxKart"); + g.image = strdup(main_image.c_str()); + for (auto const &i : info) + { + GamerzillaGameAddTrophy(&g, i.second->getRawName().c_str(), i.second->getRawDescription().c_str(), 0, true_image.c_str(), false_image.c_str()); + } + m_game_id = GamerzillaSetGame(&g); + GamerzillaClearGame(&g); +#endif +} // WebAchievementStatus + +// ---------------------------------------------------------------------------- +WebAchievementsStatus::~WebAchievementsStatus() +{ +#ifdef GAMERZILLA + GamerzillaQuit(); +#endif +} // ~WebAchievementStatus + +// ---------------------------------------------------------------------------- +/** Checks for an updates to achievements progress + * \param Current status + */ +void WebAchievementsStatus::updateAchievementsProgress(AchievementsStatus *status) +{ +#ifdef GAMERZILLA + std::map &a = status->getAllAchievements(); + for (auto ¤t : a) + { + if (current.second->isAchieved()) + { + GamerzillaSetTrophy(m_game_id, current.second->getInfo()->getRawName().c_str()); + } + } +#endif +} // updateAchievementsProgress + +// ---------------------------------------------------------------------------- +/** Sets an achievement + * \param Achievement acquired + */ +void WebAchievementsStatus::achieved(AchievementInfo *info) +{ +#ifdef GAMERZILLA + GamerzillaSetTrophy(m_game_id, info->getRawName().c_str()); +#endif +} diff --git a/src/achievements/web_achievements_status.hpp b/src/achievements/web_achievements_status.hpp new file mode 100644 index 000000000..da9df3848 --- /dev/null +++ b/src/achievements/web_achievements_status.hpp @@ -0,0 +1,52 @@ +// +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2013-2015 Glenn De Jonghe +// (C) 2014-2015 Joerg Henrichs +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 3 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#ifndef HEADER_WEB_ACHIEVEMENTS_STATUS_HPP +#define HEADER_WEB_ACHIEVEMENTS_STATUS_HPP + +#include "achievements/achievement_info.hpp" +#include + +class AchievementsStatus; + +// ============================================================================ +/** This class updates achievements on an online site. It detects when + * achievements haven't been updated and sends the changes. + * \ingroup achievements + */ +class WebAchievementsStatus +{ +private: + +#ifdef GAMERZILLA + int m_game_id; +#endif +public: + + WebAchievementsStatus(int version, std::map &info); + virtual ~WebAchievementsStatus(); + + void updateAchievementsProgress(AchievementsStatus *status); + void achieved(AchievementInfo *info); + +#ifdef GAMERZILLA + int getGameID() const { return m_game_id; } +#endif +}; // class Achievement +#endif diff --git a/src/config/player_profile.cpp b/src/config/player_profile.cpp index 3052b6445..980f805be 100644 --- a/src/config/player_profile.cpp +++ b/src/config/player_profile.cpp @@ -122,7 +122,7 @@ void PlayerProfile::loadRemainingData(const XMLNode *node) unlock_manager->createStoryModeStatus(xml_story_mode); const XMLNode *xml_achievements = node->getNode("achievements"); m_achievements_status = AchievementsManager::get() - ->createAchievementsStatus(xml_achievements); + ->createAchievementsStatus(xml_achievements, m_unique_id == 1); // Fix up any potentially missing icons. addIcon(); } // initRemainingData