DOOM-3-BFG

DOOM 3 BFG Edition
Log | Files | Refs

sys_lobby_backend.h (10044B)


      1 /*
      2 ===========================================================================
      3 
      4 Doom 3 BFG Edition GPL Source Code
      5 Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. 
      6 
      7 This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").  
      8 
      9 Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
     10 it under the terms of the GNU General Public License as published by
     11 the Free Software Foundation, either version 3 of the License, or
     12 (at your option) any later version.
     13 
     14 Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
     15 but WITHOUT ANY WARRANTY; without even the implied warranty of
     16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     17 GNU General Public License for more details.
     18 
     19 You should have received a copy of the GNU General Public License
     20 along with Doom 3 BFG Edition Source Code.  If not, see <http://www.gnu.org/licenses/>.
     21 
     22 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.
     23 
     24 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.
     25 
     26 ===========================================================================
     27 */
     28 #ifndef	__SYS_LOBBY_BACKEND_H__
     29 #define	__SYS_LOBBY_BACKEND_H__
     30 
     31 
     32 extern idCVar net_verboseResource;
     33 #define NET_VERBOSERESOURCE_PRINT if ( net_verboseResource.GetBool() ) idLib::Printf
     34 
     35 extern idCVar net_verbose;
     36 #define NET_VERBOSE_PRINT if ( net_verbose.GetBool() ) idLib::Printf
     37 
     38 class lobbyAddress_t {
     39 public:
     40 	lobbyAddress_t();
     41 	
     42 	void InitFromNetadr( const netadr_t & netadr );
     43 
     44 	void InitFromIPandPort( const char * ip, int port );
     45 
     46 	const char * ToString() const;
     47 	bool UsingRelay() const;
     48 	bool Compare( const lobbyAddress_t & addr, bool ignoreSessionCheck = false ) const;
     49 	void WriteToMsg( idBitMsg & msg ) const;
     50 	void ReadFromMsg( idBitMsg & msg );
     51 
     52 	// IP address
     53 	netadr_t	netAddr;
     54 };
     55 
     56 struct lobbyConnectInfo_t {
     57 public:
     58 	void WriteToMsg( idBitMsg & msg ) const {
     59 		msg.WriteNetadr( netAddr );
     60 	}
     61 	void ReadFromMsg( idBitMsg & msg ) {
     62 		msg.ReadNetadr( &netAddr );
     63 	}
     64 	lobbyConnectInfo_t() : netAddr() { }
     65 
     66 	netadr_t				netAddr;
     67 };
     68 
     69 class idNetSessionPort {
     70 public:
     71 	idNetSessionPort();
     72 
     73 	bool InitPort( int portNumber, bool useBackend );
     74 	bool ReadRawPacket( lobbyAddress_t & from, void * data, int & size, int maxSize  );
     75 	void SendRawPacket( const lobbyAddress_t & to, const void * data, int size );
     76 
     77 	bool IsOpen();
     78 	void Close();
     79 	
     80 private:
     81 	float	forcePacketDropCurr;	// Used with net_forceDrop and net_forceDropCorrelation
     82 	float	forcePacketDropPrev;
     83 
     84 	idUDP	UDP;
     85 };
     86 
     87 struct lobbyUser_t {
     88 	static const int INVALID_PING = 9999;
     89 	// gamertags can be up to 16 4-byte characters + \0
     90 	static const int MAX_GAMERTAG	= 64 + 1; 
     91 
     92 	lobbyUser_t() {
     93 		isBot				= false;
     94 		peerIndex			= -1;
     95 		disconnecting		= false;
     96 		level				= 1;
     97 		pingMs				= INVALID_PING;
     98 		teamNumber			= 0;
     99 		arbitrationAcked	= false;
    100 		partyToken			= 0;
    101 
    102 		selectedSkin		= 0;
    103 		weaponAutoSwitch	= true;
    104 		weaponAutoReload	= true;
    105 
    106 		migrationGameData	= -1;
    107 	}
    108 
    109 	// Common variables
    110 	bool				isBot;				// true if lobbyUser is a bot.
    111 	int					peerIndex;			// peer number on host
    112 	lobbyUserID_t		lobbyUserID;		// Locally generated to be unique, and internally keeps the local user handle
    113 	char				gamertag[MAX_GAMERTAG];
    114 	int					pingMs;				// round trip time in milliseconds
    115 	
    116 	bool				disconnecting;		// true if we've sent a msg to disconnect this user from the session
    117 	int					level;
    118 	int					teamNumber;
    119 	uint32				partyToken;			// set by the server when people join as a party
    120 
    121 	int					selectedSkin;
    122 	bool				weaponAutoSwitch;
    123 	bool				weaponAutoReload;
    124 
    125 	bool				arbitrationAcked;	// if the user is verified for arbitration
    126 
    127 	lobbyAddress_t		address;
    128 
    129 	int					migrationGameData;	// index into the local migration gamedata array that is associated with this user. -1=no migration game data available
    130 
    131 	// Platform variables
    132 	
    133 	bool IsDisconnected() const { return lobbyUserID.IsValid() ? false : true; }
    134 	
    135 	void WriteToMsg( idBitMsg & msg ) {
    136 		address.WriteToMsg( msg );
    137 		lobbyUserID.WriteToMsg( msg );
    138 		msg.WriteLong( peerIndex );
    139 		msg.WriteShort( pingMs );
    140 		msg.WriteLong( partyToken );
    141 		msg.WriteString( gamertag, MAX_GAMERTAG, false );
    142 		WriteClientMutableData( msg );
    143 	}
    144 	
    145 	void ReadFromMsg( idBitMsg & msg ) {
    146 		address.ReadFromMsg( msg );
    147 		lobbyUserID.ReadFromMsg( msg );
    148 		peerIndex = msg.ReadLong();
    149 		pingMs = msg.ReadShort();
    150 		partyToken = msg.ReadLong();
    151 		msg.ReadString( gamertag, MAX_GAMERTAG );
    152 		ReadClientMutableData( msg );
    153 	}
    154 
    155 	bool UpdateClientMutableData( const idLocalUser * localUser );
    156 
    157 	void WriteClientMutableData( idBitMsg & msg ) {
    158 		msg.WriteBits( selectedSkin, 4 );
    159 		msg.WriteBits( teamNumber, 2 );		// We need two bits since we use team value of 2 for spectating
    160 		msg.WriteBool( weaponAutoSwitch );
    161 		msg.WriteBool( weaponAutoReload );
    162 		release_assert( msg.GetWriteBit() == 0 );
    163 	}
    164 
    165 	void ReadClientMutableData( idBitMsg & msg ) {
    166 		selectedSkin = msg.ReadBits( 4 );
    167 		teamNumber = msg.ReadBits( 2 );		// We need two bits since we use team value of 2 for spectating
    168 		weaponAutoSwitch = msg.ReadBool();
    169 		weaponAutoReload = msg.ReadBool();
    170 	}
    171 };
    172 
    173 /*
    174 ================================================
    175 idLobbyBackend
    176 This class interfaces with the various back ends for the different platforms
    177 ================================================
    178 */
    179 class idLobbyBackend {
    180 public:
    181 	enum lobbyBackendState_t {
    182 		STATE_INVALID			= 0,
    183 		STATE_READY				= 1,
    184 		STATE_CREATING			= 2,		// In the process of creating the lobby as a host
    185 		STATE_SEARCHING			= 3,		// In the process of searching for a lobby to join
    186 		STATE_OBTAINING_ADDRESS	= 4,		// In the process of obtaining the address of the lobby owner
    187 		STATE_ARBITRATING		= 5,		// Arbitrating
    188 		STATE_SHUTTING_DOWN		= 6,		// In the process of shutting down
    189 		STATE_SHUTDOWN			= 7,		// Was a host or peer at one point, now ready to be deleted
    190 		STATE_FAILED			= 8,		// Failure occurred
    191 		NUM_STATES
    192 	};
    193 
    194 	static const char * GetStateString( lobbyBackendState_t state_ ) { 
    195 		static const char * stateToString[NUM_STATES] = {
    196 			"STATE_INVALID",
    197 			"STATE_READY",
    198 			"STATE_CREATING",
    199 			"STATE_SEARCHING",
    200 			"STATE_OBTAINING_ADDRESS",
    201 			"STATE_ARBITRATING",
    202 			"STATE_SHUTTING_DOWN",
    203 			"STATE_SHUTDOWN",
    204 			"STATE_FAILED"
    205 		};
    206 
    207 		return stateToString[ state_ ]; 
    208 	}
    209 	
    210 	enum lobbyBackendType_t {
    211 		TYPE_PARTY		= 0,
    212 		TYPE_GAME		= 1,
    213 		TYPE_GAME_STATE	= 2,
    214 		TYPE_INVALID	= 0xff,
    215 	};
    216 
    217 	idLobbyBackend() : type( TYPE_INVALID ), isHost( false ), isLocal( false ) {}
    218 	idLobbyBackend( lobbyBackendType_t lobbyType ) : type( lobbyType ), isHost( false ), isLocal( false ) {}
    219 
    220 	virtual void			StartHosting( const idMatchParameters & p, float skillLevel, lobbyBackendType_t type ) = 0;
    221 	virtual void			StartFinding( const idMatchParameters & p, int numPartyUsers, float skillLevel ) = 0;
    222 	virtual void			JoinFromConnectInfo( const lobbyConnectInfo_t & connectInfo ) = 0;
    223 	virtual void			GetSearchResults( idList< lobbyConnectInfo_t > & searchResults ) = 0;
    224 	virtual lobbyConnectInfo_t GetConnectInfo()	= 0;
    225 	virtual void			FillMsgWithPostConnectInfo( idBitMsg & msg ) = 0;				// Passed itno PostConnectFromMsg
    226 	virtual void			PostConnectFromMsg( idBitMsg & msg ) = 0;						// Uses results from FillMsgWithPostConnectInfo
    227 	virtual bool			IsOwnerOfConnectInfo( const lobbyConnectInfo_t & connectInfo ) const { return false; }
    228 	virtual void			Shutdown() = 0;
    229 	virtual void			GetOwnerAddress( lobbyAddress_t & outAddr ) = 0;
    230 	virtual bool			IsHost() { return isHost; }
    231 	virtual void			SetIsJoinable( bool joinable ) {}
    232 	virtual void			Pump() = 0;
    233 	virtual void			UpdateMatchParms( const idMatchParameters & p ) = 0;
    234 	virtual void			UpdateLobbySkill( float lobbySkill ) = 0;
    235 	virtual void			SetInGame( bool value ) {}
    236 	
    237 	virtual lobbyBackendState_t	GetState() = 0;
    238 	virtual bool			IsLocal() const { return isLocal; }
    239 	virtual bool			IsOnline() const { return !isLocal; }
    240 
    241 	virtual bool			StartArbitration() { return false; }
    242 	virtual void			Arbitrate() {}
    243 	virtual void			VerifyArbitration() {}
    244 	virtual bool			UserArbitrated( lobbyUser_t * user ) { return false; }
    245 
    246 	virtual void			RegisterUser( lobbyUser_t * user, bool isLocal ) {}
    247 	virtual void			UnregisterUser( lobbyUser_t * user, bool isLocal ) {}
    248 
    249 	virtual void			StartSession() {}
    250 	virtual void			EndSession() {}
    251 	virtual bool			IsSessionStarted() { return false; }
    252 	virtual void			FlushStats() {}
    253 
    254 	virtual void			BecomeHost( int numInvites ) {}						// Become the host of this lobby
    255 	virtual	void			RegisterAddress( lobbyAddress_t & address ) {}	// Called after becoming a new host, to register old addresses to send invites to
    256 	virtual void			FinishBecomeHost() {}
    257 	
    258 	void					SetLobbyType( lobbyBackendType_t lobbyType ) { type = lobbyType; }
    259 	lobbyBackendType_t		GetLobbyType() const { return type; }
    260 	const char *			GetLobbyTypeString() const { return ( GetLobbyType() == TYPE_PARTY ) ? "Party" : "Game"; }
    261 
    262 	bool					IsRanked() { return MatchTypeIsRanked( parms.matchFlags ); }
    263 	bool					IsPrivate() { return MatchTypeIsPrivate( parms.matchFlags ); }
    264 
    265 protected:
    266 	lobbyBackendType_t		type;
    267 	idMatchParameters		parms;
    268 	bool					isLocal;		// True if this lobby is restricted to local play only (won't need and can't connect to online lobbies)
    269 	bool					isHost;			// True if we created this lobby
    270 };
    271 
    272 class idLobbyToSessionCB {
    273 public:
    274 	virtual class idLobbyBackend *				GetLobbyBackend( idLobbyBackend::lobbyBackendType_t type ) const = 0;
    275 	virtual bool								CanJoinLocalHost() const = 0;
    276 
    277 	// Ugh, hate having to ifdef these, but we're doing some fairly platform specific callbacks
    278 };
    279 
    280 #endif	// __SYS_LOBBY_BACKEND_H__