From 630ae259ad216bd61f161be31e9734eb4351d6b8 Mon Sep 17 00:00:00 2001 From: kervala Date: Sun, 1 Oct 2017 15:10:51 +0200 Subject: [PATCH] Changed: Add Steam support in develop branch too --HG-- branch : develop --- code/CMakeModules/nel.cmake | 1 + code/ryzom/client/src/CMakeLists.txt | 18 +- code/ryzom/client/src/client.cpp | 22 ++- code/ryzom/client/src/far_tp.cpp | 49 ++++- code/ryzom/client/src/far_tp.h | 5 + code/ryzom/client/src/login.cpp | 177 +++++++++++++----- code/ryzom/client/src/login.h | 4 +- code/ryzom/tools/client/CMakeLists.txt | 5 +- .../client/client_config_qt/CMakeLists.txt | 4 + .../src/client_config_dialog.cpp | 5 + 10 files changed, 229 insertions(+), 61 deletions(-) diff --git a/code/CMakeModules/nel.cmake b/code/CMakeModules/nel.cmake index e35ce11b2..ed0847015 100644 --- a/code/CMakeModules/nel.cmake +++ b/code/CMakeModules/nel.cmake @@ -352,6 +352,7 @@ MACRO(NL_SETUP_RYZOM_DEFAULT_OPTIONS) OPTION(WITH_RYZOM_CLIENT_UAC "Ask to run as Administrator" OFF) OPTION(WITH_RYZOM_PATCH "Enable Ryzom in-game patch support" OFF) OPTION(WITH_RYZOM_CUSTOM_PATCH_SERVER "Only use patch server from CFG file" OFF) + OPTION(WITH_RYZOM_STEAM "Enable Steam features" OFF) OPTION(WITH_RYZOM_SANDBOX "Enable Sandbox under OS X" OFF) ENDMACRO(NL_SETUP_RYZOM_DEFAULT_OPTIONS) diff --git a/code/ryzom/client/src/CMakeLists.txt b/code/ryzom/client/src/CMakeLists.txt index 996a08efa..26b208c67 100644 --- a/code/ryzom/client/src/CMakeLists.txt +++ b/code/ryzom/client/src/CMakeLists.txt @@ -13,7 +13,11 @@ IF(WITH_RYZOM_CLIENT) MESSAGE(FATAL_ERROR "The client cannot be built without the NeL GUI Library (WITH_GUI)") ENDIF() - IF(WITH_RYZOM_PATCH) + # Patch should never be enabled on Steam + IF(WITH_RYZOM_STEAM) + ADD_DEFINITIONS(-DRZ_USE_STEAM) + FIND_PACKAGE(Steam) + ELSEIF(WITH_RYZOM_PATCH) ADD_DEFINITIONS(-DRZ_USE_PATCH) IF(WITH_RYZOM_CUSTOM_PATCH_SERVER) @@ -131,6 +135,14 @@ IF(WITH_RYZOM_CLIENT) ENDIF() ENDIF() + IF(WITH_RYZOM_STEAM AND STEAM_RUNTIME) + ADD_CUSTOM_COMMAND(TARGET ryzom_client POST_BUILD COMMAND cp -p ${STEAM_RUNTIME} ${RYZOM_CONTENTS_DIR}/MacOS) + + IF(CODESIGN_ALLOCATE AND APPLE_CERTIFICATE) + ADD_CUSTOM_COMMAND(TARGET ryzom_client POST_BUILD COMMAND CODESIGN_ALLOCATE=${CODESIGN_ALLOCATE} codesign --no-strict -fs "${APPLE_CERTIFICATE}" "${RYZOM_CONTENTS_DIR}/MacOS/${STEAM_RUNTIMENAME}" COMMENT "Signing Steam client runtime...") + ENDIF() + ENDIF() + IF(CODESIGN_ALLOCATE AND APPLE_CERTIFICATE) ADD_CUSTOM_COMMAND(TARGET ryzom_client POST_BUILD COMMAND CODESIGN_ALLOCATE=${CODESIGN_ALLOCATE} codesign ${ENTITLEMENTS} -fs "${APPLE_CERTIFICATE}" "${RYZOM_OUTPUT_DIR}" COMMENT "Signing Ryzom bundle...") ENDIF() @@ -146,6 +158,10 @@ IF(WITH_RYZOM_CLIENT) ${OPENSSL_INCLUDE_DIR} ) + IF(STEAM_FOUND) + INCLUDE_DIRECTORIES(${STEAM_INCLUDE_DIRS}) + ENDIF() + TARGET_LINK_LIBRARIES(ryzom_client nelmisc nelnet diff --git a/code/ryzom/client/src/client.cpp b/code/ryzom/client/src/client.cpp index a487bf8dd..c92bb887b 100644 --- a/code/ryzom/client/src/client.cpp +++ b/code/ryzom/client/src/client.cpp @@ -54,6 +54,10 @@ #include "far_tp.h" #include "user_agent.h" +#ifdef RZ_USE_STEAM +#include "steam_client.h" +#endif + /////////// // USING // /////////// @@ -193,13 +197,17 @@ int main(int argc, char **argv) // no shard id in ring mode std::string sLoginShardId; - if (Args.haveAdditionalArg("login") && Args.haveAdditionalArg("password")) + if (Args.haveAdditionalArg("login")) { LoginLogin = Args.getAdditionalArg("login").front(); - LoginPassword = Args.getAdditionalArg("password").front(); - if (Args.haveAdditionalArg("shard_id")) - sLoginShardId = Args.getAdditionalArg("shard_id").front(); + if (Args.haveAdditionalArg("password")) + { + LoginPassword = Args.getAdditionalArg("password").front(); + + if (Args.haveAdditionalArg("shard_id")) + sLoginShardId = Args.getAdditionalArg("shard_id").front(); + } } if (sLoginShardId.empty() || !fromString(sLoginShardId, LoginShardId)) @@ -282,6 +290,12 @@ int main(int argc, char **argv) // initialize log initLog(); +#ifdef RZ_USE_STEAM + CSteamClient steamClient; + + if (steamClient.init()) + LoginCustomParameters = "&steam_auth_session_ticket=" + steamClient.getAuthSessionTicket(); +#endif // initialize patch manager and set the ryzom full path, before it's used CPatchManager *pPM = CPatchManager::getInstance(); diff --git a/code/ryzom/client/src/far_tp.cpp b/code/ryzom/client/src/far_tp.cpp index b5a0b19d1..bafb62103 100644 --- a/code/ryzom/client/src/far_tp.cpp +++ b/code/ryzom/client/src/far_tp.cpp @@ -189,7 +189,7 @@ const std::string& CLoginStateMachine::toString(CLoginStateMachine::TEvent event break; \ } \ -extern std::string LoginLogin, LoginPassword; +extern std::string LoginLogin, LoginPassword, LoginCustomParameters; extern bool noUserChar; extern bool userChar; extern bool serverReceivedReady; @@ -246,14 +246,26 @@ void CLoginStateMachine::run() if (!ClientCfg.TestBrowser) { - if (LoginLogin.empty()) + if (LoginPassword.empty()) { - // standard procedure - SM_BEGIN_EVENT_TABLE - SM_EVENT(ev_init_done, st_login); - SM_EVENT(ev_skip_all_login, st_ingame); - SM_EVENT(ev_quit, st_end); - SM_END_EVENT_TABLE + if (!LoginCustomParameters.empty() && LoginLogin.empty()) + { + // alternate login procedure + SM_BEGIN_EVENT_TABLE + SM_EVENT(ev_init_done, st_alt_login); + SM_EVENT(ev_skip_all_login, st_ingame); + SM_EVENT(ev_quit, st_end); + SM_END_EVENT_TABLE + } + else + { + // standard procedure + SM_BEGIN_EVENT_TABLE + SM_EVENT(ev_init_done, st_login); + SM_EVENT(ev_skip_all_login, st_ingame); + SM_EVENT(ev_quit, st_end); + SM_END_EVENT_TABLE + } } else { @@ -325,6 +337,27 @@ void CLoginStateMachine::run() // SM_EVENT(ev_login_ok, st_check_patch); // SM_EVENT(ev_quit, st_end); // SM_END_EVENT_TABLE +// } + break; + case st_alt_login: + initAltLogin(); + +// if (ClientCfg.R2Mode) + { + // r2 mode + SM_BEGIN_EVENT_TABLE + SM_EVENT(ev_login_not_alt, st_login); + SM_EVENT(ev_login_ok, st_check_patch); + SM_EVENT(ev_quit, st_end); + SM_END_EVENT_TABLE + } +// else +// { +// // legacy mode +// SM_BEGIN_EVENT_TABLE +// SM_EVENT(ev_login_ok, st_check_patch); +// SM_EVENT(ev_quit, st_end); +// SM_END_EVENT_TABLE // } break; case st_shard_list: diff --git a/code/ryzom/client/src/far_tp.h b/code/ryzom/client/src/far_tp.h index cec696ba3..a4c8f77b4 100644 --- a/code/ryzom/client/src/far_tp.h +++ b/code/ryzom/client/src/far_tp.h @@ -81,6 +81,8 @@ public: st_rate_session, /// create account st_create_account, + /// try to login with alternate login system + st_alt_login, /// pseudo state to leave the state machine st_end, /// @@ -156,6 +158,8 @@ public: ev_create_account, /// the client push the 'create account' button ev_close_create_account, + /// the client want to use alternate login system + ev_login_not_alt, /// ev_unknown }; @@ -203,6 +207,7 @@ void initEula(); void initPatchCheck(); void initCatDisplay(); void initAutoLogin(); +void initAltLogin(); void initPatch(); //void initWebBrowser(); void initReboot(); diff --git a/code/ryzom/client/src/login.cpp b/code/ryzom/client/src/login.cpp index 36aaa2a54..986465986 100644 --- a/code/ryzom/client/src/login.cpp +++ b/code/ryzom/client/src/login.cpp @@ -81,7 +81,7 @@ extern bool SetMousePosFirstTime; vector Shards; -string LoginLogin, LoginPassword, ClientApp, Salt; +string LoginLogin, LoginPassword, ClientApp, Salt, LoginCustomParameters; uint32 LoginShardId = 0xFFFFFFFF; @@ -847,6 +847,55 @@ void initAutoLogin() } } +void initAltLogin() +{ + // Check the alt param + if (!LoginCustomParameters.empty()) + { + // don't use login and password for alternate login + string res = checkLogin("", "", ClientApp, LoginCustomParameters); + if (res.empty()) + { + if (ClientCfg.R2Mode) + { + LoginSM.pushEvent(CLoginStateMachine::ev_login_ok); + } + else + { + // Select good shard + ShardSelected = -1; + for (uint32 i = 0; i < Shards.size(); ++i) + { + if (Shards[i].ShardId == LoginShardId) + { + ShardSelected = i; + break; + } + } + + if (ShardSelected == -1) + { + CInterfaceManager *pIM = CInterfaceManager::getInstance(); + pIM->messageBoxWithHelp(CI18N::get("uiErrServerLost"), "ui:login"); + LoginSM.pushEvent(CLoginStateMachine::ev_quit); + } + else + { + LoginSM.pushEvent(CLoginStateMachine::ev_login_ok); + } + } + + return; + } + } + + // close the socket in case of error + HttpClient.disconnect(); + + // ignore error + LoginSM.pushEvent(CLoginStateMachine::ev_login_not_alt); +} + // *************************************************************************** // Called from client.cpp @@ -1174,7 +1223,7 @@ void onlogin(bool vanishScreen = true) // Check the login/pass // main menu page for r2mode - string res = checkLogin(LoginLogin, LoginPassword, ClientApp); + string res = checkLogin(LoginLogin, LoginPassword, ClientApp, LoginCustomParameters); if (res.empty()) { // if not in auto login, push login ok event @@ -1901,16 +1950,33 @@ class CAHOpenURL : public IActionHandler return; } + // modify existing languages + + // old site string::size_type pos_lang = url.find("/en/"); - if(pos_lang!=string::npos) - url.replace(pos_lang+1, 2, ClientCfg.getHtmlLanguageCode()); + // or new forums + if (pos_lang == string::npos) + pos_lang = url.find("=en#"); - if(url.find('?')!=string::npos) - url += "&"; + if (pos_lang != string::npos) + { + url.replace(pos_lang + 1, 2, ClientCfg.getHtmlLanguageCode()); + } else - url += "?"; - url += "language=" + ClientCfg.LanguageCode; + { + // append language + if (url.find('?') != string::npos) + url += "&"; + else + url += "?"; + + url += "language=" + ClientCfg.LanguageCode; + + if (!LoginCustomParameters.empty()) + url += LoginCustomParameters; + } + openURL(url); nlinfo("openURL %s", url.c_str()); @@ -2333,6 +2399,10 @@ bool initCreateAccount() CurlHttpClient.verifyServer(true); // set this to false if you need to connect to the test environment std::string params = "language=" + lang; + + if (!LoginCustomParameters.empty()) + params += LoginCustomParameters; + if(!CurlHttpClient.sendGet(url, params, pPM->isVerboseLog())) { ucstring errorMessage("Can't send (error code 60)"); @@ -2523,6 +2593,9 @@ class CAHOnCreateAccountSubmit : public IActionHandler if(conditionsPushed) params += "&TaC=1"; + if (!LoginCustomParameters.empty()) + params += LoginCustomParameters; + std::string md5 = results[0] + results[1] + "" + results[3]; md5 = NLMISC::getMD5((uint8*)md5.data(), (uint32)md5.size()).toString(); @@ -2707,7 +2780,7 @@ REGISTER_ACTION_HANDLER (CAHOnBackToLogin, "on_back_to_login"); // *************************************************************************** -string checkLogin(const string &login, const string &password, const string &clientApp) +string checkLogin(const string &login, const string &password, const string &clientApp, const std::string &customParameters) { CPatchManager *pPM = CPatchManager::getInstance(); Shards.clear(); @@ -2725,50 +2798,64 @@ string checkLogin(const string &login, const string &password, const string &cli std::string url = ClientCfg.ConfigFile.getVar("StartupHost").asString() + ClientCfg.ConfigFile.getVar("StartupPage").asString(); - // ask server for salt - if(!HttpClient.sendGet(url + "?cmd=ask&cp=2&login=" + login + "&lg=" + ClientCfg.LanguageCode, "", pPM->isVerboseLog())) - return "Can't send (error code 60)"; - - if(pPM->isVerboseLog()) nlinfo("Sent request for password salt"); - - if(!HttpClient.receive(res, pPM->isVerboseLog())) - return "Can't receive (error code 61)"; - - if(pPM->isVerboseLog()) nlinfo("Received request login check"); - - if(res.empty()) - return "Empty answer from server (error code 62)"; - - if(res[0] == '0') + // don't use login with alt method + if (!login.empty()) { - // server returns an error - nlwarning("server error: %s", res.substr(2).c_str()); - return res.substr(2); - } - else if(res[0] == '1') - { - Salt = res.substr(2); - } - else - { - // server returns ??? - nlwarning("%s", res.c_str()); - return res; - } + // ask server for salt + if(!HttpClient.sendGet(url + "?cmd=ask&cp=2&login=" + login + "&lg=" + ClientCfg.LanguageCode, "", pPM->isVerboseLog())) + return "Can't send (error code 60)"; - // send login + crypted password + client app and cp=2 (as crypted password) - if(!HttpClient.connectToLogin()) - return "Can't connect (error code 63)"; + if(pPM->isVerboseLog()) nlinfo("Sent request for password salt"); - if(pPM->isVerboseLog()) nlinfo("Connected"); + if(!HttpClient.receive(res, pPM->isVerboseLog())) + return "Can't receive (error code 61)"; + + if(pPM->isVerboseLog()) nlinfo("Received request login check"); + + if(res.empty()) + return "Empty answer from server (error code 62)"; + + if(res[0] == '0') + { + // server returns an error + nlwarning("server error: %s", res.substr(2).c_str()); + return res.substr(2); + } + else if(res[0] == '1') + { + Salt = res.substr(2); + } + else + { + // server returns ??? + nlwarning("%s", res.c_str()); + return res; + } + + // send login + crypted password + client app and cp=2 (as crypted password) + if(!HttpClient.connectToLogin()) + return "Can't connect (error code 63)"; + + if(pPM->isVerboseLog()) nlinfo("Connected"); + } if (ClientCfg.R2Mode) { // R2 login sequence - std::string cryptedPassword = CCrypt::crypt(password, Salt); - if(!HttpClient.sendGet(url + "?cmd=login&login=" + login + "&password=" + cryptedPassword + "&clientApplication=" + clientApp + "&cp=2" + "&lg=" + ClientCfg.LanguageCode)) - return "Can't send (error code 2)"; + if (!login.empty()) + { + std::string cryptedPassword = CCrypt::crypt(password, Salt); + + if(!HttpClient.sendGet(url + "?cmd=login&login=" + login + "&password=" + cryptedPassword + "&clientApplication=" + clientApp + "&cp=2" + "&lg=" + ClientCfg.LanguageCode + customParameters)) + return "Can't send (error code 2)"; + } + else + { + // don't send login and password if empty + if(!HttpClient.sendGet(url + "?cmd=login&clientApplication=" + clientApp + "&cp=2" + "&lg=" + ClientCfg.LanguageCode + customParameters)) + return "Can't send (error code 2)"; + } // the response should contains the result code and the cookie value if(pPM->isVerboseLog()) nlinfo("Sent request login check"); diff --git a/code/ryzom/client/src/login.h b/code/ryzom/client/src/login.h index ad2388100..2c6e8c960 100644 --- a/code/ryzom/client/src/login.h +++ b/code/ryzom/client/src/login.h @@ -46,7 +46,7 @@ struct CShard std::string EmergencyPatchURL; }; -extern std::string LoginLogin, LoginPassword; +extern std::string LoginLogin, LoginPassword, LoginCustomParameters; extern uint32 LoginShardId; @@ -54,7 +54,7 @@ extern uint32 AvailablePatchs; -std::string checkLogin(const std::string &login, const std::string &password, const std::string &clientApp); +std::string checkLogin(const std::string &login, const std::string &password, const std::string &clientApp, const std::string &customParameters = ""); std::string selectShard(uint32 shardId, std::string &cookie, std::string &addr); std::string getBGDownloaderCommandLine(); diff --git a/code/ryzom/tools/client/CMakeLists.txt b/code/ryzom/tools/client/CMakeLists.txt index 51cae98e7..66f8c9b48 100644 --- a/code/ryzom/tools/client/CMakeLists.txt +++ b/code/ryzom/tools/client/CMakeLists.txt @@ -1,5 +1,8 @@ IF(WITH_RYZOM_CLIENT) - ADD_SUBDIRECTORY(client_patcher) + # Don't need ryzom_client_patcher if using Steam + IF(NOT WITH_RYZOM_STEAM) + ADD_SUBDIRECTORY(client_patcher) + ENDIF() IF(WITH_QT OR WITH_QT5) ADD_SUBDIRECTORY(client_config_qt) diff --git a/code/ryzom/tools/client/client_config_qt/CMakeLists.txt b/code/ryzom/tools/client/client_config_qt/CMakeLists.txt index 9cbe2bd3b..c81bfcbae 100644 --- a/code/ryzom/tools/client/client_config_qt/CMakeLists.txt +++ b/code/ryzom/tools/client/client_config_qt/CMakeLists.txt @@ -29,6 +29,10 @@ ELSE() QT5_WRAP_UI(CLIENT_CONFIG_UI_HDRS ${CLIENT_CONFIG_UIS}) ENDIF() +IF(WITH_RYZOM_STEAM) + ADD_DEFINITIONS(-DRZ_USE_STEAM) +ENDIF() + SOURCE_GROUP("Resources" FILES ${CLIENT_CONFIG_RCS}) SOURCE_GROUP("Forms" FILES ${CLIENT_CONFIG_UIS}) SOURCE_GROUP("Generated Files" FILES ${CLIENT_CONFIG_UI_HDRS} ${CLIENT_CONFIG_MOC_SRC}) diff --git a/code/ryzom/tools/client/client_config_qt/src/client_config_dialog.cpp b/code/ryzom/tools/client/client_config_qt/src/client_config_dialog.cpp index ecac3ccdb..31fcfd1ac 100644 --- a/code/ryzom/tools/client/client_config_qt/src/client_config_dialog.cpp +++ b/code/ryzom/tools/client/client_config_qt/src/client_config_dialog.cpp @@ -86,6 +86,11 @@ CClientConfigDialog::CClientConfigDialog( QWidget *parent ) : item->setHidden(true); #endif +#ifdef RZ_USE_STEAM + // Hide Play Ryzom button if using Steam because we need to launch it from Steam + playButton->setHidden(true); +#endif + CategoryStackedWidget->addWidget( new CGeneralSettingsWidget( CategoryStackedWidget ) ); CategoryStackedWidget->addWidget( new CDisplaySettingsWidget( CategoryStackedWidget ) ); CategoryStackedWidget->addWidget( new CDisplaySettingsDetailsWidget( CategoryStackedWidget ) );