307 lines
9.7 KiB
C
307 lines
9.7 KiB
C
|
// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||
|
// 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 <http://www.gnu.org/licenses/>.
|
||
|
|
||
|
#ifndef FAR_TP_H
|
||
|
#define FAR_TP_H
|
||
|
|
||
|
#include "nel/misc/co_task.h"
|
||
|
#include <list>
|
||
|
#include <string>
|
||
|
#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,
|
||
|
/// 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,
|
||
|
///
|
||
|
ev_unknown
|
||
|
};
|
||
|
|
||
|
/// For displaying
|
||
|
static const std::string& toString(TEvent event);
|
||
|
|
||
|
|
||
|
private:
|
||
|
TState _CurrentState;
|
||
|
std::list<TEvent> _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 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
|