forked from SwagSoftware/Kisak-Strike
-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbaseclient.h
363 lines (291 loc) · 13.1 KB
/
baseclient.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#ifndef BASECLIENT_H
#define BASECLIENT_H
#ifdef _WIN32
#pragma once
#endif
#include <const.h>
#include <checksum_crc.h>
#include <iclient.h>
#include <protocol.h>
#include <iservernetworkable.h>
#include <bspfile.h>
#include <keyvalues.h>
#include <bitvec.h>
#include <igameevents.h>
#include "smartptr.h"
#include "userid.h"
#include "tier1/bitbuf.h"
#include "steam/steamclientpublic.h"
#include "tier1/utlarray.h"
#include "netmessages.h"
// class CClientFrame;
class CBaseServer;
class CClientFrame;
struct player_info_s;
class CFrameSnapshot;
class CEventInfo;
class CCommand;
struct NetMessageCvar_t;
class CHLTVServer;
struct Spike_t
{
public:
Spike_t() :
m_nBits( 0 )
{
m_szDesc[ 0 ] = 0;
}
char m_szDesc[ 64 ];
int m_nBits;
};
class CNetworkStatTrace
{
public:
CNetworkStatTrace() :
m_nMinWarningBytes( 0 ), m_nStartBit( 0 ), m_nCurBit( 0 )
{
}
int m_nMinWarningBytes;
int m_nStartBit;
int m_nCurBit;
CUtlVector< Spike_t > m_Records;
};
class CBaseClient : public IGameEventListener2, public IClient
{
typedef struct CustomFile_s
{
CRC32_t crc; //file CRC
unsigned int reqID; // download request ID
} CustomFile_t;
public:
CBaseClient();
virtual ~CBaseClient();
public:
int GetPlayerSlot() const { return m_nClientSlot; };
int GetUserID() const { return m_UserID; };
const USERID_t GetNetworkID() const;
const char *GetClientName() const { return m_Name; };
INetChannel *GetNetChannel() { return m_NetChannel; };
IServer *GetServer() { return (IServer*)m_Server; };
CHLTVServer *GetHltvServer();
CHLTVServer *GetAnyConnectedHltvServer();
const char *GetUserSetting(const char *cvar) const;
const char *GetNetworkIDString() const;
uint64 GetClientXuid() const;
const char *GetFriendsName() const { return m_FriendsName; }
void UpdateName( const char *pszDefault );
virtual void Connect(const char * szName, int nUserID, INetChannel *pNetChannel, bool bFakePlayer, CrossPlayPlatform_t clientPlatform, const CMsg_CVars *pVecCvars = NULL );
virtual void Inactivate( void )OVERRIDE;
virtual void Reconnect( void )OVERRIDE;
virtual void Disconnect( const char *reason ) OVERRIDE;
virtual bool CheckConnect( void );
virtual bool ChangeSplitscreenUser( int nSplitScreenUserSlot );
virtual void SetRate( int nRate, bool bForce );
virtual int GetRate( void ) const;
virtual void SetUpdateRate( float fUpdateRate, bool bForce ); // override;
virtual float GetUpdateRate( void ) const; // override;
virtual void Clear( void );
virtual void DemoRestart( void ); // called when client started demo recording
virtual int GetMaxAckTickCount() const;
virtual bool ExecuteStringCommand( const char *s );
virtual bool SendNetMsg( INetMessage &msg, bool bForceReliable = false, bool bVoice = false );
virtual void ClientPrintf ( PRINTF_FORMAT_STRING const char *fmt, ...) FMTFUNCTION( 2, 3 );
virtual bool IsConnected( void ) const { return m_nSignonState >= SIGNONSTATE_CONNECTED; };
virtual bool IsSpawned( void ) const { return m_nSignonState >= SIGNONSTATE_NEW; };
virtual bool IsActive( void ) const { return m_nSignonState == SIGNONSTATE_FULL; };
virtual bool IsFakeClient( void ) const { return m_bFakePlayer; };
virtual bool IsHLTV( void ) const { return m_bIsHLTV; }
#if defined( REPLAY_ENABLED )
virtual bool IsReplay( void ) const { return m_bIsReplay; }
#else
virtual bool IsReplay( void ) const { return false; }
#endif // REPLAY_ENABLED
// Is an actual human player or splitscreen player (not a bot and not a HLTV slot)
virtual bool IsHumanPlayer() const;
virtual bool IsHearingClient( int index ) const { return false; };
virtual bool IsProximityHearingClient( int index ) const { return false; };
virtual bool IsLowViolenceClient( void ) const { return m_bLowViolence; }
virtual void SetMaxRoutablePayloadSize( int nMaxRoutablePayloadSize );
virtual bool IsSplitScreenUser( void ) const { return m_bSplitScreenUser; }
virtual CrossPlayPlatform_t GetClientPlatform() const { return m_ClientPlatform; }
public: // Message Handlers
bool NETMsg_Tick( const CNETMsg_Tick& msg );
bool NETMsg_StringCmd( const CNETMsg_StringCmd& msg );
bool NETMsg_SignonState( const CNETMsg_SignonState& msg );
virtual bool NETMsg_PlayerAvatarData( const CNETMsg_PlayerAvatarData& msg );
virtual bool NETMsg_SetConVar( const CNETMsg_SetConVar& msg );
virtual bool CLCMsg_ClientInfo( const CCLCMsg_ClientInfo& msg );
virtual bool CLCMsg_Move( const CCLCMsg_Move& msg ) { Assert( 0 ); return true; }
virtual bool CLCMsg_VoiceData( const CCLCMsg_VoiceData& msg ) { Assert( 0 ); return true; }
bool CLCMsg_BaselineAck( const CCLCMsg_BaselineAck& msg );
virtual bool CLCMsg_ListenEvents( const CCLCMsg_ListenEvents& msg );
virtual bool CLCMsg_RespondCvarValue( const CCLCMsg_RespondCvarValue& msg ) { Assert( 0 ); return true; }
bool CLCMsg_LoadingProgress( const CCLCMsg_LoadingProgress& msg );
bool CLCMsg_SplitPlayerConnect( const CCLCMsg_SplitPlayerConnect& msg );
virtual bool CLCMsg_FileCRCCheck( const CCLCMsg_FileCRCCheck& msg ) { Assert( 0 ); return true; }
virtual bool CLCMsg_CmdKeyValues( const CCLCMsg_CmdKeyValues& msg );
virtual bool CLCMsg_HltvReplay( const CCLCMsg_HltvReplay &msg ) { return false; }
virtual bool SVCMsg_UserMessage( const CSVCMsg_UserMessage &msg ) { return true; }
enum
{
NETMSG_Tick,
NETMSG_StringCmd,
NETMSG_SetConVar,
NETMSG_SignonState,
NETMSG_ClientInfo,
NETMSG_Move,
NETMSG_VoiceData,
NETMSG_BaselineAck,
NETMSG_ListenEvents,
NETMSG_RespondCvarValue,
NETMSG_SplitPlayerConnect,
NETMSG_FileCRCCheck,
NETMSG_LoadingProgress,
NETMSG_CmdKeyValues,
NETMSG_PlayerAvatarData,
NETMSG_HltvReplay,
NETMSG_UserMessage,
NETMSG_Max
};
CUtlArray< CNetMessageBinder, NETMSG_Max > m_NetMessages;
virtual void ConnectionStart(INetChannel *chan) OVERRIDE;
virtual void ConnectionStop()OVERRIDE;
public: // IGameEventListener
virtual void FireGameEvent( IGameEvent *event ) OVERRIDE { FireGameEvent( event, false ); }
void FireGameEvent( IGameEvent *event, bool bPassthrough );
int m_nDebugID;
virtual int GetEventDebugID( void );
public:
virtual bool UpdateAcknowledgedFramecount(int tick);
virtual bool ShouldSendMessages( void );
virtual void UpdateSendState( void );
void ForceFullUpdate( void ) { UpdateAcknowledgedFramecount(-1); }
virtual bool FillUserInfo( player_info_s &userInfo );
virtual void UpdateUserSettings();
virtual void WriteGameSounds(bf_write &buf, int nMaxSounds);
virtual CClientFrame *GetDeltaFrame( int nTick );
virtual bool SendSnapshot( CClientFrame *pFrame );
virtual bool SendServerInfo( void );
virtual void OnSteamServerLogonSuccess( uint32 externalIP );
virtual bool SendSignonData( void );
virtual void SpawnPlayer( void );
virtual void ActivatePlayer( void );
virtual void SetName( const char * name );
virtual void SetUserCVar( const char *cvar, const char *value);
virtual void FreeBaselines();
virtual bool IgnoreTempEntity( CEventInfo *event );
void SetSteamID( const CSteamID &steamID );
int GetSignonState() const { return m_nSignonState; }
void SetSignonState( int nState );
bool IsTracing() const;
void SetTraceThreshold( int nThreshold );
void TraceNetworkData( bf_write &msg, PRINTF_FORMAT_STRING char const *fmt, ... ) FMTFUNCTION( 3, 4 );
void TraceNetworkMsg( int nBits, PRINTF_FORMAT_STRING char const *fmt, ... ) FMTFUNCTION( 3, 4 );
bool IsFullyAuthenticated( void ) { return m_bFullyAuthenticated; }
void SetFullyAuthenticated( void ) { m_bFullyAuthenticated = true; }
void SplitScreenDisconnect( const CCommand &args );
void DisconnectSplitScreenUser( CBaseClient *pSplitClient );
void ApplyConVars( const CMsg_CVars& list, bool bCreateIfNotExisting );
void FillSignOnFullServerInfo( class CNETMsg_SignonState_t& state );
bool IsSplitScreenPartner( const CBaseClient *pOther ) const;
virtual IClient *GetSplitScreenOwner() { return m_pAttachedTo; }
virtual int GetNumPlayers();
virtual bool StartHltvReplay( const HltvReplayParams_t ¶ms ) OVERRIDE { return false; } // not implemented for most clients
virtual void StopHltvReplay() OVERRIDE { }
virtual int GetHltvReplayDelay() OVERRIDE { return 0; }
virtual bool CanStartHltvReplay() OVERRIDE { return false; }
virtual void ResetReplayRequestTime() OVERRIDE { }
virtual CBaseClient *GetPropCullClient() { return this; }
void OverrideSignonStateTransparent( int nState ){ m_nSignonState = nState; }
protected:
virtual bool ProcessSignonStateMsg(int state, int spawncount);
virtual void PerformDisconnection( const char *pReason );
void OnPlayerAvatarDataChanged();
private:
void OnRequestFullUpdate( char const *pchReason );
int GetAvailableSplitScreenSlot() const;
void SendFullConnectEvent();
public:
// One of the subservient split screen users?
bool m_bSplitScreenUser;
bool m_bSplitAllowFastDisconnect;
int m_nSplitScreenPlayerSlot;
CBaseClient *m_SplitScreenUsers[ MAX_SPLITSCREEN_CLIENTS ];
CBaseClient *m_pAttachedTo; // If this is a split screen user, this is the "master"
bool m_bSplitPlayerDisconnecting;
// Array index in svs.clients:
int m_nClientSlot;
// entity index of this client (different from clientSlot+1 in HLTV and Replay mode):
int m_nEntityIndex;
int m_UserID; // identifying number on server
char m_Name[MAX_PLAYER_NAME_LENGTH]; // for printing to other people
char m_GUID[SIGNED_GUID_LEN + 1]; // the clients CD key
CNETMsg_PlayerAvatarData_t m_msgAvatarData; // Client avatar
CSteamID m_SteamID; // This is valid when the client is authenticated
uint32 m_nFriendsID; // client's friends' ID
char m_FriendsName[MAX_PLAYER_NAME_LENGTH];
KeyValues *m_ConVars; // stores all client side convars
bool m_bConVarsChanged; // true if convars updated and not changes process yet
bool m_bSendServerInfo; // true if we need to send server info packet to start connect
CBaseServer *m_Server; // pointer to server object
bool m_bIsHLTV; // if this a HLTV proxy ?
CHLTVServer *m_pHltvSlaveServer;
#if defined( REPLAY_ENABLED )
bool m_bIsReplay; // if this is a Replay proxy ?
#endif
// Client sends this during connection, so we can see if
// we need to send sendtable info or if the .dll matches
CRC32_t m_nSendtableCRC;
// a client can have couple of cutomized files distributed to all other players
CustomFile_t m_nCustomFiles[MAX_CUSTOM_FILES];
int m_nFilesDownloaded; // counter of how many files we downloaded from this client
//===== NETWORK ============
INetChannel *m_NetChannel; // The client's net connection.
private:
int m_nSignonState; // connection state
public:
int m_nDeltaTick; // -1 = no compression. This is where the server is creating the
// compressed info from.
int m_nStringTableAckTick; // Highest tick acked for string tables (usually m_nDeltaTick, except when it's -1)
int m_nSignonTick; // tick the client got his signon data
CSmartPtr<CFrameSnapshot,CRefCountAccessorLongName> m_pLastSnapshot; // last send snapshot
int m_nLoadingProgress; // 0..100 progress, only valid during loading
CFrameSnapshot *m_pBaseline; // current entity baselines as a snapshot
int m_nBaselineUpdateTick; // last tick we send client a update baseline signal or -1
CBitVec<MAX_EDICTS> m_BaselinesSent; // baselines sent with last update
int m_nBaselineUsed; // 0/1 toggling flag, singaling client what baseline to use
// This is used when we send out a nodelta packet to put the client in a state where we wait
// until we get an ack from them on this packet.
// This is for 3 reasons:
// 1. A client requesting a nodelta packet means they're screwed so no point in deluging them with data.
// Better to send the uncompressed data at a slow rate until we hear back from them (if at all).
// 2. Since the nodelta packet deletes all client entities, we can't ever delta from a packet previous to it.
// 3. It can eat up a lot of CPU on the server to keep building nodelta packets while waiting for
// a client to get back on its feet.
int m_nForceWaitForTick;
bool m_bFakePlayer; // JAC: This client is a fake player controlled by the game DLL
bool m_bReceivedPacket; // true, if client received a packet after the last send packet
bool m_bLowViolence; // true if client is in low-violence mode (L4D server needs to know)
bool m_bFullyAuthenticated;
// The datagram is written to after every frame, but only cleared
// when it is sent out to the client. overflow is tolerated.
// Time when we should send next world state update ( datagram )
double m_fNextMessageTime;
// Default time to wait for next message
float m_fSnapshotInterval;
CrossPlayPlatform_t m_ClientPlatform;
// Keep these as class members instead of a local variable so that we don't reallocate the
// strings and their buffers every time.
CSVCMsg_TempEntities_t m_tempentsmsg;
CSVCMsg_PacketEntities_t m_packetmsg;
private:
void StartTrace( bf_write &msg );
void EndTrace( bf_write &msg );
CNetworkStatTrace m_Trace;
};
#endif // BASECLIENT_H