/*
===========================================================================
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
Doom 3 BFG Edition Source Code 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.
Doom 3 BFG Edition Source Code 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 Doom 3 BFG Edition Source Code. If not, see .
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#undef private
#undef protected
#include "win32/win_achievements.h"
#include "win32/win_signin.h"
#include "sys_lobby_backend.h"
#include "sys_lobby.h"
class idSaveGameProcessorNextMap;
class idSaveGameProcessorSaveGame;
class idSaveGameProcessorLoadGame;
class idSaveGameProcessorDelete;
class idSaveGameProcessorEnumerateGames;
/*
================================================
idLobbyStub
================================================
*/
class idLobbyStub : public idLobbyBase {
public:
virtual bool IsHost() const { return false; }
virtual bool IsPeer() const { return false; }
virtual bool HasActivePeers() const { return false; }
virtual int GetNumLobbyUsers() const { return 0; }
virtual int GetNumActiveLobbyUsers() const { return 0; }
virtual bool IsLobbyUserConnected( int index ) const { return false; }
virtual lobbyUserID_t GetLobbyUserIdByOrdinal( int userIndex ) const { return lobbyUserID_t(); }
virtual int GetLobbyUserIndexFromLobbyUserID( lobbyUserID_t lobbyUserID ) const { return -1; }
virtual void SendReliable( int type, idBitMsg & msg, bool callReceiveReliable = true, peerMask_t sessionUserMask = MAX_UNSIGNED_TYPE( peerMask_t ) ) {}
virtual void SendReliableToLobbyUser( lobbyUserID_t lobbyUserID, int type, idBitMsg & msg ) {}
virtual void SendReliableToHost( int type, idBitMsg & msg ) {}
virtual const char * GetLobbyUserName( lobbyUserID_t lobbyUserID ) const { return "INVALID"; }
virtual void KickLobbyUser( lobbyUserID_t lobbyUserID ) {}
virtual bool IsLobbyUserValid( lobbyUserID_t lobbyUserID ) const { return false; }
virtual bool IsLobbyUserLoaded( lobbyUserID_t lobbyUserID ) const { return false; }
virtual bool LobbyUserHasFirstFullSnap( lobbyUserID_t lobbyUserID ) const { return false; }
virtual void EnableSnapshotsForLobbyUser( lobbyUserID_t lobbyUserID ) {}
virtual int GetLobbyUserSkinIndex( lobbyUserID_t lobbyUserID ) const { return 0; }
virtual bool GetLobbyUserWeaponAutoReload( lobbyUserID_t lobbyUserID ) const { return false; }
virtual bool GetLobbyUserWeaponAutoSwitch( lobbyUserID_t lobbyUserID ) const { return false; }
virtual int GetLobbyUserLevel( lobbyUserID_t lobbyUserID ) const { return 0; }
virtual int GetLobbyUserQoS( lobbyUserID_t lobbyUserID ) const { return 0; }
virtual int GetLobbyUserTeam( lobbyUserID_t lobbyUserID ) const { return 0; }
virtual bool SetLobbyUserTeam( lobbyUserID_t lobbyUserID, int teamNumber ) { return false; }
virtual int GetLobbyUserPartyToken( lobbyUserID_t lobbyUserID ) const { return 0; }
virtual idPlayerProfile * GetProfileFromLobbyUser( lobbyUserID_t lobbyUserID ) { return NULL; }
virtual idLocalUser * GetLocalUserFromLobbyUser( lobbyUserID_t lobbyUserID ) { return NULL; }
virtual int GetNumLobbyUsersOnTeam( int teamNumber ) const { return 0; }
virtual int PeerIndexFromLobbyUser( lobbyUserID_t lobbyUserID ) const { return -1; }
virtual int GetPeerTimeSinceLastPacket( int peerIndex ) const { return 0; }
virtual int PeerIndexForHost() const { return -1; }
virtual lobbyUserID_t AllocLobbyUserSlotForBot( const char * botName ) { return lobbyUserID_t(); }
virtual void RemoveBotFromLobbyUserList( lobbyUserID_t lobbyUserID ) {}
virtual bool GetLobbyUserIsBot( lobbyUserID_t lobbyUserID ) const { return false; }
virtual const char * GetHostUserName() const { return "INVALID"; }
virtual const idMatchParameters & GetMatchParms() const { return fakeParms; }
virtual bool IsLobbyFull() const { return false; }
virtual bool EnsureAllPeersHaveBaseState() { return false; }
virtual bool AllPeersInGame() const { return false; }
virtual int GetNumConnectedPeers() const { return 0; }
virtual int GetNumConnectedPeersInGame() const { return 0; }
virtual int PeerIndexOnHost() const { return -1; }
virtual bool IsPeerDisconnected( int peerIndex ) const { return false; }
virtual bool AllPeersHaveStaleSnapObj( int objId ) { return false; }
virtual bool AllPeersHaveExpectedSnapObj( int objId ) { return false; }
virtual void RefreshSnapObj( int objId ) {}
virtual void MarkSnapObjDeleted( int objId ) {}
virtual void AddSnapObjTemplate( int objID, idBitMsg & msg ) {}
virtual void DrawDebugNetworkHUD() const {}
virtual void DrawDebugNetworkHUD2() const {}
virtual void DrawDebugNetworkHUD_ServerSnapshotMetrics( bool draw ) {}
private:
idMatchParameters fakeParms;
};
/*
================================================
idSessionLocal
================================================
*/
class idSessionLocal : public idSession {
friend class idLeaderboards;
friend class idStatsSession;
friend class idLobbyBackend360;
friend class idLobbyBackendPS3;
friend class idSessionLocalCallbacks;
friend class idPsnAsyncSubmissionLookupPS3_TitleStorage;
friend class idNetSessionPort;
friend class lobbyAddress_t;
protected:
//=====================================================================================================
// Mixed Common/Platform enums/structs
//=====================================================================================================
// Overall state of the session
enum state_t {
STATE_PRESS_START, // We are at press start
STATE_IDLE, // We are at the main menu
STATE_PARTY_LOBBY_HOST, // We are in the party lobby menu as host
STATE_PARTY_LOBBY_PEER, // We are in the party lobby menu as a peer
STATE_GAME_LOBBY_HOST, // We are in the game lobby as a host
STATE_GAME_LOBBY_PEER, // We are in the game lobby as a peer
STATE_GAME_STATE_LOBBY_HOST, // We are in the game state lobby as a host
STATE_GAME_STATE_LOBBY_PEER, // We are in the game state lobby as a peer
STATE_CREATE_AND_MOVE_TO_PARTY_LOBBY, // We are creating a party lobby, and will move to that state when done
STATE_CREATE_AND_MOVE_TO_GAME_LOBBY, // We are creating a game lobby, and will move to that state when done
STATE_CREATE_AND_MOVE_TO_GAME_STATE_LOBBY, // We are creating a game state lobby, and will move to that state when done
STATE_FIND_OR_CREATE_MATCH,
STATE_CONNECT_AND_MOVE_TO_PARTY,
STATE_CONNECT_AND_MOVE_TO_GAME,
STATE_CONNECT_AND_MOVE_TO_GAME_STATE,
STATE_BUSY, // Doing something internally like a QoS/bandwidth challenge
// These are last, so >= STATE_LOADING tests work
STATE_LOADING, // We are loading the map, preparing to go into a match
STATE_INGAME, // We are currently in a match
NUM_STATES
};
enum connectType_t {
CONNECT_NONE = 0,
CONNECT_DIRECT = 1,
CONNECT_FIND_OR_CREATE = 2,
};
enum pendingInviteMode_t {
PENDING_INVITE_NONE = 0, // No invite waiting
PENDING_INVITE_WAITING = 1, // Invite is waiting
PENDING_SELF_INVITE_WAITING = 2, // We invited ourselves to a match
};
struct contentData_t {
bool isMounted;
idStrStatic<128> displayName;
idStrStatic< MAX_OSPATH > packageFileName;
idStrStatic< MAX_OSPATH > rootPath;
int dlcID;
};
public:
idSessionLocal();
virtual ~idSessionLocal();
void InitBaseState();
virtual bool IsPlatformPartyInLobby();
// Downloadable Content
virtual int GetNumContentPackages() const;
virtual int GetContentPackageID( int contentIndex ) const;
virtual const char * GetContentPackagePath( int contentIndex ) const;
virtual int GetContentPackageIndexForID( int contentID ) const;
virtual bool GetSystemMarketplaceHasNewContent() const { return marketplaceHasNewContent; }
virtual void SetSystemMarketplaceHasNewContent( bool hasNewContent ) { marketplaceHasNewContent = hasNewContent; }
// Lobby management
virtual void CreatePartyLobby( const idMatchParameters & parms_ );
virtual void FindOrCreateMatch( const idMatchParameters & parms );
virtual void CreateMatch( const idMatchParameters & parms_ );
virtual void CreateGameStateLobby( const idMatchParameters & parms_ );
virtual void UpdatePartyParms( const idMatchParameters & parms_ );
virtual void UpdateMatchParms( const idMatchParameters & parms_ );
virtual void StartMatch();
virtual void SetSessionOption( sessionOption_t option ) { sessionOptions |= option; }
virtual void ClearSessionOption( sessionOption_t option ) { sessionOptions &= ~option; }
virtual sessionState_t GetBackState();
virtual void Cancel();
virtual void MoveToPressStart();
virtual void FinishDisconnect();
virtual bool ShouldShowMigratingDialog() const; // Note this is not in sys_session.h
virtual bool IsCurrentLobbyMigrating() const;
virtual bool IsLosingConnectionToHost() const;
// Migration
virtual bool WasMigrationGame() const;
virtual bool ShouldRelaunchMigrationGame() const;
virtual bool GetMigrationGameData( idBitMsg & msg, bool reading );
virtual bool GetMigrationGameDataUser( lobbyUserID_t lobbyUserID, idBitMsg & msg, bool reading );
virtual bool WasGameLobbyCoalesced() const { return gameLobbyWasCoalesced; }
// Misc
virtual int GetLoadingID() { return loadingID; }
virtual bool IsAboutToLoad() const { return GetGameLobby().IsLobbyActive() && GetGameLobby().startLoadingFromHost; }
virtual bool GetMatchParamUpdate( int &peer, int &msg );
virtual int GetInputRouting( int inputRouting[ MAX_INPUT_DEVICES ] );
virtual void EndMatch( bool premature=false ); // Meant for host to end match gracefully, go back to lobby, tally scores, etc
virtual void MatchFinished(); // this is for when the game is over before we go back to lobby. Need this incase the host leaves during this time
virtual void QuitMatch(); // Meant for host or peer to quit the match before it ends, will instigate host migration, etc
virtual void QuitMatchToTitle(); // Will forcefully quit the match and return to the title screen.
virtual void LoadingFinished();
virtual void Pump();
virtual void ProcessSnapAckQueue();
virtual sessionState_t GetState() const;
virtual const char * GetStateString() const ;
virtual void SendUsercmds( idBitMsg & msg );
virtual void SendSnapshot( idSnapShot & ss );
virtual const char * GetPeerName( int peerNum );
virtual const char * GetLocalUserName( int i ) const { return signInManager->GetLocalUserByIndex( i )->GetGamerTag(); }
virtual void UpdateSignInManager();
virtual idPlayerProfile * GetProfileFromMasterLocalUser();
virtual void PrePickNewHost( idLobby & lobby, bool forceMe, bool inviteOldHost );
virtual bool PreMigrateInvite( idLobby & lobby );
//=====================================================================================================
// Title Storage Vars
//=====================================================================================================
virtual float GetTitleStorageFloat( const char * name, float defaultFloat ) const { return titleStorageVars.GetFloat( name, defaultFloat ); }
virtual int GetTitleStorageInt( const char * name, int defaultInt ) const { return titleStorageVars.GetInt( name, defaultInt ); }
virtual bool GetTitleStorageBool( const char * name, bool defaultBool ) const { return titleStorageVars.GetBool( name, defaultBool ); }
virtual const char * GetTitleStorageString( const char * name, const char * defaultString ) const { return titleStorageVars.GetString( name, defaultString ); }
virtual bool GetTitleStorageFloat( const char * name, float defaultFloat, float & out ) const { return titleStorageVars.GetFloat( name, defaultFloat, out ); }
virtual bool GetTitleStorageInt( const char * name, int defaultInt, int & out ) const { return titleStorageVars.GetInt( name, defaultInt, out ); }
virtual bool GetTitleStorageBool( const char * name, bool defaultBool, bool & out ) const { return titleStorageVars.GetBool( name, defaultBool, out ); }
virtual bool GetTitleStorageString( const char * name, const char * defaultString, const char ** out ) const { return titleStorageVars.GetString( name, defaultString, out ); }
virtual bool IsTitleStorageLoaded() { return titleStorageLoaded; }
//=====================================================================================================
// Voice chat
//=====================================================================================================
virtual voiceState_t GetLobbyUserVoiceState( lobbyUserID_t lobbyUserID );
virtual voiceStateDisplay_t GetDisplayStateFromVoiceState( voiceState_t voiceState ) const;
virtual void ToggleLobbyUserVoiceMute( lobbyUserID_t lobbyUserID );
virtual void SetActiveChatGroup( int groupIndex );
virtual void UpdateMasterUserHeadsetState();
//=====================================================================================================
// Bandwidth / QoS checking
//=====================================================================================================
virtual bool StartOrContinueBandwidthChallenge( bool forceStart );
virtual void DebugSetPeerSnaprate( int peerIndex, int snapRateMS );
virtual float GetIncomingByteRate();
//=====================================================================================================
// Invites
//=====================================================================================================
virtual void HandleBootableInvite( int64 lobbyId = 0 ) = 0;
virtual void ClearBootableInvite() = 0;
virtual void ClearPendingInvite() = 0;
virtual bool HasPendingBootableInvite() = 0;
virtual void SetDiscSwapMPInvite( void * parm ) = 0; // call to request a discSwap multiplayer invite
virtual void * GetDiscSwapMPInviteParms() = 0;
virtual bool IsDiscSwapMPInviteRequested() const { return inviteInfoRequested; }
bool GetFlushedStats() { return flushedStats; }
void SetFlushedStats( bool _flushedStats ) { flushedStats = _flushedStats; }
//=====================================================================================================
// Notifications
//=====================================================================================================
// This is called when a LocalUser is signed in/out
virtual void OnLocalUserSignin( idLocalUser * user );
virtual void OnLocalUserSignout( idLocalUser * user );
// This is called when the master LocalUser is signed in/out, these are called after OnLocalUserSignin/out()
virtual void OnMasterLocalUserSignout();
virtual void OnMasterLocalUserSignin();
// After a local user has signed in and their profile has loaded
virtual void OnLocalUserProfileLoaded( idLocalUser * user );
//=====================================================================================================
// Platform specific (different platforms implement these differently)
//=====================================================================================================
virtual void Initialize() = 0;
virtual void Shutdown() = 0;
virtual void InitializeSoundRelatedSystems() = 0;
virtual void ShutdownSoundRelatedSystems() = 0;
virtual void PlatformPump() = 0;
virtual void InviteFriends() = 0;
virtual void InviteParty() = 0;
virtual void ShowPartySessions() = 0;
virtual bool ProcessInputEvent( const sysEvent_t * ev ) = 0;
// Play with Friends server listing
virtual int NumServers() const = 0;
virtual void ListServers( const idCallback & callback ) = 0;
virtual void ListServersCommon();
virtual void CancelListServers() = 0;
virtual void ConnectToServer( int i ) = 0;
virtual const serverInfo_t * ServerInfo( int i ) const = 0;
virtual const idList< idStr > * ServerPlayerList( int i );
virtual void ShowServerGamerCardUI( int i ) = 0;
virtual void HandleServerQueryRequest( lobbyAddress_t & remoteAddr, idBitMsg & msg, int msgType ) = 0;
virtual void HandleServerQueryAck( lobbyAddress_t & remoteAddr, idBitMsg & msg ) = 0;
// System UI
virtual bool IsSystemUIShowing() const = 0;
virtual void SetSystemUIShowing( bool show ) = 0;
virtual void ShowSystemMarketplaceUI() const = 0;
virtual void ShowLobbyUserGamerCardUI( lobbyUserID_t lobbyUserID ) = 0;
// Leaderboards
virtual void LeaderboardUpload( lobbyUserID_t lobbyUserID, const leaderboardDefinition_t * leaderboard, const column_t * stats, const idFile_Memory * attachment = NULL ) = 0;
virtual void LeaderboardDownload( int sessionUserIndex, const leaderboardDefinition_t * leaderboard, int startingRank, int numRows, const idLeaderboardCallback & callback ) = 0;
virtual void LeaderboardDownloadAttachment( int sessionUserIndex, const leaderboardDefinition_t * leaderboard, int64 attachmentID ) = 0;
// Scoring (currently just for TrueSkill)
virtual void SetLobbyUserRelativeScore( lobbyUserID_t lobbyUserID, int relativeScore, int team ) = 0;
virtual void LeaderboardFlush() = 0;
//=====================================================================================================i'
// Savegames
//=====================================================================================================
virtual saveGameHandle_t SaveGameSync( const char * name, const saveFileEntryList_t & files, const idSaveGameDetails & description );
virtual saveGameHandle_t SaveGameAsync( const char * name, const saveFileEntryList_t & files, const idSaveGameDetails & description );
virtual saveGameHandle_t LoadGameSync( const char * name, saveFileEntryList_t & files );
virtual saveGameHandle_t EnumerateSaveGamesSync();
virtual saveGameHandle_t EnumerateSaveGamesAsync();
virtual saveGameHandle_t DeleteSaveGameSync( const char * name );
virtual saveGameHandle_t DeleteSaveGameAsync( const char * name );
virtual bool IsSaveGameCompletedFromHandle( const saveGameHandle_t & handle ) const { return saveGameManager->IsSaveGameCompletedFromHandle( handle ); }
virtual void CancelSaveGameWithHandle( const saveGameHandle_t & handle ) { GetSaveGameManager().CancelWithHandle( handle ); }
virtual const saveGameDetailsList_t & GetEnumeratedSavegames() const { return saveGameManager->GetEnumeratedSavegames(); }
virtual bool IsEnumerating() const;
virtual saveGameHandle_t GetEnumerationHandle() const;
virtual void SetCurrentSaveSlot( const char * slotName ) { currentSaveSlot = slotName; }
virtual const char * GetCurrentSaveSlot() const { return currentSaveSlot.c_str(); }
// Notifications
void OnSaveCompleted( idSaveLoadParms * parms );
void OnLoadCompleted( idSaveLoadParms * parms );
void OnDeleteCompleted( idSaveLoadParms * parms );
void OnEnumerationCompleted( idSaveLoadParms * parms );
// Error checking
virtual bool IsDLCAvailable( const char * mapName );
virtual bool LoadGameCheckDiscNumber( idSaveLoadParms & parms );
bool LoadGameCheckDescriptionFile( idSaveLoadParms & parms );
// Downloadable Content
virtual void EnumerateDownloadableContent() = 0;
void DropClient( int peerNum, int session );
protected:
float GetUpstreamDropRate() { return upstreamDropRate; }
float GetUpstreamQueueRate() { return upstreamQueueRate; }
int GetQueuedBytes() { return queuedBytes; }
//=====================================================================================================
// Common functions (sys_session_local.cpp)
//=====================================================================================================
void HandleLobbyControllerState( int lobbyType );
virtual void UpdatePendingInvite();
bool HandleState();
// The party and game lobby are the two platform lobbies that notify the backends (Steam/PSN/LIVE of changes)
idLobby & GetPartyLobby() { return partyLobby; }
const idLobby & GetPartyLobby() const { return partyLobby; }
idLobby & GetGameLobby() { return gameLobby; }
const idLobby & GetGameLobby() const { return gameLobby; }
// Game state lobby is the lobby used while in-game. It is so the dedicated server can host this lobby
// and have all platform clients join. It does NOT notify the backends of changes, it's purely for the dedicated
// server to be able to host the in-game lobby.
// Generally, you would call GetActingGameStateLobby. If we are not using game state lobby, GetActingGameStateLobby will return GetGameLobby insread.
idLobby & GetGameStateLobby() { return gameStateLobby; }
const idLobby & GetGameStateLobby() const { return gameStateLobby; }
idLobby & GetActingGameStateLobby();
const idLobby & GetActingGameStateLobby() const;
// GetActivePlatformLobby will return either the game or party lobby, it won't return the game state lobby
// This function is generally used for menus, in-game code should refer to GetActingGameStateLobby
idLobby * GetActivePlatformLobby();
const idLobby * GetActivePlatformLobby() const;
idLobby * GetLobbyFromType( idLobby::lobbyType_t lobbyType );
virtual idLobbyBase & GetPartyLobbyBase() { return partyLobby; }
virtual idLobbyBase & GetGameLobbyBase() { return gameLobby; }
virtual idLobbyBase & GetActingGameStateLobbyBase() { return GetActingGameStateLobby(); }
virtual idLobbyBase & GetActivePlatformLobbyBase();
virtual idLobbyBase & GetLobbyFromLobbyUserID( lobbyUserID_t lobbyUserID );
void SetState( state_t newState );
bool HandlePackets();
void HandleVoiceRestrictionDialog();
void SetDroppedByHost( bool dropped ) { droppedByHost = dropped; }
bool GetDroppedByHost() { return droppedByHost; }
public:
int storedPeer;
int storedMsgType;
protected:
static const char * stateToString[ NUM_STATES ];
state_t localState;
uint32 sessionOptions;
connectType_t connectType;
int connectTime;
idLobby partyLobby;
idLobby gameLobby;
idLobby gameStateLobby;
idLobbyStub stubLobby; // We use this when we request the active lobby when we are not in a lobby (i.e at press start)
int currentID; // The host used this to send out a unique id to all users so we can identify them
class idVoiceChatMgr * voiceChat;
int lastVoiceSendtime;
bool hasShownVoiceRestrictionDialog;
pendingInviteMode_t pendingInviteMode;
int pendingInviteDevice;
lobbyConnectInfo_t pendingInviteConnectInfo;
bool isSysUIShowing;
idDict titleStorageVars;
bool titleStorageLoaded;
int showMigratingInfoStartTime;
int nextGameCoalesceTime;
bool gameLobbyWasCoalesced;
int numFullSnapsReceived;
bool flushedStats;
int loadingID;
bool inviteInfoRequested;
idSaveGameProcessorSaveFiles * processorSaveFiles;
idSaveGameProcessorLoadFiles * processorLoadFiles;
idSaveGameProcessorDelete * processorDelete;
idSaveGameProcessorEnumerateGames * processorEnumerate;
idStr currentSaveSlot;
saveGameHandle_t enumerationHandle;
//------------------------
// State functions
//------------------------
bool State_Party_Lobby_Host();
bool State_Party_Lobby_Peer();
bool State_Game_Lobby_Host();
bool State_Game_Lobby_Peer();
bool State_Game_State_Lobby_Host();
bool State_Game_State_Lobby_Peer();
bool State_Loading();
bool State_InGame();
bool State_Find_Or_Create_Match();
bool State_Create_And_Move_To_Party_Lobby();
bool State_Create_And_Move_To_Game_Lobby();
bool State_Create_And_Move_To_Game_State_Lobby();
bool State_Connect_And_Move_To_Party();
bool State_Connect_And_Move_To_Game();
bool State_Connect_And_Move_To_Game_State();
bool State_Finalize_Connect();
bool State_Busy();
// -----------------------
// Downloadable Content
// -----------------------
static const int MAX_CONTENT_PACKAGES = 16;
idStaticList downloadedContent;
bool marketplaceHasNewContent;
class idQueuePacket {
public:
byte data[ idPacketProcessor::MAX_FINAL_PACKET_SIZE ];
lobbyAddress_t address;
int size;
int time;
bool dedicated;
idQueueNode queueNode;
};
idBlockAlloc< idQueuePacket, 64, TAG_NETWORKING > packetAllocator;
idQueue< idQueuePacket,&idQueuePacket::queueNode > sendQueue;
idQueue< idQueuePacket,&idQueuePacket::queueNode > recvQueue;
float upstreamDropRate; // instant rate in B/s at which we are dropping packets due to simulated upstream saturation
int upstreamDropRateTime;
float upstreamQueueRate; // instant rate in B/s at which queued packets are coming out after local buffering due to upstream saturation
int upstreamQueueRateTime;
int queuedBytes;
int waitingOnGameStateMembersToLeaveTime;
int waitingOnGameStateMembersToJoinTime;
void TickSendQueue();
void QueuePacket( idQueue< idQueuePacket,&idQueuePacket::queueNode > & queue, int time, const lobbyAddress_t & to, const void * data, int size, bool dedicated );
bool ReadRawPacketFromQueue( int time, lobbyAddress_t & from, void * data, int & size, bool & outDedicated, int maxSize );
void SendRawPacket( const lobbyAddress_t & to, const void * data, int size, bool dedicated );
bool ReadRawPacket( lobbyAddress_t & from, void * data, int & size, bool & outDedicated, int maxSize );
void ConnectAndMoveToLobby( idLobby & lobby, const lobbyConnectInfo_t & connectInfo, bool fromInvite );
void GoodbyeFromHost( idLobby & lobby, int peerNum, const lobbyAddress_t & remoteAddress, int msgType );
void WriteLeaderboardToMsg( idBitMsg & msg, const leaderboardDefinition_t * leaderboard, const column_t * stats );
void SendLeaderboardStatsToPlayer( lobbyUserID_t lobbyUserID, const leaderboardDefinition_t * leaderboard, const column_t * stats );
void RecvLeaderboardStatsForPlayer( idBitMsg & msg );
const leaderboardDefinition_t * ReadLeaderboardFromMsg( idBitMsg & msg, column_t * stats );
bool RequirePersistentMaster();
virtual idNetSessionPort & GetPort( bool dedicated = false ) = 0;
virtual idLobbyBackend * CreateLobbyBackend( const idMatchParameters & p, float skillLevel, idLobbyBackend::lobbyBackendType_t lobbyType ) = 0;
virtual idLobbyBackend * FindLobbyBackend( const idMatchParameters & p, int numPartyUsers, float skillLevel, idLobbyBackend::lobbyBackendType_t lobbyType ) = 0;
virtual idLobbyBackend * JoinFromConnectInfo( const lobbyConnectInfo_t & connectInfo , idLobbyBackend::lobbyBackendType_t lobbyType ) = 0;
virtual void DestroyLobbyBackend( idLobbyBackend * lobby ) = 0;
virtual void PumpLobbies() = 0;
virtual bool GetLobbyAddressFromNetAddress( const netadr_t & netAddr, lobbyAddress_t & outAddr ) const = 0;
virtual bool GetNetAddressFromLobbyAddress( const lobbyAddress_t & lobbyAddress, netadr_t & outNetAddr ) const = 0;
void HandleDedicatedServerQueryRequest( lobbyAddress_t & remoteAddr, idBitMsg & msg, int msgType );
void HandleDedicatedServerQueryAck( lobbyAddress_t & remoteAddr, idBitMsg & msg );
void ClearMigrationState();
// this is called when the mathc is over and returning to lobby
void EndMatchInternal( bool premature=false );
// this is called when the game finished and we are in the end match recap
void MatchFinishedInternal();
void EndMatchForMigration();
void MoveToPressStart( gameDialogMessages_t msg );
// Voice chat
void SendVoiceAudio();
void HandleOobVoiceAudio( const lobbyAddress_t & from, const idBitMsg & msg );
void SetVoiceGroupsToTeams();
void ClearVoiceGroups();
// All the new functions going here for now until it can all be cleaned up
void StartSessions();
void EndSessions();
void SetLobbiesAreJoinable( bool joinable );
void MoveToMainMenu(); // End all session (async), and return to IDLE state
bool WaitOnLobbyCreate( idLobby & lobby );
bool DetectDisconnectFromService( bool cancelAndShowMsg );
void HandleConnectionFailed( idLobby & lobby, bool wasFull );
void ConnectToNextSearchResultFailed( idLobby & lobby );
bool HandleConnectAndMoveToLobby( idLobby & lobby );
void VerifySnapshotInitialState();
void ComputeNextGameCoalesceTime();
void StartLoading();
bool ShouldHavePartyLobby();
void ValidateLobbies();
void ValidateLobby( idLobby & lobby );
void ReadTitleStorage( void * buffer, int bufferLen );
bool ReadDLCInfo( idDict & dlcInfo, void * buffer, int bufferLen );
idSessionCallbacks * sessionCallbacks;
int offlineTransitionTimerStart;
bool droppedByHost;
};
/*
========================
idSessionLocalCallbacks
The more the idLobby class needs to call back into this class, the more likely we're doing something wrong, and there is a better way.
========================
*/
class idSessionLocalCallbacks : public idSessionCallbacks {
public:
idSessionLocalCallbacks( idSessionLocal * sessionLocal_ ) { sessionLocal = sessionLocal_; }
virtual idLobby & GetPartyLobby() { return sessionLocal->GetPartyLobby(); }
virtual idLobby & GetGameLobby() { return sessionLocal->GetGameLobby(); }
virtual idLobby & GetActingGameStateLobby() { return sessionLocal->GetActingGameStateLobby(); }
virtual idLobby * GetLobbyFromType( idLobby::lobbyType_t lobbyType ) { return sessionLocal->GetLobbyFromType( lobbyType ); }
virtual int GetUniquePlayerId() const { return sessionLocal->currentID++; }
virtual idSignInManagerBase & GetSignInManager() { return *sessionLocal->signInManager; }
virtual void SendRawPacket( const lobbyAddress_t & to, const void * data, int size, bool useDirectPort ) { sessionLocal->SendRawPacket( to, data, size, useDirectPort ); }
virtual bool BecomingHost( idLobby & lobby );
virtual void BecameHost( idLobby & lobby );
virtual bool BecomingPeer( idLobby & lobby );
virtual void BecamePeer( idLobby & lobby );
virtual void FailedGameMigration( idLobby & lobby );
virtual void MigrationEnded( idLobby & lobby );
virtual void GoodbyeFromHost( idLobby & lobby, int peerNum, const lobbyAddress_t & remoteAddress, int msgType );
virtual uint32 GetSessionOptions() { return sessionLocal->sessionOptions; }
virtual bool AnyPeerHasAddress( const lobbyAddress_t & remoteAddress ) const;
virtual idSession::sessionState_t GetState() const { return sessionLocal->GetState(); }
virtual void ClearMigrationState() { GetPartyLobby().ResetAllMigrationState(); GetGameLobby().ResetAllMigrationState(); }
virtual void EndMatchInternal( bool premature=false ) { sessionLocal->EndMatchInternal( premature ); }
virtual void RecvLeaderboardStats( idBitMsg & msg );
virtual void ReceivedFullSnap();
virtual void LeaveGameLobby();
virtual void PrePickNewHost( idLobby & lobby, bool forceMe, bool inviteOldHost );
virtual bool PreMigrateInvite( idLobby & lobby );
virtual void HandleOobVoiceAudio( const lobbyAddress_t & from, const idBitMsg & msg ) { sessionLocal->HandleOobVoiceAudio( from, msg ); }
virtual void ConnectAndMoveToLobby( idLobby::lobbyType_t destLobbyType, const lobbyConnectInfo_t & connectInfo, bool waitForPartyOk );
virtual idVoiceChatMgr * GetVoiceChat() { return sessionLocal->voiceChat; }
virtual void HandleServerQueryRequest( lobbyAddress_t & remoteAddr, idBitMsg & msg, int msgType );
virtual void HandleServerQueryAck( lobbyAddress_t & remoteAddr, idBitMsg & msg );
virtual void HandlePeerMatchParamUpdate( int peer, int msg );
virtual idLobbyBackend * CreateLobbyBackend( const idMatchParameters & p, float skillLevel, idLobbyBackend::lobbyBackendType_t lobbyType );
virtual idLobbyBackend * FindLobbyBackend( const idMatchParameters & p, int numPartyUsers, float skillLevel, idLobbyBackend::lobbyBackendType_t lobbyType );
virtual idLobbyBackend * JoinFromConnectInfo( const lobbyConnectInfo_t & connectInfo , idLobbyBackend::lobbyBackendType_t lobbyType );
virtual void DestroyLobbyBackend( idLobbyBackend * lobby );
idSessionLocal * sessionLocal;
};