Fixed saving login credentials. It's now possible to switch

user (and automatically a logout and login is triggered).
This commit is contained in:
hiker
2014-05-20 22:13:26 +10:00
parent 9ae67f5c7a
commit 8441dbbd32
6 changed files with 122 additions and 61 deletions

View File

@@ -115,8 +115,8 @@ void PlayerManager::resumeSavedSession()
*/
void PlayerManager::onSTKQuit()
{
if (getCurrentPlayer())
getCurrentPlayer()->onSTKQuit();
if (getCurrentPlayer() && getCurrentPlayer()->isLoggedIn())
getCurrentPlayer()->requestSignOut();
} // onSTKQuit
// ----------------------------------------------------------------------------

View File

@@ -127,11 +127,11 @@ public:
virtual Online::OnlineProfile* getProfile() const = 0;
virtual void requestPoll() const = 0;
virtual void requestSavedSession() = 0;
virtual void onSTKQuit() const = 0;
virtual Online::XMLRequest* requestSignIn(const irr::core::stringw &username,
const irr::core::stringw &password) = 0;
virtual void signIn(bool success, const XMLNode * input) = 0;
virtual void signOut(bool success, const XMLNode * input) = 0;
virtual void signOut(bool success, const XMLNode * input,
const irr::core::stringw &info) = 0;
virtual void requestSignOut() = 0;
virtual bool isLoggedIn() const { return false; }
// ------------------------------------------------------------------------

View File

@@ -191,38 +191,77 @@ namespace Online
} // signIn
// ------------------------------------------------------------------------
/** Requests a sign out from the server. If the user should be remembered,
* a 'client-quit' request is sent (which will log the user out, but
* remember the token), otherwise a 'disconnect' is sent.
*/
void OnlinePlayerProfile::requestSignOut()
{
assert(m_online_state == OS_SIGNED_IN || m_online_state == OS_GUEST);
SignOutRequest * request = new SignOutRequest();
request->setServerURL("client-user.php");
request->addParameter("action","disconnect");
request->addParameter("token", getToken());
request->addParameter("userid", getOnlineId());
// ----------------------------------------------------------------
class SignOutRequest : public XMLRequest
{
private:
PlayerProfile *m_player;
virtual void callback()
{
m_player->signOut(isSuccess(), getXMLData(), getInfo());
}
public:
/** Sign out request, with a higher priority than signin requests,
* so that when a user is changed the signout is done first
* (to avoid potential problems with a local user logged in twice
* - even if it's only a short period of time). */
SignOutRequest(PlayerProfile *player)
: XMLRequest(true,/*priority*/20)
{
m_player = player;
m_player->setUserDetails(this,
UserConfigParams::m_remember_user ? "client-quit"
:"disconnect");
} // SignOutRequest
}; // SignOutRequest
// ----------------------------------------------------------------
HTTPRequest *request = new SignOutRequest(this);
request->queue();
m_online_state = OS_SIGNING_OUT;
} // requestSignOut
// --------------------------------------------------------------------
void OnlinePlayerProfile::SignOutRequest::callback()
{
PlayerManager::getCurrentPlayer()->signOut(isSuccess(), getXMLData());
} // SignOutRequest::callback
// ------------------------------------------------------------------------
void OnlinePlayerProfile::signOut(bool success, const XMLNode * input)
/** Callback once the logout event has been processed.
* \param success If the request was successful.
* \param input
*/
void OnlinePlayerProfile::signOut(bool success, const XMLNode *input,
const irr::core::stringw &info)
{
if(!success)
GUIEngine::Screen *screen = GUIEngine::getCurrentScreen();
BaseUserScreen *user_screen = dynamic_cast<BaseUserScreen*>(screen);
// We can't do much of error handling here, no screen waits for
// a logout to finish, so we can only log the message to screen,
// and otherwise mark the player logged out internally.
if (!success)
{
Log::warn("OnlinePlayerProfile::signOut", "%s",
Log::warn("OnlinePlayerProfile::signOut",
"There were some connection issues while signing out. "
"Report a bug if this caused issues.");
Log::warn("OnlinePlayerProfile::signOut", core::stringc(info.c_str()).c_str());
if(user_screen)
user_screen->logoutError(info);
}
m_token = "";
else
{
if(user_screen)
user_screen->logoutSuccessful();
}
ProfileManager::get()->clearPersistent();
m_profile = NULL;
m_online_state = OS_SIGNED_OUT;
PlayerManager::getCurrentPlayer()->clearSession();
// Discard token if session should not be saved.
if(!UserConfigParams::m_remember_user)
clearSession();
} // signOut
// ------------------------------------------------------------------------
@@ -376,24 +415,6 @@ namespace Online
} // PollRequest::callback
// ------------------------------------------------------------------------
/** Sends a message to the server that the client has been closed, if a
* user is signed in.
*/
void OnlinePlayerProfile::onSTKQuit() const
{
if(isLoggedIn())
{
HTTPRequest * request =
new HTTPRequest(true, RequestManager::HTTP_MAX_PRIORITY);
request->setServerURL("client-user.php");
request->addParameter("action", "client-quit");
request->addParameter("token", getToken());
request->addParameter("userid", getOnlineId());
request->queue();
}
}
// ------------------------------------------------------------------------
/** \return the online id, or 0 if the user is not signed in.
*/

View File

@@ -58,14 +58,6 @@ namespace Online
: XMLRequest(manage_memory, /*priority*/10) {}
}; // SignInRequest
// ----------------------------------------------------------------
class SignOutRequest : public XMLRequest
{
virtual void callback ();
public:
SignOutRequest() : XMLRequest(true,/*priority*/10) {}
}; // SignOutRequest
// ----------------------------------------------------------------
class PollRequest : public XMLRequest {
virtual void callback ();
@@ -85,7 +77,8 @@ namespace Online
virtual void signIn(bool success, const XMLNode * input);
virtual void signOut(bool success, const XMLNode * input);
virtual void signOut(bool success, const XMLNode * input,
const irr::core::stringw &info);
// For now declare functions that will become part of PlayerManager
// or Playerprofile to be private, and give only PlayerManager
@@ -106,7 +99,6 @@ namespace Online
const std::string &php_script = "");
virtual void requestPoll() const;
virtual void onSTKQuit() const;
// ----------------------------------------------------------------
/** Returns if this user is logged in. */
virtual bool isLoggedIn() const

View File

@@ -145,10 +145,6 @@ void BaseUserScreen::selectUser(int index)
{
PlayerProfile *profile = PlayerManager::get()->getPlayer(index);
assert(profile);
PlayerProfile *cp = PlayerManager::getCurrentPlayer();
// If the current user is logged in, a logout is required now.
if(profile!=cp && cp && cp->isLoggedIn())
cp->requestSignOut();
getWidget<TextBoxWidget >("username")->setText(profile
->getLastOnlineName());
@@ -300,24 +296,34 @@ void BaseUserScreen::login()
// If an error occurs, the callback informing this screen about the
// problem will activate the widget again.
m_options_widget->setDeactivated();
m_state = STATE_NONE;
PlayerProfile *player = getSelectedPlayer();
PlayerProfile *current = PlayerManager::getCurrentPlayer();
// If a different player is connecting, log out the current player.
if(player!=current && current && current->isLoggedIn())
{
current->requestSignOut();
m_state = (UserScreenState)(m_state | STATE_LOGOUT);
}
PlayerManager::get()->setCurrentPlayer(player);
assert(player);
// If no online login requested, go straight to the main menu screen.
// If no online login requested, log the player out (if necessary)
// and go to the main menu screen (though logout needs to finish first)
if(!m_online_cb->getState())
{
if(player->isLoggedIn())
{
// The player is logged in, but online is now disabled,
// so log the player out. There is no error handling of
// a failed logout request
player->requestSignOut();
m_state =(UserScreenState)(m_state| STATE_LOGOUT);
}
player->setWasOnlineLastTime(false);
closeScreen();
if(m_state==STATE_NONE)
{
closeScreen();
}
return;
}
@@ -328,7 +334,7 @@ void BaseUserScreen::login()
closeScreen();
return;
}
m_state = (UserScreenState) (m_state | STATE_LOGIN);
// Now we need to start a login request to the server
// This implies that this screen will wait till the server responds, so
// that error messages ('invalid password') can be shown, and the user
@@ -361,8 +367,11 @@ void BaseUserScreen::login()
void BaseUserScreen::onUpdate(float dt)
{
if (!m_options_widget->isActivated())
m_info_widget->setText(Online::Messages::loadingDots( _("Signing in")),
false);
{
const wchar_t *message = (m_state & STATE_LOGOUT) ? _("Signing out")
: _("Signing in");
m_info_widget->setText(Online::Messages::loadingDots(message), false);
}
PlayerProfile *player = getSelectedPlayer();
if(player)
{
@@ -398,6 +407,7 @@ void BaseUserScreen::loginSuccessful()
*/
void BaseUserScreen::loginError(const irr::core::stringw & error_message)
{
m_state = (UserScreenState) (m_state & ~STATE_LOGIN);
PlayerProfile *player = getSelectedPlayer();
// Clear information about saved session in case of a problem,
// which allows the player to enter a new password.
@@ -410,12 +420,44 @@ void BaseUserScreen::loginError(const irr::core::stringw & error_message)
m_options_widget->setActivated();
} // loginError
// ----------------------------------------------------------------------------
/** Callback from player profile if logout was successful.
*/
void BaseUserScreen::logoutSuccessful()
{
m_state = (UserScreenState) (m_state & ~STATE_LOGOUT);
if(m_state==STATE_NONE)
closeScreen();
// Otherwise the screen still has to wait for a login request to finish.
} // loginSuccessful
// ----------------------------------------------------------------------------
/** Callback from player profile if login was unsuccessful.
* \param error_message Contains the error message.
*/
void BaseUserScreen::logoutError(const irr::core::stringw & error_message)
{
m_state = (UserScreenState) (m_state & ~STATE_LOGOUT);
PlayerProfile *player = getSelectedPlayer();
// Clear information about saved session in case of a problem,
// which allows the player to enter a new password.
if(player && player->hasSavedSession())
player->clearSession();
makeEntryFieldsVisible();
sfx_manager->quickSound("anvil");
m_info_widget->setErrorColor();
m_info_widget->setText(error_message, false);
m_options_widget->setActivated();
} // logoutError
// ----------------------------------------------------------------------------
void BaseUserScreen::newUserAdded(const irr::core::stringw &local_name,
const irr::core::stringw &online_name)
{
PlayerProfile *player = PlayerManager::get()->getPlayer(local_name);
PlayerManager::get()->setCurrentPlayer(player);
// Set the online name, only if the user clicks on 'ok' will this
// new player become the current player (since we potentially have to
// log out the old current player).
player->setLastOnlineName(online_name);
} // newUserAdded

View File

@@ -51,6 +51,10 @@ protected:
private:
/** The state of the user screen. Note that this is a bit mask, since the
* current user can be logged out, and the new one logged in at the
* same time. */
enum UserScreenState { STATE_NONE=0, STATE_LOGIN=1, STATE_LOGOUT=2} m_state;
/** Online check box. */
GUIEngine::CheckBoxWidget *m_online_cb;
@@ -98,6 +102,8 @@ public:
void loginSuccessful();
void loginError(const irr::core::stringw &error_message);
void logoutSuccessful();
void logoutError(const irr::core::stringw &error_message);
void newUserAdded(const irr::core::stringw &local_name,
const irr::core::stringw &online_name);
}; // class BaseUserScreen