diff --git a/src/config/player_manager.cpp b/src/config/player_manager.cpp
index e2d9d09d5..a097fca69 100644
--- a/src/config/player_manager.cpp
+++ b/src/config/player_manager.cpp
@@ -265,7 +265,7 @@ bool PlayerManager::checkSteamAccount(const irr::core::stringw ¤t_name)
m_current_player = getPlayer(i);
// Update the steam name in case that the user did a rename
- m_current_player->setSteamName(Steam::get()->getUserNameWchar());
+ m_current_player->setToCurrentSteamUser();
return true;
} // same steam user id
} // for i in m_all_players
@@ -283,8 +283,7 @@ bool PlayerManager::checkSteamAccount(const irr::core::stringw ¤t_name)
current_name.c_str(), steam_name.c_str());
m_current_player = getPlayer(i);
- m_current_player->setSteamUserID(steam_id);
- m_current_player->setSteamName(steam_name);
+ m_current_player->setToCurrentSteamUser();
return true;
} // if steam and current name are different
} // for i in m_all_players
@@ -296,6 +295,20 @@ bool PlayerManager::checkSteamAccount(const irr::core::stringw ¤t_name)
return false;
} // checkSteamAccount
+// ----------------------------------------------------------------------------
+/** Disconnects all account(s) that uses the given steam id from steam.
+ */
+void PlayerManager::disconnectSteamAccount(const std::string &steam_id)
+{
+ for (unsigned int i = 0; i < m_all_players.size(); i++)
+ {
+ PlayerProfile &player = m_all_players[i];
+ if (player.isSteamUser() && player.getSteamUserID() == steam_id)
+ {
+ player.clearSteamData();
+ } // if right steam user
+ } // for i in m_all_players
+} // disconnectSteamAccount
// ----------------------------------------------------------------------------
/** The 2nd loading stage. During this stage achievements and story mode
* data is initialised for each player. In case of existing player (i.e. not
diff --git a/src/config/player_manager.hpp b/src/config/player_manager.hpp
index 5d74ebd2c..420f3fac0 100644
--- a/src/config/player_manager.hpp
+++ b/src/config/player_manager.hpp
@@ -102,6 +102,8 @@ public:
static void setUserDetails(Online::HTTPRequest *request,
const std::string &action,
const std::string &php_name = "");
+ void disconnectSteamAccount(const std::string &steam_id);
+
static unsigned int getCurrentOnlineId();
static bool isCurrentLoggedIn();
static Online::OnlineProfile* getCurrentOnlineProfile();
diff --git a/src/config/player_profile.cpp b/src/config/player_profile.cpp
index 8d3bb47b8..ecb1d572f 100644
--- a/src/config/player_profile.cpp
+++ b/src/config/player_profile.cpp
@@ -302,6 +302,30 @@ void PlayerProfile::raceFinished()
m_achievements_status->onRaceEnd();
} // raceFinished
+//------------------------------------------------------------------------------
+/** Connects this user to the currently logged in Steam account. It saves the
+ * unique steam id and the (not necessarily unique) steam user name.
+ */
+void PlayerProfile::setToCurrentSteamUser()
+{
+ if (!Steam::get()->isSteamAvailable())
+ {
+ Log::error("PlayerProfile",
+ "Can not set to current steam user, steam is not available.");
+ return;
+ }
+ m_steam_id = Steam::get()->getSteamID();
+ m_steam_name = Steam::get()->getUserNameWchar();
+} // setToCurrentSteamUser
+
+//------------------------------------------------------------------------------
+/** Disconnects this player from its steam account.
+ */
+void PlayerProfile::clearSteamData()
+{
+ m_steam_id = "";
+ m_steam_name = "";
+} // clearSteamData
//------------------------------------------------------------------------------
/** Comparison used to sort players.
*/
diff --git a/src/config/player_profile.hpp b/src/config/player_profile.hpp
index bbd0ca8d2..f349d0937 100644
--- a/src/config/player_profile.hpp
+++ b/src/config/player_profile.hpp
@@ -134,6 +134,8 @@ public:
void saveSession(int user_id, const std::string &token);
void clearSession(bool save=true);
void addIcon();
+ void setToCurrentSteamUser();
+ void clearSteamData();
/** Abstract virtual classes, to be implemented by the OnlinePlayer. */
virtual void setUserDetails(Online::HTTPRequest *request,
@@ -315,16 +317,10 @@ public:
/** Returns the steam user id of this player ("" if not a steam account).*/
const std::string &getSteamUserID() const { return m_steam_id; }
// ------------------------------------------------------------------------
- /** Sets the steam user id of this player. */
- void setSteamUserID(const std::string &id) { m_steam_id = id; }
- // ------------------------------------------------------------------------
/** Returns the steam name of the connected steam account (or "" if
* this account is not a steam account. */
const core::stringw &getSteamName() const { return m_steam_name; }
// ------------------------------------------------------------------------
- /** Sets the steam name of this account. */
- void setSteamName(const core::stringw &name) { m_steam_name = name; }
- // ------------------------------------------------------------------------
}; // class PlayerProfile
#endif
diff --git a/src/states_screens/user_screen.cpp b/src/states_screens/user_screen.cpp
index 91071c597..688e7a98d 100644
--- a/src/states_screens/user_screen.cpp
+++ b/src/states_screens/user_screen.cpp
@@ -26,6 +26,7 @@
#include "guiengine/widgets/label_widget.hpp"
#include "guiengine/widgets/list_widget.hpp"
#include "guiengine/widgets/text_box_widget.hpp"
+#include "online/steam.hpp"
#include "states_screens/dialogs/message_dialog.hpp"
#include "states_screens/dialogs/recovery_dialog.hpp"
#include "states_screens/main_menu_screen.hpp"
@@ -55,6 +56,10 @@ BaseUserScreen::BaseUserScreen(const std::string &name) : Screen(name.c_str())
void BaseUserScreen::loadedFromFile()
{
+ m_steam_cb = getWidget("steam");
+ assert(m_steam_cb);
+ m_steam_label = getWidget("label-steam");
+ assert(m_steam_label);
m_online_cb = getWidget("online");
assert(m_online_cb);
m_username_tb = getWidget("username");
@@ -184,10 +189,10 @@ void BaseUserScreen::tearDown()
// ----------------------------------------------------------------------------
EventPropagation BaseUserScreen::filterActions(PlayerAction action,
- int deviceID,
- const unsigned int value,
- Input::InputType type,
- int playerId)
+ int deviceID,
+ const unsigned int value,
+ Input::InputType type,
+ int playerId )
{
if (action == PA_MENU_SELECT)
{
@@ -218,6 +223,27 @@ void BaseUserScreen::selectUser(int index)
m_players->setSelection(StringUtils::toString(index), PLAYER_ID_GAME_MASTER,
focus_it);
+ m_steam_cb->setVisible (Steam::get()->isSteamAvailable());
+ m_steam_label->setVisible(Steam::get()->isSteamAvailable());
+ if (Steam::get()->isSteamAvailable())
+ {
+ m_steam_cb->setState(profile->isSteamUser());
+ if (profile->isSteamUser())
+ {
+ //I18N: Checkbox text shown when this player is a steam user
+ // with the name displayed in ().
+ core::stringw label = _("Is Steam user (%s)",
+ profile->getSteamName() );
+ m_steam_label->setText(label, true);
+ }
+ else
+ {
+ //I18N: Checbox text shown when the user is not a steam user
+ // but can select the check box in order to become one
+ m_steam_label->setText(_("Is Steam user"), true);
+ } // no steam user
+ } // If steam is available
+
if (!m_new_registered_data)
m_username_tb->setText(profile->getLastOnlineName(true/*ignoreRTL*/));
@@ -300,9 +326,8 @@ void BaseUserScreen::makeEntryFieldsVisible()
// ----------------------------------------------------------------------------
/** Called when the user selects anything on the screen.
*/
-void BaseUserScreen::eventCallback(Widget* widget,
- const std::string& name,
- const int player_id)
+void BaseUserScreen::eventCallback(Widget* widget, const std::string& name,
+ const int player_id)
{
// Clean any error message still shown
m_info_widget->setText("", true);
@@ -389,11 +414,48 @@ void BaseUserScreen::eventCallback(Widget* widget,
{
StateManager::get()->escapePressed();
}
-
+ else if (name == "steam")
+ {
+ handleSteamAccount(player_id);
+ }
return;
} // eventCallback
+// ----------------------------------------------------------------------------
+/** Called when an STK account is connected or disconnected to a steam
+ * account.
+ * \param player_id The index of the currently selected player.
+ */
+void BaseUserScreen::handleSteamAccount(int player_id)
+{
+ // Shouldn't happen, this option is only shown when
+ // steam is available
+ if (!Steam::get()->isSteamAvailable()) return;
+
+ const std::string &s_index = getWidget("players")
+ ->getSelectionIDString(player_id);
+
+ if (s_index == "") return; // can happen if the list is empty
+
+ unsigned int id = 0;
+ StringUtils::fromString(s_index, id);
+ PlayerProfile *profile = PlayerManager::get()->getPlayer(id);
+
+ bool steam_user = m_steam_cb->getState();
+ if (m_steam_cb->getState())
+ {
+ // We need to disconnect any other STK account which uses the
+ // same steam account
+ PlayerManager::get()->disconnectSteamAccount(Steam::get()->getSteamID());
+ profile->setToCurrentSteamUser();
+ }
+ else
+ profile->clearSteamData();
+
+ selectUser(id);
+} // handleSteamAccount
+
// ----------------------------------------------------------------------------
/** Closes the BaseUserScreen, and makes sure that the right screen is displayed
* next.
diff --git a/src/states_screens/user_screen.hpp b/src/states_screens/user_screen.hpp
index a54dab37e..9988577ae 100644
--- a/src/states_screens/user_screen.hpp
+++ b/src/states_screens/user_screen.hpp
@@ -65,6 +65,12 @@ private:
* display more meaningful sign-out message. */
irr::core::stringw m_sign_in_name;
+ /** Online check box. */
+ GUIEngine::CheckBoxWidget *m_steam_cb;
+
+ /** Label field for steam details. */
+ GUIEngine::LabelWidget * m_steam_label;
+
/** Online check box. */
GUIEngine::CheckBoxWidget *m_online_cb;
@@ -98,6 +104,7 @@ private:
void closeScreen();
void deletePlayer();
void doDeletePlayer();
+ void handleSteamAccount(int player_id);
PlayerProfile* getSelectedPlayer();
virtual void onUpdate(float dt) OVERRIDE;