aboutsummaryrefslogtreecommitdiff
path: root/src/parsec_server/include/e_connmanager.h
blob: 446a8ae5ae2c5b9d9a2eb7c45717cea8ece73e41 (plain)
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
/*
* PARSEC HEADER: e_connmanager.h
*/

#ifndef _E_CONNMANAGER_H_
#define _E_CONNMANAGER_H_

// forward decls --------------------------------------------------------------
//
class E_GameServer;
class E_PacketHandler;
class E_SimPlayerInfo;


// class holding the challenges sent to requesting clients --------------------
//
class E_ClientChallengeInfo
{
public:
	int			m_challenge;
	node_t		m_node;
	refframe_t  m_frame_generated;
public:
	E_ClientChallengeInfo() : 
	  m_challenge( -1 ),
		  m_frame_generated( 0 )
	  {
		  memset( &m_node, 0, sizeof( node_t ) );
	  }
};

// class holding basic client information -------------------------------------
//
class E_BasicClientInfo 
{
public:
	int		m_nVersionMajor;
	int		m_nVersionMinor;
	char	m_szName	[ MAX_PLAYER_NAME  + 1 ];
	char	m_szOSLine  [ MAX_OSNAME_LEN   + 1 ];	
	char	m_szHostName[ MAX_HOSTNAME_LEN + 1 ];
	node_t	m_node;
	int		m_challenge;
	int		m_nRecvRate;				// byte/sec. this client wants data
	int		m_nSendFreq;				// packets/sec. this client sends data
	
public:
	E_BasicClientInfo ()
	{
		Reset();
	}

	void Reset()
	{
		m_nVersionMajor = -1;
		m_nVersionMinor = -1;
		memset( m_szName, 0, MAX_PLAYER_NAME  + 1 );
		memset( m_szOSLine,     0, MAX_OSNAME_LEN   + 1 );
		memset( m_szHostName,	0, MAX_HOSTNAME_LEN + 1 );
		memset( &m_node,		0, sizeof( node_t ) );
		m_challenge = -1;
		m_nRecvRate = DEFAULT_CLIENT_RECV_RATE;
		m_nSendFreq = DEFAULT_CLIENT_SEND_FREQUENCY;
	}

	// return the NET.SERVERRATE for this client
	int GetRecvRate() { return m_nRecvRate; }

	// return the NET.CLIENTRATE for this client
	int GetSendFreq() { return m_nSendFreq; }
};


// class holding client information ( when connecting ) -----------------------
//
class E_ClientConnectInfo : public E_BasicClientInfo
{
public:
	int			m_selected_slot;
public:
	E_ClientConnectInfo() : 
		E_BasicClientInfo(),
		m_selected_slot(-1)
	  {
	  }
};


// class holding client information ( when connected ) ------------------------
//
class E_ClientInfo : public E_BasicClientInfo
{
protected:
	int					m_slotfree;	
	int					m_nAliveCounter;
	E_SimPlayerInfo*	m_pSimPlayerInfo;

public:
	E_ClientInfo() : 
	  m_slotfree( TRUE ),
	  m_nAliveCounter( MAX_ALIVE_COUNTER ),
	  m_pSimPlayerInfo( NULL )
	{
	}

	void CopyClientConnectInfo( E_ClientConnectInfo* pClientConnectInfo );

	void Reset()
	{
		E_BasicClientInfo::Reset();

		m_slotfree		= TRUE;
		m_nAliveCounter = MAX_ALIVE_COUNTER;
	}

	// mark the client alive
	void MarkAlive();

	// check whether the client is alive
	int IsAlive();

	// check whether the slot is free
	int IsSlotFree() { return m_slotfree; }

	// set the status of slot 
	void SetSlotFree( int slotfree ) { m_slotfree = slotfree; }
};


// connection manager class ---------------------------------------------------
//
class E_ConnManager
{
protected:

	E_ClientChallengeInfo*		m_ChallengInfos;
	int						m_nMaxNumChallengeInfos;
	int						m_nCurChallengeInfo;

	E_ClientInfo*			m_ClientInfos;
	int						m_nNumConnected;

	int						m_inDisconnectClient;

	E_ConnManager();
	~E_ConnManager();

public:

	// SINGLETON pattern
	static E_ConnManager* GetConnManager()
	{
		static E_ConnManager _TheConnManager;
		return &_TheConnManager;
	}

	// request a challenge for a client
	int RequestChallenge( node_t* clientnode );

	enum ConnResults {
		CONN_CHALLENGE_INVALID   = 0,
		CONN_CLIENT_INCOMAPTIBLE = 1,
		CONN_CLIENT_BANNED       = 2,
		CONN_SERVER_FULL		 = 3,
		CONN_NAME_TAKEN			 = 4,
		CONN_OK					 = 5
	};

	enum DisconnResults {
		DISC_NOT_CONNECTED		 = 0,
		DISC_OK					 = 1
	};

	enum NameChangeResults {
		NAMECHANGE_NOT_CONNECTED = 0,
		NAMECHANGE_ALREADY_TAKEN = 1,
		NAMECHANGE_OK            = 2
	};
	
	// check whether the client connection is valid
	int CheckClientConnect( E_ClientConnectInfo* pClientConnectInfo );

	// check for a client disconnect
	int CheckClientDisconnect( node_t* clientnode );

	// check for a client namechange
	int CheckNameChange( node_t* clientnode, char* newplayername );

	// get the client information for a specific slot
	E_ClientInfo* GetClientInfo( int nSlot );

	// check the alive counter of all connected clients and disconnect any timed out clients
	int CheckAliveStatus();

	// check node of client with node used at connection
	int CheckNodesMatch( int nClientID, node_t* node );

	// return the # of connected clients
	int GetNumConnected() { return m_nNumConnected; }

	// set some client-info fields according to RE
	void NET_ExecRmEvClientInfo( int nClientID, RE_ClientInfo* re_clientinfo );

	// disconnect a client
	int DisconnectClient( int nClientID );

	// return the name of the client
	char* GetClientName( int nClientID );

protected:

	// check if client version is compatible
	int _IsClientCompatible( E_ClientConnectInfo* pClientConnectInfo );

	// check if client is banned
	int _IsClientBanned( E_ClientConnectInfo* pClientConnectInfo );

	// check if challenge is correct
	int _IsChallengeCorrect( E_ClientConnectInfo* pClientConnectInfo, E_ClientChallengeInfo** pChallengeInfo );

	// ensure a client is not connected
	int _EnsureClientIsDisconnected( E_ClientConnectInfo* pClientConnectInfo );

	// connect a client 
	int _ConnectClient( E_ClientConnectInfo* pClientConnectInfo );
	
	// change the name of a client
	int _ChangeClientName( int nSlot, char* newplayername );

	// send client connected notifications to the other clients
	int _NotifyClientConnected( int nSlotConnected );

	// send client disconnected notifications to the other clients
	int _NotifyClientDisconnected( int nSlotDisconnected );

	// send client namechange notifications to the other clients
	int _NotifyClientNameChange( int nSlotNamechanged );

	// find the assigned slot for a specific node
	int _FindSlotWithNode( node_t* clientnode );

	// find the slot of a connected client by its name
	int _FindClientName( char* name );
};


#endif // _E_CONNMANAGER_H_