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
|
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#if !defined( SOCKET_H )
#define SOCKET_H
#ifdef _WIN32
#pragma once
#endif
#include "netadr.h"
#include "MsgBuffer.h"
#include "utlvector.h"
#include <stdio.h>
class CMsgBuffer;
class CSocket;
class IGameList;
// Use this to pick apart the network stream, must be packed
#pragma pack(1)
typedef struct
{
int netID;
int sequenceNumber;
char packetID;
} SPLITPACKET;
#pragma pack()
#define MAX_PACKETS 16 // 4 bits for the packet count, so only
#define MAX_RETRIES 2 // the number of fragments from other packets to drop before we declare the outstanding
// fragment lost :)
//-----------------------------------------------------------------------------
// Purpose: Instances a message handler for incoming messages.
//-----------------------------------------------------------------------------
class CMsgHandler
{
public:
enum
{
MAX_HANDLER_STRING = 64
};
typedef enum
{
MSGHANDLER_ALL = 0,
MSGHANDLER_BYTECODE,
MSGHANDLER_STRING
} HANDLERTYPE;
// Construction
CMsgHandler( HANDLERTYPE type, void *typeinfo = 0 );
virtual ~CMsgHandler( void );
// Message received, process it
virtual bool Process( netadr_t *from, CMsgBuffer *msg ) = 0;
// For linking togethr handler chains
virtual CMsgHandler *GetNext( void ) const;
virtual void SetNext( CMsgHandler *next );
// Access/set associated socket
virtual CSocket *GetSocket( void ) const;
virtual void SetSocket( CSocket *socket );
private:
// Internal message received, crack type info and check it before calling process
bool ProcessMessage( netadr_t *from, CMsgBuffer *msg );
// Opaque pointer to underlying recipient class
IGameList *m_pBaseObject;
// Next handler in chain
HANDLERTYPE m_Type;
unsigned char m_ByteCode;
char m_szString[ MAX_HANDLER_STRING ];
// Next handler in chain
CMsgHandler *m_pNext;
// Associated socket
CSocket *m_pSocket;
friend CSocket;
};
//-----------------------------------------------------------------------------
// Purpose: Creates a non-blocking, broadcast capable, UDP socket. If port is
// specified, binds it to listen on that port, otherwise, chooses a random port.
//-----------------------------------------------------------------------------
class CSocket
{
public:
// Construction/destruction
CSocket( const char *socketname, int port = -1 );
virtual ~CSocket( void );
// Adds the message hander to the head of the sockets handler chain
virtual void AddMessageHandler( CMsgHandler *handler );
// Removes the specified message handler
virtual void RemoveMessageHandler( CMsgHandler *handler );
// Send the message to the recipient, if msg == NULL, use the internal message buffer
virtual int SendMessage( netadr_t *to, CMsgBuffer *msg = NULL );
// Broadcast the message on the specified port, if msg == NULL use the internal message buffer
virtual int Broadcast( int port, CMsgBuffer *msg = NULL );
// Get access to the internal message buffer
virtual CMsgBuffer *GetSendBuffer( void );
// Called once per frame to check for new data
virtual void Frame( void );
// Check whether the socket was created and set up properly
virtual bool IsValid( void ) const;
// Get the address this socket is bound to
virtual const netadr_t *GetAddress( void );
// Allow creating object to store a 32 bit value and retrieve it
virtual void SetUserData( unsigned int userData );
virtual unsigned int GetUserData(void ) const;
// Allow other objects to get the raw socket interger
virtual int GetSocketNumber( void ) const;
// Called when FD_ISSET noted that the socket has incoming data
virtual bool ReceiveData( void );
// Called to get current time
static float GetClock( void );
private:
const char *m_pSocketName;
// Socket listen address
bool m_bValid;
// Socket IP address
netadr_t m_Address;
// Has the IP address been resolved
bool m_bResolved;
// Internal message buffers
CUtlVector<CMsgBuffer> m_MsgBuffers;
CMsgBuffer m_SendBuffer;
// critical section for accessing buffers
void *m_pBufferCS;
// One or more listeners for the incoming message
CMsgHandler *m_pMessageHandlers;
// Winsock socket number
int m_Socket;
// User 32 bit value
unsigned int m_nUserData;
// Socket to which non Broadcast SendMessage was directed. The socket will wait for a response
// from that exact address
netadr_t m_ToAddress;
// Set to true if the send was a Broadcast, and therefore from != to address is okay
bool m_bBroadcastSend;
int m_iTotalPackets; // total number of packets in a fragment
int m_iCurrentPackets; // current packet count
int m_iSeqNo; // the sequence number of the packet
int m_iRetries;
CMsgBuffer m_CurPacket[MAX_PACKETS]; // store for the packet
};
#endif // SOCKET_H
|