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_
|