1 //
2 //  SuperTuxKart - a fun racing game with go-kart
3 //  Copyright (C) 2010-2015 Joerg Henrichs
4 //
5 //  This program is free software; you can redistribute it and/or
6 //  modify it under the terms of the GNU General Public License
7 //  as published by the Free Software Foundation; either version 3
8 //  of the License, or (at your option) any later version.
9 //
10 //  This program is distributed in the hope that it will be useful,
11 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 //  GNU General Public License for more details.
14 //
15 //  You should have received a copy of the GNU General Public License
16 //  along with this program; if not, write to the Free Software
17 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18 
19 #ifndef HEADER_PLAYER_MANAGER_HPP
20 #define HEADER_PLAYER_MANAGER_HPP
21 
22 #include "achievements/achievement.hpp"
23 #include "achievements/achievements_status.hpp"
24 #include "config/player_profile.hpp"
25 #include "utils/no_copy.hpp"
26 #include "utils/ptr_vector.hpp"
27 
28 #include <irrString.h>
29 
30 #include <cstddef>  // NULL
31 #include <memory>
32 
33 class AchievementsStatus;
34 
35 namespace Online
36 {
37     class CurrentUser;
38     class HTTPRequest;
39     class OnlineProfile;
40     class XMLRequest;
41 }
42 class PlayerProfile;
43 
44 /** A special class that manages all local player accounts. It reads all player
45  *  accounts from the players.xml file in the user config directory. For each
46  *  player an instance of PlayerProfile is created, which keeps track of
47  *  story mode progress, achievements and other data. It also keeps track of
48  *  the currently logged in player.
49  *  It includes several handy static functions which avoid long call
50  *  sequences, e.g.:
51  *    PlayerManager::getCurrentOnlineId()
52  *  which is just:
53  *    PlayerManager::get()->getCurrentUser()->getID();
54  */
55 class PlayerManager : public NoCopy
56 {
57 private:
58     static PlayerManager* m_player_manager;
59 
60     PtrVector<PlayerProfile> m_all_players;
61 
62     /** A pointer to the current player. */
63     PlayerProfile* m_current_player;
64 
65     /** Saves the XML tree from players.xml for use in the 2nd
66      * loading stage (initRemainingData). */
67     const XMLNode *m_player_data;
68 
69     void load();
70      PlayerManager();
71     ~PlayerManager();
72 
73 
74 public:
75     static void create();
76     // ------------------------------------------------------------------------
77     /** Static singleton get function. */
get()78     static PlayerManager* get()
79     {
80         assert(m_player_manager);
81         return m_player_manager;
82     }   // get
83     // ------------------------------------------------------------------------
destroy()84     static void destroy()
85     {
86         delete m_player_manager;
87         m_player_manager = NULL;
88     }   // destroy
89 
90     void save();
91     void initRemainingData();
92     unsigned int getUniqueId() const;
93     void addDefaultPlayer();
94     PlayerProfile* addNewPlayer(const irr::core::stringw& name);
95     void createGuestPlayers(int n);
96     void deletePlayer(PlayerProfile *player);
97     void setCurrentPlayer(PlayerProfile *player);
98     const PlayerProfile *getPlayerById(unsigned int id);
99     void enforceCurrentPlayer();
100     unsigned int getNumNonGuestPlayers() const;
101     static void setUserDetails(std::shared_ptr<Online::HTTPRequest> request,
102                                const std::string &action,
103                                const std::string &php_name = "");
104     static unsigned int getCurrentOnlineId();
105     static bool isCurrentLoggedIn();
106     static Online::OnlineProfile* getCurrentOnlineProfile();
107 
108     static PlayerProfile::OnlineState getCurrentOnlineState();
109     static void requestOnlinePoll();
110     static void resumeSavedSession();
111     static void onSTKQuit();
112     static void requestSignOut();
113     static void requestSignIn(const irr::core::stringw &username,
114                               const irr::core::stringw &password);
115 
116     // ------------------------------------------------------------------------
117     /** Returns the current player. */
getCurrentPlayer()118     static PlayerProfile* getCurrentPlayer()
119     {
120         return get()->m_current_player;
121     }   // getCurrentPlayer
122 
123     // ------------------------------------------------------------------------
124     PlayerProfile *getPlayer(const irr::core::stringw &name);
125     // ------------------------------------------------------------------------
126     /** Returns the number of players in the config file.*/
getNumPlayers() const127     unsigned int getNumPlayers() const { return m_all_players.size(); }
128     // ------------------------------------------------------------------------
129     /** Returns a player with a given unique id. */
getPlayer(unsigned int n) const130     const PlayerProfile *getPlayer(unsigned int n) const
131     {
132         return &m_all_players[n];
133     }   // getPlayer
134     // ------------------------------------------------------------------------
135     /** Returns a player with a given unique id. */
getPlayer(unsigned int n)136     PlayerProfile *getPlayer(unsigned int n)  { return &m_all_players[n];}
137     // ------------------------------------------------------------------------
138     /** A handy shortcut funtion. */
getCurrentAchievementsStatus()139     static AchievementsStatus* getCurrentAchievementsStatus()
140     {
141         return PlayerManager::getCurrentPlayer()->getAchievementsStatus();
142     }   // getCurrentAchievementsStatus
143 
144     // ------------------------------------------------------------------------
145     /** A handy shortcut to increase points for an achievement data of the
146      *  current player.
147      *  \param achievement_data_id The achievement data id
148      *  \param increase How much to increase the current value.
149      */
increaseAchievement(unsigned int achievement_data_id,int increase=1)150     static void increaseAchievement(unsigned int achievement_data_id,
151                                     int increase = 1)
152     {
153         getCurrentAchievementsStatus()
154             ->increaseDataVar(achievement_data_id, increase);
155     }   // increaseAchievement
156 
157     // ------------------------------------------------------------------------
158     /** Reset an achievement data for current player.
159      *  \param achievement_data_id The achievement data id
160      */
resetAchievementData(unsigned int achievement_data_id)161     static void resetAchievementData(unsigned int achievement_data_id)
162     {
163         getCurrentAchievementsStatus()
164             ->resetDataVar(achievement_data_id);
165     }   // resetAchievementData
166 
167     // ------------------------------------------------------------------------
168     /** Reset achievements which have to be done in one race
169      *  \param restart - if the race has been restarted
170      */
onRaceEnd(bool restart)171     static void onRaceEnd(bool restart)
172     {
173         getCurrentAchievementsStatus()->onRaceEnd(restart);
174     }   // onRaceEnd
175 
176 
177     // ----------------------------------------------------------------------------
178     /** Transmit an incrementation request of one of the track event counters
179      *  \param track_ident - the internal name of the track
180      *  \param event - the type of counter to increment */
trackEvent(std::string track_ident,AchievementsStatus::TrackData event)181     static void trackEvent(std::string track_ident, AchievementsStatus::TrackData event)
182     {
183         getCurrentAchievementsStatus()->trackEvent(track_ident, event);
184     } // trackEvent
185 
186     // ----------------------------------------------------------------------------
resetKartHits(int num_karts)187     static void resetKartHits(int num_karts)
188     {
189         getCurrentAchievementsStatus()->resetKartHits(num_karts);
190     } // resetKartHits
191 
192     // ----------------------------------------------------------------------------
addKartHit(int kart_id)193     static void addKartHit(int kart_id)
194     {
195         getCurrentAchievementsStatus()->addKartHit(kart_id);
196     } // addKartHit
197 
198     // ------------------------------------------------------------------------
199 };   // PlayerManager
200 #endif
201