Source

skulltag-gully / src / networkshared.h

The default branch has multiple heads

Full commit
Torr_Samaho 61717e4 












































Torr_Samaho 8c808fb 
Torr_Samaho 61717e4 





Torr_Samaho e86ce10 
Torr_Samaho 61717e4 



Torr_Samaho 337eaf5 
Torr_Samaho 8c808fb 
Torr_Samaho 3c3285b 
Torr_Samaho 61717e4 


Torr_Samaho 8c808fb 


Torr_Samaho 61717e4 



Torr_Samaho a76b954 
Torr_Samaho 8c808fb 
Torr_Samaho a76b954 
Torr_Samaho 79e66f9 


Torr_Samaho 61717e4 
Brad Carney 5784e8d 






Torr_Samaho 8c808fb 
Torr_Samaho 6a15c50 

Torr_Samaho 31d936e 







Torr_Samaho 43964e1 
Torr_Samaho 31d936e 





Phil Cohen 6c6b61c 
Torr_Samaho 6a15c50 

Phil Cohen 6c6b61c 





Torr_Samaho 6a15c50 

Phil Cohen 6c6b61c 
Torr_Samaho 6a15c50 















Torr_Samaho 31d936e 

Torr_Samaho 41b5cfc 


Torr_Samaho 1779693 


Torr_Samaho 6a15c50 

Torr_Samaho 31d936e 
Torr_Samaho b20482b 
Torr_Samaho 31d936e 
Torr_Samaho 6a15c50 


Torr_Samaho e079ef0 



















Torr_Samaho 2616392 
Torr_Samaho 8c808fb 




Torr_Samaho 6a15c50 
Torr_Samaho 9e66d67 


Torr_Samaho 8c808fb 



Brad Carney 5784e8d 
Torr_Samaho 61717e4 

Brad Carney 3a62562 









Torr_Samaho 61717e4 

Brad Carney 3a62562 
Torr_Samaho 61717e4 
Torr_Samaho 5b555fd 





Torr_Samaho 3c3285b 


Torr_Samaho 5b555fd 




Brad Carney 5784e8d 






Torr_Samaho 79e66f9 







Brad Carney 5784e8d 

Torr_Samaho 5b555fd 
Brad Carney 5784e8d 


Brad Carney 3a62562 
Brad Carney 5784e8d 
Torr_Samaho 61717e4 
Brad Carney 3a62562 
Brad Carney 5784e8d 
Torr_Samaho 61717e4 
Brad Carney 3a62562 
Brad Carney 5784e8d 
Torr_Samaho 61717e4 
Brad Carney 5784e8d 





Torr_Samaho 61717e4 
Brad Carney 3a62562 
Torr_Samaho 61717e4 
Torr_Samaho b81285a 



Torr_Samaho 8c808fb 


Brad Carney 3a62562 
Torr_Samaho 9e66d67 



Torr_Samaho 8c808fb 
Torr_Samaho 6a15c50 
Torr_Samaho 6b77bb2 


Torr_Samaho 9e66d67 
Torr_Samaho 8c808fb 



Torr_Samaho 9e66d67 






Torr_Samaho d7becdf 
Torr_Samaho 0bf1590 
Torr_Samaho 9e66d67 
Torr_Samaho 628e56a 
Torr_Samaho 0bf1590 
Torr_Samaho b81285a 
Torr_Samaho 8c808fb 

Torr_Samaho 61717e4 
Torr_Samaho 8c808fb 


Torr_Samaho 088d0fe 
Torr_Samaho 8c808fb 















Torr_Samaho 61717e4 
Torr_Samaho 8c808fb 
Torr_Samaho 61717e4 



Torr_Samaho 8c808fb 
Torr_Samaho 61717e4 



Torr_Samaho 8c808fb 
Torr_Samaho 134f22a 


Torr_Samaho 61717e4 
Torr_Samaho 337eaf5 
Torr_Samaho 8c808fb 

Torr_Samaho 61717e4 
Torr_Samaho 8c808fb 


Torr_Samaho 3c3285b 
Torr_Samaho 8c808fb 
Torr_Samaho 61717e4 

Torr_Samaho 8c808fb 








Torr_Samaho fba9024 

Torr_Samaho 8c808fb 




Torr_Samaho 088d0fe 
Torr_Samaho 8c808fb 
Torr_Samaho b81285a 


Torr_Samaho 8c808fb 


Torr_Samaho 3c3285b 
Torr_Samaho 8c808fb 

Torr_Samaho 3c3285b 


Torr_Samaho 8c808fb 

Torr_Samaho 3c3285b 



Torr_Samaho 088d0fe 
Torr_Samaho 8c808fb 





Torr_Samaho 088d0fe 
Torr_Samaho 8c808fb 
Torr_Samaho c12cf4e 

Torr_Samaho 088d0fe 

Torr_Samaho 8c808fb 








Torr_Samaho fba9024 

Torr_Samaho 8c808fb 




Torr_Samaho d7becdf 
Torr_Samaho 8c808fb 

Torr_Samaho d7becdf 


Torr_Samaho 8c808fb 

Torr_Samaho d7becdf 
Torr_Samaho 8c808fb 

Torr_Samaho fba9024 
Torr_Samaho 8c808fb 







Torr_Samaho d7becdf 
Torr_Samaho 8c808fb 
Torr_Samaho d7becdf 


Torr_Samaho 8c808fb 



Torr_Samaho d7becdf 

Torr_Samaho e51ef10 

































Torr_Samaho 61717e4 
  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
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
//-----------------------------------------------------------------------------
//
// Skulltag Source
// Copyright (C) 2007 Brad Carney, Benjamin Berkels
// Copyright (C) 2007-2012 Skulltag Development Team
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
//    this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
// 3. Neither the name of the Skulltag Development Team nor the names of its
//    contributors may be used to endorse or promote products derived from this
//    software without specific prior written permission.
// 4. Redistributions in any form must be accompanied by information on how to
//    obtain complete source code for the software and any accompanying
//    software that uses the software. The source code must either be included
//    in the distribution or be available for no more than the cost of
//    distribution plus a nominal fee, and must be freely redistributable
//    under reasonable conditions. For an executable file, complete source
//    code means the source code for all modules it contains. It does not
//    include source code for modules or files that typically accompany the
//    major components of the operating system on which the executable file
//    runs.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
//
//
// Filename: networkshared.h
//
// Description: Contains shared network code shared between Skulltag and its satellites (master server, statsmaker, rcon utility, etc).
//
//-----------------------------------------------------------------------------

#ifndef __NETWORKSHARED_H__
#define __NETWORKSHARED_H__

#include "platform.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <iostream>
#include <vector>
#include <list>
#include <time.h>
#include <ctype.h>
#include <math.h>

//--------------------------------------------------------------------------------------------------------------------------------------------------
//-- DEFINES ---------------------------------------------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------------------------------------------

// Maximum size of the packets sent out by the server.
#define	MAX_UDP_PACKET				8192

// [BB] Number of packets that are stored to recover from packet loss.
#define PACKET_BUFFER_SIZE			1024

// [RC] A security debug feature to catch malicious packets.
// #define CREATE_PACKET_LOG

//*****************************************************************************
typedef enum
{
	BUFFERTYPE_READ,
	BUFFERTYPE_WRITE,

} BUFFERTYPE_e;

//*****************************************************************************
enum
{
	MSC_BEGINSERVERLIST,
	MSC_SERVER,
	MSC_ENDSERVERLIST,
	MSC_IPISBANNED,
	MSC_REQUESTIGNORED,
	MSC_WRONGVERSION,
	MSC_BEGINSERVERLISTPART,
	MSC_ENDSERVERLISTPART,
	MSC_SERVERBLOCK,

};

//*****************************************************************************
enum
{
	// Server is letting master server of its existence.
	SERVER_MASTER_CHALLENGE = 5660020,

	// [RC] This is no longer used.
	/*
		// Server is letting master server of its existence, along with sending an IP the master server
		// should use for this server.
		SERVER_MASTER_CHALLENGE_OVERRIDE = 5660021,
	*/

	// Server is sending some statistics to the master server.
	SERVER_MASTER_STATISTICS = 5660022,

	// Server is sending its info to the launcher.
	SERVER_LAUNCHER_CHALLENGE,

	// Server is telling a launcher that it's ignoring it.
	SERVER_LAUNCHER_IGNORING,

	// Server is telling a launcher that his IP is banned from the server.
	SERVER_LAUNCHER_BANNED,

	// Client is trying to create a new account with the master server.
	CLIENT_MASTER_NEWACCOUNT,

	// Client is trying to log in with the master server.
	CLIENT_MASTER_LOGIN,

	// [BB] Launcher is querying the master server for a full server list, possibly split into several packets.
	LAUNCHER_MASTER_CHALLENGE,

	// [BB] Server is answering a MasterBanlistVerificationString verification request.
	SERVER_MASTER_VERIFICATION,

	// [BB] Server is acknowledging the receipt of a ban list.
	SERVER_MASTER_BANLIST_RECEIPT,
};

// [BB] Protocol version of the master server, currently only used in conjunction with LAUNCHER_MASTER_CHALLENGE.
#define MASTER_SERVER_VERSION		2

// Launcher is querying the server, or master server.
#define	LAUNCHER_SERVER_CHALLENGE	199

enum
{
	// Master server is sending its banlist to a server.
	MASTER_SERVER_BANLIST = 205,

	// [BB] Master is asking the server to verify its MasterBanlistVerificationString.
	MASTER_SERVER_VERIFICATION,

	// [BB] Master server is sending a part of its banlist to a server.
	MASTER_SERVER_BANLISTPART,
};

// [BB] Various enums used in MASTER_SERVER_BANLISTPART packets.
enum
{
	MSB_BAN,
	MSB_BANEXEMPTION,
	MSB_ENDBANLISTPART,
	MSB_ENDBANLIST,
};

#define	DEFAULT_SERVER_PORT			10666
#define	DEFAULT_CLIENT_PORT			10667
#define	DEFAULT_MASTER_PORT			15300
#define	DEFAULT_BROADCAST_PORT		15101
#define	DEFAULT_STATS_PORT			15201

// This is the longest possible string we can pass over the network.
#define	MAX_NETWORK_STRING			2048

//--------------------------------------------------------------------------------------------------------------------------------------------------
//-- STRUCTURES ------------------------------------------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------------------------------------------

//*****************************************************************************
typedef struct
{
	// Four digit IP address.
	BYTE		abIP[4];

	// The IP address's port extension.
	USHORT		usPort;

	// What's this for?
	USHORT		usPad;

} NETADDRESS_s;

//*****************************************************************************
typedef struct
{
	// The IP address in char form (can be a number or a wildcard).
	char		szIP[4][4];

	// Comment regarding the banned address.
	char		szComment[128];

	// [RC] Time that the ban expires, or NULL for an infinite ban.
	time_t		tExpirationDate;

} IPADDRESSBAN_s;

//*****************************************************************************
typedef struct
{
	// Pointer to our stream of data.
	BYTE		*pbStream;

	// Pointer to the end of the stream. When pbStream > pbStreamEnd, the
	// entire stream has been read.
	BYTE		*pbStreamEnd;

#ifdef CREATE_PACKET_LOG
	// [RC] Pointer to the start of the stream.
	BYTE		*pbStreamBeginning;

	// [RC] Whether or not we've logged this.
	bool		bPacketAlreadyLogged;
#endif

} BYTESTREAM_s;


//*****************************************************************************
typedef struct
{
	// This is the data in our packet.
	BYTE			*pbData;

	// The maximum amount of data this packet can hold.
	ULONG			ulMaxSize;

	// How much data is currently in this packet?
	ULONG			ulCurrentSize;

	// Byte stream for this buffer for managing our current position and where
	// the end of the stream is.
	BYTESTREAM_s	ByteStream;

	// Is this a buffer that we write to, or read from?
	BUFFERTYPE_e	BufferType;

} NETBUFFER_s;

//*****************************************************************************
// [BB] Allows to easily use char[4][4] references as function arguments.
typedef char IPStringArray[4][4];

//--------------------------------------------------------------------------------------------------------------------------------------------------
//-- PROTOTYPES ------------------------------------------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------------------------------------------

void			NETWORK_InitBuffer( NETBUFFER_s *pBuffer, ULONG ulLength, BUFFERTYPE_e BufferType );
void			NETWORK_FreeBuffer( NETBUFFER_s *pBuffer );
void			NETWORK_ClearBuffer( NETBUFFER_s *pBuffer );
LONG			NETWORK_CalcBufferSize( NETBUFFER_s *pBuffer );
void			NETWORK_WriteBuffer( BYTESTREAM_s *pByteStream, const void *pvBuffer, int nLength );

void			NETWORK_StartTrafficMeasurement ( );
int				NETWORK_StopTrafficMeasurement ( );

int				NETWORK_ReadByte( BYTESTREAM_s *pByteStream );
int				NETWORK_ReadShort( BYTESTREAM_s *pByteStream );
int				NETWORK_ReadLong( BYTESTREAM_s *pByteStream );
float			NETWORK_ReadFloat( BYTESTREAM_s *pByteStream );
const char		*NETWORK_ReadString( BYTESTREAM_s *pByteStream );
void			NETWORK_WriteByte( BYTESTREAM_s *pByteStream, int Byte );
void			NETWORK_WriteShort( BYTESTREAM_s *pByteStream, int Short );
void			NETWORK_WriteLong( BYTESTREAM_s *pByteStream, int Long );
void			NETWORK_WriteFloat( BYTESTREAM_s *pByteStream, float Float );
void			NETWORK_WriteString( BYTESTREAM_s *pByteStream, const char *pszString );

void			NETWORK_WriteHeader( BYTESTREAM_s *pByteStream, int Byte );
bool			NETWORK_CompareAddress( NETADDRESS_s Address1, NETADDRESS_s Address2, bool bIgnorePort );
bool			NETWORK_StringToAddress( const char *pszString, NETADDRESS_s *pAddress );
void			NETWORK_SocketAddressToNetAddress( struct sockaddr_in *s, NETADDRESS_s *a );
void			NETWORK_NetAddressToSocketAddress( NETADDRESS_s &Address, struct sockaddr_in &SocketAddress );
bool			NETWORK_StringToIP( const char *pszAddress, char *pszIP0, char *pszIP1, char *pszIP2, char *pszIP3 );
void			NETWORK_AddressToIPStringArray( const NETADDRESS_s &Address, IPStringArray &szAddress );
const char		*NETWORK_GetHostByIPAddress( NETADDRESS_s Address );
std::string		GenerateCouldNotOpenFileErrorString( const char *pszFunctionHeader, const char *pszFileName, LONG lErrorCode );

//--------------------------------------------------------------------------------------------------------------------------------------------------
//-- CLASSES ---------------------------------------------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------------------------------------------

//==========================================================================
//
// IPFileParser
//
// Reads a list of IPs from a file (ie, a banlist). Supports wildcards and comments.
// @author Benjamin Berkels, Brad Carney
//
//==========================================================================

class IPFileParser
{
	const unsigned int	_listLength;
	ULONG				_numberOfEntries;
	char				_errorMessage[1024];

//*************************************************************************
public:
	IPFileParser( const int IPListLength ) : _listLength( IPListLength )
	{
		_errorMessage[0] = '\0';
	}
		
	const char* getErrorMessage( )
	{
		return _errorMessage;
	}

	ULONG getNumberOfEntries ( )
	{
		return _numberOfEntries;
	}

	bool parseIPList( const char* FileName, std::vector<IPADDRESSBAN_s> &IPArray );

//*************************************************************************
private:
	char		skipWhitespace( FILE *pFile );
	char		skipComment( FILE *pFile );
	void		readReason( FILE *pFile, char *Reason, const int MaxReasonLength );
	time_t		readExpirationDate( FILE *pFile );
	bool		parseNextLine( FILE *pFile, IPADDRESSBAN_s &IP, ULONG &BanIdx );
};

//==========================================================================
//
// IPList
//
// Stores a list of IPs. Supports wildcards.
// @author Benjamin Berkels
//
//==========================================================================

class IPList
{
	std::vector<IPADDRESSBAN_s>		_ipVector;
	std::string						_filename;
	std::string						_error;

//*************************************************************************
public:
	bool			clearAndLoadFromFile( const char *Filename );
	ULONG			getFirstMatchingEntryIndex( const IPStringArray &szAddress ) const;
	ULONG			getFirstMatchingEntryIndex( const NETADDRESS_s &Address ) const;
	bool			isIPInList( const IPStringArray &szAddress ) const;
	bool			isIPInList( const NETADDRESS_s &Address ) const;
	ULONG			doesEntryExist( const char *pszIP0, const char *pszIP1, const char *pszIP2, const char *pszIP3 ) const;
	IPADDRESSBAN_s	getEntry( const ULONG ulIdx ) const;
	std::string		getEntryAsString( const ULONG ulIdx, bool bIncludeComment = true, bool bIncludeExpiration = true, bool bInludeNewline = true ) const;
	ULONG			getEntryIndex( const NETADDRESS_s &Address ) const; // [RC]
	const char		*getEntryComment( const NETADDRESS_s &Address ) const; // [RC]
	time_t			getEntryExpiration( const NETADDRESS_s &Address ) const; // [RC]
	void			addEntry( const char *pszIP0, const char *pszIP1, const char *pszIP2, const char *pszIP3, const char *pszPlayerName, const char *pszComment, std::string &Message, time_t tExpiration );
	void			addEntry( const char *pszIPAddress, const char *pszPlayerName, const char *pszComment, std::string &Message, time_t tExpiration );
	void			removeEntry( const char *pszIP0, const char *pszIP1, const char *pszIP2, const char *pszIP3, std::string &Message );
	void			removeEntry( const char *pszIPAddress, std::string &Message );
	void			removeEntry( ULONG ulEntryIdx ); // [RC]
	void			copy( IPList &destination ); // [RC]
	void			sort(); // [RC]
	void			removeExpiredEntries( void ); // [RC]

	unsigned int	size() const { return static_cast<unsigned int>( _ipVector.size( )); }
	void			clear() { _ipVector.clear(); }
	void			push_back ( IPADDRESSBAN_s &IP ) { _ipVector.push_back(IP); }
	const char*		getErrorMessage() const { return _error.c_str(); }
	
	std::vector<IPADDRESSBAN_s>&	getVector() { return _ipVector; }

//*************************************************************************
private:
	bool rewriteListToFile ();
};

//==========================================================================
//
// QueryIPQueue
//
// Stores IPs that have recently queried us to prevent flooding.
// @author Benjamin Berkels, Rivecoder
//
//==========================================================================

class QueryIPQueue
{
	//*************************************************************************
	typedef struct 
	{
		// The IP address.
		NETADDRESS_s		Address;

		// Expiration date.
		long				lNextAllowedTime;

	} STORED_QUERY_IP_t;

	// The maximum number of entries that we can store.
	static const unsigned int	MAX_QUERY_IPS = 512;

	// The array of IPs.
	STORED_QUERY_IP_t			_IPQueue[MAX_QUERY_IPS];

	// Head and tail of the queue.
	unsigned int				_iQueueHead;
	unsigned int				_iQueueTail;

	// How long entries will last (seconds).
	unsigned int				_iEntryLength;

//*************************************************************************
public:
	QueryIPQueue( int iEntryLength ) : _iQueueHead( 0 ), _iQueueTail( 0 ), _iEntryLength( iEntryLength )
	{
	}

	void	adjustHead( const LONG CurrentTime );
	bool	addressInQueue( const NETADDRESS_s AddressFrom ) const;
	void	addAddress( const NETADDRESS_s AddressFrom, const LONG lCurrentTime, std::ostream *errorOut = NULL );
	bool	isFull( ) const;
};

//==========================================================================
//
// RingBuffer
//
// @author Benjamin Berkels
//
//==========================================================================
template<typename DataType, int Length>
class RingBuffer
{
	DataType _data[Length];
	// Position of the entry that will be overwritten next AKA the oldest entry.
	unsigned int _position;
public:
	RingBuffer ( )
	{
		clear();
	}
	void clear ( )
	{
		memset( _data, 0, sizeof( _data ));
		_position = 0;
	}
	void put ( DataType Entry )
	{
		_data[_position] = Entry;
		_position = ( ++_position % Length );
	}
	DataType getOldestEntry ( unsigned int Offset = 0 ) const
	{
		return _data[ ( _position + Offset ) % Length ];
	}
};

#endif	// __NETWORKSHARED_H__