1 /// \file
2 /// \brief Types used by RakNet, most of which involve user code.
3 ///
4 /// This file is part of RakNet Copyright 2003 Jenkins Software LLC
5 ///
6 /// Raknet is available under the terms of the GPLv3 license, see /usr/local/share/licenses/raknet-3.9.2_10,1/GPLv3.
7 
8 
9 #ifndef __NETWORK_TYPES_H
10 #define __NETWORK_TYPES_H
11 
12 #include "RakNetDefines.h"
13 #include "NativeTypes.h"
14 #include "RakNetTime.h"
15 #include "Export.h"
16 
17 /// Forward declaration
18 namespace RakNet
19 {
20 	class BitStream;
21 };
22 
23 /// Given a number of bits, return how many bytes are needed to represent that.
24 #define BITS_TO_BYTES(x) (((x)+7)>>3)
25 #define BYTES_TO_BITS(x) ((x)<<3)
26 
27 /// \sa NetworkIDObject.h
28 typedef unsigned char UniqueIDType;
29 typedef unsigned short SystemIndex;
30 typedef unsigned char RPCIndex;
31 const int MAX_RPC_MAP_SIZE=((RPCIndex)-1)-1;
32 const int UNDEFINED_RPC_INDEX=((RPCIndex)-1);
33 
34 /// First byte of a network message
35 typedef unsigned char MessageID;
36 
37 typedef uint32_t BitSize_t;
38 
39 #if defined(_MSC_VER) && _MSC_VER > 0
40 #define PRINTF_64_BIT_MODIFIER "I64"
41 #else
42 #define PRINTF_64_BIT_MODIFIER "ll"
43 #endif
44 
45 /// Describes the local socket to use for RakPeer::Startup
46 struct RAK_DLL_EXPORT SocketDescriptor
47 {
48 	SocketDescriptor();
49 	SocketDescriptor(unsigned short _port, const char *_hostAddress);
50 
51 	/// The local port to bind to.  Pass 0 to have the OS autoassign a port.
52 	unsigned short port;
53 
54 	/// The local network card address to bind to, such as "127.0.0.1".  Pass an empty string to use INADDR_ANY.
55 	char hostAddress[32];
56 
57 	// Only need to set for the PS3, when using signaling.
58 	// Connect with the port returned by signaling. Set this to whatever port RakNet was actually started on
59 	unsigned short remotePortRakNetWasStartedOn_PS3;
60 };
61 
62 extern bool NonNumericHostString( const char *host );
63 
64 /// \brief Network address for a system
65 /// \details Corresponds to a network address<BR>
66 /// This is not necessarily a unique identifier. For example, if a system has both LAN and internet connections, the system may be identified by either one, depending on who is communicating<BR>
67 /// Use RakNetGUID for a unique per-instance of RakPeer to identify systems
68 struct RAK_DLL_EXPORT SystemAddress
69 {
70 	SystemAddress();
71 	explicit SystemAddress(const char *a, unsigned short b);
72 	explicit SystemAddress(unsigned int a, unsigned short b);
73 
74 	///The peer address from inet_addr.
75 	uint32_t binaryAddress;
76 	///The port number
77 	unsigned short port;
78 	// Used internally for fast lookup. Optional (use -1 to do regular lookup). Don't transmit this.
79 	SystemIndex systemIndex;
sizeSystemAddress80 	static int size() {return (int) sizeof(uint32_t)+sizeof(unsigned short);}
81 
82 	// Return the systemAddress as a string in the format <IP>:<Port>
83 	// Returns a static string
84 	// NOT THREADSAFE
85 	const char *ToString(bool writePort=true) const;
86 
87 	// Return the systemAddress as a string in the format <IP>:<Port>
88 	// dest must be large enough to hold the output
89 	// THREADSAFE
90 	void ToString(bool writePort, char *dest) const;
91 
92 	// Sets the binary address part from a string.  Doesn't set the port
93 	void SetBinaryAddress(const char *str);
94 
95 	SystemAddress& operator = ( const SystemAddress& input )
96 	{
97 		binaryAddress = input.binaryAddress;
98 		port = input.port;
99 		systemIndex = input.systemIndex;
100 		return *this;
101 	}
102 
103 	bool operator==( const SystemAddress& right ) const;
104 	bool operator!=( const SystemAddress& right ) const;
105 	bool operator > ( const SystemAddress& right ) const;
106 	bool operator < ( const SystemAddress& right ) const;
107 };
108 
109 
110 /// Size of SystemAddress data
111 #define SystemAddress_Size 6
112 
113 class RakPeerInterface;
114 
115 /// All RPC functions have the same parameter list - this structure.
116 /// \deprecated use RakNet::RPC3 instead
117 struct RPCParameters
118 {
119 	/// The data from the remote system
120 	unsigned char *input;
121 
122 	/// How many bits long \a input is
123 	BitSize_t numberOfBitsOfData;
124 
125 	/// Which system called this RPC
126 	SystemAddress sender;
127 
128 	/// Which instance of RakPeer (or a derived RakPeer or RakPeer) got this call
129 	RakPeerInterface *recipient;
130 
131 	RakNetTime remoteTimestamp;
132 
133 	/// The name of the function that was called.
134 	char *functionName;
135 
136 	/// You can return values from RPC calls by writing them to this BitStream.
137 	/// This is only sent back if the RPC call originally passed a BitStream to receive the reply.
138 	/// If you do so and your send is reliable, it will block until you get a reply or you get disconnected from the system you are sending to, whichever is first.
139 	/// If your send is not reliable, it will block for triple the ping time, or until you are disconnected, or you get a reply, whichever is first.
140 	RakNet::BitStream *replyToSender;
141 };
142 
143 /// Uniquely identifies an instance of RakPeer. Use RakPeer::GetGuidFromSystemAddress() and RakPeer::GetSystemAddressFromGuid() to go between SystemAddress and RakNetGUID
144 /// Use RakPeer::GetGuidFromSystemAddress(UNASSIGNED_SYSTEM_ADDRESS) to get your own GUID
145 struct RAK_DLL_EXPORT RakNetGUID
146 {
RakNetGUIDRakNetGUID147 	RakNetGUID() {systemIndex=(SystemIndex)-1;}
RakNetGUIDRakNetGUID148 	explicit RakNetGUID(uint64_t _g) {g=_g; systemIndex=(SystemIndex)-1;}
149 //	uint32_t g[6];
150 	uint64_t g;
151 
152 	// Return the GUID as a string
153 	// Returns a static string
154 	// NOT THREADSAFE
155 	const char *ToString(void) const;
156 
157 	// Return the GUID as a string
158 	// dest must be large enough to hold the output
159 	// THREADSAFE
160 	void ToString(char *dest) const;
161 
162 	bool FromString(const char *source);
163 
164 	RakNetGUID& operator = ( const RakNetGUID& input )
165 	{
166 		g=input.g;
167 		systemIndex=input.systemIndex;
168 		return *this;
169 	}
170 
171 	// Used internally for fast lookup. Optional (use -1 to do regular lookup). Don't transmit this.
172 	SystemIndex systemIndex;
sizeRakNetGUID173 	static const int size() {return (int) sizeof(uint64_t);}
174 
175 	bool operator==( const RakNetGUID& right ) const;
176 	bool operator!=( const RakNetGUID& right ) const;
177 	bool operator > ( const RakNetGUID& right ) const;
178 	bool operator < ( const RakNetGUID& right ) const;
179 };
180 
181 /// Index of an invalid SystemAddress
182 //const SystemAddress UNASSIGNED_SYSTEM_ADDRESS =
183 //{
184 //	0xFFFFFFFF, 0xFFFF
185 //};
186 #ifndef SWIG
187 const SystemAddress UNASSIGNED_SYSTEM_ADDRESS(0xFFFFFFFF, 0xFFFF);
188 const RakNetGUID UNASSIGNED_RAKNET_GUID((uint64_t)-1);
189 #endif
190 //{
191 //	{0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF}
192 //	0xFFFFFFFFFFFFFFFF
193 //};
194 
195 
196 struct RAK_DLL_EXPORT AddressOrGUID
197 {
198 	RakNetGUID rakNetGuid;
199 	SystemAddress systemAddress;
200 
GetSystemIndexAddressOrGUID201 	SystemIndex GetSystemIndex(void) const {if (rakNetGuid!=UNASSIGNED_RAKNET_GUID) return rakNetGuid.systemIndex; else return systemAddress.systemIndex;}
IsUndefinedAddressOrGUID202 	bool IsUndefined(void) const {return rakNetGuid==UNASSIGNED_RAKNET_GUID && systemAddress==UNASSIGNED_SYSTEM_ADDRESS;}
SetUndefinedAddressOrGUID203 	void SetUndefined(void) {rakNetGuid=UNASSIGNED_RAKNET_GUID; systemAddress=UNASSIGNED_SYSTEM_ADDRESS;}
204 
AddressOrGUIDAddressOrGUID205 	AddressOrGUID() {}
AddressOrGUIDAddressOrGUID206 	AddressOrGUID( const AddressOrGUID& input )
207 	{
208 		rakNetGuid=input.rakNetGuid;
209 		systemAddress=input.systemAddress;
210 	}
AddressOrGUIDAddressOrGUID211 	AddressOrGUID( const SystemAddress& input )
212 	{
213 		rakNetGuid=UNASSIGNED_RAKNET_GUID;
214 		systemAddress=input;
215 	}
AddressOrGUIDAddressOrGUID216 	AddressOrGUID( const RakNetGUID& input )
217 	{
218 		rakNetGuid=input;
219 		systemAddress=UNASSIGNED_SYSTEM_ADDRESS;
220 	}
221 	AddressOrGUID& operator = ( const AddressOrGUID& input )
222 	{
223 		rakNetGuid=input.rakNetGuid;
224 		systemAddress=input.systemAddress;
225 		return *this;
226 	}
227 
228 	AddressOrGUID& operator = ( const SystemAddress& input )
229 	{
230 		rakNetGuid=UNASSIGNED_RAKNET_GUID;
231 		systemAddress=input;
232 		return *this;
233 	}
234 
235 	AddressOrGUID& operator = ( const RakNetGUID& input )
236 	{
237 		rakNetGuid=input;
238 		systemAddress=UNASSIGNED_SYSTEM_ADDRESS;
239 		return *this;
240 	}
241 };
242 
243 struct RAK_DLL_EXPORT NetworkID
244 {
245 	// This is done because we don't know the global constructor order
NetworkIDNetworkID246 	NetworkID()
247 		:
248 #if NETWORK_ID_SUPPORTS_PEER_TO_PEER
249 	guid((uint64_t)-1), systemAddress(0xFFFFFFFF, 0xFFFF),
250 #endif // NETWORK_ID_SUPPORTS_PEER_TO_PEER
251 		localSystemAddress(65535)
252 	{
253 	}
~NetworkIDNetworkID254 	~NetworkID() {}
255 
256 	/// \deprecated Use NETWORK_ID_SUPPORTS_PEER_TO_PEER in RakNetDefines.h
257 	// Set this to true to use peer to peer mode for NetworkIDs.
258 	// Obviously the value of this must match on all systems.
259 	// True, and this will write the systemAddress portion with network sends.  Takes more bandwidth, but NetworkIDs can be locally generated
260 	// False, and only localSystemAddress is used.
261 //	static bool peerToPeerMode;
262 
263 #if NETWORK_ID_SUPPORTS_PEER_TO_PEER==1
264 
265 	RakNetGUID guid;
266 
267 	// deprecated: Use guid instead
268 	// In peer to peer, we use both systemAddress and localSystemAddress
269 	// In client / server, we only use localSystemAddress
270 	SystemAddress systemAddress;
271 #endif
272 	unsigned short localSystemAddress;
273 
274 	NetworkID& operator = ( const NetworkID& input );
275 
276 	static bool IsPeerToPeerMode(void);
277 	static void SetPeerToPeerMode(bool isPeerToPeer);
278 	bool operator==( const NetworkID& right ) const;
279 	bool operator!=( const NetworkID& right ) const;
280 	bool operator > ( const NetworkID& right ) const;
281 	bool operator < ( const NetworkID& right ) const;
282 };
283 
284 /// This represents a user message from another system.
285 struct Packet
286 {
287 	// This is now in the systemAddress struct and is used for lookups automatically
288 	/// Server only - this is the index into the player array that this systemAddress maps to
289 //	SystemIndex systemIndex;
290 
291 	/// The system that send this packet.
292 	SystemAddress systemAddress;
293 
294 	/// A unique identifier for the system that sent this packet, regardless of IP address (internal / external / remote system)
295 	/// Only valid once a connection has been established (ID_CONNECTION_REQUEST_ACCEPTED, or ID_NEW_INCOMING_CONNECTION)
296 	/// Until that time, will be UNASSIGNED_RAKNET_GUID
297 	RakNetGUID guid;
298 
299 	/// The length of the data in bytes
300 	unsigned int length;
301 
302 	/// The length of the data in bits
303 	BitSize_t bitSize;
304 
305 	/// The data from the sender
306 	unsigned char* data;
307 
308 	/// @internal
309 	/// Indicates whether to delete the data, or to simply delete the packet.
310 	bool deleteData;
311 
312 	/// @internal
313 	/// If true, this message is meant for the user, not for the plugins, so do not process it through plugins
314 	bool bypassPlugins;
315 };
316 
317 ///  Index of an unassigned player
318 const SystemIndex UNASSIGNED_PLAYER_INDEX = 65535;
319 
320 /// Unassigned object ID
321 const NetworkID UNASSIGNED_NETWORK_ID;
322 
323 const int PING_TIMES_ARRAY_SIZE = 5;
324 
325 /// \brief RPC Function Implementation
326 /// \Deprecated Use RPC3
327 /// \details The Remote Procedure Call Subsystem provide the RPC paradigm to
328 /// RakNet user. It consists in providing remote function call over the
329 /// network.  A call to a remote function require you to prepare the
330 /// data for each parameter (using BitStream) for example.
331 ///
332 /// Use the following C function prototype for your callbacks
333 /// @code
334 /// void functionName(RPCParameters *rpcParms);
335 /// @endcode
336 /// If you pass input data, you can parse the input data in two ways.
337 /// 1.
338 /// Cast input to a struct (such as if you sent a struct)
339 /// i.e. MyStruct *s = (MyStruct*) input;
340 /// Make sure that the sizeof(MyStruct) is equal to the number of bytes passed!
341 /// 2.
342 /// Create a BitStream instance with input as data and the number of bytes
343 /// i.e. BitStream myBitStream(input, (numberOfBitsOfData-1)/8+1)
344 /// (numberOfBitsOfData-1)/8+1 is how convert from bits to bytes
345 /// Full example:
346 /// @code
347 /// void MyFunc(RPCParameters *rpcParms) {}
348 /// RakPeer *rakClient;
349 /// REGISTER_AS_REMOTE_PROCEDURE_CALL(rakClient, MyFunc);
350 /// This would allow MyFunc to be called from the server using  (for example)
351 /// rakServer->RPC("MyFunc", 0, clientID, false);
352 /// @endcode
353 
354 
355 /// \def REGISTER_STATIC_RPC
356 /// \ingroup RAKNET_RPC
357 /// Register a C function as a Remote procedure.
358 /// \param[in] networkObject Your instance of RakPeer, RakPeer, or RakPeer
359 /// \param[in] functionName The name of the C function to call
360 /// \attention 12/01/05 REGISTER_AS_REMOTE_PROCEDURE_CALL renamed to REGISTER_STATIC_RPC.  Delete the old name sometime in the future
361 //#pragma deprecated(REGISTER_AS_REMOTE_PROCEDURE_CALL)
362 //#define REGISTER_AS_REMOTE_PROCEDURE_CALL(networkObject, functionName) REGISTER_STATIC_RPC(networkObject, functionName)
363 /// \deprecated Use RakNet::RPC3 instead
364 #define REGISTER_STATIC_RPC(networkObject, functionName) (networkObject)->RegisterAsRemoteProcedureCall((#functionName),(functionName))
365 
366 /// \def CLASS_MEMBER_ID
367 /// \ingroup RAKNET_RPC
368 /// \brief Concatenate two strings
369 
370 /// \def REGISTER_CLASS_MEMBER_RPC
371 /// \ingroup RAKNET_RPC
372 /// \brief Register a member function of an instantiated object as a Remote procedure call.
373 /// \details RPC member Functions MUST be marked __cdecl!
374 /// \sa ObjectMemberRPC.cpp
375 /// \b CLASS_MEMBER_ID is a utility macro to generate a unique signature for a class and function pair and can be used for the Raknet functions RegisterClassMemberRPC(...) and RPC(...)
376 /// \b REGISTER_CLASS_MEMBER_RPC is a utility macro to more easily call RegisterClassMemberRPC
377 /// \param[in] networkObject Your instance of RakPeer, RakPeer, or RakPeer
378 /// \param[in] className The class containing the function
379 /// \param[in] functionName The name of the function (not in quotes, just the name)
380 /// \deprecated Use RakNet::RPC3 instead
381 #define CLASS_MEMBER_ID(className, functionName) #className "_" #functionName
382 /// \deprecated Use RakNet::RPC3 instead
383 #define REGISTER_CLASS_MEMBER_RPC(networkObject, className, functionName) {union {void (__cdecl className::*cFunc)( RPCParameters *rpcParms ); void* voidFunc;}; cFunc=&className::functionName; networkObject->RegisterClassMemberRPC(CLASS_MEMBER_ID(className, functionName),voidFunc);}
384 
385 /// \def UNREGISTER_AS_REMOTE_PROCEDURE_CALL
386 /// \brief Only calls UNREGISTER_STATIC_RPC
387 
388 /// \def UNREGISTER_STATIC_RPC
389 /// \ingroup RAKNET_RPC
390 /// Unregisters a remote procedure call
391 /// RPC member Functions MUST be marked __cdecl!  See the ObjectMemberRPC example.
392 /// \param[in] networkObject The object that manages the function
393 /// \param[in] functionName The function name
394 // 12/01/05 UNREGISTER_AS_REMOTE_PROCEDURE_CALL Renamed to UNREGISTER_STATIC_RPC.  Delete the old name sometime in the future
395 //#pragma deprecated(UNREGISTER_AS_REMOTE_PROCEDURE_CALL)
396 //#define UNREGISTER_AS_REMOTE_PROCEDURE_CALL(networkObject,functionName) UNREGISTER_STATIC_RPC(networkObject,functionName)
397 /// \deprecated Use RakNet::RPC3 instead
398 #define UNREGISTER_STATIC_RPC(networkObject,functionName) (networkObject)->UnregisterAsRemoteProcedureCall((#functionName))
399 
400 /// \def UNREGISTER_CLASS_INST_RPC
401 /// \ingroup RAKNET_RPC
402 /// \deprecated Use the AutoRPC plugin instead
403 /// \brief Unregisters a member function of an instantiated object as a Remote procedure call.
404 /// \param[in] networkObject The object that manages the function
405 /// \param[in] className The className that was originally passed to REGISTER_AS_REMOTE_PROCEDURE_CALL
406 /// \param[in] functionName The function name
407 /// \deprecated Use RakNet::RPC3 instead
408 #define UNREGISTER_CLASS_MEMBER_RPC(networkObject, className, functionName) (networkObject)->UnregisterAsRemoteProcedureCall((#className "_" #functionName))
409 
410 struct RAK_DLL_EXPORT uint24_t
411 {
412 	uint32_t val;
413 
uint24_tuint24_t414 	uint24_t() {}
uint32_tuint24_t415 	inline operator uint32_t() { return val; }
uint32_tuint24_t416 	inline operator uint32_t() const { return val; }
417 
uint24_tuint24_t418 	inline uint24_t(const uint24_t& a) {val=a.val;}
419 	inline uint24_t operator++() {++val; val&=0x00FFFFFF; return *this;}
420 	inline uint24_t operator--() {--val; val&=0x00FFFFFF; return *this;}
421 	inline uint24_t operator++(int) {uint24_t temp(val); ++val; val&=0x00FFFFFF; return temp;}
422 	inline uint24_t operator--(int) {uint24_t temp(val); --val; val&=0x00FFFFFF; return temp;}
423 	inline uint24_t operator&(const uint24_t& a) {return uint24_t(val&a.val);}
424 	inline uint24_t& operator=(const uint24_t& a) { val=a.val; return *this; }
425 	inline uint24_t& operator+=(const uint24_t& a) { val+=a.val; val&=0x00FFFFFF; return *this; }
426 	inline uint24_t& operator-=(const uint24_t& a) { val-=a.val; val&=0x00FFFFFF; return *this; }
427 	inline bool operator==( const uint24_t& right ) const {return val==right.val;}
428 	inline bool operator!=( const uint24_t& right ) const {return val!=right.val;}
429 	inline bool operator > ( const uint24_t& right ) const {return val>right.val;}
430 	inline bool operator < ( const uint24_t& right ) const {return val<right.val;}
431 	inline const uint24_t operator+( const uint24_t &other ) const { return uint24_t(val+other.val); }
432 	inline const uint24_t operator-( const uint24_t &other ) const { return uint24_t(val-other.val); }
433 	inline const uint24_t operator/( const uint24_t &other ) const { return uint24_t(val/other.val); }
434 	inline const uint24_t operator*( const uint24_t &other ) const { return uint24_t(val*other.val); }
435 
uint24_tuint24_t436 	inline uint24_t(const uint32_t& a) {val=a; val&=0x00FFFFFF;}
437 	inline uint24_t operator&(const uint32_t& a) {return uint24_t(val&a);}
438 	inline uint24_t& operator=(const uint32_t& a) { val=a; val&=0x00FFFFFF; return *this; }
439 	inline uint24_t& operator+=(const uint32_t& a) { val+=a; val&=0x00FFFFFF; return *this; }
440 	inline uint24_t& operator-=(const uint32_t& a) { val-=a; val&=0x00FFFFFF; return *this; }
441 	inline bool operator==( const uint32_t& right ) const {return val==(right&0x00FFFFFF);}
442 	inline bool operator!=( const uint32_t& right ) const {return val!=(right&0x00FFFFFF);}
443 	inline bool operator > ( const uint32_t& right ) const {return val>(right&0x00FFFFFF);}
444 	inline bool operator < ( const uint32_t& right ) const {return val<(right&0x00FFFFFF);}
445 	inline const uint24_t operator+( const uint32_t &other ) const { return uint24_t(val+other); }
446 	inline const uint24_t operator-( const uint32_t &other ) const { return uint24_t(val-other); }
447 	inline const uint24_t operator/( const uint32_t &other ) const { return uint24_t(val/other); }
448 	inline const uint24_t operator*( const uint32_t &other ) const { return uint24_t(val*other); }
449 };
450 
451 #endif
452