Compare commits
16 Commits
master
...
steam-test
Author | SHA1 | Date | |
---|---|---|---|
|
90f4855938 | ||
|
9d350ebaa6 | ||
|
059b77d34b | ||
|
31f970f625 | ||
|
d651e0c710 | ||
|
b0408d414c | ||
|
dddd00142b | ||
|
01aeb9f2fd | ||
|
29e1541b47 | ||
|
92709b2ada | ||
|
ffca9b14d8 | ||
|
bff3989bfc | ||
|
1d7aa7a2f5 | ||
|
de795b766a | ||
|
eb4989c2ef | ||
|
9760826252 |
@ -14,6 +14,12 @@
|
||||
|
||||
<spacer height="15" width="10"/>
|
||||
<div width="90%" align="center" layout="vertical-row" proportion="1">
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<checkbox width="fit" id="steam" I18N="In the user screen" text_align="left"/>
|
||||
<spacer width="10"/>
|
||||
<label proportion="1" id="label-steam" height="100%" text_align="left"
|
||||
I18N="In the user screen" text="Is a Steam account"/>
|
||||
</div>
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<checkbox width="fit" id="online" I18N="In the user screen" text_align="left"/>
|
||||
<spacer width="10"/>
|
||||
|
@ -23,6 +23,12 @@
|
||||
|
||||
<spacer height="15" width="10"/>
|
||||
<div width="90%" align="center" layout="vertical-row" height="fit">
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<checkbox width="fit" id="steam" I18N="In the user screen" text_align="left"/>
|
||||
<spacer width="10"/>
|
||||
<label proportion="1" id="label-steam" height="100%" text_align="left"
|
||||
I18N="In the user screen" text="Is a Steam account"/>
|
||||
</div>
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<checkbox width="fit" id="online" I18N="In the user screen" text_align="left"/>
|
||||
<spacer width="10"/>
|
||||
|
@ -162,6 +162,11 @@
|
||||
work anymore - so for now don't enable this. -->
|
||||
<networking enable="false"/>
|
||||
|
||||
<!-- Steam related settings:
|
||||
ask-for-internet - If true the user on first start will be asked
|
||||
for permission to connect to stk servers. -->
|
||||
<steam ask-for-internet="false"/>
|
||||
|
||||
<!-- The field od views for 1-4 player split screen. fov-3 is
|
||||
actually not used (since 3 player split screen uses the
|
||||
same layout as 4 player split screen) -->
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Modify this file to change the last-modified date when you add/remove a file.
|
||||
# This will then trigger a new cmake run automatically.
|
||||
# This will then trigger a new cmake run automatically.
|
||||
file(GLOB_RECURSE STK_HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.hpp")
|
||||
file(GLOB_RECURSE STK_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.cpp")
|
||||
file(GLOB_RECURSE STK_SHADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "data/shaders/*")
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "io/utf_writer.hpp"
|
||||
#include "io/xml_node.hpp"
|
||||
#include "online/online_player_profile.hpp"
|
||||
#include "online/steam.hpp"
|
||||
#include "utils/log.hpp"
|
||||
#include "utils/translation.hpp"
|
||||
|
||||
@ -209,17 +210,126 @@ void PlayerManager::load()
|
||||
PlayerProfile *player = new Online::OnlinePlayerProfile(player_xml);
|
||||
m_all_players.push_back(player);
|
||||
}
|
||||
|
||||
m_current_player = NULL;
|
||||
const XMLNode *current = m_player_data->getNode("current");
|
||||
if(current)
|
||||
stringw current_name;
|
||||
|
||||
if (current)
|
||||
{
|
||||
stringw name;
|
||||
current->getAndDecode("player", &name);
|
||||
m_current_player = getPlayer(name);
|
||||
current->getAndDecode("player", ¤t_name);
|
||||
}
|
||||
if (!checkSteamAccount(current_name))
|
||||
{
|
||||
m_current_player = getPlayer(current_name);
|
||||
} // if current
|
||||
|
||||
} // load
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** This functions checks if a stk user exists with the same steam id as the
|
||||
* current steam user, and if so switches to that player (ignoring that stk
|
||||
* might have a different 'current' player). If no stk account with same
|
||||
* steam id is found, it then also checks if a non-steam stk account with the
|
||||
* same name (case independent) exists, and if so, switches that account
|
||||
* to be connect to the current steam user.
|
||||
* If no matching stk account can be found, do nothing - the user then would
|
||||
* have to rename an existing account or create a new account to be connected
|
||||
* to the steam id.
|
||||
* \return True if a matching steam account was found (which means that the
|
||||
* current user in stk is ignored).
|
||||
*/
|
||||
bool PlayerManager::checkSteamAccount(const irr::core::stringw ¤t_name)
|
||||
{
|
||||
if (!Steam::get()->isSteamAvailable())
|
||||
return false;
|
||||
|
||||
// First check for an stk account with same steam id:
|
||||
const stringw &steam_name = Steam::get()->getUserNameWchar();
|
||||
const std::string &steam_id = Steam::get()->getSteamID();
|
||||
|
||||
for (unsigned int i = 0; i < m_all_players.size(); i++)
|
||||
{
|
||||
if (m_all_players[i].isSteamUser() &&
|
||||
m_all_players[i].getSteamUserID() == steam_id)
|
||||
{
|
||||
// Check if the previously (current) name is different from
|
||||
// the steam name, and if so print a warning, but continue
|
||||
// with switching to the correct steam user id.
|
||||
if (!current_name.equals_ignore_case(steam_name))
|
||||
{
|
||||
Log::warn("PlayerManager",
|
||||
"Switching from previous user '%ls' to '%ls'.",
|
||||
current_name.c_str(), steam_name.c_str() );
|
||||
} // if steam and current name are different
|
||||
|
||||
m_current_player = getPlayer(i);
|
||||
// Update the steam name in case that the user did a rename
|
||||
m_current_player->setToCurrentSteamUser();
|
||||
return true;
|
||||
} // same steam user id
|
||||
} // for i in m_all_players
|
||||
|
||||
// Now check for an existing account name that matches the steam name.
|
||||
// This is only done on the first time an STK version is running that
|
||||
// connects to steam. From then on the user must go to the user screen
|
||||
// to connect or disconnect STK accounts to steam accounts.
|
||||
if (UserConfigParams::m_steam_first_start)
|
||||
{
|
||||
for (unsigned int i = 0; i < m_all_players.size(); i++)
|
||||
{
|
||||
// Ignore existing steam users, they must have a different id
|
||||
// (otherwise they would have been picked in the previous loop)
|
||||
if (m_all_players[i].isSteamUser()) continue;
|
||||
stringw name = m_all_players[i].getName();
|
||||
if (name.equals_ignore_case(steam_name))
|
||||
{
|
||||
Log::warn("PlayerManager",
|
||||
"Connecting '%ls' to current steam account '%ls'.",
|
||||
current_name.c_str(), steam_name.c_str());
|
||||
|
||||
m_current_player = getPlayer(i);
|
||||
m_current_player->setToCurrentSteamUser();
|
||||
return true;
|
||||
} // if steam and current name are different
|
||||
} // for i in m_all_players
|
||||
|
||||
// No matching existing user found. Last try: if there is only
|
||||
// one stk account, connect it to the current steam account:
|
||||
if (m_all_players.size() == 1)
|
||||
{
|
||||
m_current_player = getPlayer(0);
|
||||
m_current_player->setToCurrentSteamUser();
|
||||
Log::warn("PlayerManager",
|
||||
"Connecting only account '%ls' to current steam account '%ls'.",
|
||||
m_current_player->getName().c_str(), steam_name.c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
} // If first time steam version is started.
|
||||
|
||||
// Otherwise now current user is NULL: if this is the first time that
|
||||
// stk starts under steam (and an stk account existed, otherwise this
|
||||
// function is not called), main() will bring up the user login screen
|
||||
// where the user can connect and disconnect stk- and steam-accounts.
|
||||
|
||||
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
|
||||
|
@ -66,6 +66,7 @@ private:
|
||||
const XMLNode *m_player_data;
|
||||
|
||||
void load();
|
||||
bool checkSteamAccount(const irr::core::stringw ¤t_name);
|
||||
PlayerManager();
|
||||
~PlayerManager();
|
||||
|
||||
@ -101,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();
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "karts/kart_properties.hpp"
|
||||
#include "karts/kart_properties_manager.hpp"
|
||||
#include "online/online_player_profile.hpp"
|
||||
#include "online/steam.hpp"
|
||||
#include "io/xml_node.hpp"
|
||||
#include "io/utf_writer.hpp"
|
||||
#include "utils/string_utils.hpp"
|
||||
@ -38,6 +39,17 @@ PlayerProfile::PlayerProfile(const core::stringw& name, bool is_guest)
|
||||
#ifdef DEBUG
|
||||
m_magic_number = 0xABCD1234;
|
||||
#endif
|
||||
if(Steam::get()->isSteamAvailable() &&
|
||||
name == Steam::get()->getUserNameWchar() )
|
||||
{
|
||||
m_steam_id = Steam::get()->getSteamID();
|
||||
m_steam_name = Steam::get()->getUserNameWchar();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_steam_id = "";
|
||||
m_steam_name = "";
|
||||
}
|
||||
m_local_name = name;
|
||||
m_is_guest_account = is_guest;
|
||||
m_use_frequency = is_guest ? -1 : 0;
|
||||
@ -68,6 +80,8 @@ PlayerProfile::PlayerProfile(const core::stringw& name, bool is_guest)
|
||||
*/
|
||||
PlayerProfile::PlayerProfile(const XMLNode* node)
|
||||
{
|
||||
m_steam_id = "";
|
||||
m_steam_name = "";
|
||||
m_saved_session = false;
|
||||
m_saved_token = "";
|
||||
m_saved_user_id = 0;
|
||||
@ -78,7 +92,9 @@ PlayerProfile::PlayerProfile(const XMLNode* node)
|
||||
m_achievements_status = NULL;
|
||||
m_icon_filename = "";
|
||||
|
||||
node->getAndDecode("name", &m_local_name);
|
||||
node->getAndDecode("name", &m_local_name );
|
||||
node->get("steam-id", &m_steam_id );
|
||||
node->get("steam-name", &m_steam_name );
|
||||
node->get("guest", &m_is_guest_account );
|
||||
node->get("use-frequency", &m_use_frequency );
|
||||
node->get("unique-id", &m_unique_id );
|
||||
@ -154,6 +170,23 @@ void PlayerProfile::addIcon()
|
||||
if (m_icon_filename.size() > 0 || isGuestAccount())
|
||||
return;
|
||||
|
||||
if (isSteamUser())
|
||||
{
|
||||
std::ostringstream out;
|
||||
out << m_unique_id << ".png";
|
||||
std::string full_path = file_manager->getUserConfigFile(out.str());
|
||||
Steam::get()->saveAvatarAs(full_path);
|
||||
if (file_manager->fileExists(full_path))
|
||||
{
|
||||
m_icon_filename = out.str();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_icon_filename = "";
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
int n = (m_unique_id + kart_properties_manager->getKartId("tux") - 1)
|
||||
% kart_properties_manager->getNumberOfKarts();
|
||||
|
||||
@ -202,6 +235,9 @@ void PlayerProfile::save(UTFWriter &out)
|
||||
<< L"\" guest=\"" << m_is_guest_account
|
||||
<< L"\" use-frequency=\"" << m_use_frequency << L"\"\n";
|
||||
|
||||
out << L" steam-id=\"" << m_steam_id
|
||||
<< L"\" steam-name=\"" << m_steam_name << L"\"\n";
|
||||
|
||||
out << L" icon-filename=\"" << m_icon_filename << L"\"\n";
|
||||
|
||||
out << L" unique-id=\"" << m_unique_id
|
||||
@ -266,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.
|
||||
*/
|
||||
|
@ -97,6 +97,15 @@ private:
|
||||
/** The token of the saved session. */
|
||||
std::string m_saved_token;
|
||||
|
||||
/** If the account is a steam account, this stores the steam user id.
|
||||
* Otherwise it is empty. A steam account can only be selected if
|
||||
* the user is logged into steam! */
|
||||
std::string m_steam_id;
|
||||
|
||||
/** Name of the corresponding steam account. Empty if this is
|
||||
* not a steam account. */
|
||||
core::stringw m_steam_name;
|
||||
|
||||
/** The online user name used last (empty if not used online). */
|
||||
core::stringw m_last_online_name;
|
||||
|
||||
@ -125,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,
|
||||
@ -300,6 +311,16 @@ public:
|
||||
/** Sets if this player was logged in last time it was used. */
|
||||
void setRememberPassword(bool b) { m_remember_password = b; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns if this account is a steam account. */
|
||||
bool isSteamUser() const { return m_steam_id != ""; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the steam user id of this player ("" if not a steam account).*/
|
||||
const std::string &getSteamUserID() const { return m_steam_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; }
|
||||
// ------------------------------------------------------------------------
|
||||
}; // class PlayerProfile
|
||||
|
||||
#endif
|
||||
|
@ -181,6 +181,7 @@ void STKConfig::init_defaults()
|
||||
m_disable_steer_while_unskid = false;
|
||||
m_camera_follow_skid = false;
|
||||
m_cutscene_fov = 0.61f;
|
||||
m_steam_ask_for_internet = false;
|
||||
|
||||
m_score_increase.clear();
|
||||
m_leader_intervals.clear();
|
||||
@ -274,6 +275,11 @@ void STKConfig::getAllData(const XMLNode * root)
|
||||
camera->get("cutscene-fov", &m_cutscene_fov);
|
||||
}
|
||||
|
||||
if (const XMLNode *steam = root->getNode("steam"))
|
||||
{
|
||||
steam->get("ask-for-internet", &m_steam_ask_for_internet);
|
||||
}
|
||||
|
||||
if (const XMLNode *music_node = root->getNode("music"))
|
||||
{
|
||||
std::string title_music;
|
||||
|
@ -152,6 +152,10 @@ public:
|
||||
|
||||
float m_cutscene_fov;
|
||||
|
||||
/** True if the internet question should still be asked when
|
||||
* a steam connection is make. */
|
||||
bool m_steam_ask_for_internet;
|
||||
|
||||
/** Lists of TTF files used in STK. */
|
||||
std::vector<std::string> m_normal_ttf;
|
||||
std::vector<std::string> m_digit_ttf;
|
||||
|
@ -914,6 +914,16 @@ namespace UserConfigParams
|
||||
&m_online_group,
|
||||
"Version of the server API to use."));
|
||||
|
||||
// ---- Online gameplay related
|
||||
PARAM_PREFIX GroupUserConfigParam m_steam_group
|
||||
PARAM_DEFAULT(GroupUserConfigParam("Steam",
|
||||
"Everything related to steam."));
|
||||
|
||||
PARAM_PREFIX BoolUserConfigParam m_steam_first_start
|
||||
PARAM_DEFAULT(BoolUserConfigParam(true,
|
||||
"steam-first-start",
|
||||
&m_steam_group,
|
||||
"If this is the first time the STK steam version was started"));
|
||||
|
||||
// ---- Addon server related entries
|
||||
PARAM_PREFIX GroupUserConfigParam m_addon_group
|
||||
|
56
src/main.cpp
56
src/main.cpp
@ -215,6 +215,7 @@
|
||||
#include "network/protocols/get_public_address.hpp"
|
||||
#include "online/profile_manager.hpp"
|
||||
#include "online/request_manager.hpp"
|
||||
#include "online/steam.hpp"
|
||||
#include "race/grand_prix_manager.hpp"
|
||||
#include "race/highscore_manager.hpp"
|
||||
#include "race/history.hpp"
|
||||
@ -1458,6 +1459,16 @@ void askForInternetPermission()
|
||||
Online::RequestManager::IPERM_NOT_ASKED)
|
||||
return;
|
||||
|
||||
// If a steam connection is available, we could skip the
|
||||
// internet permission question (depending on settings).
|
||||
if (Steam::get()->isSteamAvailable() &&
|
||||
!stk_config->m_steam_ask_for_internet)
|
||||
{
|
||||
UserConfigParams::m_internet_status =
|
||||
Online::RequestManager::IPERM_ALLOWED;
|
||||
return;
|
||||
}
|
||||
|
||||
class ConfirmServer :
|
||||
public MessageDialog::IConfirmDialogListener
|
||||
{
|
||||
@ -1515,6 +1526,8 @@ int main(int argc, char *argv[] )
|
||||
{
|
||||
CommandLine::init(argc, argv);
|
||||
|
||||
Steam::create();
|
||||
|
||||
CrashReporting::installHandlers();
|
||||
|
||||
srand(( unsigned ) time( 0 ));
|
||||
@ -1688,23 +1701,43 @@ int main(int argc, char *argv[] )
|
||||
// so we immediately start the main menu (unless it was requested
|
||||
// to always show the login screen). Otherwise show the login
|
||||
// screen first.
|
||||
if(PlayerManager::getCurrentPlayer() && !
|
||||
UserConfigParams::m_always_show_login_screen)
|
||||
if(PlayerManager::getCurrentPlayer() &&
|
||||
!UserConfigParams::m_always_show_login_screen)
|
||||
{
|
||||
MainMenuScreen::getInstance()->push();
|
||||
// If this is the first time that steam starts, and at startup
|
||||
// we could not detect a 'matching' stk account to the steam
|
||||
// account, bring up the user screen (on top of the main menu),
|
||||
// so that the user can manually connect an stk account with
|
||||
// a steam account.
|
||||
if (UserConfigParams::m_steam_first_start &&
|
||||
!PlayerManager::getCurrentPlayer()->isSteamUser())
|
||||
{
|
||||
UserScreen::getInstance()->push();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UserScreen::getInstance()->push();
|
||||
// If there is no player, push the RegisterScreen on top of
|
||||
// the login screen. This way on first start players are
|
||||
// forced to create a player.
|
||||
if (PlayerManager::get()->getNumPlayers() == 0)
|
||||
if (Steam::get()->isSteamAvailable())
|
||||
{
|
||||
RegisterScreen::getInstance()->push();
|
||||
RegisterScreen::getInstance()->setParent(UserScreen::getInstance());
|
||||
PlayerProfile *steam_player = PlayerManager::get()
|
||||
->addNewPlayer(Steam::get()->getUserNameWchar());
|
||||
PlayerManager::get()->setCurrentPlayer(steam_player);
|
||||
MainMenuScreen::getInstance()->push();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UserScreen::getInstance()->push();
|
||||
// If there is no player, push the RegisterScreen on top of
|
||||
// the login screen. This way on first start players are
|
||||
// forced to create a player.
|
||||
if (PlayerManager::get()->getNumPlayers() == 0)
|
||||
{
|
||||
RegisterScreen::getInstance()->push();
|
||||
RegisterScreen::getInstance()->setParent(UserScreen::getInstance());
|
||||
}
|
||||
} // !steam->isAvailable
|
||||
} // no player available
|
||||
#ifdef ENABLE_WIIUSE
|
||||
// Show a dialog to allow connection of wiimotes. */
|
||||
if(WiimoteManager::isEnabled())
|
||||
@ -1778,7 +1811,7 @@ int main(int argc, char *argv[] )
|
||||
}
|
||||
|
||||
/* Program closing...*/
|
||||
|
||||
UserConfigParams::m_steam_first_start = false;
|
||||
#ifdef ENABLE_WIIUSE
|
||||
if(wiimote_manager)
|
||||
delete wiimote_manager;
|
||||
@ -1792,6 +1825,7 @@ int main(int argc, char *argv[] )
|
||||
if(NetworkConfig::get()->isNetworking() && STKHost::existHost())
|
||||
STKHost::get()->abort();
|
||||
|
||||
Steam::destroy();
|
||||
cleanSuperTuxKart();
|
||||
|
||||
#ifdef DEBUG
|
||||
|
389
src/online/steam.cpp
Normal file
389
src/online/steam.cpp
Normal file
@ -0,0 +1,389 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2017 Joerg Henrichs
|
||||
//
|
||||
// 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 "online/steam.hpp"
|
||||
|
||||
#include "utils/log.hpp"
|
||||
#include "utils/string_utils.hpp"
|
||||
|
||||
#ifdef WIN32
|
||||
# include <windows.h>
|
||||
#else
|
||||
# include <iostream>
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
Steam * Steam::m_steam = NULL;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
Steam::Steam()
|
||||
{
|
||||
m_steam_available = false;
|
||||
|
||||
// Create the child process SSM to mamage steam:
|
||||
if (!createChildProcess())
|
||||
{
|
||||
Log::error("Steam", "Could not start ssm.exe");
|
||||
return;
|
||||
}
|
||||
|
||||
Log::info("Steam", "Starting steam manager");
|
||||
|
||||
std::string s = sendCommand("init");
|
||||
if (s != "1")
|
||||
{
|
||||
Log::error("Steam", "Could not initialise Steam API.");
|
||||
return;
|
||||
}
|
||||
|
||||
s = sendCommand("name");
|
||||
m_user_name = decodeString(s);
|
||||
if (m_user_name == "")
|
||||
{
|
||||
Log::error("Steam", "Can not get Steam user name.");
|
||||
return;
|
||||
}
|
||||
|
||||
m_user_name_wchar = StringUtils::utf8ToWide(m_user_name);
|
||||
|
||||
s = sendCommand("id");
|
||||
m_steam_id = decodeString(s);
|
||||
if (m_steam_id== "")
|
||||
{
|
||||
Log::error("Steam", "Can not get Steam id.");
|
||||
return;
|
||||
}
|
||||
|
||||
m_steam_available = true;
|
||||
} // Steam
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Terminates the child processes and shuts down the Steam API.
|
||||
*/
|
||||
Steam::~Steam()
|
||||
{
|
||||
std::string s = sendCommand("quit");
|
||||
if (s != "quit")
|
||||
{
|
||||
Log::error("Steam", "Could not shutdown Steam process properly");
|
||||
}
|
||||
|
||||
#ifdef LINUX
|
||||
close(m_child_stdin_write);
|
||||
close(m_child_stdout_read);
|
||||
#endif
|
||||
Log::info("Steam", "Shutting down steam manager");
|
||||
|
||||
} // ~Steam
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Starts ssm.exe (on windows) or ssm (other platforms) as a child process
|
||||
* and sets up communication via pipes.
|
||||
* \return True if the child process creation was successful.
|
||||
*/
|
||||
#ifdef WIN32
|
||||
bool Steam::createChildProcess()
|
||||
{
|
||||
// Based on: https://msdn.microsoft.com/en-us/library/windows/desktop/ms682499(v=vs.85).aspx
|
||||
SECURITY_ATTRIBUTES sec_attr;
|
||||
|
||||
// Set the bInheritHandle flag so pipe handles are inherited.
|
||||
sec_attr.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||
sec_attr.bInheritHandle = TRUE;
|
||||
sec_attr.lpSecurityDescriptor = NULL;
|
||||
|
||||
// Create a pipe for the child process's STDOUT.
|
||||
|
||||
if (!CreatePipe(&m_child_stdout_read, &m_child_stdout_write, &sec_attr, 0))
|
||||
{
|
||||
Log::error("Steam", "Error creating StdoutRd CreatePipe");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Ensure the read handle to the pipe for STDOUT is not inherited.
|
||||
if (!SetHandleInformation(m_child_stdout_read, HANDLE_FLAG_INHERIT, 0))
|
||||
{
|
||||
Log::error("Steam", "Stdout SetHandleInformation");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create a pipe for the child process's STDIN.
|
||||
if (!CreatePipe(&m_child_stdin_read, &m_child_stdin_write, &sec_attr, 0))
|
||||
{
|
||||
Log::error("Steam", "Stdin CreatePipe");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Ensure the write handle to the pipe for STDIN is not inherited.
|
||||
if (!SetHandleInformation(m_child_stdin_write, HANDLE_FLAG_INHERIT, 0))
|
||||
{
|
||||
Log::error("Steam", "Stdin SetHandleInformation");
|
||||
return false;
|
||||
}
|
||||
|
||||
TCHAR command_line[] = TEXT("ssm.exe");
|
||||
PROCESS_INFORMATION piProcInfo;
|
||||
STARTUPINFO siStartInfo;
|
||||
|
||||
// Set up members of the PROCESS_INFORMATION structure.
|
||||
|
||||
ZeroMemory(&piProcInfo, sizeof(PROCESS_INFORMATION));
|
||||
|
||||
// Set up members of the STARTUPINFO structure.
|
||||
// This structure specifies the STDIN and STDOUT handles for redirection.
|
||||
|
||||
ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
|
||||
siStartInfo.cb = sizeof(STARTUPINFO);
|
||||
siStartInfo.hStdError = m_child_stdout_write;
|
||||
siStartInfo.hStdOutput = m_child_stdout_write;
|
||||
siStartInfo.hStdInput = m_child_stdin_read;
|
||||
siStartInfo.dwFlags |= STARTF_USESTDHANDLES;
|
||||
|
||||
// Create the child process.
|
||||
|
||||
bool success = CreateProcess(NULL,
|
||||
command_line, // command line
|
||||
NULL, // process security attributes
|
||||
NULL, // primary thread security attributes
|
||||
TRUE, // handles are inherited
|
||||
0, // creation flags
|
||||
NULL, // use parent's environment
|
||||
NULL, // use parent's current directory
|
||||
&siStartInfo, // STARTUPINFO pointer
|
||||
&piProcInfo) != 0; // receives PROCESS_INFORMATION
|
||||
|
||||
if (!success)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Close handles to the child process and its primary thread.
|
||||
// Some applications might keep these handles to monitor the status
|
||||
// of the child process, for example.
|
||||
|
||||
CloseHandle(piProcInfo.hProcess);
|
||||
CloseHandle(piProcInfo.hThread);
|
||||
|
||||
return true;
|
||||
} // createChildProcess - windows version
|
||||
|
||||
#else // linux and osx
|
||||
|
||||
bool Steam::createChildProcess()
|
||||
{
|
||||
const int PIPE_READ=0;
|
||||
const int PIPE_WRITE=1;
|
||||
int stdin_pipe[2];
|
||||
int stdout_pipe[2];
|
||||
int child;
|
||||
|
||||
if (pipe(stdin_pipe) < 0)
|
||||
{
|
||||
Log::error("Steam", "Can't allocate pipe for input redirection.");
|
||||
return -1;
|
||||
}
|
||||
if (pipe(stdout_pipe) < 0)
|
||||
{
|
||||
close(stdin_pipe[PIPE_READ]);
|
||||
close(stdin_pipe[PIPE_WRITE]);
|
||||
Log::error("Steam", "allocating pipe for child output redirect");
|
||||
return false;
|
||||
}
|
||||
|
||||
child = fork();
|
||||
if (child == 0)
|
||||
{
|
||||
// Child process:
|
||||
Log::info("Steam", "Child process started.");
|
||||
|
||||
// redirect stdin
|
||||
if (dup2(stdin_pipe[PIPE_READ], STDIN_FILENO) == -1)
|
||||
{
|
||||
Log::error("Steam", "Redirecting stdin");
|
||||
return false;
|
||||
}
|
||||
|
||||
// redirect stdout
|
||||
if (dup2(stdout_pipe[PIPE_WRITE], STDOUT_FILENO) == -1)
|
||||
{
|
||||
Log::error("Steam", "Redirecting stdout");
|
||||
return false;
|
||||
}
|
||||
|
||||
// all these are for use by parent only
|
||||
close(stdin_pipe[PIPE_READ]);
|
||||
close(stdin_pipe[PIPE_WRITE]);
|
||||
close(stdout_pipe[PIPE_READ]);
|
||||
close(stdout_pipe[PIPE_WRITE]);
|
||||
|
||||
// run child process image
|
||||
execl("./ssm", "", NULL);
|
||||
Log::error("Steam", "Error in execl: errnp %d", errno);
|
||||
|
||||
// if we get here at all, an error occurred, but we are in the child
|
||||
// process, so just exit
|
||||
perror("Steam: execl error");
|
||||
exit(-1);
|
||||
}
|
||||
else if (child > 0)
|
||||
{
|
||||
// parent continues here
|
||||
// close unused file descriptors, these are for child only
|
||||
close(stdin_pipe[PIPE_READ]);
|
||||
close(stdout_pipe[PIPE_WRITE]);
|
||||
m_child_stdin_write = stdin_pipe[PIPE_WRITE];
|
||||
m_child_stdout_read = stdout_pipe[PIPE_READ];
|
||||
}
|
||||
else // child < 0
|
||||
{
|
||||
// failed to create child
|
||||
close(stdin_pipe[PIPE_READ]);
|
||||
close(stdin_pipe[PIPE_WRITE]);
|
||||
close(stdout_pipe[PIPE_READ]);
|
||||
close(stdout_pipe[PIPE_WRITE]);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} // createChildProcess
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Reads a command from the input pipe.
|
||||
*/
|
||||
std::string Steam::getLine()
|
||||
{
|
||||
#define BUFSIZE 1024
|
||||
char buffer[BUFSIZE];
|
||||
|
||||
#ifdef WIN32
|
||||
DWORD bytes_read;
|
||||
// Read from pipe that is the standard output for child process.
|
||||
bool success = ReadFile(m_child_stdout_read, buffer, BUFSIZE-1,
|
||||
&bytes_read, NULL)!=0;
|
||||
if (success && bytes_read < BUFSIZE)
|
||||
{
|
||||
buffer[bytes_read] = 0;
|
||||
std::string s = buffer;
|
||||
return s;
|
||||
}
|
||||
#else
|
||||
//std::string s;
|
||||
//std::getline(std::cin, s);
|
||||
//return s;
|
||||
|
||||
int bytes_read = read(m_child_stdout_read, buffer, BUFSIZE-1);
|
||||
if(bytes_read>0)
|
||||
{
|
||||
buffer[bytes_read] = 0;
|
||||
std::string s = buffer;
|
||||
return s;
|
||||
}
|
||||
#endif
|
||||
return std::string("");
|
||||
} // getLine
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Sends a command to the SSM via a pipe, and reads the answer.
|
||||
* \return Answer from SSM.
|
||||
*/
|
||||
std::string Steam::sendCommand(const std::string &command)
|
||||
{
|
||||
#ifdef WIN32
|
||||
// Write to the pipe that is the standard input for a child process.
|
||||
// Data is written to the pipe's buffers, so it is not necessary to wait
|
||||
// until the child process is running before writing data.
|
||||
DWORD bytes_written;
|
||||
bool success = WriteFile(m_child_stdin_write, command.c_str(),
|
||||
command.size()+1, &bytes_written, NULL ) != 0;
|
||||
#else
|
||||
write(m_child_stdin_write, (command+"\n").c_str(), command.size()+1);
|
||||
#endif
|
||||
return getLine();
|
||||
|
||||
return std::string("");
|
||||
} // sendCommand
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** All answer strings from 'SSM' are in the form: "length string", i.e. the
|
||||
* length of the string, followed by a space and then the actual strings.
|
||||
* This allows for checking on some potential problems (e.g. if a pipe should
|
||||
* only send part of the answer string - todo: handle this problem instead of
|
||||
* ignoring it.
|
||||
*/
|
||||
std::string Steam::decodeString(const std::string &s)
|
||||
{
|
||||
std::vector<std::string> l = StringUtils::split(s, ' ');
|
||||
if (l.size() != 2) return "INVALID ANSWER - wrong number of fields";
|
||||
|
||||
int n;
|
||||
StringUtils::fromString(l[0], n);
|
||||
if (n != (int)l[1].size()) return "INVALID ANSWER - incorrect length";
|
||||
|
||||
return l[1];
|
||||
|
||||
} // decodeString
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Returns the steam user name. SSM returns 'N name" where N is
|
||||
* the length of the name.
|
||||
*/
|
||||
const std::string& Steam::getUserName()
|
||||
{
|
||||
assert(m_steam_available);
|
||||
return m_user_name;
|
||||
} // getUserName
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Returns a unique id (string) from steam. SSM returns 'N ID" where N is
|
||||
* the length of the ID.
|
||||
*/
|
||||
const std::string& Steam::getSteamID()
|
||||
{
|
||||
assert(m_steam_available);
|
||||
return m_steam_id;
|
||||
} // getSteamID
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Returns a std::vector with the names of all friends. SSM returns a first
|
||||
* line with the number of friends, then one friend in a line.
|
||||
*/
|
||||
std::vector<std::string> Steam::getFriends()
|
||||
{
|
||||
std::string s = sendCommand("friends");
|
||||
int num_friends;
|
||||
StringUtils::fromString(s, num_friends);
|
||||
std::vector<std::string> result;
|
||||
for (int i = 0; i < num_friends; i++)
|
||||
{
|
||||
std::string f = getLine();
|
||||
result.push_back(decodeString(f));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Instructs the SSM to save the avatar of the user with the specified
|
||||
* filename. Note that the avatar is always saved in png format (independent
|
||||
* on what is specified as filename).
|
||||
*/
|
||||
int Steam::saveAvatarAs(const std::string &filename)
|
||||
{
|
||||
std::string s = sendCommand("avatar");
|
||||
if(s=="filename")
|
||||
s=sendCommand(filename);
|
||||
return s == "done";
|
||||
|
||||
} // saveAvatarAs
|
123
src/online/steam.hpp
Normal file
123
src/online/steam.hpp
Normal file
@ -0,0 +1,123 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2017 Joerg Henrichs
|
||||
//
|
||||
// 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_STEAM_HPP
|
||||
#define HEADER_STEAM_HPP
|
||||
|
||||
#include "irrString.h"
|
||||
|
||||
#ifdef WIN32
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
/** This class provides a simple interface to the SteamWorks API. Due to
|
||||
* our current license, the SteamWorks lib can not be linked with STK.
|
||||
* So this wrapper class actually starts a seprate process (ssm, see
|
||||
* https://github.com/hiker/steam-synchron-manager) and communicats
|
||||
* with the SSM using pipes.
|
||||
*/
|
||||
class Steam
|
||||
{
|
||||
private:
|
||||
/** Singleton pointer. */
|
||||
static Steam *m_steam;
|
||||
|
||||
/** True if a connection to steam was made successfully. */
|
||||
bool m_steam_available;
|
||||
|
||||
/** Steam user name. Only defined if m_steam_available. */
|
||||
std::string m_user_name;
|
||||
|
||||
/** User name as irr::stringw (wchar), which is used in STK. */
|
||||
irr::core::stringw m_user_name_wchar;
|
||||
|
||||
/** Unique steam id. */
|
||||
std::string m_steam_id;
|
||||
|
||||
#ifdef WIN32
|
||||
// Various handles for the window pipes
|
||||
HANDLE m_child_stdin_read;
|
||||
HANDLE m_child_stdin_write;
|
||||
HANDLE m_child_stdout_read;
|
||||
HANDLE m_child_stdout_write;
|
||||
|
||||
#else
|
||||
int m_child_stdin_read;
|
||||
int m_child_stdin_write;
|
||||
int m_child_stdout_read;
|
||||
int m_child_stdout_write;
|
||||
|
||||
#endif
|
||||
bool createChildProcess();
|
||||
|
||||
std::string decodeString(const std::string &s);
|
||||
std::string sendCommand(const std::string &command);
|
||||
std::string getLine();
|
||||
|
||||
Steam();
|
||||
~Steam();
|
||||
|
||||
public:
|
||||
|
||||
/** Creates a singleton. */
|
||||
static void create()
|
||||
{
|
||||
assert(!m_steam);
|
||||
m_steam = new Steam();
|
||||
} // create;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the singleton pf the Steam class. */
|
||||
static Steam *get()
|
||||
{
|
||||
assert(m_steam);
|
||||
return m_steam;
|
||||
} // get
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Destroys the singleton of the Steam class. */
|
||||
static void destroy()
|
||||
{
|
||||
assert(m_steam);
|
||||
delete m_steam;
|
||||
m_steam = NULL;
|
||||
} // destroy
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
const std::string& getUserName();
|
||||
const std::string& getSteamID();
|
||||
int saveAvatarAs(const std::string &filename);
|
||||
std::vector<std::string> getFriends();
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the user name as wide string. */
|
||||
const irr::core::stringw& getUserNameWchar()
|
||||
{
|
||||
assert(m_steam_available);
|
||||
return m_user_name_wchar;
|
||||
} // getUserNameWchar
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns true if the connection to the Steam API was successful, i.e.
|
||||
* connection to steam worked, and SteamWorks API could be initialised. */
|
||||
bool isSteamAvailable() const { return m_steam_available; }
|
||||
}; // class Steam
|
||||
|
||||
#endif // HEADER_STEAM_HPP
|
@ -24,6 +24,7 @@
|
||||
#include "guiengine/widgets/label_widget.hpp"
|
||||
#include "guiengine/widgets/ribbon_widget.hpp"
|
||||
#include "guiengine/widgets/text_box_widget.hpp"
|
||||
#include "online/steam.hpp"
|
||||
#include "online/xml_request.hpp"
|
||||
#include "states_screens/dialogs/registration_dialog.hpp"
|
||||
#include "states_screens/dialogs/message_dialog.hpp"
|
||||
@ -88,7 +89,9 @@ void RegisterScreen::init()
|
||||
}
|
||||
else if (PlayerManager::get()->getNumPlayers() == 0)
|
||||
{
|
||||
if (getenv("USERNAME") != NULL) // for windows
|
||||
if (Steam::get()->isSteamAvailable())
|
||||
username = StringUtils::utf8ToWide( Steam::get()->getUserName());
|
||||
else if (getenv("USERNAME") != NULL) // for windows
|
||||
username = getenv("USERNAME");
|
||||
else if (getenv("USER") != NULL) // Linux, Macs
|
||||
username = getenv("USER");
|
||||
|
@ -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<CheckBoxWidget>("steam");
|
||||
assert(m_steam_cb);
|
||||
m_steam_label = getWidget<LabelWidget>("label-steam");
|
||||
assert(m_steam_label);
|
||||
m_online_cb = getWidget<CheckBoxWidget>("online");
|
||||
assert(m_online_cb);
|
||||
m_username_tb = getWidget<TextBoxWidget >("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,47 @@ 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<DynamicRibbonWidget>("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);
|
||||
|
||||
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.
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user