Moved saved session data from UserConfig to PlayerProfile - which

means that now each player can individually save an online session.
This commit is contained in:
hiker 2014-04-09 08:33:42 +10:00
parent de697f26c8
commit 25c96d88ec
8 changed files with 145 additions and 50 deletions

View File

@ -71,32 +71,48 @@ void PlayerManager::load()
{
std::string filename = file_manager->getUserConfigFile("players.xml");
const XMLNode *players = file_manager->createXMLTree(filename);
if(!players)
m_player_data = file_manager->createXMLTree(filename);
if(!m_player_data)
{
Log::info("player_manager", "A new players.xml file will be created.");
return;
}
else if(players->getName()!="players")
else if(m_player_data->getName()!="players")
{
Log::info("player_manager", "The players.xml file is invalid.");
return;
}
m_current_player = NULL;
for(unsigned int i=0; i<players->getNumNodes(); i++)
for(unsigned int i=0; i<m_player_data->getNumNodes(); i++)
{
const XMLNode *player_xml = players->getNode(i);
const XMLNode *player_xml = m_player_data->getNode(i);
PlayerProfile *player = new PlayerProfile(player_xml);
m_all_players.push_back(player);
if(player->isDefault())
m_current_player = player;
}
m_all_players.insertionSort(/*start*/0, /*desc*/true);
delete players;
} // load
// ----------------------------------------------------------------------------
/** The 2nd loading stage. During this stage achievements and story mode
* data is read for each player.
*/
void PlayerManager::loadRemainingData()
{
for (unsigned int i = 0; i<m_player_data->getNumNodes(); i++)
{
const XMLNode *player_xml = m_player_data->getNode(i);
m_all_players[i].loadRemainingData(player_xml);
}
delete m_player_data;
m_player_data = NULL;
// Sort player by frequency
m_all_players.insertionSort(/*start*/0, /*desc*/true);
} // loadRemainingData
// ----------------------------------------------------------------------------
/** Saves all player profiles to players.xml.
*/

View File

@ -48,6 +48,10 @@ private:
/** A pointer to the current player. */
PlayerProfile* m_current_player;
/** Saves the XML tree from players.xml for use in the 2nd
* loading stage (loadRemainingData). */
const XMLNode *m_player_data;
void load();
PlayerManager();
~PlayerManager();
@ -72,6 +76,7 @@ public:
// ------------------------------------------------------------------------
void save();
void loadRemainingData();
unsigned int getUniqueId() const;
void addDefaultPlayer();
void addNewPlayer(const irr::core::stringw& name);

View File

@ -50,26 +50,52 @@ PlayerProfile::PlayerProfile(const core::stringw& name, bool is_guest)
} // PlayerProfile
//------------------------------------------------------------------------------
/** Constructor to deserialize a player that was saved to a XML file.
/** Constructor to deserialize player data that was saved to a XML file. The
* constructor will only load the main player data (like name, id, saved
* online data), but not the achievements and story mode data. Reason is
* that the achievement and story mode data depends on other data to be
* read first (challenges and achievement files), which in turn can only be
* created later in the startup process (they depend on e.g. all tracks to
* be known). On the other hand, automatic login needs to happen asap
* (i.e. as soon as the network thread is started), which needs the main
* player data (i.e. the default player, and saved session data). So the
* constructor only reads this data, the rest of the player data is handled
* in loadRemainingData later in the initialisation process.
* \param node The XML node representing this player.
*/
PlayerProfile::PlayerProfile(const XMLNode* node)
{
m_saved_session = false;
m_saved_token = "";
m_saved_user_id = 0;
m_story_mode_status = NULL;
m_achievements_status = NULL;
node->get("name", &m_name );
node->get("guest", &m_is_guest_account);
node->get("use-frequency", &m_use_frequency );
node->get("unique-id", &m_unique_id );
node->get("is-default", &m_is_default );
node->get("saved-session", &m_saved_session );
node->get("saved-user", &m_saved_user_id );
node->get("saved-token", &m_saved_token );
#ifdef DEBUG
m_magic_number = 0xABCD1234;
#endif
} // PlayerProfile
//------------------------------------------------------------------------------
/** This function loads the achievement and story mode data. This
*/
void PlayerProfile::loadRemainingData(const XMLNode *node)
{
const XMLNode *xml_story_mode = node->getNode("story-mode");
m_story_mode_status = unlock_manager->createStoryModeStatus(xml_story_mode);
const XMLNode *xml_achievements = node->getNode("achievements");
m_achievements_status = AchievementsManager::get()
->createAchievementsStatus(xml_achievements);
} // PlayerProfile
->createAchievementsStatus(xml_achievements);
} // loadRemainingData
//------------------------------------------------------------------------------
/** Writes the data for this player to the specified UTFWriter.
@ -79,9 +105,15 @@ void PlayerProfile::save(UTFWriter &out)
{
out << L" <player name=\"" << m_name
<< L"\" guest=\"" << m_is_guest_account
<< L"\" use-frequency=\"" << m_use_frequency
<< L"\" is-default=\"" << m_is_default
<< L"\" unique-id=\"" << m_unique_id << L"\">\n";
<< L"\" use-frequency=\"" << m_use_frequency << L"\"\n";
out << L" is-default=\"" << m_is_default
<< L"\" unique-id=\"" << m_unique_id
<< L"\" saved-session=\"" << m_saved_session << L"\"\n";
out << L" saved-user=\"" << m_saved_user_id
<< L"\" saved-token=\"" << m_saved_token << L"\">\n";
{
assert(m_story_mode_status);
m_story_mode_status->save(out);
@ -92,6 +124,31 @@ void PlayerProfile::save(UTFWriter &out)
out << L" </player>\n";
} // save
//------------------------------------------------------------------------------
// ------------------------------------------------------------------------
/** Saves the online data, so that it will automatically re-connect
* next time this profile is loaded.
* \param user_id Id of the online profile.
* \param token Token used for authentication.
*/
void PlayerProfile::saveSession(int user_id, const std::string &token)
{
m_saved_session = true;
m_saved_user_id = user_id;
m_saved_token = token;
PlayerManager::get()->save();
} // saveSession
// ------------------------------------------------------------------------
/** Unsets any saved session data. */
void PlayerProfile::clearSession()
{
m_saved_session = false;
m_saved_user_id = 0;
m_saved_token = "";
PlayerManager::get()->save();
} // clearSession
//------------------------------------------------------------------------------
/** Increments how often that account was used. Guest accounts are not counted.
*/

View File

@ -62,6 +62,15 @@ private:
/** True if this is the default (last used) player. */
bool m_is_default;
/** True if this user has a saved session. */
bool m_saved_session;
/** If a session was saved, this will be the online user id to use. */
int m_saved_user_id;
/** The token of the saved session. */
std::string m_saved_token;
/** The complete challenge state. */
StoryModeStatus *m_story_mode_status;
@ -69,15 +78,18 @@ private:
public:
PlayerProfile(const core::stringw& name, bool is_guest = false);
PlayerProfile(const core::stringw &name, bool is_guest = false);
PlayerProfile(const XMLNode* node);
PlayerProfile(const XMLNode *node);
void save(UTFWriter &out);
void loadRemainingData(const XMLNode *node);
void incrementUseFrequency();
bool operator<(const PlayerProfile &other);
bool operator>(const PlayerProfile &other);
void raceFinished();
void saveSession(int user_id, const std::string &token);
void clearSession();
// ------------------------------------------------------------------------
~PlayerProfile()
@ -190,7 +202,24 @@ public:
{
return m_achievements_status;
} // getAchievementsStatus
// ------------------------------------------------------------------------
/** Returns true if a session was saved for this player. */
bool hasSavedSession() const { return m_saved_session; }
// ------------------------------------------------------------------------
/** If a session was saved, return the id of the saved user. */
int getSavedUserId() const
{
assert(m_saved_session);
return m_saved_user_id;
} // getSavedUserId
// ------------------------------------------------------------------------
/** If a session was saved, return the token to use. */
const std::string& getSavedToken() const
{
assert(m_saved_session);
return m_saved_token;
} // getSavedToken
// ------------------------------------------------------------------------
}; // class PlayerProfile
#endif

View File

@ -669,25 +669,6 @@ namespace UserConfigParams
&m_online_group,
"The server used for online multiplayer."));
PARAM_PREFIX BoolUserConfigParam m_saved_session
PARAM_DEFAULT( BoolUserConfigParam( false,
"saved_session",
&m_online_group,
"Is there a saved session?") );
PARAM_PREFIX IntUserConfigParam m_saved_user
PARAM_DEFAULT( IntUserConfigParam( 0,
"saved_user",
&m_online_group,
"User ID of the saved session.") );
PARAM_PREFIX StringUserConfigParam m_saved_token
PARAM_DEFAULT( StringUserConfigParam( "",
"saved_token",
&m_online_group,
"Token of the saved session.") );
// ---- Addon server related entries
PARAM_PREFIX GroupUserConfigParam m_addon_group
PARAM_DEFAULT( GroupUserConfigParam("AddonAndNews",

View File

@ -1030,6 +1030,11 @@ void initRest()
addons_manager = new AddonsManager();
Online::ProfileManager::create();
// The request manager will start the login process in case of a saved
// session, so we need to read the main data from the players.xml file.
// The rest will be read later (since the rest needs the unlock- and
// achievement managers to be created, which can only be created later).
PlayerManager::create();
Online::RequestManager::get()->startNetworkThread();
NewsManager::get(); // this will create the news manager
@ -1165,13 +1170,15 @@ int main(int argc, char *argv[] )
handleXmasMode();
// Needs the kart and track directories to load potential challenges
// in those dirs.
// in those dirs, so it can only be created after reading tracks
// and karts.
unlock_manager = new UnlockManager();
AchievementsManager::create();
// Needs the unlock manager to initialise the game slots of all players
// and the AchievementsManager to initialise the AchievementsStatus.
PlayerManager::create();
// Reading the rest of the player data needs the unlock manager to
// initialise the game slots of all players and the AchievementsManager
// to initialise the AchievementsStatus, so it is done only now.
PlayerManager::get()->loadRemainingData();
GUIEngine::addLoadingIcon( irr_driver->getTexture(FileManager::GUI,
"gui_lock.png" ) );

View File

@ -97,14 +97,14 @@ namespace Online
void CurrentUser::requestSavedSession()
{
SignInRequest * request = NULL;
if(m_state == US_SIGNED_OUT && UserConfigParams::m_saved_session)
const PlayerProfile *cp = PlayerManager::getCurrentPlayer();
if (m_state == US_SIGNED_OUT && cp->hasSavedSession() )
{
request = new SignInRequest(true);
request->setServerURL("client-user.php");
request->addParameter("action","saved-session");
request->addParameter("userid", UserConfigParams::m_saved_user);
request->addParameter("token",
UserConfigParams::m_saved_token.c_str());
request->addParameter("userid", cp->getSavedUserId());
request->addParameter("token", cp->getSavedToken());
request->queue();
m_state = US_SIGNING_IN;
}
@ -179,9 +179,8 @@ namespace Online
m_state = US_SIGNED_IN;
if(saveSession())
{
UserConfigParams::m_saved_user = getID();
UserConfigParams::m_saved_token = getToken();
UserConfigParams::m_saved_session = true;
PlayerManager::getCurrentPlayer()->saveSession(getID(),
getToken() );
}
ProfileManager::get()->addPersistent(m_profile);
std::string achieved_string("");
@ -231,9 +230,7 @@ namespace Online
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;
PlayerManager::getCurrentPlayer()->clearSession();
} // signOut
// ------------------------------------------------------------------------

View File

@ -102,6 +102,9 @@ namespace Online
* variable has not been assigned at that stage, and the thread might
* use network_http - a very subtle race condition. So the thread can
* only be started after the assignment (in main) has been done.
* \pre PlayerManager was created and has read the main data for each
* player so that all data for automatic login is
* availale.
*/
void RequestManager::startNetworkThread()
{