1 /* 2 Copyright (C) 1996-1997 Id Software, Inc. 3 Copyright (C) 2003 Forest Hale 4 5 This program is free software; you can redistribute it and/or 6 modify it under the terms of the GNU General Public License 7 as published by the Free Software Foundation; either version 2 8 of the License, or (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 13 14 See the GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program; if not, write to the Free Software 18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 19 20 */ 21 22 #ifndef NET_H 23 #define NET_H 24 25 #include "lhnet.h" 26 27 #define NET_HEADERSIZE (2 * sizeof(unsigned int)) 28 29 // NetHeader flags 30 #define NETFLAG_LENGTH_MASK 0x0000ffff 31 #define NETFLAG_DATA 0x00010000 32 #define NETFLAG_ACK 0x00020000 33 #define NETFLAG_NAK 0x00040000 34 #define NETFLAG_EOM 0x00080000 35 #define NETFLAG_UNRELIABLE 0x00100000 36 #define NETFLAG_CRYPTO0 0x10000000 37 #define NETFLAG_CRYPTO1 0x20000000 38 #define NETFLAG_CRYPTO2 0x40000000 39 #define NETFLAG_CTL 0x80000000 40 41 42 #define NET_PROTOCOL_VERSION 3 43 #define NET_EXTRESPONSE_MAX 16 44 45 /// \page netconn The network info/connection protocol. 46 /// It is used to find Quake 47 /// servers, get info about them, and connect to them. Once connected, the 48 /// Quake game protocol (documented elsewhere) is used. 49 /// 50 /// 51 /// General notes:\code 52 /// game_name is currently always "QUAKE", but is there so this same protocol 53 /// can be used for future games as well; can you say Quake2? 54 /// 55 /// CCREQ_CONNECT 56 /// string game_name "QUAKE" 57 /// byte net_protocol_version NET_PROTOCOL_VERSION 58 /// 59 /// CCREQ_SERVER_INFO 60 /// string game_name "QUAKE" 61 /// byte net_protocol_version NET_PROTOCOL_VERSION 62 /// 63 /// CCREQ_PLAYER_INFO 64 /// byte player_number 65 /// 66 /// CCREQ_RULE_INFO 67 /// string rule 68 /// 69 /// CCREQ_RCON 70 /// string password 71 /// string command 72 /// 73 /// 74 /// 75 /// CCREP_ACCEPT 76 /// long port 77 /// 78 /// CCREP_REJECT 79 /// string reason 80 /// 81 /// CCREP_SERVER_INFO 82 /// string server_address 83 /// string host_name 84 /// string level_name 85 /// byte current_players 86 /// byte max_players 87 /// byte protocol_version NET_PROTOCOL_VERSION 88 /// 89 /// CCREP_PLAYER_INFO 90 /// byte player_number 91 /// string name 92 /// long colors 93 /// long frags 94 /// long connect_time 95 /// string address 96 /// 97 /// CCREP_RULE_INFO 98 /// string rule 99 /// string value 100 /// 101 /// CCREP_RCON 102 /// string reply 103 /// \endcode 104 /// \note 105 /// There are two address forms used above. The short form is just a 106 /// port number. The address that goes along with the port is defined as 107 /// "whatever address you receive this reponse from". This lets us use 108 /// the host OS to solve the problem of multiple host addresses (possibly 109 /// with no routing between them); the host will use the right address 110 /// when we reply to the inbound connection request. The long from is 111 /// a full address and port in a string. It is used for returning the 112 /// address of a server that is not running locally. 113 114 #define CCREQ_CONNECT 0x01 115 #define CCREQ_SERVER_INFO 0x02 116 #define CCREQ_PLAYER_INFO 0x03 117 #define CCREQ_RULE_INFO 0x04 118 #define CCREQ_RCON 0x05 // RocketGuy: ProQuake rcon support 119 120 #define CCREP_ACCEPT 0x81 121 #define CCREP_REJECT 0x82 122 #define CCREP_SERVER_INFO 0x83 123 #define CCREP_PLAYER_INFO 0x84 124 #define CCREP_RULE_INFO 0x85 125 #define CCREP_RCON 0x86 // RocketGuy: ProQuake rcon support 126 127 typedef struct netgraphitem_s 128 { 129 double time; 130 int reliablebytes; 131 int unreliablebytes; 132 int ackbytes; 133 double cleartime; 134 } 135 netgraphitem_t; 136 137 typedef struct netconn_s 138 { 139 struct netconn_s *next; 140 141 lhnetsocket_t *mysocket; 142 lhnetaddress_t peeraddress; 143 144 // this is mostly identical to qsocket_t from quake 145 146 /// if this time is reached, kick off peer 147 double connecttime; 148 double timeout; 149 double lastMessageTime; 150 double lastSendTime; 151 152 /// writing buffer to send to peer as the next reliable message 153 /// can be added to at any time, copied into sendMessage buffer when it is 154 /// possible to send a reliable message and then cleared 155 /// @{ 156 sizebuf_t message; 157 unsigned char messagedata[NET_MAXMESSAGE]; 158 /// @} 159 160 /// reliable message that is currently sending 161 /// (for building fragments) 162 int sendMessageLength; 163 unsigned char sendMessage[NET_MAXMESSAGE]; 164 165 /// reliable message that is currently being received 166 /// (for putting together fragments) 167 int receiveMessageLength; 168 unsigned char receiveMessage[NET_MAXMESSAGE]; 169 170 /// used by both NQ and QW protocols 171 unsigned int outgoing_unreliable_sequence; 172 173 struct netconn_nq_s 174 { 175 unsigned int ackSequence; 176 unsigned int sendSequence; 177 178 unsigned int receiveSequence; 179 unsigned int unreliableReceiveSequence; 180 } 181 nq; 182 struct netconn_qw_s 183 { 184 // QW protocol 185 qboolean fatal_error; 186 187 float last_received; // for timeouts 188 189 // the statistics are cleared at each client begin, because 190 // the server connecting process gives a bogus picture of the data 191 float frame_latency; // rolling average 192 float frame_rate; 193 194 int drop_count; ///< dropped packets, cleared each level 195 int good_count; ///< cleared each level 196 197 int qport; 198 199 // sequencing variables 200 unsigned int incoming_sequence; 201 unsigned int incoming_acknowledged; 202 qboolean incoming_reliable_acknowledged; ///< single bit 203 204 qboolean incoming_reliable_sequence; ///< single bit, maintained local 205 206 qboolean reliable_sequence; ///< single bit 207 unsigned int last_reliable_sequence; ///< sequence number of last send 208 } 209 qw; 210 211 // bandwidth estimator 212 double cleartime; // if realtime > nc->cleartime, free to go 213 double incoming_cleartime; // if realtime > nc->cleartime, free to go (netgraph cleartime simulation only) 214 215 // this tracks packet loss and packet sizes on the most recent packets 216 // used by shownetgraph feature 217 #define NETGRAPH_PACKETS 256 218 #define NETGRAPH_NOPACKET 0 219 #define NETGRAPH_LOSTPACKET -1 220 #define NETGRAPH_CHOKEDPACKET -2 221 int incoming_packetcounter; 222 netgraphitem_t incoming_netgraph[NETGRAPH_PACKETS]; 223 int outgoing_packetcounter; 224 netgraphitem_t outgoing_netgraph[NETGRAPH_PACKETS]; 225 226 char address[128]; 227 crypto_t crypto; 228 229 // statistic counters 230 int packetsSent; 231 int packetsReSent; 232 int packetsReceived; 233 int receivedDuplicateCount; 234 int droppedDatagrams; 235 int unreliableMessagesSent; 236 int unreliableMessagesReceived; 237 int reliableMessagesSent; 238 int reliableMessagesReceived; 239 } netconn_t; 240 241 extern netconn_t *netconn_list; 242 extern mempool_t *netconn_mempool; 243 244 extern cvar_t hostname; 245 extern cvar_t developer_networking; 246 247 #ifdef CONFIG_MENU 248 #define SERVERLIST_VIEWLISTSIZE SERVERLIST_TOTALSIZE 249 250 typedef enum serverlist_maskop_e 251 { 252 // SLMO_CONTAINS is the default for strings 253 // SLMO_GREATEREQUAL is the default for numbers (also used when OP == CONTAINS or NOTCONTAINS 254 SLMO_CONTAINS, 255 SLMO_NOTCONTAIN, 256 257 SLMO_LESSEQUAL, 258 SLMO_LESS, 259 SLMO_EQUAL, 260 SLMO_GREATER, 261 SLMO_GREATEREQUAL, 262 SLMO_NOTEQUAL, 263 SLMO_STARTSWITH, 264 SLMO_NOTSTARTSWITH 265 } serverlist_maskop_t; 266 267 /// struct with all fields that you can search for or sort by 268 typedef struct serverlist_info_s 269 { 270 /// address for connecting 271 char cname[128]; 272 /// ping time for sorting servers 273 int ping; 274 /// name of the game 275 char game[32]; 276 /// name of the mod 277 char mod[32]; 278 /// name of the map 279 char map[32]; 280 /// name of the session 281 char name[128]; 282 /// qc-defined short status string 283 char qcstatus[128]; 284 /// frags/ping/name list (if they fit in the packet) 285 char players[1400]; 286 /// max client number 287 int maxplayers; 288 /// number of currently connected players (including bots) 289 int numplayers; 290 /// number of currently connected players that are bots 291 int numbots; 292 /// number of currently connected players that are not bots 293 int numhumans; 294 /// number of free slots 295 int freeslots; 296 /// protocol version 297 int protocol; 298 /// game data version 299 /// (an integer that is used for filtering incompatible servers, 300 /// not filterable by QC) 301 int gameversion; 302 303 // categorized sorting 304 int category; 305 /// favorite server flag 306 qboolean isfavorite; 307 } serverlist_info_t; 308 309 typedef enum 310 { 311 SLIF_CNAME, 312 SLIF_PING, 313 SLIF_GAME, 314 SLIF_MOD, 315 SLIF_MAP, 316 SLIF_NAME, 317 SLIF_MAXPLAYERS, 318 SLIF_NUMPLAYERS, 319 SLIF_PROTOCOL, 320 SLIF_NUMBOTS, 321 SLIF_NUMHUMANS, 322 SLIF_FREESLOTS, 323 SLIF_QCSTATUS, 324 SLIF_PLAYERS, 325 SLIF_CATEGORY, 326 SLIF_ISFAVORITE, 327 SLIF_COUNT 328 } serverlist_infofield_t; 329 330 typedef enum 331 { 332 SLSF_DESCENDING = 1, 333 SLSF_FAVORITES = 2, 334 SLSF_CATEGORIES = 4 335 } serverlist_sortflags_t; 336 337 typedef enum 338 { 339 SQS_NONE = 0, 340 SQS_QUERYING, 341 SQS_QUERIED, 342 SQS_TIMEDOUT, 343 SQS_REFRESHING 344 } serverlist_query_state; 345 346 typedef struct serverlist_entry_s 347 { 348 /// used to determine whether this entry should be included into the final view 349 serverlist_query_state query; 350 /// used to count the number of times the host has tried to query this server already 351 unsigned querycounter; 352 /// used to calculate ping when update comes in 353 double querytime; 354 /// query protocol to use on this server, may be PROTOCOL_QUAKEWORLD or PROTOCOL_DARKPLACES7 355 int protocol; 356 357 serverlist_info_t info; 358 359 // legacy stuff 360 char line1[128]; 361 char line2[128]; 362 } serverlist_entry_t; 363 364 typedef struct serverlist_mask_s 365 { 366 qboolean active; 367 serverlist_maskop_t tests[SLIF_COUNT]; 368 serverlist_info_t info; 369 } serverlist_mask_t; 370 371 #define ServerList_GetCacheEntry(x) (&serverlist_cache[(x)]) 372 #define ServerList_GetViewEntry(x) (ServerList_GetCacheEntry(serverlist_viewlist[(x)])) 373 374 extern serverlist_mask_t serverlist_andmasks[SERVERLIST_ANDMASKCOUNT]; 375 extern serverlist_mask_t serverlist_ormasks[SERVERLIST_ORMASKCOUNT]; 376 377 extern serverlist_infofield_t serverlist_sortbyfield; 378 extern int serverlist_sortflags; // not using the enum, as it is a bitmask 379 380 #if SERVERLIST_TOTALSIZE > 65536 381 #error too many servers, change type of index array 382 #endif 383 extern int serverlist_viewcount; 384 extern unsigned short serverlist_viewlist[SERVERLIST_VIEWLISTSIZE]; 385 386 extern int serverlist_cachecount; 387 extern serverlist_entry_t *serverlist_cache; 388 extern const serverlist_entry_t *serverlist_callbackentry; 389 390 extern qboolean serverlist_consoleoutput; 391 392 void ServerList_GetPlayerStatistics(int *numplayerspointer, int *maxplayerspointer); 393 #endif 394 395 //============================================================================ 396 // 397 // public network functions 398 // 399 //============================================================================ 400 401 extern char cl_net_extresponse[NET_EXTRESPONSE_MAX][1400]; 402 extern int cl_net_extresponse_count; 403 extern int cl_net_extresponse_last; 404 405 extern char sv_net_extresponse[NET_EXTRESPONSE_MAX][1400]; 406 extern int sv_net_extresponse_count; 407 extern int sv_net_extresponse_last; 408 409 #ifdef CONFIG_MENU 410 extern double masterquerytime; 411 extern int masterquerycount; 412 extern int masterreplycount; 413 extern int serverquerycount; 414 extern int serverreplycount; 415 #endif 416 417 extern sizebuf_t cl_message; 418 extern sizebuf_t sv_message; 419 extern char cl_readstring[MAX_INPUTLINE]; 420 extern char sv_readstring[MAX_INPUTLINE]; 421 422 extern cvar_t sv_public; 423 424 extern cvar_t cl_netlocalping; 425 426 extern cvar_t cl_netport; 427 extern cvar_t sv_netport; 428 extern cvar_t net_address; 429 extern cvar_t net_address_ipv6; 430 extern cvar_t net_usesizelimit; 431 extern cvar_t net_burstreserve; 432 433 qboolean NetConn_CanSend(netconn_t *conn); 434 int NetConn_SendUnreliableMessage(netconn_t *conn, sizebuf_t *data, protocolversion_t protocol, int rate, int burstsize, qboolean quakesignon_suppressreliables); 435 qboolean NetConn_HaveClientPorts(void); 436 qboolean NetConn_HaveServerPorts(void); 437 void NetConn_CloseClientPorts(void); 438 void NetConn_OpenClientPorts(void); 439 void NetConn_CloseServerPorts(void); 440 void NetConn_OpenServerPorts(int opennetports); 441 void NetConn_UpdateSockets(void); 442 lhnetsocket_t *NetConn_ChooseClientSocketForAddress(lhnetaddress_t *address); 443 lhnetsocket_t *NetConn_ChooseServerSocketForAddress(lhnetaddress_t *address); 444 void NetConn_Init(void); 445 void NetConn_Shutdown(void); 446 netconn_t *NetConn_Open(lhnetsocket_t *mysocket, lhnetaddress_t *peeraddress); 447 void NetConn_Close(netconn_t *conn); 448 void NetConn_Listen(qboolean state); 449 int NetConn_Read(lhnetsocket_t *mysocket, void *data, int maxlength, lhnetaddress_t *peeraddress); 450 int NetConn_Write(lhnetsocket_t *mysocket, const void *data, int length, const lhnetaddress_t *peeraddress); 451 int NetConn_WriteString(lhnetsocket_t *mysocket, const char *string, const lhnetaddress_t *peeraddress); 452 int NetConn_IsLocalGame(void); 453 void NetConn_ClientFrame(void); 454 void NetConn_ServerFrame(void); 455 void NetConn_SleepMicroseconds(int microseconds); 456 void NetConn_Heartbeat(int priority); 457 void Net_Stats_f(void); 458 459 #ifdef CONFIG_MENU 460 void NetConn_QueryMasters(qboolean querydp, qboolean queryqw); 461 void NetConn_QueryQueueFrame(void); 462 void Net_Slist_f(void); 463 void Net_SlistQW_f(void); 464 void Net_Refresh_f(void); 465 466 /// ServerList interface (public) 467 /// manually refresh the view set, do this after having changed the mask or any other flag 468 void ServerList_RebuildViewList(void); 469 void ServerList_ResetMasks(void); 470 void ServerList_QueryList(qboolean resetcache, qboolean querydp, qboolean queryqw, qboolean consoleoutput); 471 472 /// called whenever net_slist_favorites changes 473 void NetConn_UpdateFavorites(void); 474 #endif 475 476 #define MAX_CHALLENGES 128 477 typedef struct challenge_s 478 { 479 lhnetaddress_t address; 480 double time; 481 char string[12]; 482 } 483 challenge_t; 484 485 extern challenge_t challenges[MAX_CHALLENGES]; 486 487 #endif 488 489