// Ryzom - MMORPG Framework // Copyright (C) 2010 Winch Gate Property Limited // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero 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 Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . #ifndef FAR_TP_H #define FAR_TP_H #include "nel/misc/co_task.h" #include #include #include "game_share/security_check.h" class CLoginStateMachine : private NLMISC::CCoTask { public: enum TState { /// initial state st_start, /// display login screen and options st_login, /// auto login using cmd lien parameters (used with patch reboot) st_auto_login, /// display the shard list st_shard_list, /// lauch the configurator and close ryzom st_start_config, /// run the scan data thread st_scan_data, /// display the eula and wait for validation st_display_eula, /// check the data to determine need for patch st_check_patch, /// display the list of optional patch category for patching st_display_cat, /// run the patch process and display progress st_patch, /// terminate the client and quit st_close_client, /// display the reboot screen and wait validation st_reboot_screen, /// restart the client with login bypass params st_restart_client, /// connect to the FS (start the 'in game' mode) st_connect, /// show the outgame browser st_browser_screen, /// ingame state st_ingame, /// leave the current shard (the exit action progress, Far TP part 1.1; Server Hop part 1-2) st_leave_shard, /// let the main loop finish the current frame and leave it (Far TP part 1.2) st_enter_far_tp_main_loop, /// disconnect from the FS (Far TP part 2) st_disconnect, /// connect to a new FS (Far TP & Server Hop part 3.1) st_reconnect_fs, /// after reconnecting, bypass character selection ui & select the same character (Far TP & Server Hop part 3.2) st_reconnect_select_char, /// after reconnecting and receiving ready, send ready (Far TP part 3.3) st_reconnect_ready, /// between global menu exit and sending ready (Server Hop part 3.3) st_exit_global_menu, /// error while reconnecting st_reconnect_error, /// Rate a ring session. should pop a web windows pointing the rate session page 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, /// st_unknown }; /// For displaying static const std::string& toString(TState state); enum TEvent { /// the client click the 'quit' button ev_quit, /// the client is connecting without authentication (dev mode) ev_skip_all_login, /// the init is done ev_init_done, /// the client push the 'config' button ev_game_conf, /// the client push the 'scan data' button ev_data_scan, /// the client push the 'scan data' button ev_close_data_scan, /// the login is validated and cookie is received ev_login_ok, /// the login check as failed ev_bad_login, /// the client has selected a shard ev_shard_selected, /// the patch checker says we need to ev_patch_needed ev_patch_needed, /// the patch check says we are clean, no patch needed ev_no_patch, /// the user validate the category screen, patch can begin ev_run_patch, /// the client validate the patch result ev_close_patch, /// Client accept the eula screen ev_accept_eula, /// Client decline the eula screen ev_decline_eula, /// the client valide the reboot message box ev_reboot, /// the ingame session terminates (CONNECTION:SERVER_QUIT_OK msg) ev_ingame_return, /// the far tp main loop is entered ev_far_tp_main_loop_entered, /// the lua script (from web usually) starts the client connection to a shard ev_connect, /// the connection fail for some reason ev_conn_failed, /// the connection was dropped by the server ev_conn_dropped, /// the client enters the game main loop ev_enter_game, // a self reconnetion is complete, get back to outgame menu ev_self_reconnected, /// characters received (CONNECTION:USER_CHARS msg) ev_chars_received, /// characters received but empty (CONNECTION:NO_USER_CHAR msg) ev_no_user_char, /// ready received (CONNECTION:READY msg) ev_ready_received, /// reselect character (CONNECTION:RECO // ev_reselect_char, /// reconnect ok received (CONNECTION:SERVER_RECONNECT_OK msg) ev_reconnect_ok_received, /// global menu exited ev_global_menu_exited, /// The client click the 'relog' button ev_relog, /// the client push the 'create account' button 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 }; /// For displaying static const std::string& toString(TEvent event); private: TState _CurrentState; std::list _NextEvents; public: // Create the state machine with the wanted start. // Note that, because it is a co-task, restarting the state machine after it has finished // require to delete then recreate this object CLoginStateMachine() : _CurrentState(st_start) { } TState getCurrentState() { return _CurrentState; } void pushEvent(TEvent eventId); TEvent waitEvent(); private: void run(); }; extern CLoginStateMachine LoginSM; void initLoginScreen(); void initShardDisplay(); void initDataScan(); bool initCreateAccount(); void initEula(); void initPatchCheck(); void initCatDisplay(); void initAutoLogin(); void initAltLogin(); void initPatch(); //void initWebBrowser(); void initReboot(); void ConnectToShard(); void waitForUserCharReceived(); /** */ class CFarTP { public: // See definition of _URLTable for url binding enum TJoinMode { LaunchEditor, JoinSession, JoinMainland, NbJoinModes }; CFarTP() : _Reason(NULL), _SessionIdToJoinFast(0), _InGameMode(false), _PreviousR2EdEnabled(false), _ReselectingChar(false), _IsServerHopEmbedded(false), _HookedForEditor(false), _DSSDown(false) /*, _SelfReconnecting(false)*/ {} // Get the address of a front-end service via http, then begin Far TP bool requestFarTPToSession(TSessionId sessionId, uint8 charSlot, CFarTP::TJoinMode joinMode, bool bailOutIfSessionVanished); // Ask the EGS to pop the top position if applicable void requestReturnToPreviousSession(TSessionId rejectedSessionId=TSessionId(0)); // Store the result of a JoinSession request for the next disconnection request void setJoinSessionResult(TSessionId sessionId, const CSecurityCode& securityCode); // Tell to ignore the next Far TP request, it will be replaced by a Far TP to the edition session (allows to shortcut anim-mainland-edition by anim-edition) void hookNextFarTPForEditor(); /// Begin a Character Reselect sequence void requestReconnection(); // These states can overlap bool isIngame() const { return _InGameMode; } bool isFarTPInProgress() const; bool isServerHopInProgress() const; bool isLeavingEGS() const { return (LoginSM.getCurrentState() == CLoginStateMachine::st_leave_shard); } bool isLeavingShard() const; // from begin of Far TP to disconnection bool isJoiningShard() const; // from reconnection to game entering bool isReselectingChar() const { return _ReselectingChar; } bool isServerHopEmbedded() const { return _IsServerHopEmbedded; } bool isFastDisconnectGranted() const { return _SessionIdToJoinFast != 0; } // Far TP from the main loop void farTPmainLoop(); void writeSecurityCodeForDisconnection(NLMISC::IStream& msgout); void onServerQuitOk(); void onServerQuitAbort(); void disconnectFromPreviousShard(); void connectToNewShard(); bool reselectCharacter(); void selectCharAndEnter(); void sendReady(); void onFailure(); void onDssDown(bool forceReturn=false); void setIngame() { _InGameMode = true; } void setOutgame() { _InGameMode = false; } void setMainLoopEntered() { setIngame(); _ReselectingChar = false; } void beginEmbeddedServerHop() { _IsServerHopEmbedded = true; setOutgame(); _ReselectingChar = false; } void endEmbeddedServerHop() { _IsServerHopEmbedded = false; setIngame(); _ReselectingChar = true; } void setURLBase(const std::string& urlBase) { _URLBase = urlBase; } private: // called back from session browser after a far tp request void joinSessionResult(uint32 userId, TSessionId sessionId, uint32 result, const std::string &shardAddr, const std::string &participantStatus); std::string *_Reason; static const char *_URLTable[NbJoinModes]; std::string _URLBase; TSessionId _SessionIdToJoinFast; // if non 0, fast disconnection allowed to session CSecurityCode _SecurityCodeForDisconnection; bool _InGameMode; // formerly known as EnterWorld bool _PreviousR2EdEnabled; bool _ReselectingChar; bool _IsServerHopEmbedded; // allows to embed a server hop inside a char reselect (e.g. click on Launch Editor of PLAY with a character on a remote shard) bool _HookedForEditor; // allows to Far TP to editor instead of following the next Far TP request bool _DSSDown; // remembers a DSSDown event if occurs during a FarTP // bool _SelfReconnecting; // allows to disconnect after character selection and reconnect until the player can choose another character }; extern CFarTP FarTP; #endif // FAR_TP_H