aboutsummaryrefslogtreecommitdiff
path: root/src/parsec_server/include/net_packetdriver.h
blob: f4b1f1d3d57c0e79147fa9c6e7410da89668ea51 (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
/*
* PARSEC HEADER: NET_PacketDriver.h
*/

#ifndef _NET_PACKETDRIVER_H_
#define _NET_PACKETDRIVER_H_

// forward decls --------------------------------------------------------------
//
struct NetPacket_GMSV;
class NET_UDPDriver;
class NET_Stream;
class E_GameServer;
class E_PacketHandler;


// number of listen buffers in listen buffers array ---------------------------
//
#define NUM_LISTEN_BUFFERS		( MAX_NET_ALLOC_SLOTS * 2 )

// high level packet chain (preprocessed to meet ordering requirements) -------
//
struct PacketChainBlock {
	
	int 				bufferno;
	NetPacket_GMSV*		gamepacket;
	int 				messageid;
	PacketChainBlock*	nextblock;
};

struct PacketChainHead : PacketChainBlock {
	int chainlength;
};


// general packet handling function -------------------------------------------
//
class NET_PacketDriver
{
protected:

	NetPacketExternal_GMSV* SendNetPacketExternal;
	NetPacketExternal_GMSV* RecvNetPacketExternal;
	int						ListenStatus		[ NUM_LISTEN_BUFFERS ];
	sockaddr_in				ListenAddress		[ NUM_LISTEN_BUFFERS ];
	node_t					ListenSenderStorage	[ NUM_LISTEN_BUFFERS ];
	NetPacket_GMSV*			NetPacketsInternal	[ NUM_LISTEN_BUFFERS ];
	
	PacketChainHead*		ReceivedPacketsChain;

	NET_Stream*				m_Streams;			// add one player for PLAYERID_ANONYMOUS

protected:
	// retrieve next packet from received packets chain 
	PacketChainBlock* _FetchPacketFromChain();

	// allocate received packets chain (head node)
	int _AllocPacketsChain();
	
	// free all blocks in received packets chain 
	void _FreePacketsChain();

	// release block containing pointer and info of packet 
	void _ReleasePacketFromChain( PacketChainBlock* block );
	
	// pre-process received packets 
	void _BuildReceivedPacketsChain();
	
	// insert received packet into chain
	int _ChainPacket( NetPacket_GMSV* gamepacket, int bufid );
	
	// check regular player packets for duplicates 
	int _FilterPacketDuplicate( int senderid, int messageid );
	
	// process packet before inserting it into packet chain 
	void _PreprocessInPacket( NetPacket_GMSV* gamepacket );

	// log packet loss statistics 
	void _LogPacketLossStats( int numpackets, int packetok, int incoming );
	
	// fetch a packet into a listen buffer
	int _UDP_FetchPacket( int bufid );

	// determine if packet should be artificially dropped
	int _CheckForcePacketDrop();

	// record a packet
	void _RecordPacket( int bufid );

	NET_PacketDriver();
	virtual ~NET_PacketDriver();

public:

	// SINGLETON pattern
	static NET_PacketDriver* GetPacketDriver()
	{
		static NET_PacketDriver _ThePacketDriver;
		return &_ThePacketDriver;
	}

	// invoke processing function for all packets currently in chain 
	void NET_ProcessPacketChain();

	// retrieve sender's node address from listen header
	node_t* GetPktSender( int bufid );

	// send a packet to a node
	int SendPacket( NetPacket_GMSV* gamepacket, node_t* node, int nClientID, E_REList* pReliable, E_REList* pUnreliable );

	// send a datagram ( unreliable, unnumbered packet ) to a node
	int SendDatagram( NetPacket_GMSV* gamepacket, node_t* node, int nClientID, E_REList* pUnreliable );

	// fill standard fields in gamepacket header
	void FillStdGameHeader( byte command, NetPacket_GMSV* gamepacket );

	// reset all data members
	void Reset();

	// reset the stream of a specific client
	void ResetStream( int nClientID );

	// connect the stream of a client
	void ConnectStream( int nClientID );

	// flush the reliable backbuffer of a stream
	void FlushReliableBuffer( int nClientID );

	// return the message id used in the next packet that is sent
	int GetNextOutMessageId( int nClientID );
		
	// get the stream message status
	NET_Stream* GetStream( int nClientID );

	friend class E_GameServer;
};

#endif // _NET_PACKETDRIVER_H_