merging uni's branch and fixing compilation problems

git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/hilnius@13690 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hilnius 2013-09-15 10:12:54 +00:00
commit 0ce03186ee
59 changed files with 2208 additions and 270 deletions

17
data/achievements.xml Normal file
View File

@ -0,0 +1,17 @@
<?xml version="1.0"?>
<achievements>
<achievement id="1" type="map" title="Christoffel Columbus" description="Play every official track at least once." >
<entry key="farm" goal="1"/>
<entry key="scotland" goal="1"/>
<entry key="lighthouse" goal="1"/>
<entry key="sandtrack" goal="1"/>
<entry key="olivermath" goal="1"/>
<entry key="subsea" goal="1"/>
<entry key="mansion" goal="1"/>
<entry key="minigolf" goal="1"/>
<entry key="hacienda" goal="1"/>
<entry key="jungle" goal="1"/>
</achievement>
<achievement id="2" type="single" goal="10" title="Strike!" description="Hit 10 karts with a bowling-ball." />
</achievements>

View File

@ -0,0 +1,47 @@
<stkgui>
<div x="2%" y="5%" width="96%" height="90%" layout="vertical-row" >
<header id="title" width="96%" height="fit" text_align="center" word_wrap="true"
I18N="In the change password dialog" text="Password Change"/>
<spacer height="40" width="50">
<div width="80%" align="center" layout="vertical-row" height="fit" >
<div width="100%" height="fit" layout="horizontal-row" >
<label proportion="1" height="100%" text_align="left" I18N="In the change password dialog" text="Current Password"/>
<textbox proportion="2" height="fit" id="current_password" I18N="In the change password dialog"/>
</div>
<spacer height="20" width="20">
<div width="100%" height="fit" layout="horizontal-row" >
<label proportion="1" height="100%" text_align="left" I18N="In the change password dialog" text="New Password"/>
<textbox proportion="2" height="fit" id="new_password1" I18N="In the change password dialog"/>
</div>
<spacer height="20" width="20">
<div width="100%" height="fit" layout="horizontal-row" >
<label proportion="1" height="100%" text_align="left" I18N="In the change password dialog" text="Confirm"/>
<textbox proportion="2" height="fit" id="new_password2" I18N="In the change password dialog"/>
</div>
</div>
<spacer height="20" width="50">
<label id="info" proportion="1" width="90%" align="center" text_align="center" word_wrap="true" text=""/>
<spacer height="20" width="50">
<buttonbar id="options" width="90%" height="16%" align="center">
<icon-button id="submit" width="64" height="64" icon="gui/green_check.png"
I18N="In the change password dialog" text="Submit" label_location="bottom"/>
<icon-button id="cancel" width="64" height="64" icon="gui/main_quit.png"
I18N="In the change password dialog" text="Close" label_location="bottom"/>
</buttonbar>
</div>
</stkgui>

View File

@ -3,7 +3,7 @@
<div x="2%" y="5%" width="96%" height="90%" layout="vertical-row" >
<header id="title" width="96%" height="fit" text_align="center" word_wrap="true"
I18N="In the login dialog' dialog" text="Sign in"/>
I18N="In the login dialog" text="Sign in"/>
<spacer height="25" width="50">

View File

@ -8,7 +8,7 @@
<buttonbar id="options" width="90%" height="30%" align="center">
<icon-button id="view" width="64" height="64" icon="gui/difficulty_medium.png"
I18N="User info dialog" text="View friends" label_location="bottom"/>
I18N="User info dialog" text="View" label_location="bottom"/>
<icon-button id="cancel" width="64" height="64" icon="gui/main_quit.png"
I18N="User info dialog" text="Close" label_location="bottom"/>
</buttonbar>

View File

@ -0,0 +1,23 @@
<stkgui>
<icon-button id="back" x="0" y="0" height="8%" icon="gui/back.png"/>
<div x="1%" y="1%" width="98%" height="98%" layout="vertical-row" >
<header id="title" text_align="center" width="80%" align="center" text="..."/>
<spacer height="25" width="10"/>
<tabs id="profile_tabs" height="10%" max_height="110" x="2%" width="98%" align="center">
<icon-button id="tab_overview" width="128" height="128" icon="gui/options_ui.png" />
<icon-button id="tab_friends" width="128" height="128" icon="gui/options_players.png"/>
<icon-button id="tab_achievements" width="128" height="128" icon="gui/options_players.png" I18N="Section in the profile menu" text="Achievements"/>
<icon-button id="tab_settings" width="128" height="128" icon="gui/main_options.png"/>
</tabs>
<box proportion="1" width="100%" layout="vertical-row" padding="6">
<list id="achievements_list" x="0" y="0" width="100%" height="100%"/>
</box>
</div>
</stkgui>

View File

@ -2,7 +2,7 @@
<icon-button id="back" x="0" y="0" height="8%" icon="gui/back.png"/>
<div x="1%" y="2%" width="98%" height="96%" layout="vertical-row" >
<div x="1%" y="1%" width="98%" height="98%" layout="vertical-row" >
<header id="title" text_align="center" width="80%" align="center" text="..."/>
@ -11,6 +11,8 @@
<tabs id="profile_tabs" height="10%" max_height="110" x="2%" width="98%" align="center">
<icon-button id="tab_overview" width="128" height="128" icon="gui/options_ui.png" />
<icon-button id="tab_friends" width="128" height="128" icon="gui/options_players.png" I18N="Section in the profile menu" text="Friends"/>
<icon-button id="tab_achievements" width="128" height="128" icon="gui/options_players.png"/>
<icon-button id="tab_settings" width="128" height="128" icon="gui/main_options.png"/>
</tabs>
<box proportion="1" width="100%" layout="vertical-row" padding="6">

View File

@ -1,5 +1,7 @@
<stkgui>
<icon-button id="back" x="0" y="0" height="8%" icon="gui/back.png"/>
<div x="1%" y="1%" width="98%" height="98%" layout="vertical-row" >
<header id="title" text_align="center" width="80%" align="center" text="..."/>
@ -9,6 +11,8 @@
<tabs id="profile_tabs" height="10%" max_height="110" x="2%" width="98%" align="center">
<icon-button id="tab_overview" width="128" height="128" icon="gui/options_ui.png" I18N="Section in the profile menu" text="Overview"/>
<icon-button id="tab_friends" width="128" height="128" icon="gui/options_players.png" />
<icon-button id="tab_achievements" width="128" height="128" icon="gui/options_players.png"/>
<icon-button id="tab_settings" width="128" height="128" icon="gui/main_options.png"/>
</tabs>
<box proportion="1" width="100%" layout="vertical-row">
@ -18,6 +22,4 @@
</box>
</div>
<icon-button id="back" x="0" y="0" height="8%" icon="gui/back.png"/>
</stkgui>

View File

@ -0,0 +1,29 @@
<stkgui>
<icon-button id="back" x="0" y="0" height="8%" icon="gui/back.png"/>
<div x="1%" y="1%" width="98%" height="98%" layout="vertical-row" >
<header id="title" text_align="center" width="80%" align="center" text="..."/>
<spacer height="25" width="10"/>
<tabs id="profile_tabs" height="10%" max_height="110" x="2%" width="98%" align="center">
<icon-button id="tab_overview" width="128" height="128" icon="gui/options_ui.png"/>
<icon-button id="tab_friends" width="128" height="128" icon="gui/options_players.png" />
<icon-button id="tab_achievements" width="128" height="128" icon="gui/options_players.png"/>
<icon-button id="tab_settings" width="128" height="128" icon="gui/main_options.png" I18N="Section in the profile menu" text="Account Settings"/>
</tabs>
<box proportion="1" width="100%" layout="vertical-row">
<div x="1%" y="2%" width="98%" height="96%" layout="vertical-row" >
<div width="fit" height="fit" layout="horizontal-row" >
<label proportion="1" height="fit" text_align="left" I18N="In the online account settings screen" text="Password :"/>
<spacer width="20" height="1"/>
<button id="change_password_button" height="100%" width="fit" text="Change" />
</div>
</div>
</box>
</div>
</stkgui>

View File

@ -1,5 +1,9 @@
# Generated by ./update_file_list.sh. Do not edit this file manually.
set(STK_SOURCES
src/achievements/achievement.cpp
src/achievements/achievement_info.cpp
src/achievements/achievements_manager.cpp
src/achievements/achievements_slot.cpp
src/addons/addon.cpp
src/addons/addons_manager.cpp
src/addons/inetwork_http.cpp
@ -201,6 +205,7 @@ src/states_screens/credits.cpp
src/states_screens/cutscene_gui.cpp
src/states_screens/dialogs/add_device_dialog.cpp
src/states_screens/dialogs/addons_loading.cpp
src/states_screens/dialogs/change_password_dialog.cpp
src/states_screens/dialogs/confirm_resolution_dialog.cpp
src/states_screens/dialogs/custom_video_settings.cpp
src/states_screens/dialogs/enter_player_name_dialog.cpp
@ -231,9 +236,11 @@ src/states_screens/main_menu_screen.cpp
src/states_screens/networking_lobby.cpp
src/states_screens/network_kart_selection.cpp
src/states_screens/offline_kart_selection.cpp
src/states_screens/online_profile_achievements.cpp
src/states_screens/online_profile_base.cpp
src/states_screens/online_profile_friends.cpp
src/states_screens/online_profile_overview.cpp
src/states_screens/online_profile_settings.cpp
src/states_screens/online_screen.cpp
src/states_screens/online_user_search.cpp
src/states_screens/options_screen_audio.cpp
@ -293,6 +300,10 @@ src/utils/translation.cpp
src/utils/vec3.cpp
)
set(STK_HEADERS
src/achievements/achievement.hpp
src/achievements/achievement_info.hpp
src/achievements/achievements_manager.hpp
src/achievements/achievements_slot.hpp
src/addons/addon.hpp
src/addons/addons_manager.hpp
src/addons/dummy_network_http.hpp
@ -504,6 +515,7 @@ src/states_screens/credits.hpp
src/states_screens/cutscene_gui.hpp
src/states_screens/dialogs/add_device_dialog.hpp
src/states_screens/dialogs/addons_loading.hpp
src/states_screens/dialogs/change_password_dialog.hpp
src/states_screens/dialogs/confirm_resolution_dialog.hpp
src/states_screens/dialogs/custom_video_settings.hpp
src/states_screens/dialogs/enter_player_name_dialog.hpp
@ -534,9 +546,11 @@ src/states_screens/main_menu_screen.hpp
src/states_screens/networking_lobby.hpp
src/states_screens/network_kart_selection.hpp
src/states_screens/offline_kart_selection.hpp
src/states_screens/online_profile_achievements.hpp
src/states_screens/online_profile_base.hpp
src/states_screens/online_profile_friends.hpp
src/states_screens/online_profile_overview.hpp
src/states_screens/online_profile_settings.hpp
src/states_screens/online_screen.hpp
src/states_screens/online_user_search.hpp
src/states_screens/options_screen_audio.hpp

View File

@ -0,0 +1,209 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2013 Glenn De Jonghe
//
// 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/achievement.hpp"
#include "achievements/achievement_info.hpp"
#include "guiengine/dialog_queue.hpp"
#include "states_screens/dialogs/notification_dialog.hpp"
#include "io/xml_writer.hpp"
#include "utils/log.hpp"
#include "utils/translation.hpp"
#include <sstream>
#include <stdlib.h>
#include <assert.h>
// ============================================================================
Achievement::Achievement(const AchievementInfo * info)
:m_achievement_info(info)
{
m_id = info->getID();
m_achieved = false;
}
// ============================================================================
Achievement::~Achievement()
{
}
// ============================================================================
void Achievement::onRaceEnd()
{
if(m_achievement_info->needsResetAfterRace())
this->reset();
}
// ============================================================================
void Achievement::check()
{
if(m_achieved)
return;
if(m_achievement_info->checkCompletion(this))
{
//show achievement
GUIEngine::DialogQueue::get()->pushDialog(
new NotificationDialog(NotificationDialog::T_Achievements,
irr::core::stringw(_("Completed achievement")) + irr::core::stringw(" \"") + m_achievement_info->getTitle() + irr::core::stringw("\".")
));
//send to server
Online::CurrentUser::get()->onAchieving(m_id);
m_achieved = true;
}
}
// ============================================================================
SingleAchievement::SingleAchievement(const AchievementInfo * info)
: Achievement(info)
{
m_progress = 0;
m_achieved = false;
}
// ============================================================================
void SingleAchievement::load(XMLNode * input)
{
std::string achieved("");
input->get("achieved", &achieved);
if(achieved == "true")
{
m_achieved = true;
return;
}
input->get("value", &m_progress);
}
// ============================================================================
void SingleAchievement::save(std::ofstream & out)
{
out << " <achievement id=\"" << m_id << "\" "
<< "achieved=\"" << StringUtils::boolstr(m_achieved) << "\"";
if(!m_achieved)
{
out << " value=\"" << StringUtils::toString(m_progress) << "\"";
}
out << "/>\n";
} // save
// ============================================================================
void SingleAchievement::reset()
{
m_progress = 0;
} // reset
// ============================================================================
void SingleAchievement::increase(int increase)
{
m_progress += increase;
check();
}
// ============================================================================
irr::core::stringw SingleAchievement::getProgressAsString()
{
return StringUtils::toWString(m_progress) + "/" + StringUtils::toWString(((SingleAchievementInfo *) m_achievement_info)->getGoalValue());
}
// ============================================================================
MapAchievement::MapAchievement(const AchievementInfo * info)
: Achievement(info)
{
}
// ============================================================================
void MapAchievement::load(XMLNode * input)
{
std::string achieved("");
input->get("achieved", &achieved);
if(achieved == "true")
{
m_achieved = true;
return;
}
std::vector<XMLNode*> xml_entries;
input->getNodes("entry", xml_entries);
for (unsigned int n=0; n < xml_entries.size(); n++)
{
std::string key("");
xml_entries[n]->get("key", &key);
int value(0);
xml_entries[n]->get("value", &value);
m_progress_map[key] = value;
}
}
// ============================================================================
void MapAchievement::save(std::ofstream & out)
{
out << " <achievement id=\"" << m_id << "\" achieved=\"" << StringUtils::boolstr(m_achieved) << "\">\n";
if(!m_achieved)
{
std::map<std::string, int>::iterator iter;
for ( iter = m_progress_map.begin(); iter != m_progress_map.end(); ++iter ) {
out << " <entry key=\"" << iter->first.c_str() << "\" value=\"" << StringUtils::toString(iter->second) << "\"/>\n";
}
}
out << " </achievement>\n";
} // save
// ============================================================================
int MapAchievement::getValue(const std::string & key)
{
if ( m_progress_map.find(key) != m_progress_map.end())
return m_progress_map[key];
return 0;
}
// ============================================================================
void MapAchievement::reset()
{
std::map<std::string, int>::iterator iter;
for ( iter = m_progress_map.begin(); iter != m_progress_map.end(); ++iter ) {
iter->second = 0;
}
} // reset
// ============================================================================
void MapAchievement::increase(const std::string & key, int increase)
{
if ( m_progress_map.find(key) != m_progress_map.end())
{
m_progress_map[key] += increase;
check();
}
}
// ============================================================================
irr::core::stringw MapAchievement::getProgressAsString()
{
int progress(0);
int goal(0);
const std::map<std::string, int> goal_values = ((MapAchievementInfo *) m_achievement_info)->getGoalValues();
std::map<std::string, int>::const_iterator iter;
for ( iter = goal_values.begin(); iter != goal_values.end(); ++iter ) {
goal += iter->second;
progress += m_progress_map[iter->first];
}
return StringUtils::toWString(progress) + "/" + StringUtils::toWString(goal);
}

View File

@ -0,0 +1,101 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2013 Glenn De Jonghe
//
// 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_ACHIEVEMENT_HPP
#define HEADER_ACHIEVEMENT_HPP
#include "utils/types.hpp"
#include <irrString.h>
#include <string>
#include "io/xml_node.hpp"
// ============================================================================
/**
* \brief
* \ingroup
*/
class AchievementInfo;
class Achievement
{
protected:
uint32_t m_id;
bool m_achieved;
const AchievementInfo * m_achievement_info;
void check ();
public:
Achievement (const AchievementInfo * info);
virtual ~Achievement ();
uint32_t getID () const { return m_id; }
const AchievementInfo * getInfo () const { return m_achievement_info;}
virtual void load (XMLNode * input) = 0;
virtual void save (std::ofstream & out) = 0;
virtual void reset () = 0;
void onRaceEnd ();
void setAchieved () {m_achieved = true; };
virtual irr::core::stringw getProgressAsString () = 0;
enum AchievementType
{
AT_SINGLE,
AT_MAP
};
}; // class Achievement
class SingleAchievement : public Achievement
{
protected:
int m_progress;
public:
SingleAchievement (const AchievementInfo * info);
virtual ~SingleAchievement () {};
void load (XMLNode * input);
int getValue () const { return m_progress; }
void save (std::ofstream & out);
void increase (int increase = 1);
void reset ();
virtual irr::core::stringw getProgressAsString ();
}; // class SingleAchievement
class MapAchievement : public Achievement
{
protected:
std::map<std::string, int> m_progress_map;
public:
MapAchievement (const AchievementInfo * info);
virtual ~MapAchievement () {};
void load (XMLNode * input);
int getValue (const std::string & key);
void increase (const std::string & key, int increase = 1);
void save (std::ofstream & out);
void reset ();
virtual irr::core::stringw getProgressAsString ();
}; // class MapAchievement
#endif
/*EOF*/

View File

@ -0,0 +1,87 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2013 Glenn De Jonghe
//
// 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/achievement_info.hpp"
#include "utils/log.hpp"
#include "utils/translation.hpp"
#include "io/xml_writer.hpp"
#include <sstream>
#include <stdlib.h>
#include <assert.h>
// ============================================================================
AchievementInfo::AchievementInfo(const XMLNode * input)
{
input->get("id", &m_id);
input->get("title", &m_title);
input->get("description", &m_description);
std::string reset_after_race("");
input->get("reset_after_race", &reset_after_race);
m_reset_after_race = reset_after_race == "true";
}
// ============================================================================
SingleAchievementInfo::SingleAchievementInfo(const XMLNode * input)
: AchievementInfo(input)
{
input->get("goal", &m_goal_value);
}
// ============================================================================
bool SingleAchievementInfo::checkCompletion(Achievement * achievement) const
{
SingleAchievement * single_achievement = (SingleAchievement *) achievement;
if(single_achievement->getValue() >= m_goal_value)
return true;
return false;
}
// ============================================================================
MapAchievementInfo::MapAchievementInfo(const XMLNode * input)
: AchievementInfo(input)
{
std::vector<XMLNode*> xml_entries;
input->getNodes("entry", xml_entries);
for (unsigned int n=0; n < xml_entries.size(); n++)
{
std::string key("");
xml_entries[n]->get("key", &key);
int goal(0);
xml_entries[n]->get("goal", &goal);
m_goal_values[key] = goal;
}
if(m_goal_values.size() != xml_entries.size())
Log::error("MapAchievementInfo","Duplicate keys for the entries of a MapAchievement found.");
}
// ============================================================================
bool MapAchievementInfo::checkCompletion(Achievement * achievement) const
{
MapAchievement * map_achievement = (MapAchievement *) achievement;
std::map<std::string, int>::const_iterator iter;
for ( iter = m_goal_values.begin(); iter != m_goal_values.end(); iter++ ) {
if(map_achievement->getValue(iter->first) < iter->second)
return false;
}
return true;
}

View File

@ -0,0 +1,87 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2013 Glenn De Jonghe
//
// 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_ACHIEVEMENT_INFO_HPP
#define HEADER_ACHIEVEMENT_INFO_HPP
#include "utils/types.hpp"
#include <irrString.h>
#include <string>
#include "io/xml_node.hpp"
#include "achievements/achievement.hpp"
// ============================================================================
class Achievement;
/**
* \brief
* \ingroup
*/
class AchievementInfo
{
protected:
uint32_t m_id;
irr::core::stringw m_title;
irr::core::stringw m_description;
bool m_reset_after_race;
public:
AchievementInfo (const XMLNode * input);
virtual ~AchievementInfo () {};
uint32_t getID () const { return m_id; }
irr::core::stringw getDescription () const { return m_description; }
irr::core::stringw getTitle () const { return m_title; }
virtual Achievement::AchievementType getType () const = 0;
virtual bool checkCompletion (Achievement * achievement) const = 0;
bool needsResetAfterRace() const {return m_reset_after_race; }
}; // class AchievementInfo
class SingleAchievementInfo : public AchievementInfo
{
protected:
int m_goal_value;
public:
SingleAchievementInfo (const XMLNode * input);
virtual ~SingleAchievementInfo () {};
int getGoalValue () const { return m_goal_value; }
virtual bool checkCompletion (Achievement * achievement) const;
virtual Achievement::AchievementType getType() const { return Achievement::AT_SINGLE; };
}; // class SingleAchievementInfo
class MapAchievementInfo : public AchievementInfo
{
protected:
std::map<std::string, int> m_goal_values;
public:
MapAchievementInfo (const XMLNode * input);
virtual ~MapAchievementInfo () {};
int getGoalValue (const std::string & key) { return m_goal_values[key];}
const std::map<std::string, int> & getGoalValues() const {return m_goal_values;}
virtual bool checkCompletion (Achievement * achievement) const;
virtual Achievement::AchievementType getType() const { return Achievement::AT_MAP; };
}; // class MapAchievementInfo
#endif
/*EOF*/

View File

@ -0,0 +1,247 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2013 Glenn De Jonghe
//
// 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/achievements_manager.hpp"
#include "utils/log.hpp"
#include "utils/translation.hpp"
#include "io/file_manager.hpp"
#include "io/xml_writer.hpp"
#include "config/player.hpp"
#include "config/user_config.hpp"
#include "online/current_user.hpp"
#include "challenges/unlock_manager.hpp"
#include <sstream>
#include <stdlib.h>
#include <assert.h>
static AchievementsManager* achievements_manager_singleton(NULL);
AchievementsManager* AchievementsManager::get()
{
if (achievements_manager_singleton == NULL)
achievements_manager_singleton = new AchievementsManager();
return achievements_manager_singleton;
}
void AchievementsManager::deallocate()
{
delete achievements_manager_singleton;
achievements_manager_singleton = NULL;
} // deallocate
// ============================================================================
AchievementsManager::AchievementsManager()
{
parseDataFile();
}
// ============================================================================
void AchievementsManager::init()
{
parseConfigFile();
}
// ============================================================================
AchievementsManager::~AchievementsManager()
{
save();
m_slots.clearAndDeleteAll();
std::map<uint32_t, AchievementInfo *>::iterator it;
for ( it = m_achievements_info.begin(); it != m_achievements_info.end(); ++it ) {
delete it->second;
}
m_achievements_info.clear();
}
// ============================================================================
void AchievementsManager::parseDataFile()
{
const std::string file_name = file_manager->getDataFile("achievements.xml");
const XMLNode *root = file_manager->createXMLTree(file_name);
unsigned int num_nodes = root->getNumNodes();
for(unsigned int i = 0; i < num_nodes; i++)
{
const XMLNode *node = root->getNode(i);
std::string type("");
node->get("type", &type);
AchievementInfo * achievement_info;
if(type == "single")
{
achievement_info = new SingleAchievementInfo(node);
}
else if(type == "map")
{
achievement_info = new MapAchievementInfo(node);
}
else
{
Log::error("AchievementsManager::parseAchievements","Non-existent achievement type. Skipping - definitely results in unwanted behaviour.");
continue;
}
m_achievements_info[achievement_info->getID()] = achievement_info;
}
if(num_nodes != m_achievements_info.size())
Log::error("AchievementsManager::parseAchievements","Multiple achievements with the same id!");
}
// ============================================================================
void AchievementsManager::parseConfigFile()
{
const std::string filename=file_manager->getConfigFile("achievements.xml");
XMLNode* root = file_manager->createXMLTree(filename);
if(!root || root->getName() != "achievements")
{
Log::info("AchievementsManager", "Achievements file '%s' will be created.",filename.c_str());
createSlotsIfNeeded();
if (root) delete root;
return;
}
std::vector<XMLNode*> xml_slots;
root->getNodes("slot", xml_slots);
for (unsigned int n=0; n < xml_slots.size(); n++)
{
AchievementsSlot * slot = new AchievementsSlot(xml_slots[n]);
if(!slot->isValid())
{
Log::warn("AchievementsManager", "Found game slot with faulty or missing information. Discarding it.");
delete slot;
continue;
}
m_slots.push_back(slot);
}
delete root;
} // load
AchievementsSlot * AchievementsManager::createNewSlot(std::string id, bool online)
{
AchievementsSlot* slot = new AchievementsSlot(id, online);
m_slots.push_back(slot);
return slot;
}
//-----------------------------------------------------------------------------
/** Creates a slot for players that don't have one yet
* \return true if any were created
*/
void AchievementsManager::createSlotsIfNeeded()
{
bool something_changed = false;
// make sure all players have at least one game slot associated
PtrVector<PlayerProfile>& players = UserConfigParams::m_all_players;
for (int n=0; n<players.size(); n++)
{
if (getSlot(players[n].getUniqueID(), false) == NULL )
{
createNewSlot(players[n].getUniqueID(), false);
something_changed = true;
}
}
if(something_changed){
save();
}
} // UnlockManager::createSlotsIfNeeded
// ============================================================================
void AchievementsManager::save()
{
std::string filename = file_manager->getConfigFile("achievements.xml");
std::ofstream achievements_file(filename.c_str(), std::ios::out);
if (!achievements_file.is_open())
{
Log::warn("AchievementsManager::save",
"Failed to open '%s' for writing, achievements won't be saved\n",
filename.c_str());
return;
}
achievements_file << "<?xml version=\"1.0\"?>\n";
achievements_file << "<achievements>\n";
for (int i = 0; i < m_slots.size(); i++)
{
m_slots[i].save(achievements_file);
}
achievements_file << "</achievements>\n\n";
achievements_file.close();
}
// ============================================================================
void AchievementsManager::onRaceEnd()
{
//reset all values that need to be reset
m_active_slot->onRaceEnd();
}
// ============================================================================
AchievementsSlot * AchievementsManager::getSlot(const std::string & id, bool online)
{
for(int i = 0; i < m_slots.size(); i++)
{
if(m_slots[i].isOnline() == online && m_slots[i].getID() == id)
{
return m_slots.get(i);
}
}
return NULL;
}
// ============================================================================
void AchievementsManager::updateCurrentPlayer()
{
if(Online::CurrentUser::get()->isRegisteredUser())
{
m_active_slot = getSlot(StringUtils::toString(Online::CurrentUser::get()->getID()), true);
if(m_active_slot == NULL)
{
m_active_slot = createNewSlot(StringUtils::toString(Online::CurrentUser::get()->getID()), true);
save();
}
}
else
{
m_active_slot = getSlot(unlock_manager->getCurrentPlayer()->getUniqueID(), false);
if(m_active_slot == NULL)
{
m_active_slot = createNewSlot(unlock_manager->getCurrentPlayer()->getUniqueID(), false);
save();
}
}
}
// ============================================================================
AchievementInfo * AchievementsManager::getAchievementInfo(uint32_t id)
{
if ( m_achievements_info.find(id) != m_achievements_info.end())
return m_achievements_info[id];
return NULL;
}

View File

@ -0,0 +1,70 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2013 Glenn De Jonghe
//
// 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_ACHIEVEMENTS_MANAGER_HPP
#define HEADER_ACHIEVEMENTS_MANAGER_HPP
#include "utils/types.hpp"
#include "utils/ptr_vector.hpp"
#include "achievements/achievement_info.hpp"
#include "achievements/achievements_slot.hpp"
#include <irrString.h>
#include <string>
#include <vector>
#include <map>
// ============================================================================
/**
* \brief Class that takes care of online profiles
* \ingroup online
*/
class AchievementsManager
{
private :
AchievementsSlot * m_active_slot;
PtrVector<AchievementsSlot> m_slots;
std::map<uint32_t, AchievementInfo *> m_achievements_info;
AchievementsManager ();
~AchievementsManager ();
AchievementsSlot * createNewSlot(std::string id, bool online);
void parseDataFile();
void parseConfigFile();
public:
/**Singleton */
static AchievementsManager * get();
static void deallocate();
void init();
void save();
void onRaceEnd();
void updateCurrentPlayer();
AchievementsSlot * getActive() const { return m_active_slot; }
AchievementsSlot * getSlot(const std::string & id, bool online);
void createSlotsIfNeeded();
AchievementInfo * getAchievementInfo(uint32_t id);
const std::map<uint32_t, AchievementInfo *> & getAllInfo() { return m_achievements_info;}
}; // class AchievementsManager
#endif
/*EOF*/

View File

@ -0,0 +1,153 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2013 Glenn De Jonghe
//
// 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/achievements_slot.hpp"
#include "achievements/achievement_info.hpp"
#include "achievements/achievements_manager.hpp"
#include "utils/log.hpp"
#include "utils/ptr_vector.hpp"
#include "utils/translation.hpp"
#include "io/xml_writer.hpp"
#include "online/current_user.hpp"
#include <sstream>
#include <stdlib.h>
#include <assert.h>
// ============================================================================
AchievementsSlot::AchievementsSlot(const XMLNode * input)
{
int fetched_user_id = input->get("user_id", &m_id);
std::string online;
int fetched_online = input->get("online", &online);
if(!fetched_user_id || !fetched_online || !(online == "true" || online == "false"))
{
m_valid = false;
}
m_valid = true;
m_online = online == "true";
createFreshSlot();
std::vector<XMLNode*> xml_achievements;
input->getNodes("achievement", xml_achievements);
for( unsigned int i=0; i<xml_achievements.size(); i++)
{
uint32_t achievement_id(0);
xml_achievements[i]->get("id", &achievement_id);
Achievement * achievement = getAchievement(achievement_id);
if(achievement == NULL)
{
Log::warn("AchievementsSlot", "Found saved achievement data for a non-existent achievement. Discarding.");
continue;
}
achievement->load(xml_achievements[i]);
}
}
// ============================================================================
AchievementsSlot::AchievementsSlot(std::string id, bool online)
{
m_valid = true;
m_online = online;
m_id = id;
createFreshSlot();
}
// ============================================================================
AchievementsSlot::~AchievementsSlot()
{
deleteAchievements();
}
// ============================================================================
void AchievementsSlot::deleteAchievements()
{
std::map<uint32_t, Achievement *>::iterator it;
for ( it = m_achievements.begin(); it != m_achievements.end(); ++it ) {
delete it->second;
}
m_achievements.clear();
}
// ============================================================================
void AchievementsSlot::createFreshSlot()
{
deleteAchievements();
const std::map<uint32_t, AchievementInfo *> all_info = AchievementsManager::get()->getAllInfo();
std::map<uint32_t, AchievementInfo *>::const_iterator it;
for ( it = all_info.begin(); it != all_info.end(); ++it ) {
Achievement::AchievementType achievement_type = it->second->getType();
Achievement * achievement;
if(achievement_type == Achievement::AT_SINGLE)
{
achievement = new SingleAchievement(it->second);
}
else if(achievement_type == Achievement::AT_MAP)
{
achievement = new MapAchievement(it->second);
}
m_achievements[achievement->getID()] = achievement;
}
}
// ============================================================================
void AchievementsSlot::save(std::ofstream & out)
{
out << " <slot user_id=\"" << m_id.c_str()
<< "\" online=\"" << StringUtils::boolstr(m_online)
<< "\"> \n";
std::map<uint32_t, Achievement*>::const_iterator i;
for(i = m_achievements.begin(); i != m_achievements.end(); i++)
{
if (i->second != NULL)
i->second->save(out);
}
out << " </slot>\n";
}
// ============================================================================
Achievement * AchievementsSlot::getAchievement(uint32_t id)
{
if ( m_achievements.find(id) != m_achievements.end())
return m_achievements[id];
return NULL;
}
// ============================================================================
void AchievementsSlot::sync(const std::vector<uint32_t> & achieved_ids)
{
for(unsigned int i =0; i < achieved_ids.size(); ++i)
{
Achievement * achievement = getAchievement(achieved_ids[i]);
if(achievement != NULL)
achievement->setAchieved();
}
}
// ============================================================================
void AchievementsSlot::onRaceEnd()
{
//reset all values that need to be reset
std::map<uint32_t, Achievement *>::iterator iter;
for ( iter = m_achievements.begin(); iter != m_achievements.end(); ++iter ) {
iter->second->onRaceEnd();
}
}

View File

@ -0,0 +1,64 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2013 Glenn De Jonghe
//
// 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_ACHIEVEMENTS_SLOT_HPP
#define HEADER_ACHIEVEMENTS_SLOT_HPP
#include "utils/types.hpp"
#include "achievements/achievement.hpp"
#include "online/http_manager.hpp"
#include <irrString.h>
#include <string>
#include "io/xml_node.hpp"
class AchievementsSlot
{
private:
std::map<uint32_t, Achievement *> m_achievements;
bool m_online;
bool m_valid;
std::string m_id;
void createFreshSlot();
void deleteAchievements();
class SyncAchievementsRequest : public Online::XMLRequest {
virtual void callback ();
public:
SyncAchievementsRequest() : Online::XMLRequest(true) {}
};
public :
AchievementsSlot(const XMLNode * input);
AchievementsSlot(std::string id, bool online);
~AchievementsSlot();
bool isValid() const { return m_valid;}
void save(std::ofstream & out);
bool isOnline() const {return m_online;}
void sync(const std::vector<uint32_t> & achieved_ids);
void onRaceEnd();
const std::string & getID() const {return m_id;}
const std::map<uint32_t, Achievement *> & getAllAchievements() {return m_achievements;}
Achievement * getAchievement(uint32_t id);
};
#endif
/*EOF*/

View File

@ -90,17 +90,11 @@ void Challenge::setSolved(RaceManager::Difficulty d)
//-----------------------------------------------------------------------------
const char* boolstr(bool b)
{
return (b ? "true" : "false");
}
void Challenge::save(std::ofstream& writer)
{
writer << " <" << m_data->getId().c_str() << ">\n"
<< " <easy solved=\"" << boolstr(isSolved(RaceManager::DIFFICULTY_EASY)) << "\"/>\n"
<< " <medium solved=\"" << boolstr(isSolved(RaceManager::DIFFICULTY_MEDIUM)) << "\"/>\n"
<< " <hard solved=\"" << boolstr(isSolved(RaceManager::DIFFICULTY_HARD)) << "\"/>\n"
<< " <easy solved=\"" << StringUtils::boolstr(isSolved(RaceManager::DIFFICULTY_EASY)) << "\"/>\n"
<< " <medium solved=\"" << StringUtils::boolstr(isSolved(RaceManager::DIFFICULTY_MEDIUM)) << "\"/>\n"
<< " <hard solved=\"" << StringUtils::boolstr(isSolved(RaceManager::DIFFICULTY_HARD)) << "\"/>\n"
<< " </" << m_data->getId().c_str() << ">\n";
} // save

View File

@ -24,6 +24,7 @@
#include <stdio.h>
#include <iostream>
#include "achievements/achievements_manager.hpp"
#include "audio/sfx_base.hpp"
#include "audio/sfx_manager.hpp"
#include "config/player.hpp"
@ -204,7 +205,7 @@ const ChallengeData* UnlockManager::getChallenge(const std::string& id)
*/
void UnlockManager::load()
{
const std::string filename=file_manager->getChallengeFile("challenges.xml");
const std::string filename=file_manager->getConfigFile("challenges.xml");
XMLNode* root = file_manager->createXMLTree(filename);
if(!root || root->getName() != "challenges")
{
@ -263,7 +264,7 @@ void UnlockManager::load()
void UnlockManager::save()
{
std::string filename = file_manager->getChallengeFile("challenges.xml");
std::string filename = file_manager->getConfigFile("challenges.xml");
std::ofstream challenge_file(filename.c_str(), std::ios::out);
@ -421,6 +422,15 @@ void UnlockManager::updateActiveChallengeList()
getCurrentSlot()->computeActive();
}
//-----------------------------------------------------------------------------
void UnlockManager::setCurrentSlot(std::string slotid)
{
m_current_game_slot = slotid;
AchievementsManager::get()->updateCurrentPlayer();
}
//-----------------------------------------------------------------------------
void UnlockManager::findWhatWasUnlocked(int points_before, int points_now,

View File

@ -82,8 +82,7 @@ public:
}
/** \param slotid name of the player */
void setCurrentSlot(std::string slotid) { m_current_game_slot = slotid; }
void setCurrentSlot(std::string slotid);
void findWhatWasUnlocked(int pointsBefore, int pointsNow,
std::vector<std::string>& tracks,
std::vector<std::string>& gps);

View File

@ -734,7 +734,7 @@ EventPropagation EventHandler::onGUIEvent(const SEvent& event)
if (playerID == -1) break;
if (input_manager->masterPlayerOnly() && playerID != PLAYER_ID_GAME_MASTER) break;
if (ribbon->mouseHovered(w, playerID) == EVENT_LET) sendEventToUser(ribbon, ribbon->m_properties[PROP_ID], playerID);
ribbon->mouseHovered(w, playerID);
if (ribbon->m_event_handler != NULL) ribbon->m_event_handler->mouseHovered(w, playerID);
ribbon->setFocusForPlayer(playerID);
}

View File

@ -844,7 +844,7 @@ std::string FileManager::checkAndCreateLinuxDir(const char *env_name,
void FileManager::redirectOutput()
{
//Enable logging of stdout and stderr to logfile
std::string logoutfile = getLogFile("stdout.log");
std::string logoutfile = getConfigFile("stdout.log");
Log::verbose("main", "Error messages and other text output will "
"be logged to %s.", logoutfile.c_str());
Log::openOutputFiles(logoutfile);
@ -874,16 +874,6 @@ std::string FileManager::getConfigDir() const
return m_config_dir;
} // getConfigDir
//-----------------------------------------------------------------------------
/** Returns the full path of a file in the user config directory which is
* used to store stdout/stderr if it is redirected.
* \param name Name of the file.
*/
std::string FileManager::getLogFile(const std::string& file_name) const
{
return getConfigDir()+"/"+file_name;
} // getLogFile
//-----------------------------------------------------------------------------
/** Returns the full path of a music file by searching all music search paths.
* It throws an exception if the file is not found.
@ -921,33 +911,14 @@ std::string FileManager::getFontFile(const std::string& file_name) const
} // getFontFile
//-----------------------------------------------------------------------------
/** Returns the full path of a highscore file (which is stored in the user
* specific config directory).
* \param file_name Name of the sound effect file.
*/
std::string FileManager::getHighscoreFile(const std::string& file_name) const
{
return getConfigDir()+"/"+file_name;
} // getHighscoreFile
//-----------------------------------------------------------------------------
/** Returns the full path of the challenge file (which is stored in a user
* specific config area).
/** Returns the full path of a file in the config dir
* \param file_name Name of the file.
*/
std::string FileManager::getChallengeFile(const std::string &file_name) const
std::string FileManager::getConfigFile(const std::string &file_name) const
{
return getConfigDir()+"/"+file_name;
return getConfigDir()+file_name;
} // getChallengeFile
//-----------------------------------------------------------------------------
/** Returns the full path of the tutorial file.
* \param file_name Name of the tutorial file to return.
*/
std::string FileManager::getTutorialFile(const std::string &file_name) const
{
return getConfigDir()+"/"+file_name;
} // getTutorialFile
//-----------------------------------------------------------------------------
/** Returns true if the given name is a directory.

View File

@ -106,10 +106,7 @@ public:
std::vector<std::string>getMusicDirs() const;
std::string getTextureFile (const std::string& fname) const;
std::string getDataFile (const std::string& fname) const;
std::string getHighscoreFile (const std::string& fname) const;
std::string getChallengeFile (const std::string& fname) const;
std::string getTutorialFile (const std::string& fname) const;
std::string getLogFile (const std::string& fname) const;
std::string getConfigFile (const std::string& fname) const;
std::string getItemFile (const std::string& fname) const;
std::string getGfxFile (const std::string& fname) const;
std::string getMusicFile (const std::string& fname) const;

View File

@ -139,6 +139,7 @@
#include <IEventReceiver.h>
#include "main_loop.hpp"
#include "achievements/achievements_manager.hpp"
#include "addons/addons_manager.hpp"
#include "addons/inetwork_http.hpp"
#include "addons/news_manager.hpp"
@ -155,6 +156,7 @@
#include "graphics/referee.hpp"
#include "guiengine/engine.hpp"
#include "guiengine/event_handler.hpp"
#include "guiengine/dialog_queue.hpp"
#include "input/input_manager.hpp"
#include "input/device_manager.hpp"
#include "input/wiimote_manager.hpp"
@ -180,6 +182,8 @@
#include "network/protocols/server_lobby_room_protocol.hpp"
#include "online/current_user.hpp"
#include "online/http_manager.hpp"
#include "online/profile_manager.hpp"
#include "online/servers_manager.hpp"
#include "race/grand_prix_manager.hpp"
#include "race/highscore_manager.hpp"
#include "race/history.hpp"
@ -1200,6 +1204,8 @@ void initRest()
// to network_http (since the thread might use network_http, otherwise
// a race condition can be introduced resulting in a crash).
INetworkHttp::get()->startNetworkThread();
Online::HTTPManager::get()->startNetworkThread();
AchievementsManager::get()->init();
music_manager = new MusicManager();
sfx_manager = new SFXManager();
// The order here can be important, e.g. KartPropertiesManager needs
@ -1253,9 +1259,15 @@ static void cleanSuperTuxKart()
INetworkHttp::get()->stopNetworkThread();
if(Online::HTTPManager::isRunning())
Online::HTTPManager::get()->stopNetworkThread();
//delete in reverse order of what they were created in.
//delete in reverse order of what they were created in.
//see InitTuxkart()
Online::ServersManager::deallocate();
Online::ProfileManager::deallocate();
AchievementsManager::deallocate();
Online::CurrentUser::deallocate();
GUIEngine::DialogQueue::deallocate();
Referee::cleanup();
if(ReplayPlay::get()) ReplayPlay::destroy();
if(race_manager) delete race_manager;
@ -1300,6 +1312,7 @@ static void cleanSuperTuxKart()
StateManager::deallocate();
GUIEngine::EventHandler::deallocate();
Online::HTTPManager::deallocate();
} // cleanSuperTuxKart
//=============================================================================
@ -1523,7 +1536,6 @@ int main(int argc, char *argv[] )
StateManager::get()->enterGameState();
}
// If an important news message exists it is shown in a popup dialog.
const core::stringw important_message =
news_manager->getImportantMessage();

View File

@ -24,6 +24,7 @@
#include <algorithm>
#include <ctime>
#include "achievements/achievements_manager.hpp"
#include "audio/music_manager.hpp"
#include "audio/sfx_base.hpp"
#include "audio/sfx_manager.hpp"
@ -444,6 +445,10 @@ void World::terminateRace()
unlock_manager->getCurrentSlot()->raceFinished();
}
unlock_manager->getCurrentSlot()->raceFinished();
((MapAchievement *) AchievementsManager::get()->getActive()->getAchievement(1))->increase(getTrack()->getIdent(), 1);
AchievementsManager::get()->onRaceEnd();
if (m_race_gui) m_race_gui->clearAllMessages();
// we can't delete the race gui here, since it is needed in case of
// a restart: the constructor of it creates some textures which assume

View File

@ -19,6 +19,7 @@
#include "online/current_user.hpp"
#include "achievements/achievements_manager.hpp"
#include "addons/addons_manager.hpp"
#include "config/user_config.hpp"
#include "online/servers_manager.hpp"
@ -27,6 +28,8 @@
#include "utils/translation.hpp"
#include "addons/addon.hpp"
#include "guiengine/dialog_queue.hpp"
#include "states_screens/dialogs/change_password_dialog.hpp"
#include "states_screens/dialogs/login_dialog.hpp"
#include "states_screens/dialogs/user_info_dialog.hpp"
#include "states_screens/dialogs/notification_dialog.hpp"
#include "states_screens/online_profile_friends.hpp"
@ -34,6 +37,7 @@
#include <sstream>
#include <stdlib.h>
#include <assert.h>
#include <algorithm>
using namespace Online;
@ -100,7 +104,7 @@ namespace Online{
void CurrentUser::requestSavedSession()
{
SignInRequest * request = NULL;
if(m_state != US_SIGNED_IN && UserConfigParams::m_saved_session)
if(m_state == US_SIGNED_OUT && UserConfigParams::m_saved_session)
{
request = new SignInRequest(true);
request->setURL((std::string)UserConfigParams::m_server_multiplayer + "client-user.php");
@ -118,11 +122,12 @@ namespace Online{
{
assert(m_state == US_SIGNED_OUT);
m_save_session = save_session;
SignInRequest * request = new SignInRequest();
SignInRequest * request = new SignInRequest(request_now);
request->setURL((std::string)UserConfigParams::m_server_multiplayer + "client-user.php");
request->setParameter("action",std::string("connect"));
request->setParameter("username",username);
request->setParameter("password",password);
request->setParameter("save-session", StringUtils::boolstr(save_session));
if (request_now)
{
HTTPManager::get()->addRequest(request);
@ -135,9 +140,7 @@ namespace Online{
{
if (success)
{
std::string token("");
int token_fetched = input->get("token", &token);
setToken(token);
int token_fetched = input->get("token", &m_token);
irr::core::stringw username("");
int username_fetched = input->get("username", &username);
uint32_t userid(0);
@ -152,16 +155,35 @@ namespace Online{
UserConfigParams::m_saved_session = true;
}
ProfileManager::get()->addPersistent(m_profile);
AchievementsManager::get()->updateCurrentPlayer();
std::string achieved_string("");
if(input->get("achieved", &achieved_string) == 1)
{
std::vector<uint32_t> achieved_ids = StringUtils::splitToUInt(achieved_string, ' ');
AchievementsManager::get()->getActive()->sync(achieved_ids);
}
m_profile->fetchFriends();
HTTPManager::get()->startPolling();
}
else
{
m_state = US_SIGNED_OUT;
}
}
void CurrentUser::SignInRequest::callback()
{
CurrentUser::get()->signIn(m_success, m_result);
if(GUIEngine::ModalDialog::isADialogActive())
{
LoginDialog * dialog = dynamic_cast<LoginDialog*>(GUIEngine::ModalDialog::getCurrent());
if(dialog != NULL)
{
if(m_success)
dialog->success();
else
dialog->error(m_info);
}
}
}
// ============================================================================
@ -201,7 +223,6 @@ namespace Online{
request->setParameter("userid", getID());
HTTPManager::get()->addRequest(request);
m_state = US_SIGNING_OUT;
HTTPManager::get()->stopPolling();
return request;
}
@ -209,15 +230,16 @@ namespace Online{
{
if(!success)
{
Log::warn("CurrentUser::signOut", "%s", _("There were some connection issues while signing out. Report a bug if this caused issues."));
Log::warn("CurrentUser::signOut", "%s", "There were some connection issues while signing out. Report a bug if this caused issues.");
}
setToken("");
m_token = "";
ProfileManager::get()->clearPersistent();
m_profile = NULL;
m_state = US_SIGNED_OUT;
UserConfigParams::m_saved_user = 0;
UserConfigParams::m_saved_token = "";
UserConfigParams::m_saved_session = false;
AchievementsManager::get()->updateCurrentPlayer();
}
void CurrentUser::SignOutRequest::callback()
@ -472,6 +494,37 @@ namespace Online{
GUIEngine::DialogQueue::get()->pushDialog( new UserInfoDialog(id, info_text,!m_success, true), true);
}
// ============================================================================
void CurrentUser::requestPasswordChange(const irr::core::stringw &current_password,
const irr::core::stringw &new_password,
const irr::core::stringw &new_password_ver) const
{
assert(m_state == US_SIGNED_IN);
ChangePasswordRequest * request = new ChangePasswordRequest();
request->setURL((std::string)UserConfigParams::m_server_multiplayer + "client-user.php");
request->setParameter("action", std::string("change_password"));
request->setParameter("userid", getID());
request->setParameter("current", current_password);
request->setParameter("new1", new_password);
request->setParameter("new2", new_password_ver);
HTTPManager::get()->addRequest(request);
}
void CurrentUser::ChangePasswordRequest::callback()
{
if(GUIEngine::ModalDialog::isADialogActive())
{
ChangePasswordDialog * dialog = dynamic_cast<ChangePasswordDialog*>(GUIEngine::ModalDialog::getCurrent());
if(dialog != NULL)
{
if(m_success)
dialog->success();
else
dialog->error(m_info);
}
}
}
// ============================================================================
void CurrentUser::requestPoll()
{
@ -488,83 +541,82 @@ namespace Online{
{
if(m_success)
{
std::string online_friends_string("");
if(m_result->get("online", &online_friends_string) == 1)
if(!CurrentUser::get()->isRegisteredUser())
return;
if(CurrentUser::get()->getProfile()->hasFetchedFriends())
{
std::vector<std::string> parts = StringUtils::split(online_friends_string, ' ');
std::vector<uint32_t> online_friends;
for(unsigned int i = 0; i < parts.size(); ++i)
std::string online_friends_string("");
if(m_result->get("online", &online_friends_string) == 1)
{
online_friends.push_back(atoi(parts[i].c_str()));
}
bool went_offline = false;
std::vector<uint32_t> friends = CurrentUser::get()->getProfile()->getFriends();
std::vector<irr::core::stringw> to_notify;
for(unsigned int i = 0; i < friends.size(); ++i)
{
bool now_online = false;
std::vector<uint32_t>::iterator iter;
for (iter = online_friends.begin(); iter != online_friends.end();)
{
if (*iter == friends[i])
std::vector<uint32_t> online_friends = StringUtils::splitToUInt(online_friends_string, ' ');
bool went_offline = false;
std::vector<uint32_t> friends = CurrentUser::get()->getProfile()->getFriends();
std::vector<irr::core::stringw> to_notify;
for(unsigned int i = 0; i < friends.size(); ++i)
{
bool now_online = false;
std::vector<uint32_t>::iterator iter =
std::find(online_friends.begin(),online_friends.end(), friends[i]);
if (iter != online_friends.end())
{
now_online = true;
online_friends.erase(iter);
}
Profile * profile = ProfileManager::get()->getProfileByID(friends[i]);
Profile::RelationInfo * relation_info = profile->getRelationInfo();
if( relation_info->isOnline() )
{
if (!now_online)
{
relation_info->setOnline(false);
went_offline = true;
}
}
else
{
if (now_online)
{
relation_info->setOnline(true);
profile->setFriend();
to_notify.push_back(profile->getUserName());
}
}
}
if(to_notify.size() > 0)
{
irr::core::stringw message("");
if(to_notify.size() == 1)
{
now_online = true;
online_friends.erase(iter++);
break;
message = to_notify[0] + irr::core::stringw(_(" is now online."));
}
else
++iter;
}
Profile * profile = ProfileManager::get()->getProfileByID(friends[i]);
Profile::RelationInfo * relation_info = profile->getRelationInfo();
if( relation_info->isOnline() )
{
if (!now_online)
{
relation_info->setOnline(false);
went_offline = true;
}
}
else
{
if (now_online)
{
relation_info->setOnline(true);
profile->setFriend();
to_notify.push_back(profile->getUserName());
}
}
}
if(to_notify.size() > 0)
{
irr::core::stringw message("");
if(to_notify.size() == 1)
{
message = to_notify[0] + irr::core::stringw(_(" is now online."));
else if(to_notify.size() == 2)
{
message = to_notify[0] + irr::core::stringw(_(" and ")) + to_notify[1] + irr::core::stringw(_(" are now online."));
}
else if(to_notify.size() == 3)
{
message = to_notify[0] + irr::core::stringw(_(", ")) + to_notify[1] + irr::core::stringw(_(" and ")) + to_notify[2] + irr::core::stringw(_(" are now online."));
}
else if(to_notify.size() > 3)
{
message = StringUtils::toWString(to_notify.size()) + irr::core::stringw(_(" friends are now online."));
}
GUIEngine::DialogQueue::get()->pushDialog( new NotificationDialog(NotificationDialog::T_Friends, message), false);
OnlineProfileFriends::getInstance()->refreshFriendsList();
}
else if(to_notify.size() == 2)
else if(went_offline)
{
message = to_notify[0] + irr::core::stringw(_(" and ")) + to_notify[1] + irr::core::stringw(_(" are now online."));
OnlineProfileFriends::getInstance()->refreshFriendsList();
}
else if(to_notify.size() == 3)
{
message = to_notify[0] + irr::core::stringw(_(", ")) + to_notify[1] + irr::core::stringw(_(" and ")) + to_notify[2] + irr::core::stringw(_(" are now online."));
}
else if(to_notify.size() > 3)
{
message = StringUtils::toWString(to_notify.size()) + irr::core::stringw(_(" friends are now online."));
}
GUIEngine::DialogQueue::get()->pushDialog( new NotificationDialog(NotificationDialog::T_Friends, message), false);
OnlineProfileFriends::getInstance()->refreshFriendsList();
}
else if(went_offline)
{
OnlineProfileFriends::getInstance()->refreshFriendsList();
}
}
else
{
CurrentUser::get()->getProfile()->fetchFriends();
}
int friend_request_count = 0;
for(unsigned int i = 0; i < m_result->getNumNodes(); i++)
{
@ -597,6 +649,37 @@ namespace Online{
// after 2 misses I'll show something
}
// ============================================================================
void CurrentUser::onSTKQuit() const
{
if(isRegisteredUser())
{
HTTPRequest * request = new HTTPRequest(true, HTTPManager::MAX_PRIORITY);
request->setURL((std::string)UserConfigParams::m_server_multiplayer + "client-user.php");
request->setParameter("action", std::string("client-quit"));
request->setParameter("token", getToken());
request->setParameter("userid", getID());
HTTPManager::get()->addRequest(request);
}
}
// ============================================================================
void CurrentUser::onAchieving(uint32_t achievement_id) const
{
if(isRegisteredUser())
{
HTTPRequest * request = new HTTPRequest(true);
request->setURL((std::string)UserConfigParams::m_server_multiplayer + "client-user.php");
request->setParameter("action", std::string("achieving"));
request->setParameter("token", getToken());
request->setParameter("userid", getID());
request->setParameter("achievementid", achievement_id);
HTTPManager::get()->addRequest(request);
}
}
// ============================================================================
irr::core::stringw CurrentUser::getUserName() const

View File

@ -43,7 +43,7 @@ namespace Online{
public:
enum UserState
{
US_SIGNED_OUT,
US_SIGNED_OUT = 0,
US_SIGNED_IN,
US_GUEST,
US_SIGNING_IN,
@ -120,6 +120,13 @@ namespace Online{
PollRequest() : XMLRequest(true) {}
};
class ChangePasswordRequest : public XMLRequest
{
virtual void callback ();
public:
ChangePasswordRequest() : XMLRequest(true) {}
};
private:
std::string m_token;
@ -129,10 +136,6 @@ namespace Online{
bool getSaveSession() const { return m_save_session; }
void setUserState (UserState user_state) { m_state = user_state; }
void setSaveSession (bool save_session) { m_save_session = save_session; }
void setToken (const std::string & token) { m_token= token; }
CurrentUser();
void signIn (bool success, const XMLNode * input);
@ -170,10 +173,14 @@ namespace Online{
void requestDeclineFriend(const uint32_t friend_id) const;
void requestRemoveFriend(const uint32_t friend_id) const;
void requestCancelFriend(const uint32_t friend_id) const;
void requestPasswordChange( const irr::core::stringw &current_password,
const irr::core::stringw &new_password,
const irr::core::stringw &new_password_ver) const;
const XMLRequest * requestUserSearch(const irr::core::stringw & search_string) const;
void onSTKQuit() const;
void onAchieving(uint32_t achievement_id) const;
/** Returns the username if signed in. */
irr::core::stringw getUserName() const;

View File

@ -49,16 +49,17 @@ namespace Online{
if (http_singleton == NULL)
{
http_singleton = new HTTPManager();
http_singleton->startNetworkThread();
CurrentUser::get()->requestSavedSession();
}
return http_singleton;
} // get
void HTTPManager::deallocate()
{
delete http_singleton;
http_singleton = NULL;
if (http_singleton != NULL)
{
delete http_singleton;
http_singleton = NULL;
}
} // deallocate
bool HTTPManager::isRunning()
@ -71,12 +72,16 @@ namespace Online{
curl_global_init(CURL_GLOBAL_DEFAULT);
pthread_cond_init(&m_cond_request, NULL);
m_abort.setAtomic(false);
m_time_since_poll = MENU_POLLING_INTERVAL * (2.0/3.0);
m_polling = false;
m_time_since_poll = MENU_POLLING_INTERVAL * 0.9;
}
// ============================================================================
HTTPManager::~HTTPManager(){
m_thread_id.lock();
pthread_join(*m_thread_id.getData(), NULL);
delete m_thread_id.getData();
m_thread_id.unlock();
pthread_cond_destroy(&m_cond_request);
curl_global_cleanup();
}
@ -109,10 +114,10 @@ namespace Online{
Log::error("HTTP Manager", "Could not create thread, error=%d.\n", errno);
}
pthread_attr_destroy(&attr);
CurrentUser::get()->requestSavedSession();
} // startNetworkThread
// ---------------------------------------------------------------------------
/** This function inserts a high priority request to quit into the request
* queue of the network thead, and also aborts any ongoing download.
@ -127,8 +132,9 @@ namespace Online{
// and we couldn't finish STK. This way we request an abort of
// a download, which mean we can get the mutex and ask the service
// thread here to cancel properly.
cancelAllDownloads();
addRequest(new Request(true, 9999, Request::RT_QUIT));
//cancelAllDownloads(); FIXME if used this way it also cancels the client-quit action
CurrentUser::get()->onSTKQuit();
addRequest(new Request(true, MAX_PRIORITY, Request::RT_QUIT));
} // stopNetworkThread
@ -183,7 +189,7 @@ namespace Online{
{
HTTPManager *me = (HTTPManager*) obj;
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
//pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
me->m_current_request = NULL;
me->m_request_queue.lock();
@ -216,7 +222,6 @@ namespace Online{
delete request;
}
me->m_request_queue.unlock();
pthread_exit(NULL);
return 0;
} // mainLoop

View File

@ -49,7 +49,6 @@ namespace Online{
protected:
float m_time_since_poll;
bool m_polling;
/** The current requested being worked on. */
Online::Request * m_current_request;
@ -77,21 +76,18 @@ namespace Online{
void handleResultQueue();
static void *mainLoop(void *obj);
void startNetworkThread();
HTTPManager(); //const std::string &url
~HTTPManager();
public:
static const int MAX_PRIORITY = 9999;
// singleton
static HTTPManager* get();
static void deallocate();
static bool isRunning();
void startPolling(){ m_polling = true; }
void stopPolling(){ m_polling = false; }
//Execute
std::string getPage(Online::Request * request);
XMLNode * getXMLFromPage(Online::Request * request);
@ -99,6 +95,7 @@ namespace Online{
void synchronousRequest(Online::Request *request);
void addRequest(Online::Request *request);
void cancelAllDownloads();
void startNetworkThread();
void stopNetworkThread();
bool getAbort(){ return m_abort.getAtomic(); };

View File

@ -35,14 +35,9 @@ namespace Online
return irr::core::stringw(_("Signing out")) + loadingDots();
}
// ------------------------------------------------------------------------
irr::core::stringw signingUp()
irr::core::stringw validatingInfo()
{
return irr::core::stringw(_("Validating registration info")) + loadingDots();
}
// ------------------------------------------------------------------------
irr::core::stringw recovery()
{
return irr::core::stringw(_("Validating recovery info")) + loadingDots();
return irr::core::stringw(_("Validating info")) + loadingDots();
}
// ------------------------------------------------------------------------
irr::core::stringw searching()
@ -84,6 +79,13 @@ namespace Online
// ------------------------------------------------------------------------
irr::core::stringw fetchingAchievements()
{
return irr::core::stringw(_("Fetching achievements")) + loadingDots();
}
// ------------------------------------------------------------------------
irr::core::stringw processing()
{
return irr::core::stringw(_("Processing")) + loadingDots();

View File

@ -29,13 +29,13 @@ namespace Online
irr::core::stringw loadingDots (bool spaces = true, float interval = 0.5f, int max_dots = 3);
irr::core::stringw signingIn ();
irr::core::stringw signingOut ();
irr::core::stringw signingUp ();
irr::core::stringw recovery ();
irr::core::stringw validatingInfo ();
irr::core::stringw searching ();
irr::core::stringw joiningServer ();
irr::core::stringw creatingServer ();
irr::core::stringw fetchingServers ();
irr::core::stringw fetchingFriends ();
irr::core::stringw fetchingAchievements ();
irr::core::stringw processing ();
irr::core::stringw signedInAs (const irr::core::stringw & name);
} // namespace Messages

View File

@ -63,6 +63,7 @@ namespace Online{
m_is_current_user = is_current_user;
m_username = username;
m_has_fetched_friends = false;
m_has_fetched_achievements = false;
m_relation_info = NULL;
m_is_friend = false;
}
@ -100,6 +101,7 @@ namespace Online{
xml->get("user_name", &m_username);
m_cache_bit = true;
m_has_fetched_friends = false;
m_has_fetched_achievements = false;
m_is_current_user = (m_id == CurrentUser::get()->getID());
m_state = S_READY;
}
@ -109,6 +111,52 @@ namespace Online{
delete m_relation_info;
}
// ============================================================================
void Profile::fetchAchievements()
{
assert(CurrentUser::get()->isRegisteredUser());
if(m_has_fetched_achievements || m_is_current_user)
return;
m_state = S_FETCHING;
requestAchievements();
}
// ============================================================================
void Profile::achievementsCallback(const XMLNode * input)
{
m_achievements.clear();
std::string achieved_string("");
if(input->get("achieved", &achieved_string) == 1)
{
m_achievements = StringUtils::splitToUInt(achieved_string, ' ');
}
m_has_fetched_achievements = true;
m_state = S_READY;
Log::info("test","tit");
}
// ============================================================================
void Profile::requestAchievements()
{
assert(CurrentUser::get()->isRegisteredUser() && !m_is_current_user);
AchievementsRequest * request = new AchievementsRequest();
request->setURL((std::string)UserConfigParams::m_server_multiplayer + "client-user.php");
request->setParameter("action",std::string("get-achievements"));
request->setParameter("token", CurrentUser::get()->getToken());
request->setParameter("userid", CurrentUser::get()->getID());
request->setParameter("visitingid", m_id);
HTTPManager::get()->addRequest(request);
}
void Profile::AchievementsRequest::callback()
{
uint32_t user_id(0);
m_result->get("visitingid", &user_id);
if( ProfileManager::get()->getProfileByID(user_id) != NULL )
ProfileManager::get()->getProfileByID(user_id)->achievementsCallback(m_result);
}
// ============================================================================
void Profile::fetchFriends()
{
@ -119,8 +167,6 @@ namespace Online{
requestFriendsList();
}
// ============================================================================
void Profile::friendsListCallback(const XMLNode * input)
{
const XMLNode * friends_xml = input->getNode("friends");
@ -144,11 +190,11 @@ namespace Online{
m_state = S_READY;
}
// ============================================================================
void Profile::requestFriendsList()
{
assert(CurrentUser::get()->isRegisteredUser());
FriendsListRequest * request = new FriendsListRequest();
request->setURL((std::string)UserConfigParams::m_server_multiplayer + "client-user.php");
request->setParameter("action",std::string("get-friends-list"));
@ -162,8 +208,8 @@ namespace Online{
{
uint32_t user_id(0);
m_result->get("visitingid", &user_id);
assert(ProfileManager::get()->getProfileByID(user_id) != NULL);
ProfileManager::get()->getProfileByID(user_id)->friendsListCallback(m_result);
if( ProfileManager::get()->getProfileByID(user_id) != NULL )
ProfileManager::get()->getProfileByID(user_id)->friendsListCallback(m_result);
}
// ============================================================================
@ -201,12 +247,17 @@ namespace Online{
}
// ============================================================================
const std::vector<uint32_t> & Profile::getFriends()
{
assert (m_has_fetched_friends && m_state == S_READY);
return m_friends;
}
// ============================================================================
const std::vector<uint32_t> & Profile::getAchievements()
{
assert (m_has_fetched_achievements && m_state == S_READY && !m_is_current_user);
return m_achievements;
}
} // namespace Online

View File

@ -66,6 +66,12 @@ namespace Online{
public:
FriendsListRequest() : XMLRequest(0, true) {}
};
class AchievementsRequest : public XMLRequest
{
virtual void callback ();
public:
AchievementsRequest() : XMLRequest(0, true) {}
};
typedef std::vector<uint32_t> IDList;
private:
@ -86,11 +92,17 @@ namespace Online{
bool m_has_fetched_friends;
std::vector<uint32_t> m_friends;
bool m_has_fetched_achievements;
std::vector<uint32_t> m_achievements;
bool m_cache_bit;
void requestFriendsList();
void friendsListCallback(const XMLNode * input);
void requestAchievements();
void achievementsCallback(const XMLNode * input);
public:
Profile( const uint32_t & userid,
const irr::core::stringw & username,
@ -100,6 +112,11 @@ namespace Online{
~Profile();
void fetchFriends();
const std::vector<uint32_t> & getFriends();
bool hasFetchedFriends() { return m_has_fetched_friends;}
void fetchAchievements();
const std::vector<uint32_t> & getAchievements();
bool hasFetchedAchievements() { return m_has_fetched_achievements;}
bool isFetching() const { return m_state == S_FETCHING; }
bool isReady() const { return m_state == S_READY; }

View File

@ -49,6 +49,7 @@ namespace Online{
ProfileManager::ProfileManager()
{
assert(m_max_cache_size > 1);
m_currently_visiting = NULL;
}
// ============================================================================
@ -58,7 +59,7 @@ namespace Online{
for ( it = m_profiles_persistent.begin(); it != m_profiles_persistent.end(); ++it ) {
delete it->second;
}
for ( it = m_profiles_cache.begin(); it != m_profiles_persistent.end(); ++it ) {
for ( it = m_profiles_cache.begin(); it != m_profiles_cache.end(); ++it ) {
delete it->second;
}
}
@ -224,6 +225,7 @@ namespace Online{
return m_profiles_persistent[id];
if(cacheHit(id))
return m_profiles_cache[id];
//FIXME not able to get! fetch it ourselves and put it in cache
return NULL;
}

View File

@ -106,6 +106,7 @@ namespace Online{
curl_easy_setopt(m_curl_session, CURLOPT_CAINFO, (file_manager->getDataDir() + "web.tuxfamily.org.pem").c_str());
curl_easy_setopt(m_curl_session, CURLOPT_SSL_VERIFYPEER, 0L);
//curl_easy_setopt(m_curl_session, CURLOPT_VERBOSE, 1L);
curl_easy_setopt(m_curl_session, CURLOPT_WRITEDATA, &m_string_buffer);
}
void HTTPRequest::operation()
@ -126,6 +127,7 @@ namespace Online{
postString.append(escaped);
curl_free(escaped);
}
Log::info( "HTTPRequest::operation", "Sending : %s", postString.c_str());
curl_easy_setopt(m_curl_session, CURLOPT_POSTFIELDS, postString.c_str());
std::string uagent( std::string("SuperTuxKart/") + STK_VERSION );
#ifdef WIN32
@ -224,7 +226,6 @@ namespace Online{
void XMLRequest::prepareOperation()
{
HTTPRequest::prepareOperation();
curl_easy_setopt(m_curl_session, CURLOPT_WRITEDATA, &m_string_buffer);
}

View File

@ -150,6 +150,7 @@ namespace Online{
Parameters * m_parameters;
CURL * m_curl_session;
CURLcode m_curl_code;
std::string m_string_buffer;
virtual void prepareOperation() OVERRIDE;
virtual void operation() OVERRIDE;
@ -201,9 +202,6 @@ namespace Online{
class XMLRequest : public HTTPRequest
{
private:
std::string m_string_buffer;
protected :
XMLNode * m_result;
irr::core::stringw m_info;

View File

@ -8,7 +8,7 @@
// 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 ofati
// 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.
//
@ -18,6 +18,7 @@
#include "physics/physics.hpp"
#include "achievements/achievements_manager.hpp"
#include "animations/three_d_animation.hpp"
#include "karts/abstract_kart.hpp"
#include "graphics/irr_driver.hpp"
@ -237,12 +238,12 @@ void Physics::update(float dt)
// Only explode a bowling ball if the target is
// not invulnerable
AbstractKart* target_kart = p->getUserPointer(1)->getPointerKart();
if(p->getUserPointer(0)->getPointerFlyable()->getType()
!=PowerupManager::POWERUP_BOWLING ||
!target_kart->isInvulnerable() )
PowerupManager::PowerupType type = p->getUserPointer(0)->getPointerFlyable()->getType();
if(type != PowerupManager::POWERUP_BOWLING || !target_kart->isInvulnerable())
{
p->getUserPointer(0)->getPointerFlyable()
->hit(target_kart);
p->getUserPointer(0)->getPointerFlyable()->hit(target_kart);
if ( type ==PowerupManager::POWERUP_BOWLING )
((SingleAchievement *) AchievementsManager::get()->getActive()->getAchievement(2))->increase(1);
}
}

View File

@ -59,7 +59,7 @@ void HighscoreManager::setFilename()
}
else
{
m_filename=file_manager->getHighscoreFile("highscore.xml");
m_filename=file_manager->getConfigFile("highscore.xml");
}
return;

View File

@ -0,0 +1,184 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2013 Glenn De Jonghe
//
// 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 "states_screens/dialogs/change_password_dialog.hpp"
#include <IGUIEnvironment.h>
#include "audio/sfx_manager.hpp"
#include "config/player.hpp"
#include "guiengine/engine.hpp"
#include "states_screens/state_manager.hpp"
#include "utils/translation.hpp"
#include "utils/string_utils.hpp"
#include "online/messages.hpp"
using namespace GUIEngine;
using namespace irr;
using namespace irr::gui;
using namespace Online;
// -----------------------------------------------------------------------------
ChangePasswordDialog::ChangePasswordDialog() :
ModalDialog(0.8f,0.7f)
{
m_self_destroy = false;
m_success = false;
loadFromFile("online/change_password.stkgui");
m_current_password_widget = getWidget<TextBoxWidget>("current_password");
assert(m_current_password_widget != NULL);
m_current_password_widget->setFocusForPlayer(PLAYER_ID_GAME_MASTER);
m_current_password_widget->setPasswordBox(true,L'*');
m_new_password1_widget = getWidget<TextBoxWidget>("new_password1");
assert(m_new_password1_widget != NULL);
m_new_password1_widget->setPasswordBox(true,L'*');
m_new_password2_widget = getWidget<TextBoxWidget>("new_password2");
assert(m_new_password2_widget != NULL);
m_new_password2_widget->setPasswordBox(true,L'*');
m_info_widget = getWidget<LabelWidget>("info");
assert(m_info_widget != NULL);
m_options_widget = getWidget<RibbonWidget>("options");
assert(m_options_widget != NULL);
m_submit_widget = getWidget<IconButtonWidget>("submit");
assert(m_submit_widget != NULL);
m_cancel_widget = getWidget<IconButtonWidget>("cancel");
assert(m_cancel_widget != NULL);
}
// -----------------------------------------------------------------------------
ChangePasswordDialog::~ChangePasswordDialog()
{
}
// -----------------------------------------------------------------------------
void ChangePasswordDialog::submit()
{
const stringw current_password = m_current_password_widget->getText().trim();
const stringw new_password1 = m_new_password1_widget->getText().trim();
const stringw new_password2 = m_new_password2_widget->getText().trim();
if (current_password.size() < 8 || current_password.size() > 30)
{
sfx_manager->quickSound("anvil");
m_info_widget->setErrorColor();
m_info_widget->setText(_("Current password invalid."), false);
}
else if (new_password1.size() < 8 || new_password1.size() > 30)
{
sfx_manager->quickSound("anvil");
m_info_widget->setErrorColor();
m_info_widget->setText(_("Password has to be between 8 and 30 characters long!"), false);
}
else if (new_password1 != new_password2)
{
sfx_manager->quickSound("anvil");
m_info_widget->setErrorColor();
m_info_widget->setText(_("Passwords don't match!"), false);
}
else
{
m_options_widget->setDeactivated();
m_info_widget->setDefaultColor();
Online::CurrentUser::get()->requestPasswordChange(current_password, new_password1, new_password2);
}
}
// -----------------------------------------------------------------------------
GUIEngine::EventPropagation ChangePasswordDialog::processEvent(const std::string& eventSource)
{
if (eventSource == m_options_widget->m_properties[PROP_ID])
{
const std::string& selection = m_options_widget->getSelectionIDString(PLAYER_ID_GAME_MASTER);
if (selection == m_cancel_widget->m_properties[PROP_ID])
{
m_self_destroy = true;
return GUIEngine::EVENT_BLOCK;
}
else if(selection == m_submit_widget->m_properties[PROP_ID])
{
submit();
return GUIEngine::EVENT_BLOCK;
}
}
return GUIEngine::EVENT_LET;
}
// -----------------------------------------------------------------------------
void ChangePasswordDialog::onEnterPressedInternal()
{
const int playerID = PLAYER_ID_GAME_MASTER;
if (GUIEngine::isFocusedForPlayer(m_options_widget, playerID))
return;
if (m_submit_widget->isActivated())
submit();
}
// -----------------------------------------------------------------------------
bool ChangePasswordDialog::onEscapePressed()
{
if (m_cancel_widget->isActivated())
m_self_destroy = true;
return false;
}
// -----------------------------------------------------------------------------
void ChangePasswordDialog::success()
{
m_info_widget->setDefaultColor();
m_info_widget->setText(_("Password successfully changed."), false);
m_options_widget->setActivated();
m_current_password_widget->setText("");
m_new_password1_widget->setText("");
m_new_password2_widget->setText("");
}
// -----------------------------------------------------------------------------
void ChangePasswordDialog::error(const irr::core::stringw & error)
{
sfx_manager->quickSound("anvil");
m_info_widget->setErrorColor();
m_info_widget->setText(error, false);
m_options_widget->setActivated();
m_current_password_widget->setText("");
m_new_password1_widget->setText("");
m_new_password2_widget->setText("");
}
// -----------------------------------------------------------------------------
void ChangePasswordDialog::onUpdate(float dt)
{
if(!m_options_widget->isActivated())
m_info_widget->setText(Online::Messages::validatingInfo(), false);
// It's unsafe to delete from inside the event handler so we do it here
if (m_self_destroy)
{
ModalDialog::dismiss();
}
}

View File

@ -0,0 +1,70 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2013 Glenn De Jonghe
//
// 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_CHANGE_PASSWORD_DIALOG_HPP
#define HEADER_CHANGE_PASSWORD_DIALOG_HPP
#include <irrString.h>
#include "online/current_user.hpp"
#include "guiengine/modaldialog.hpp"
#include "guiengine/widgets.hpp"
/**
* \brief Dialog that allows a user to sign in
* \ingroup states_screens
*/
class ChangePasswordDialog : public GUIEngine::ModalDialog
{
public:
/**
* Creates a modal dialog with given percentage of screen width and height
*/
ChangePasswordDialog();
~ChangePasswordDialog();
virtual void onEnterPressedInternal();
GUIEngine::EventPropagation processEvent(const std::string& eventSource);
virtual bool onEscapePressed();
virtual void onUpdate(float dt);
void success();
void error(const irr::core::stringw & error_message);
private:
bool m_self_destroy;
bool m_success;
GUIEngine::TextBoxWidget * m_current_password_widget;
GUIEngine::TextBoxWidget * m_new_password1_widget;
GUIEngine::TextBoxWidget * m_new_password2_widget;
GUIEngine::LabelWidget * m_info_widget;
GUIEngine::RibbonWidget * m_options_widget;
GUIEngine::IconButtonWidget * m_submit_widget;
GUIEngine::IconButtonWidget * m_cancel_widget;
void submit();
};
#endif

View File

@ -44,12 +44,13 @@ LoginDialog::LoginDialog(const Message message_type, const LoginDialog::Listener
m_open_registration_dialog = false;
m_open_recovery_dialog = false;
m_success = false;
m_sign_in_request = NULL;
loadFromFile("online/login_dialog.stkgui");
m_message_widget = getWidget<LabelWidget>("message");
assert(m_message_widget != NULL);
irr::core::stringw message;
irr::core::stringw message("");
if (message_type == Normal)
message = _("Fill in your username and password. ");
else if (message_type == Signing_In_Required)
@ -92,19 +93,14 @@ LoginDialog::LoginDialog(const Message message_type, const LoginDialog::Listener
m_as_guest_widget->setDeactivated();
m_cancel_widget = getWidget<IconButtonWidget>("cancel");
assert(m_cancel_widget != NULL);
}
// -----------------------------------------------------------------------------
LoginDialog::~LoginDialog()
{
delete m_sign_in_request;
}
// -----------------------------------------------------------------------------
void LoginDialog::login()
{
@ -119,7 +115,8 @@ void LoginDialog::login()
else
{
m_options_widget->setDeactivated();
m_sign_in_request = Online::CurrentUser::get()->requestSignIn(username,password, m_remember_widget->getState());
m_info_widget->setDefaultColor();
Online::CurrentUser::get()->requestSignIn(username,password, m_remember_widget->getState());
}
}
@ -158,8 +155,6 @@ GUIEngine::EventPropagation LoginDialog::processEvent(const std::string& eventSo
void LoginDialog::onEnterPressedInternal()
{
//If enter was pressed while none of the buttons was focused interpret as sign_in event
const int playerID = PLAYER_ID_GAME_MASTER;
if (GUIEngine::isFocusedForPlayer(m_options_widget, playerID))
return;
@ -176,47 +171,47 @@ bool LoginDialog::onEscapePressed()
return false;
}
// -----------------------------------------------------------------------------
void LoginDialog::success()
{
m_success = true;
}
// -----------------------------------------------------------------------------
void LoginDialog::error(const irr::core::stringw & error)
{
sfx_manager->quickSound("anvil");
m_info_widget->setErrorColor();
m_info_widget->setText(error, false);
m_options_widget->setActivated();
m_as_guest_widget->setDeactivated();
}
// -----------------------------------------------------------------------------
void LoginDialog::onUpdate(float dt)
{
if(m_sign_in_request != NULL)
{
if(m_sign_in_request->isDone())
{
if(m_sign_in_request->isSuccess())
{
m_success = true;
}
else
{
sfx_manager->quickSound( "anvil" );
m_info_widget->setErrorColor();
m_info_widget->setText(m_sign_in_request->getInfo(), false);
}
delete m_sign_in_request;
m_sign_in_request = NULL;
m_options_widget->setActivated();
}
else
{
m_info_widget->setDefaultColor();
m_info_widget->setText(Online::Messages::signingIn(), false);
}
}
if(!m_options_widget->isActivated())
m_info_widget->setText(Online::Messages::signingIn(), false);
//If we want to open another dialog, we need to close this one first
(m_open_registration_dialog || m_open_recovery_dialog || m_success) && (m_self_destroy = true);
m_self_destroy |= (m_open_registration_dialog || m_open_recovery_dialog || m_success);
bool open_registration_dialog = m_open_registration_dialog;
bool open_recovery_dialog = m_open_recovery_dialog;
bool success = m_success;
const LoginDialog::Listener *listener = m_listener;
// It's unsafe to delete from inside the event handler so we do it here
if (m_self_destroy)
{
ModalDialog::dismiss();
if (m_open_registration_dialog)
if (open_registration_dialog)
new RegistrationDialog();
else if (m_open_recovery_dialog)
else if (open_recovery_dialog)
new RecoveryDialog();
else if (m_success && (m_listener != NULL) )
m_listener->onSuccess();
else if (success && (listener != NULL) )
listener->onClose();
return;
}
}

View File

@ -37,9 +37,31 @@ public:
class Listener
{
public :
virtual void onSuccess() const = 0;
virtual void onClose() const = 0;
};
enum Message
{
Normal = 0, // If the user presses the sign in button himself
Signing_In_Required = 1, // If the user needs to be signed in
Registration_Required = 2 // If the user needs to be registered
};
/**
* Creates a modal dialog with given percentage of screen width and height
*/
LoginDialog(const Message = Normal, const LoginDialog::Listener * = NULL);
~LoginDialog();
virtual void onEnterPressedInternal();
void success();
void error(const irr::core::stringw & error_message);
GUIEngine::EventPropagation processEvent(const std::string& eventSource);
virtual bool onEscapePressed();
virtual void onUpdate(float dt);
private:
const Listener * m_listener;
@ -48,7 +70,7 @@ private:
bool m_open_registration_dialog;
bool m_open_recovery_dialog;
bool m_success;
const Online::CurrentUser::SignInRequest * m_sign_in_request;
GUIEngine::LabelWidget * m_message_widget;
GUIEngine::TextBoxWidget * m_username_widget;
GUIEngine::TextBoxWidget * m_password_widget;
@ -63,29 +85,6 @@ private:
GUIEngine::IconButtonWidget * m_cancel_widget;
void login();
public:
enum Message
{
Normal = 1, // If the user presses the sign in button himself
Signing_In_Required = 2, // If the user needs to be signed in
Registration_Required = 3 // If the user needs to be registered
};
/**
* Creates a modal dialog with given percentage of screen width and height
*/
LoginDialog(const Message, const LoginDialog::Listener * = NULL);
~LoginDialog();
void onEnterPressedInternal();
GUIEngine::EventPropagation processEvent(const std::string& eventSource);
virtual bool onEscapePressed();
virtual void onUpdate(float dt);
//virtual void onTextUpdated();
};
#endif

View File

@ -57,6 +57,14 @@ void NotificationDialog::beforeAddingWidgets()
assert(m_options_widget != NULL);
m_view_widget = getWidget<IconButtonWidget>("view");
assert(m_view_widget != NULL);
if(m_type == T_Friends)
{
m_view_widget->setText(_("View Friends"));
}
else if (m_type == T_Achievements)
{
m_view_widget->setText(_("View Achievements"));
}
m_cancel_widget = getWidget<IconButtonWidget>("cancel");
assert(m_cancel_widget != NULL);
m_options_widget->setFocusForPlayer(PLAYER_ID_GAME_MASTER);
@ -129,6 +137,10 @@ void NotificationDialog::onUpdate(float dt)
ProfileManager::get()->setVisiting(CurrentUser::get()->getID());
StateManager::get()->pushScreen(OnlineProfileFriends::getInstance());
}
else if (m_type == T_Achievements)
{
//FIXME
}
}
return;
}

View File

@ -36,7 +36,8 @@ class NotificationDialog : public GUIEngine::ModalDialog
public:
enum Type
{
T_Friends = 1
T_Friends = 1,
T_Achievements = 2
};
private:

View File

@ -177,7 +177,7 @@ void RecoveryDialog::onUpdate(float dt)
}
else
{
m_info_widget->setText(Messages::recovery(), false);
m_info_widget->setText(Messages::validatingInfo(), false);
}
}
// It's unsafe to delete from inside the event handler so we do it here

View File

@ -237,7 +237,7 @@ bool RegistrationDialog::processTermsEvent(const std::string& eventSource)
assert(m_accept_terms_widget->getState());
m_options_widget->setDeactivated();
m_info_widget->setDefaultColor();
m_info_widget->setText(Messages::signingUp(), false);
m_info_widget->setText(Messages::validatingInfo(), false);
m_sign_up_request = CurrentUser::get()->requestSignUp(m_username, m_password, m_password_confirm, m_email, true);
return true;
}
@ -333,7 +333,7 @@ void RegistrationDialog::onUpdate(float dt)
else
{
m_info_widget->setDefaultColor();
m_info_widget->setText(Messages::signingUp(), false);
m_info_widget->setText(Messages::validatingInfo(), false);
}
}
}

View File

@ -39,7 +39,7 @@ public :
const std::string m_addon_id;
public :
LoginListener(const std::string & addon_id) : m_addon_id(addon_id) {}
virtual void onSuccess() const { new VoteDialog(m_addon_id); }
virtual void onClose() const { new VoteDialog(m_addon_id); }
};
private:

View File

@ -0,0 +1,134 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2013 Glenn De Jonghe
//
// 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 "states_screens/online_profile_achievements.hpp"
#include "achievements/achievements_manager.hpp"
#include "guiengine/engine.hpp"
#include "guiengine/scalable_font.hpp"
#include "guiengine/screen.hpp"
#include "guiengine/widget.hpp"
#include "states_screens/dialogs/message_dialog.hpp"
#include "states_screens/state_manager.hpp"
#include "states_screens/dialogs/user_info_dialog.hpp"
#include "utils/translation.hpp"
#include "online/messages.hpp"
#include <IGUIButton.h>
#include <iostream>
#include <sstream>
using namespace GUIEngine;
using namespace irr::core;
using namespace irr::gui;
using namespace Online;
DEFINE_SCREEN_SINGLETON( OnlineProfileAchievements );
// -----------------------------------------------------------------------------
OnlineProfileAchievements::OnlineProfileAchievements() : OnlineProfileBase("online/profile_achievements.stkgui")
{
m_selected_achievement_index = -1;
} // OnlineProfileAchievements
// -----------------------------------------------------------------------------
void OnlineProfileAchievements::loadedFromFile()
{
OnlineProfileBase::loadedFromFile();
m_achievements_list_widget = getWidget<GUIEngine::ListWidget>("achievements_list");
assert(m_achievements_list_widget != NULL);
} // loadedFromFile
// ----------------------------------------------------------------------------
void OnlineProfileAchievements::beforeAddingWidget()
{
OnlineProfileBase::beforeAddingWidget();
m_achievements_list_widget->clearColumns();
m_achievements_list_widget->addColumn( _("Name"), 2 );
if(m_visiting_profile->isCurrentUser())
{
m_achievements_list_widget->addColumn( _("Progress"), 1 );
}
}
// -----------------------------------------------------------------------------
void OnlineProfileAchievements::init()
{
OnlineProfileBase::init();
m_profile_tabs->select( m_achievements_tab->m_properties[PROP_ID], PLAYER_ID_GAME_MASTER );
assert(m_visiting_profile != NULL);
if(m_visiting_profile->isCurrentUser())
{
m_waiting_for_achievements = false;
m_achievements_list_widget->clear();
const std::map<uint32_t, Achievement *> & all_achievements = AchievementsManager::get()->getActive()->getAllAchievements();
std::map<uint32_t, Achievement *>::const_iterator it;
for ( it = all_achievements.begin(); it != all_achievements.end(); ++it ) {
PtrVector<GUIEngine::ListWidget::ListCell> * row = new PtrVector<GUIEngine::ListWidget::ListCell>;
row->push_back(new GUIEngine::ListWidget::ListCell(it->second->getInfo()->getTitle(),-1,2));
row->push_back(new GUIEngine::ListWidget::ListCell(it->second->getProgressAsString(),-1,1, true));
m_achievements_list_widget->addItem(StringUtils::toString(it->second->getInfo()->getID()), row);
}
}
else
{
m_waiting_for_achievements = true;
m_visiting_profile->fetchAchievements();
m_achievements_list_widget->clear();
m_achievements_list_widget->addItem("loading", Messages::fetchingAchievements());
}
} // init
// -----------------------------------------------------------------------------
void OnlineProfileAchievements::eventCallback(Widget* widget, const std::string& name, const int playerID)
{
OnlineProfileBase::eventCallback( widget, name, playerID);
if (name == m_achievements_list_widget->m_properties[GUIEngine::PROP_ID])
{
m_selected_achievement_index = m_achievements_list_widget->getSelectionID();
new MessageDialog(AchievementsManager::get()->getAchievementInfo(atoi(m_achievements_list_widget->getSelectionInternalName().c_str()))->getDescription());
}
} // eventCallback
// ----------------------------------------------------------------------------
void OnlineProfileAchievements::onUpdate(float delta, irr::video::IVideoDriver* driver)
{
if(m_waiting_for_achievements)
{
if(m_visiting_profile->isReady())
{
m_achievements_list_widget->clear();
for(unsigned int i = 0; i < m_visiting_profile->getAchievements().size(); i++)
{
AchievementInfo * info = AchievementsManager::get()->getAchievementInfo(m_visiting_profile->getAchievements()[i]);
m_achievements_list_widget->addItem(StringUtils::toString(info->getID()), info->getTitle());
}
m_waiting_for_achievements = false;
}
else
{
m_achievements_list_widget->renameItem("loading", Messages::fetchingFriends());
}
}
}

View File

@ -0,0 +1,67 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2013 Glenn De Jonghe
//
// 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_ONLINE_PROFILE_ACHIEVEMENTS_HPP__
#define __HEADER_ONLINE_PROFILE_ACHIEVEMENTS_HPP__
#include <string>
#include <irrString.h>
#include "guiengine/screen.hpp"
#include "guiengine/widgets.hpp"
#include "states_screens/online_profile_base.hpp"
#include "online/profile_manager.hpp"
namespace GUIEngine { class Widget; }
/**
* \brief Online profiel overview screen
* \ingroup states_screens
*/
class OnlineProfileAchievements : public OnlineProfileBase, public GUIEngine::ScreenSingleton<OnlineProfileAchievements>
{
private:
OnlineProfileAchievements();
GUIEngine::ListWidget * m_achievements_list_widget;
int m_selected_achievement_index;
bool m_waiting_for_achievements;
public:
friend class GUIEngine::ScreenSingleton<OnlineProfileAchievements>;
/** \brief implement callback from parent class GUIEngine::Screen */
virtual void loadedFromFile() OVERRIDE;
/** \brief implement callback from parent class GUIEngine::Screen */
virtual void eventCallback(GUIEngine::Widget* widget, const std::string& name, const int playerID) OVERRIDE;
/** \brief implement callback from parent class GUIEngine::Screen */
virtual void init() OVERRIDE;
virtual void onUpdate(float delta, irr::video::IVideoDriver* driver) OVERRIDE;
virtual void beforeAddingWidget() OVERRIDE;
virtual void refreshAchievementsList() { m_waiting_for_achievements = true; }
};
#endif

View File

@ -25,6 +25,8 @@
#include "utils/translation.hpp"
#include "states_screens/online_profile_overview.hpp"
#include "states_screens/online_profile_friends.hpp"
#include "states_screens/online_profile_achievements.hpp"
#include "states_screens/online_profile_settings.hpp"
#include <iostream>
#include <sstream>
@ -52,23 +54,37 @@ void OnlineProfileBase::loadedFromFile()
assert(m_overview_tab != NULL);
m_friends_tab = (IconButtonWidget *) m_profile_tabs->findWidgetNamed("tab_friends");
assert(m_friends_tab != NULL);
m_achievements_tab = (IconButtonWidget *) m_profile_tabs->findWidgetNamed("tab_achievements");
assert(m_achievements_tab != NULL);
m_settings_tab = (IconButtonWidget *) m_profile_tabs->findWidgetNamed("tab_settings");
assert(m_settings_tab != NULL);
} // loadedFromFile
// -----------------------------------------------------------------------------
void OnlineProfileBase::beforeAddingWidget()
{
m_visiting_profile = ProfileManager::get()->getVisitingProfile();
if (!m_visiting_profile->isCurrentUser())
m_settings_tab->setVisible(false);
}
// -----------------------------------------------------------------------------
void OnlineProfileBase::init()
{
Screen::init();
m_overview_tab->setTooltip( _("Overview") );
m_friends_tab->setTooltip( _("Friends") );
m_achievements_tab->setTooltip( _("Achievements") );
m_settings_tab->setTooltip( _("Account Settings") );
m_visiting_profile = ProfileManager::get()->getVisitingProfile();
if (m_visiting_profile->isCurrentUser())
m_header->setText(_("Your profile"), false);
else
{
m_header->setText( m_visiting_profile->getUserName() + _("'s profile"), false);
}
} // init
@ -82,6 +98,8 @@ void OnlineProfileBase::eventCallback(Widget* widget, const std::string& name, c
if (selection == m_overview_tab->m_properties[PROP_ID]) StateManager::get()->replaceTopMostScreen(OnlineProfileOverview::getInstance());
else if (selection == m_friends_tab->m_properties[PROP_ID]) StateManager::get()->replaceTopMostScreen(OnlineProfileFriends::getInstance());
else if (selection == m_achievements_tab->m_properties[PROP_ID]) StateManager::get()->replaceTopMostScreen(OnlineProfileAchievements::getInstance());
else if (selection == m_settings_tab->m_properties[PROP_ID]) StateManager::get()->replaceTopMostScreen(OnlineProfileSettings::getInstance());
}
else if (name == "back")
{

View File

@ -24,13 +24,13 @@
#include "guiengine/screen.hpp"
#include "guiengine/widgets.hpp"
#include "online/profile.hpp"
#include "online/profile_manager.hpp"
namespace GUIEngine { class Widget; }
/**
* \brief Online profiel overview screen
* \brief Online profile base screen
* \ingroup states_screens
*/
class OnlineProfileBase : public GUIEngine::Screen
@ -41,6 +41,8 @@ protected:
GUIEngine::RibbonWidget* m_profile_tabs;
GUIEngine::IconButtonWidget * m_overview_tab;
GUIEngine::IconButtonWidget * m_friends_tab;
GUIEngine::IconButtonWidget * m_achievements_tab;
GUIEngine::IconButtonWidget * m_settings_tab;
Online::Profile * m_visiting_profile;
@ -54,6 +56,8 @@ public:
/** \brief implement callback from parent class GUIEngine::Screen */
virtual void init() OVERRIDE;
virtual void beforeAddingWidget() OVERRIDE;
};
#endif

View File

@ -44,7 +44,6 @@ DEFINE_SCREEN_SINGLETON( OnlineProfileFriends );
OnlineProfileFriends::OnlineProfileFriends() : OnlineProfileBase("online/profile_friends.stkgui")
{
m_selected_friend_index = -1;
m_own_profile = true;
} // OnlineProfileFriends
// -----------------------------------------------------------------------------
@ -65,9 +64,10 @@ void OnlineProfileFriends::loadedFromFile()
void OnlineProfileFriends::beforeAddingWidget()
{
OnlineProfileBase::beforeAddingWidget();
m_friends_list_widget->clearColumns();
m_friends_list_widget->addColumn( _("Username"), 2 );
if(m_own_profile)
if(m_visiting_profile->isCurrentUser())
{
m_friends_list_widget->addColumn( _("Since"), 1 );
m_friends_list_widget->addColumn( _("Status"), 2 );
@ -79,12 +79,6 @@ void OnlineProfileFriends::beforeAddingWidget()
void OnlineProfileFriends::init()
{
OnlineProfileBase::init();
if(m_own_profile != m_visiting_profile->isCurrentUser())
{
m_own_profile = m_visiting_profile->isCurrentUser();
GUIEngine::reshowCurrentScreen();
return;
}
m_profile_tabs->select( m_friends_tab->m_properties[PROP_ID], PLAYER_ID_GAME_MASTER );
assert(m_visiting_profile != NULL);
m_visiting_profile->fetchFriends();

View File

@ -46,8 +46,6 @@ private:
int m_selected_friend_index;
bool m_waiting_for_friends;
bool m_own_profile;
bool m_refresh_screen;
public:
friend class GUIEngine::ScreenSingleton<OnlineProfileFriends>;

View File

@ -0,0 +1,73 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2010 Glenn De Jonghe
//
// 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 "states_screens/online_profile_settings.hpp"
#include "guiengine/engine.hpp"
#include "guiengine/scalable_font.hpp"
#include "guiengine/screen.hpp"
#include "guiengine/widget.hpp"
#include "states_screens/state_manager.hpp"
#include "states_screens/dialogs/change_password_dialog.hpp"
#include "utils/translation.hpp"
#include <IGUIButton.h>
#include <iostream>
#include <sstream>
using namespace GUIEngine;
using namespace irr::core;
using namespace irr::gui;
using namespace Online;
DEFINE_SCREEN_SINGLETON( OnlineProfileSettings );
// -----------------------------------------------------------------------------
OnlineProfileSettings::OnlineProfileSettings() : OnlineProfileBase("online/profile_settings.stkgui")
{
} // OnlineProfileSettings
// -----------------------------------------------------------------------------
void OnlineProfileSettings::loadedFromFile()
{
OnlineProfileBase::loadedFromFile();
m_change_password_button = this->getWidget<ButtonWidget>("change_password_button");
assert(m_change_password_button != NULL);
} // loadedFromFile
// -----------------------------------------------------------------------------
void OnlineProfileSettings::init()
{
OnlineProfileBase::init();
m_profile_tabs->select( m_settings_tab->m_properties[PROP_ID], PLAYER_ID_GAME_MASTER );
} // init
// -----------------------------------------------------------------------------
void OnlineProfileSettings::eventCallback(Widget* widget, const std::string& name, const int playerID)
{
OnlineProfileBase::eventCallback( widget, name, playerID);
if (name == m_change_password_button->m_properties[GUIEngine::PROP_ID])
{
new ChangePasswordDialog();
}
} // eventCallback

View File

@ -0,0 +1,56 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2013 Glenn De Jonghe
//
// 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_ONLINE_PROFILE_SETTINGS_HPP__
#define __HEADER_ONLINE_PROFILE_SETTINGS_HPP__
#include <string>
#include <irrString.h>
#include "guiengine/screen.hpp"
#include "guiengine/widgets.hpp"
#include "states_screens/online_profile_base.hpp"
namespace GUIEngine { class Widget; }
/**
* \brief Online profiel overview screen
* \ingroup states_screens
*/
class OnlineProfileSettings : public OnlineProfileBase, public GUIEngine::ScreenSingleton<OnlineProfileSettings>
{
protected:
OnlineProfileSettings();
GUIEngine::ButtonWidget * m_change_password_button;
public:
friend class GUIEngine::ScreenSingleton<OnlineProfileSettings>;
/** \brief implement callback from parent class GUIEngine::Screen */
virtual void loadedFromFile() OVERRIDE;
/** \brief implement callback from parent class GUIEngine::Screen */
virtual void eventCallback(GUIEngine::Widget* widget, const std::string& name,
const int playerID) OVERRIDE;
/** \brief implement callback from parent class GUIEngine::Screen */
virtual void init() OVERRIDE;
};
#endif

View File

@ -72,7 +72,9 @@ OnlineScreen::~OnlineScreen()
void OnlineScreen::loadedFromFile()
{
//Box ? FIXME
m_back_widget = getWidget<IconButtonWidget>("back");
assert(m_back_widget != NULL);
m_top_menu_widget = getWidget<RibbonWidget>("menu_toprow");
assert(m_top_menu_widget != NULL);
m_quick_play_widget = (IconButtonWidget *) m_top_menu_widget->findWidgetNamed("quick_play");
@ -152,14 +154,17 @@ void OnlineScreen::init()
setInitialFocus();
DemoWorld::resetIdleTime();
m_online_status_widget->setText(Messages::signedInAs(CurrentUser::get()->getUserName()), false);
} // init
// ----------------------------------------------------------------------------
void OnlineScreen::onUpdate(float delta, irr::video::IVideoDriver* driver)
{
if (hasStateChanged())
{
GUIEngine::reshowCurrentScreen();
return;
}
if (m_recorded_state == CurrentUser::US_SIGNING_IN)
{
m_online_status_widget->setText(Messages::signingIn(), false);
@ -174,7 +179,7 @@ void OnlineScreen::onUpdate(float delta, irr::video::IVideoDriver* driver)
void OnlineScreen::eventCallback(Widget* widget, const std::string& name, const int playerID)
{
if (name == "back")
if (name == m_back_widget->m_properties[PROP_ID])
{
StateManager::get()->escapePressed();
return;

View File

@ -40,6 +40,8 @@ private:
OnlineScreen();
~OnlineScreen();
GUIEngine::IconButtonWidget * m_back_widget;
GUIEngine::RibbonWidget * m_top_menu_widget;
GUIEngine::IconButtonWidget * m_quick_play_widget;
GUIEngine::IconButtonWidget * m_find_server_widget;

View File

@ -263,6 +263,18 @@ namespace StringUtils
} // split
std::vector<uint32_t> splitToUInt(const std::string& s, char c, bool keepSplitChar)
{
std::vector<std::string> parts = split(s, c, keepSplitChar);
std::vector<uint32_t> ints;
for(unsigned int i = 0; i < parts.size(); ++i)
{
ints.push_back(atoi(parts[i].c_str()));
}
return ints;
}
// ------------------------------------------------------------------------
/** Splits a : separated string (like PATH) into its individual components.
* It especially handles Windows-style paths (c:/mydir1:d:/mydir2)
@ -709,6 +721,11 @@ namespace StringUtils
printf("Invalid version string '%s'.\n", s.c_str());
return version;
} // versionToInt
const char* boolstr(bool b)
{
return (b ? "true" : "false");
}
} // namespace StringUtils

View File

@ -24,6 +24,7 @@
#include <vector>
#include <sstream>
#include <irrString.h>
#include "utils/types.hpp"
namespace StringUtils
{
@ -92,7 +93,9 @@ namespace StringUtils
bool keepSplitChar=false);
std::vector<irr::core::stringw> split(const irr::core::stringw& s,
char c, bool keepSplitChar=false);
std::vector<std::string> splitPath(const std::string& path);
std::vector<uint32_t> splitToUInt(const std::string& s, char c,
bool keepSplitChar=false);
std::vector<std::string> splitPath(const std::string& path);
// ------------------------------------------------------------------------
/**
@ -413,6 +416,8 @@ namespace StringUtils
/** Compute a simple hash of a string */
unsigned int simpleHash(const char* input);
const char* boolstr(bool b);
} // namespace StringUtils
#endif