-
Notifications
You must be signed in to change notification settings - Fork 33
/
qserver.h
232 lines (200 loc) · 5.96 KB
/
qserver.h
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
/*
* qstat
* by Steve Jankowski
*
* qserver functions and definitions
* Copyright 2004 Ludwig Nussel
*
* Licensed under the Artistic License, see LICENSE.txt for license terms
*/
#ifndef QSTAT_QSERVER_H
#define QSTAT_QSERVER_H
struct query_param {
char *key;
char *value;
int i_value;
unsigned int ui_value;
struct query_param *next;
};
typedef struct SavedData {
char *data;
int datalen;
int pkt_index;
int pkt_max;
unsigned int pkt_id;
struct SavedData *next;
} SavedData;
typedef enum {
STATE_INIT = 0,
STATE_CONNECTING = 1,
STATE_CONNECTED = 2,
STATE_QUERYING = 3,
STATE_QUERIED = 4,
STATE_TIMEOUT = -1,
STATE_SYS_ERROR = -2,
} server_state_t;
struct qserver {
char *arg;
char *host_name;
unsigned int ipaddr;
int flags;
server_type *type;
int fd;
server_state_t state;
char *outfilename;
char *query_arg;
char *challenge_string;
struct query_param *params;
unsigned long challenge;
unsigned short port;
unsigned short orig_port; // This port is always constant from creation where as port can be updated based on the query results
unsigned short query_port;
// State variable to flag if the current processing call is a call from combine_packets
// This should really by done via a flag to the method itself but that would require changes
// to all handlers :(
unsigned short combined;
/** \brief number of retries _left_ for status query or rule query.
*
* That means
* if s->retry1 == (global)n_retries then no retries were necessary so far.
* if s->retry1 == 0 then the server has to be cleaned up after timeout */
int retry1;
/** \brief number retries _left_ for player query. @see retry1 */
int retry2;
/** \brief how much retry packets were sent */
int n_retries;
/** \brief time when the last packet to the server was sent */
struct timeval packet_time1;
struct timeval packet_time2;
/** \brief sum of packet deltas
*
* average server ping is ping_total / n_requests
*/
int ping_total;
/** \brief number of requests send to a server.
*
* used for ping calculation
* @see ping_total
*/
int n_requests;
/** \brief number of packets already sent to this server
*
* doesn't seemt to have any use
*/
int n_packets;
/** \brief number of servers in master_pkt
*
* normally master_pkt_len/6
*/
int n_servers;
/** \brief length of master_pkt */
int master_pkt_len;
/** \brief IPs received from master.
*
* array of four bytes ip, two bytes port in network byte order
*/
char *master_pkt;
/** \brief state info
*
* used for progressive master 4 bytes for WON 22 for Steam
*/
char master_query_tag[22];
char *error;
/** \brief in-game name of the server.
*
* A server that has a NULL name did not receive any packets yet and is
* considered down after a timeout.
*/
char *server_name;
char *address;
char *map_name;
char *game;
int max_players;
int num_players;
int protocol_version;
int max_spectators;
int num_spectators;
SavedData saved_data;
/** \brief number of the next player to retrieve info for.
*
* Only meaningful for servers that have type->player_packet.
* This is used by q1 as it sends packets for each player individually.
* cleanup_qserver() cleans up a server if next_rule == NULL and
* next_player_info >= num_players
*/
int next_player_info;
/** \brief number of player info packets received */
int n_player_info;
struct player *players;
/** \brief name of next rule to retreive
*
* Used by Q1 as it needs to send a packet for each rule. Other games would
* set this to an empty string to indicate that rules need to be retrieved.
* After rule packet is received set this to NULL.
*/
char *next_rule;
int n_rules;
struct rule *rules;
struct rule **last_rule;
int missing_rules;
struct qserver *next;
struct qserver *prev;
};
void qserver_disconnect(struct qserver *server);
/* server specific query parameters */
void add_query_param(struct qserver *server, char *arg);
/** \brief get a parameter for the server as string
*
* @param server the server to get the value from
* @param key which key to get
* @param default_value value to return if key was not found
* @return value for key or default_value
*/
char *get_param_value(struct qserver *server, const char *key, char *default_value);
/** @see get_param_value */
int get_param_i_value(struct qserver *server, char *key, int default_value);
/** @see get_param_value */
unsigned int get_param_ui_value(struct qserver *server, char *key,
unsigned int default_value);
/** \brief send an initial query packet to a server
*
* Sends a unicast packet to the server's file descriptor. The descriptor must
* be connected. Updates n_requests or n_retries, retry1, n_packets, packet_time1
*
* \param server the server
* \param data data to send
* \param len length of data
* \returns number of bytes sent or SOCKET_ERROR
*/
query_status_t qserver_send_initial(struct qserver *server, const char *data, size_t len);
/** \brief send an initial query packet to a server
*
* Sends a unicast packet to the server's file descriptor. The descriptor must
* be connected. Updates n_requests, n_packets, packet_time1. Sets retry1 to
* (global) n_retries
*
* @see qserver_send_initial
*/
query_status_t qserver_send(struct qserver *server, const char *data, size_t len);
int send_broadcast(struct qserver *server, const char *pkt, size_t pktlen);
/**
* Registers the send of a request packet.
*
* This updates n_requests, n_packets, packet_time1 and decrements n_retries
*/
int register_send(struct qserver *server);
/**
* Sends a packet to the server either direct or via broadcast.
*
* Once sent calls register_send to register the send of the packet
*/
query_status_t send_packet(struct qserver *server, const char *data, size_t len);
/**
* Sends a packet to the server either direct or via broadcast.
*/
query_status_t send_packet_raw(struct qserver *server, const char *data, size_t len);
/**
* Logs the error from a socket send
*/
query_status_t send_error(struct qserver *server, int rc);
#endif