cvar_t hostname = {CVAR_SERVER | CVAR_SAVE, "hostname", "UNNAMED", "server message to show in server browser"};
cvar_t developer_networking = {CVAR_CLIENT | CVAR_SERVER, "developer_networking", "0", "prints all received and sent packets (recommended only for debugging)"};
-cvar_t cl_netlocalping = {CVAR_CLIENT, "cl_netlocalping","0", "lags local loopback connection by this much ping time (useful to play more fairly on your own server with people with higher pings)"};
-static cvar_t cl_netpacketloss_send = {CVAR_CLIENT, "cl_netpacketloss_send","0", "drops this percentage of outgoing packets, useful for testing network protocol robustness (jerky movement, prediction errors, etc)"};
-static cvar_t cl_netpacketloss_receive = {CVAR_CLIENT, "cl_netpacketloss_receive","0", "drops this percentage of incoming packets, useful for testing network protocol robustness (jerky movement, effects failing to start, sounds failing to play, etc)"};
+cvar_t net_fakelag = {CVAR_CLIENT, "net_fakelag","0", "lags local loopback connection by this much ping time (useful to play more fairly on your own server with people with higher pings)"};
+static cvar_t net_fakeloss_send = {CVAR_CLIENT, "net_fakeloss_send","0", "drops this percentage of outgoing packets, useful for testing network protocol robustness (jerky movement, prediction errors, etc)"};
+static cvar_t net_fakeloss_receive = {CVAR_CLIENT, "net_fakeloss_receive","0", "drops this percentage of incoming packets, useful for testing network protocol robustness (jerky movement, effects failing to start, sounds failing to play, etc)"};
static cvar_t net_slist_queriespersecond = {CVAR_CLIENT, "net_slist_queriespersecond", "20", "how many server information requests to send per second"};
static cvar_t net_slist_queriesperframe = {CVAR_CLIENT, "net_slist_queriesperframe", "4", "maximum number of server information requests to send each rendered frame (guards against low framerates causing problems)"};
static cvar_t net_slist_timeout = {CVAR_CLIENT, "net_slist_timeout", "4", "how long to listen for a server information response before giving up"};
static cvar_t net_slist_favorites = {CVAR_CLIENT | CVAR_SAVE | CVAR_NQUSERINFOHACK, "net_slist_favorites", "", "contains a list of IP addresses and ports to always query explicitly"};
static cvar_t net_tos_dscp = {CVAR_CLIENT | CVAR_SAVE, "net_tos_dscp", "32", "DiffServ Codepoint for network sockets (may need game restart to apply)"};
static cvar_t gameversion = {CVAR_SERVER, "gameversion", "0", "version of game data (mod-specific) to be sent to querying clients"};
-static cvar_t gameversion_min = {CVAR_CLIENT, "gameversion_min", "-1", "minimum version of game data (mod-specific), when client and server gameversion mismatch in the server browser the server is shown as incompatible; if -1, gameversion is used alone"};
-static cvar_t gameversion_max = {CVAR_CLIENT, "gameversion_max", "-1", "maximum version of game data (mod-specific), when client and server gameversion mismatch in the server browser the server is shown as incompatible; if -1, gameversion is used alone"};
+static cvar_t gameversion_min = {CVAR_CLIENT | CVAR_SERVER, "gameversion_min", "-1", "minimum version of game data (mod-specific), when client and server gameversion mismatch in the server browser the server is shown as incompatible; if -1, gameversion is used alone"};
+static cvar_t gameversion_max = {CVAR_CLIENT | CVAR_SERVER, "gameversion_max", "-1", "maximum version of game data (mod-specific), when client and server gameversion mismatch in the server browser the server is shown as incompatible; if -1, gameversion is used alone"};
static cvar_t rcon_restricted_password = {CVAR_SERVER | CVAR_PRIVATE, "rcon_restricted_password", "", "password to authenticate rcon commands in restricted mode; may be set to a string of the form user1:pass1 user2:pass2 user3:pass3 to allow multiple user accounts - the client then has to specify ONE of these combinations"};
static cvar_t rcon_restricted_commands = {CVAR_SERVER, "rcon_restricted_commands", "", "allowed commands for rcon when the restricted mode password was used"};
static cvar_t rcon_secure_maxdiff = {CVAR_SERVER, "rcon_secure_maxdiff", "5", "maximum time difference between rcon request and server system clock (to protect against replay attack)"};
void ServerList_QueryList(qboolean resetcache, qboolean querydp, qboolean queryqw, qboolean consoleoutput)
{
- masterquerytime = realtime;
+ masterquerytime = host.realtime;
masterquerycount = 0;
masterreplycount = 0;
if( resetcache ) {
Thread_UnlockMutex(netconn_mutex);
if (length == 0)
return 0;
- if (cl_netpacketloss_receive.integer)
+ if (net_fakeloss_receive.integer)
for (i = 0;i < cl_numsockets;i++)
- if (cl_sockets[i] == mysocket && (rand() % 100) < cl_netpacketloss_receive.integer)
+ if (cl_sockets[i] == mysocket && (rand() % 100) < net_fakeloss_receive.integer)
return 0;
if (developer_networking.integer)
{
{
int ret;
int i;
- if (cl_netpacketloss_send.integer)
+ if (net_fakeloss_send.integer)
for (i = 0;i < cl_numsockets;i++)
- if (cl_sockets[i] == mysocket && (rand() % 100) < cl_netpacketloss_send.integer)
+ if (cl_sockets[i] == mysocket && (rand() % 100) < net_fakeloss_send.integer)
return length;
if (mysocket->address.addresstype == LHNETADDRESSTYPE_LOOP && netconn_mutex)
Thread_LockMutex(netconn_mutex);
qboolean NetConn_CanSend(netconn_t *conn)
{
conn->outgoing_packetcounter = (conn->outgoing_packetcounter + 1) % NETGRAPH_PACKETS;
- conn->outgoing_netgraph[conn->outgoing_packetcounter].time = realtime;
+ conn->outgoing_netgraph[conn->outgoing_packetcounter].time = host.realtime;
conn->outgoing_netgraph[conn->outgoing_packetcounter].unreliablebytes = NETGRAPH_NOPACKET;
conn->outgoing_netgraph[conn->outgoing_packetcounter].reliablebytes = NETGRAPH_NOPACKET;
conn->outgoing_netgraph[conn->outgoing_packetcounter].ackbytes = NETGRAPH_NOPACKET;
conn->outgoing_netgraph[conn->outgoing_packetcounter].cleartime = conn->cleartime;
- if (realtime > conn->cleartime)
+ if (host.realtime > conn->cleartime)
return true;
else
{
double bursttime = burstsize / (double)rate;
// delay later packets to obey rate limit
- if (*cleartime < realtime - bursttime)
- *cleartime = realtime - bursttime;
+ if (*cleartime < host.realtime - bursttime)
+ *cleartime = host.realtime - bursttime;
*cleartime = *cleartime + len / (double)rate;
// limit bursts to one packet in size ("dialup mode" emulating old behaviour)
if (net_test.integer)
{
- if (*cleartime < realtime)
- *cleartime = realtime;
+ if (*cleartime < host.realtime)
+ *cleartime = host.realtime;
}
}
size_t sendmelen;
// if a reliable message fragment has been lost, send it again
- if (conn->sendMessageLength && (realtime - conn->lastSendTime) > 1.0)
+ if (conn->sendMessageLength && (host.realtime - conn->lastSendTime) > 1.0)
{
if (conn->sendMessageLength <= MAX_PACKETFRAGMENT)
{
sendme = Crypto_EncryptPacket(&conn->crypto, &sendbuffer, packetLen, &cryptosendbuffer, &sendmelen, sizeof(cryptosendbuffer));
if (sendme && NetConn_Write(conn->mysocket, sendme, (int)sendmelen, &conn->peeraddress) == (int)sendmelen)
{
- conn->lastSendTime = realtime;
+ conn->lastSendTime = host.realtime;
conn->packetsReSent++;
}
if(sendme)
NetConn_Write(conn->mysocket, sendme, (int)sendmelen, &conn->peeraddress);
- conn->lastSendTime = realtime;
+ conn->lastSendTime = host.realtime;
conn->packetsSent++;
conn->reliableMessagesSent++;
else
{
LHNETADDRESS_ToString(&address, addressstring2, sizeof(addressstring2), true);
- Con_Printf("Client failed to open a socket on address %s\n", addressstring2);
+ Con_Errorf("Client failed to open a socket on address %s\n", addressstring2);
}
}
else
- Con_Printf("Client unable to parse address %s\n", addressstring);
+ Con_Errorf("Client unable to parse address %s\n", addressstring);
}
void NetConn_OpenClientPorts(void)
else
{
LHNETADDRESS_ToString(&address, addressstring2, sizeof(addressstring2), true);
- Con_Printf("Server failed to open socket on address %s\n", addressstring2);
+ Con_Errorf("Server failed to open socket on address %s\n", addressstring2);
}
}
else
{
- Con_Printf("Server unable to parse address %s\n", addressstring);
+ Con_Errorf("Server unable to parse address %s\n", addressstring);
// if it cant parse one address, it wont be able to parse another for sure
return false;
}
conn = (netconn_t *)Mem_Alloc(netconn_mempool, sizeof(*conn));
conn->mysocket = mysocket;
conn->peeraddress = *peeraddress;
- conn->lastMessageTime = realtime;
+ conn->lastMessageTime = host.realtime;
conn->message.data = conn->messagedata;
conn->message.maxsize = sizeof(conn->messagedata);
conn->message.cursize = 0;
// LadyHavoc: (inspired by ProQuake) use a short connect timeout to
// reduce effectiveness of connection request floods
- conn->timeout = realtime + net_connecttimeout.value;
+ conn->timeout = host.realtime + net_connecttimeout.value;
LHNETADDRESS_ToString(&conn->peeraddress, conn->address, sizeof(conn->address), true);
conn->next = netconn_list;
netconn_list = conn;
i = (cls.rcon_ringpos + j + 1) % MAX_RCONS;
if(cls.rcon_commands[i][0])
{
- if(realtime > cls.rcon_timeout[i])
+ if(host.realtime > cls.rcon_timeout[i])
{
char s[128];
LHNETADDRESS_ToString(&cls.rcon_addresses[i], s, sizeof(s), true);
while (count--)
{
conn->incoming_packetcounter = (conn->incoming_packetcounter + 1) % NETGRAPH_PACKETS;
- conn->incoming_netgraph[conn->incoming_packetcounter].time = realtime;
+ conn->incoming_netgraph[conn->incoming_packetcounter].time = host.realtime;
conn->incoming_netgraph[conn->incoming_packetcounter].cleartime = conn->incoming_cleartime;
conn->incoming_netgraph[conn->incoming_packetcounter].unreliablebytes = NETGRAPH_LOSTPACKET;
conn->incoming_netgraph[conn->incoming_packetcounter].reliablebytes = NETGRAPH_NOPACKET;
}
}
conn->incoming_packetcounter = (conn->incoming_packetcounter + 1) % NETGRAPH_PACKETS;
- conn->incoming_netgraph[conn->incoming_packetcounter].time = realtime;
+ conn->incoming_netgraph[conn->incoming_packetcounter].time = host.realtime;
conn->incoming_netgraph[conn->incoming_packetcounter].cleartime = conn->incoming_cleartime;
conn->incoming_netgraph[conn->incoming_packetcounter].unreliablebytes = originallength + 28;
conn->incoming_netgraph[conn->incoming_packetcounter].reliablebytes = NETGRAPH_NOPACKET;
// limit bursts to one packet in size ("dialup mode" emulating old behaviour)
if (net_test.integer)
{
- if (conn->cleartime < realtime)
- conn->cleartime = realtime;
+ if (conn->cleartime < host.realtime)
+ conn->cleartime = host.realtime;
}
if (reliable_ack == conn->qw.reliable_sequence)
conn->qw.incoming_reliable_acknowledged = reliable_ack;
if (reliable_message)
conn->qw.incoming_reliable_sequence ^= 1;
- conn->lastMessageTime = realtime;
- conn->timeout = realtime + newtimeout;
+ conn->lastMessageTime = host.realtime;
+ conn->timeout = host.realtime + newtimeout;
conn->unreliableMessagesReceived++;
if (conn == cls.netcon)
{
while (count--)
{
conn->incoming_packetcounter = (conn->incoming_packetcounter + 1) % NETGRAPH_PACKETS;
- conn->incoming_netgraph[conn->incoming_packetcounter].time = realtime;
+ conn->incoming_netgraph[conn->incoming_packetcounter].time = host.realtime;
conn->incoming_netgraph[conn->incoming_packetcounter].cleartime = conn->incoming_cleartime;
conn->incoming_netgraph[conn->incoming_packetcounter].unreliablebytes = NETGRAPH_LOSTPACKET;
conn->incoming_netgraph[conn->incoming_packetcounter].reliablebytes = NETGRAPH_NOPACKET;
}
}
conn->incoming_packetcounter = (conn->incoming_packetcounter + 1) % NETGRAPH_PACKETS;
- conn->incoming_netgraph[conn->incoming_packetcounter].time = realtime;
+ conn->incoming_netgraph[conn->incoming_packetcounter].time = host.realtime;
conn->incoming_netgraph[conn->incoming_packetcounter].cleartime = conn->incoming_cleartime;
conn->incoming_netgraph[conn->incoming_packetcounter].unreliablebytes = originallength + 28;
conn->incoming_netgraph[conn->incoming_packetcounter].reliablebytes = NETGRAPH_NOPACKET;
NetConn_UpdateCleartime(&conn->incoming_cleartime, cl_rate.integer, cl_rate_burstsize.integer, originallength + 28);
conn->nq.unreliableReceiveSequence = sequence + 1;
- conn->lastMessageTime = realtime;
- conn->timeout = realtime + newtimeout;
+ conn->lastMessageTime = host.realtime;
+ conn->timeout = host.realtime + newtimeout;
conn->unreliableMessagesReceived++;
if (length > 0)
{
conn->nq.ackSequence++;
if (conn->nq.ackSequence != conn->nq.sendSequence)
Con_DPrint("ack sequencing error\n");
- conn->lastMessageTime = realtime;
- conn->timeout = realtime + newtimeout;
+ conn->lastMessageTime = host.realtime;
+ conn->timeout = host.realtime + newtimeout;
if (conn->sendMessageLength > MAX_PACKETFRAGMENT)
{
unsigned int packetLen;
sendme = Crypto_EncryptPacket(&conn->crypto, &sendbuffer, packetLen, &cryptosendbuffer, &sendmelen, sizeof(cryptosendbuffer));
if (sendme && NetConn_Write(conn->mysocket, sendme, (int)sendmelen, &conn->peeraddress) == (int)sendmelen)
{
- conn->lastSendTime = realtime;
+ conn->lastSendTime = host.realtime;
conn->packetsSent++;
}
}
NetConn_Write(conn->mysocket, sendme, (int)sendmelen, &conn->peeraddress);
if (sequence == conn->nq.receiveSequence)
{
- conn->lastMessageTime = realtime;
- conn->timeout = realtime + newtimeout;
+ conn->lastMessageTime = host.realtime;
+ conn->timeout = host.realtime + newtimeout;
conn->nq.receiveSequence++;
if( conn->receiveMessageLength + length <= (int)sizeof( conn->receiveMessage ) ) {
memcpy(conn->receiveMessage + conn->receiveMessageLength, data, length);
#ifdef CONFIG_MENU
M_Update_Return_Reason("");
#endif
- // the connection request succeeded, stop current connection and set up a new connection
- CL_Disconnect();
// if we're connecting to a remote server, shut down any local server
if (LHNETADDRESS_GetAddressType(peeraddress) != LHNETADDRESSTYPE_LOOP && sv.active)
{
// store the data the engine cares about (address and ping)
strlcpy(entry->info.cname, addressstring, sizeof(entry->info.cname));
entry->info.ping = 100000;
- entry->querytime = realtime;
+ entry->querytime = host.realtime;
// if not in the slist menu we should print the server to console
if (serverlist_consoleoutput)
Con_Printf("querying %s\n", addressstring);
++serverlist_cachecount;
}
// if this is the first reply from this server, count it as having replied
- pingtime = (int)((realtime - entry->querytime) * 1000.0 + 0.5);
+ pingtime = (int)((host.realtime - entry->querytime) * 1000.0 + 0.5);
pingtime = bound(0, pingtime, 9999);
if (entry->query == SQS_REFRESHING) {
entry->info.ping = pingtime;
// begin or resume serverlist queries
serverlist_querysleep = false;
- serverlist_querywaittime = realtime + 3;
+ serverlist_querywaittime = host.realtime + 3;
}
#endif
for (l = 0;l < MAX_RCONS;l++)
if(cls.rcon_commands[l][0])
if (!LHNETADDRESS_Compare(peeraddress, &cls.rcon_addresses[l]))
- cls.rcon_timeout[l] = realtime + rcon_secure_challengetimeout.value;
+ cls.rcon_timeout[l] = host.realtime + rcon_secure_challengetimeout.value;
}
return true; // we used up the challenge, so we can't use this oen for connecting now anyway
return true;
}
#ifdef CONFIG_MENU
- if (length >= 15 && !memcmp(string, "statusResponse\x0A", 15))
+ if(key_dest != key_game)
{
- serverlist_info_t *info;
- char *p;
- int n;
-
- string += 15;
- // search the cache for this server and update it
- n = NetConn_ClientParsePacket_ServerList_ProcessReply(addressstring2);
- if (n < 0)
- return true;
-
- info = &serverlist_cache[n].info;
- info->game[0] = 0;
- info->mod[0] = 0;
- info->map[0] = 0;
- info->name[0] = 0;
- info->qcstatus[0] = 0;
- info->players[0] = 0;
- info->protocol = -1;
- info->numplayers = 0;
- info->numbots = -1;
- info->maxplayers = 0;
- info->gameversion = 0;
-
- p = strchr(string, '\n');
- if(p)
+ if (length >= 15 && !memcmp(string, "statusResponse\x0A", 15))
{
- *p = 0; // cut off the string there
- ++p;
- }
- else
- Con_Printf("statusResponse without players block?\n");
-
- if ((s = InfoString_GetValue(string, "gamename" , infostringvalue, sizeof(infostringvalue))) != NULL) strlcpy(info->game, s, sizeof (info->game));
- if ((s = InfoString_GetValue(string, "modname" , infostringvalue, sizeof(infostringvalue))) != NULL) strlcpy(info->mod , s, sizeof (info->mod ));
- if ((s = InfoString_GetValue(string, "mapname" , infostringvalue, sizeof(infostringvalue))) != NULL) strlcpy(info->map , s, sizeof (info->map ));
- if ((s = InfoString_GetValue(string, "hostname" , infostringvalue, sizeof(infostringvalue))) != NULL) strlcpy(info->name, s, sizeof (info->name));
- if ((s = InfoString_GetValue(string, "protocol" , infostringvalue, sizeof(infostringvalue))) != NULL) info->protocol = atoi(s);
- if ((s = InfoString_GetValue(string, "clients" , infostringvalue, sizeof(infostringvalue))) != NULL) info->numplayers = atoi(s);
- if ((s = InfoString_GetValue(string, "bots" , infostringvalue, sizeof(infostringvalue))) != NULL) info->numbots = atoi(s);
- if ((s = InfoString_GetValue(string, "sv_maxclients", infostringvalue, sizeof(infostringvalue))) != NULL) info->maxplayers = atoi(s);
- if ((s = InfoString_GetValue(string, "gameversion" , infostringvalue, sizeof(infostringvalue))) != NULL) info->gameversion = atoi(s);
- if ((s = InfoString_GetValue(string, "qcstatus" , infostringvalue, sizeof(infostringvalue))) != NULL) strlcpy(info->qcstatus, s, sizeof(info->qcstatus));
- if (p != NULL) strlcpy(info->players, p, sizeof(info->players));
- info->numhumans = info->numplayers - max(0, info->numbots);
- info->freeslots = info->maxplayers - info->numplayers;
+ serverlist_info_t *info;
+ char *p;
+ int n;
- NetConn_ClientParsePacket_ServerList_UpdateCache(n);
+ string += 15;
+ // search the cache for this server and update it
+ n = NetConn_ClientParsePacket_ServerList_ProcessReply(addressstring2);
+ if (n < 0)
+ return true;
- return true;
- }
- if (length >= 13 && !memcmp(string, "infoResponse\x0A", 13))
- {
- serverlist_info_t *info;
- int n;
+ info = &serverlist_cache[n].info;
+ info->game[0] = 0;
+ info->mod[0] = 0;
+ info->map[0] = 0;
+ info->name[0] = 0;
+ info->qcstatus[0] = 0;
+ info->players[0] = 0;
+ info->protocol = -1;
+ info->numplayers = 0;
+ info->numbots = -1;
+ info->maxplayers = 0;
+ info->gameversion = 0;
+
+ p = strchr(string, '\n');
+ if(p)
+ {
+ *p = 0; // cut off the string there
+ ++p;
+ }
+ else
+ Con_Printf("statusResponse without players block?\n");
+
+ if ((s = InfoString_GetValue(string, "gamename" , infostringvalue, sizeof(infostringvalue))) != NULL) strlcpy(info->game, s, sizeof (info->game));
+ if ((s = InfoString_GetValue(string, "modname" , infostringvalue, sizeof(infostringvalue))) != NULL) strlcpy(info->mod , s, sizeof (info->mod ));
+ if ((s = InfoString_GetValue(string, "mapname" , infostringvalue, sizeof(infostringvalue))) != NULL) strlcpy(info->map , s, sizeof (info->map ));
+ if ((s = InfoString_GetValue(string, "hostname" , infostringvalue, sizeof(infostringvalue))) != NULL) strlcpy(info->name, s, sizeof (info->name));
+ if ((s = InfoString_GetValue(string, "protocol" , infostringvalue, sizeof(infostringvalue))) != NULL) info->protocol = atoi(s);
+ if ((s = InfoString_GetValue(string, "clients" , infostringvalue, sizeof(infostringvalue))) != NULL) info->numplayers = atoi(s);
+ if ((s = InfoString_GetValue(string, "bots" , infostringvalue, sizeof(infostringvalue))) != NULL) info->numbots = atoi(s);
+ if ((s = InfoString_GetValue(string, "sv_maxclients", infostringvalue, sizeof(infostringvalue))) != NULL) info->maxplayers = atoi(s);
+ if ((s = InfoString_GetValue(string, "gameversion" , infostringvalue, sizeof(infostringvalue))) != NULL) info->gameversion = atoi(s);
+ if ((s = InfoString_GetValue(string, "qcstatus" , infostringvalue, sizeof(infostringvalue))) != NULL) strlcpy(info->qcstatus, s, sizeof(info->qcstatus));
+ if (p != NULL) strlcpy(info->players, p, sizeof(info->players));
+ info->numhumans = info->numplayers - max(0, info->numbots);
+ info->freeslots = info->maxplayers - info->numplayers;
+
+ NetConn_ClientParsePacket_ServerList_UpdateCache(n);
- string += 13;
- // search the cache for this server and update it
- n = NetConn_ClientParsePacket_ServerList_ProcessReply(addressstring2);
- if (n < 0)
return true;
+ }
+ if (length >= 13 && !memcmp(string, "infoResponse\x0A", 13))
+ {
+ serverlist_info_t *info;
+ int n;
- info = &serverlist_cache[n].info;
- info->game[0] = 0;
- info->mod[0] = 0;
- info->map[0] = 0;
- info->name[0] = 0;
- info->qcstatus[0] = 0;
- info->players[0] = 0;
- info->protocol = -1;
- info->numplayers = 0;
- info->numbots = -1;
- info->maxplayers = 0;
- info->gameversion = 0;
-
- if ((s = InfoString_GetValue(string, "gamename" , infostringvalue, sizeof(infostringvalue))) != NULL) strlcpy(info->game, s, sizeof (info->game));
- if ((s = InfoString_GetValue(string, "modname" , infostringvalue, sizeof(infostringvalue))) != NULL) strlcpy(info->mod , s, sizeof (info->mod ));
- if ((s = InfoString_GetValue(string, "mapname" , infostringvalue, sizeof(infostringvalue))) != NULL) strlcpy(info->map , s, sizeof (info->map ));
- if ((s = InfoString_GetValue(string, "hostname" , infostringvalue, sizeof(infostringvalue))) != NULL) strlcpy(info->name, s, sizeof (info->name));
- if ((s = InfoString_GetValue(string, "protocol" , infostringvalue, sizeof(infostringvalue))) != NULL) info->protocol = atoi(s);
- if ((s = InfoString_GetValue(string, "clients" , infostringvalue, sizeof(infostringvalue))) != NULL) info->numplayers = atoi(s);
- if ((s = InfoString_GetValue(string, "bots" , infostringvalue, sizeof(infostringvalue))) != NULL) info->numbots = atoi(s);
- if ((s = InfoString_GetValue(string, "sv_maxclients", infostringvalue, sizeof(infostringvalue))) != NULL) info->maxplayers = atoi(s);
- if ((s = InfoString_GetValue(string, "gameversion" , infostringvalue, sizeof(infostringvalue))) != NULL) info->gameversion = atoi(s);
- if ((s = InfoString_GetValue(string, "qcstatus" , infostringvalue, sizeof(infostringvalue))) != NULL) strlcpy(info->qcstatus, s, sizeof(info->qcstatus));
- info->numhumans = info->numplayers - max(0, info->numbots);
- info->freeslots = info->maxplayers - info->numplayers;
+ string += 13;
+ // search the cache for this server and update it
+ n = NetConn_ClientParsePacket_ServerList_ProcessReply(addressstring2);
+ if (n < 0)
+ return true;
- NetConn_ClientParsePacket_ServerList_UpdateCache(n);
+ info = &serverlist_cache[n].info;
+ info->game[0] = 0;
+ info->mod[0] = 0;
+ info->map[0] = 0;
+ info->name[0] = 0;
+ info->qcstatus[0] = 0;
+ info->players[0] = 0;
+ info->protocol = -1;
+ info->numplayers = 0;
+ info->numbots = -1;
+ info->maxplayers = 0;
+ info->gameversion = 0;
+
+ if ((s = InfoString_GetValue(string, "gamename" , infostringvalue, sizeof(infostringvalue))) != NULL) strlcpy(info->game, s, sizeof (info->game));
+ if ((s = InfoString_GetValue(string, "modname" , infostringvalue, sizeof(infostringvalue))) != NULL) strlcpy(info->mod , s, sizeof (info->mod ));
+ if ((s = InfoString_GetValue(string, "mapname" , infostringvalue, sizeof(infostringvalue))) != NULL) strlcpy(info->map , s, sizeof (info->map ));
+ if ((s = InfoString_GetValue(string, "hostname" , infostringvalue, sizeof(infostringvalue))) != NULL) strlcpy(info->name, s, sizeof (info->name));
+ if ((s = InfoString_GetValue(string, "protocol" , infostringvalue, sizeof(infostringvalue))) != NULL) info->protocol = atoi(s);
+ if ((s = InfoString_GetValue(string, "clients" , infostringvalue, sizeof(infostringvalue))) != NULL) info->numplayers = atoi(s);
+ if ((s = InfoString_GetValue(string, "bots" , infostringvalue, sizeof(infostringvalue))) != NULL) info->numbots = atoi(s);
+ if ((s = InfoString_GetValue(string, "sv_maxclients", infostringvalue, sizeof(infostringvalue))) != NULL) info->maxplayers = atoi(s);
+ if ((s = InfoString_GetValue(string, "gameversion" , infostringvalue, sizeof(infostringvalue))) != NULL) info->gameversion = atoi(s);
+ if ((s = InfoString_GetValue(string, "qcstatus" , infostringvalue, sizeof(infostringvalue))) != NULL) strlcpy(info->qcstatus, s, sizeof(info->qcstatus));
+ info->numhumans = info->numplayers - max(0, info->numbots);
+ info->freeslots = info->maxplayers - info->numplayers;
+
+ NetConn_ClientParsePacket_ServerList_UpdateCache(n);
- return true;
- }
- if (!strncmp(string, "getserversResponse\\", 19) && serverlist_cachecount < SERVERLIST_TOTALSIZE)
- {
- // Extract the IP addresses
- data += 18;
- length -= 18;
- NetConn_ClientParsePacket_ServerList_ParseDPList(peeraddress, data, length, false);
- return true;
- }
- if (!strncmp(string, "getserversExtResponse", 21) && serverlist_cachecount < SERVERLIST_TOTALSIZE)
- {
- // Extract the IP addresses
- data += 21;
- length -= 21;
- NetConn_ClientParsePacket_ServerList_ParseDPList(peeraddress, data, length, true);
- return true;
- }
- if (!memcmp(string, "d\n", 2) && serverlist_cachecount < SERVERLIST_TOTALSIZE)
- {
- // Extract the IP addresses
- data += 2;
- length -= 2;
- masterreplycount++;
- if (serverlist_consoleoutput)
- Con_Printf("received QuakeWorld server list from %s...\n", addressstring2);
- while (length >= 6 && (data[0] != 0xFF || data[1] != 0xFF || data[2] != 0xFF || data[3] != 0xFF) && data[4] * 256 + data[5] != 0)
+ return true;
+ }
+ if (!strncmp(string, "getserversResponse\\", 19) && serverlist_cachecount < SERVERLIST_TOTALSIZE)
{
- dpsnprintf (ipstring, sizeof (ipstring), "%u.%u.%u.%u:%u", data[0], data[1], data[2], data[3], data[4] * 256 + data[5]);
- if (serverlist_consoleoutput && developer_networking.integer)
- Con_Printf("Requesting info from QuakeWorld server %s\n", ipstring);
-
- if( !NetConn_ClientParsePacket_ServerList_PrepareQuery( PROTOCOL_QUAKEWORLD, ipstring, false ) ) {
- break;
- }
+ // Extract the IP addresses
+ data += 18;
+ length -= 18;
+ NetConn_ClientParsePacket_ServerList_ParseDPList(peeraddress, data, length, false);
+ return true;
+ }
+ if (!strncmp(string, "getserversExtResponse", 21) && serverlist_cachecount < SERVERLIST_TOTALSIZE)
+ {
+ // Extract the IP addresses
+ data += 21;
+ length -= 21;
+ NetConn_ClientParsePacket_ServerList_ParseDPList(peeraddress, data, length, true);
+ return true;
+ }
+ if (!memcmp(string, "d\n", 2) && serverlist_cachecount < SERVERLIST_TOTALSIZE)
+ {
+ // Extract the IP addresses
+ data += 2;
+ length -= 2;
+ masterreplycount++;
+ if (serverlist_consoleoutput)
+ Con_Printf("received QuakeWorld server list from %s...\n", addressstring2);
+ while (length >= 6 && (data[0] != 0xFF || data[1] != 0xFF || data[2] != 0xFF || data[3] != 0xFF) && data[4] * 256 + data[5] != 0)
+ {
+ dpsnprintf (ipstring, sizeof (ipstring), "%u.%u.%u.%u:%u", data[0], data[1], data[2], data[3], data[4] * 256 + data[5]);
+ if (serverlist_consoleoutput && developer_networking.integer)
+ Con_Printf("Requesting info from QuakeWorld server %s\n", ipstring);
+
+ if( !NetConn_ClientParsePacket_ServerList_PrepareQuery( PROTOCOL_QUAKEWORLD, ipstring, false ) ) {
+ break;
+ }
- // move on to next address in packet
- data += 6;
- length -= 6;
+ // move on to next address in packet
+ data += 6;
+ length -= 6;
+ }
+ // begin or resume serverlist queries
+ serverlist_querysleep = false;
+ serverlist_querywaittime = host.realtime + 3;
+ return true;
}
- // begin or resume serverlist queries
- serverlist_querysleep = false;
- serverlist_querywaittime = realtime + 3;
- return true;
}
#endif
if (!strncmp(string, "extResponse ", 12))
// apply a cool down time after master server replies,
// to avoid messing up the ping times on the servers
- if (serverlist_querywaittime > realtime)
+ if (serverlist_querywaittime > host.realtime)
return;
// each time querycounter reaches 1.0 issue a query
// scan serverlist and issue queries as needed
serverlist_querysleep = true;
- timeouttime = realtime - net_slist_timeout.value;
+ timeouttime = host.realtime - net_slist_timeout.value;
for( index = 0, queries = 0 ; index < serverlist_cachecount && queries < maxqueries ; index++ )
{
serverlist_entry_t *entry = &serverlist_cache[ index ];
}
// update the entry fields
- entry->querytime = realtime;
+ entry->querytime = host.realtime;
entry->querycounter++;
// if not in the slist menu we should print the server to console
lhnetaddress_t peeraddress;
unsigned char readbuffer[NET_HEADERSIZE+NET_MAXMESSAGE];
NetConn_UpdateSockets();
- if (cls.connect_trying && cls.connect_nextsendtime < realtime)
+ if (cls.connect_trying && cls.connect_nextsendtime < host.realtime)
{
#ifdef CONFIG_MENU
if (cls.connect_remainingtries == 0)
M_Update_Return_Reason("Connect: Waiting 10 seconds for reply");
#endif
- cls.connect_nextsendtime = realtime + 1;
+ cls.connect_nextsendtime = host.realtime + 1;
cls.connect_remainingtries--;
if (cls.connect_remainingtries <= -10)
{
#ifdef CONFIG_MENU
NetConn_QueryQueueFrame();
#endif
- if (cls.netcon && realtime > cls.netcon->timeout && !sv.active)
+ if (cls.netcon && host.realtime > cls.netcon->timeout && !sv.active)
{
Con_Print("Connection timed out\n");
CL_Disconnect();
if (floodlist[floodslotnum].lasttime && LHNETADDRESS_Compare(&noportpeeraddress, &floodlist[floodslotnum].address) == 0)
{
// this address matches an ongoing flood address
- if (realtime < floodlist[floodslotnum].lasttime + floodtime)
+ if (host.realtime < floodlist[floodslotnum].lasttime + floodtime)
{
if(renew)
{
// renew the ban on this address so it does not expire
// until the flood has subsided
- floodlist[floodslotnum].lasttime = realtime;
+ floodlist[floodslotnum].lasttime = host.realtime;
}
//Con_Printf("Flood detected!\n");
return true;
}
// begin a new timeout on this address
floodlist[bestfloodslotnum].address = noportpeeraddress;
- floodlist[bestfloodslotnum].lasttime = realtime;
+ floodlist[bestfloodslotnum].lasttime = host.realtime;
//Con_Printf("Flood detection initiated!\n");
return false;
}
long t1, t2;
if (!password[0]) {
- Con_Print("^4LOGIC ERROR: RCon_Authenticate should never call the comparator with an empty password. Please report.\n");
+ Con_Error("LOGIC ERROR: RCon_Authenticate should never call the comparator with an empty password. Please report.\n");
return false;
}
t1 = (long) time(NULL);
t2 = strtol(s, NULL, 0);
- if(abs(t1 - t2) > rcon_secure_maxdiff.integer)
+ if(labs(t1 - t2) > rcon_secure_maxdiff.integer)
return false;
if(!HMAC_MDFOUR_16BYTES((unsigned char *) mdfourbuf, (unsigned char *) s, slen, (unsigned char *) password, (int)strlen(password)))
int i;
if (!password[0]) {
- Con_Print("^4LOGIC ERROR: RCon_Authenticate should never call the comparator with an empty password. Please report.\n");
+ Con_Error("LOGIC ERROR: RCon_Authenticate should never call the comparator with an empty password. Please report.\n");
return false;
}
static qboolean plaintext_matching(lhnetaddress_t *peeraddress, const char *password, const char *hash, const char *s, int slen)
{
if (!password[0]) {
- Con_Print("^4LOGIC ERROR: RCon_Authenticate should never call the comparator with an empty password. Please report.\n");
+ Con_Error("LOGIC ERROR: RCon_Authenticate should never call the comparator with an empty password. Please report.\n");
return false;
}
{
int i, ret, clientnum, best;
double besttime;
- char *string, response[1400], addressstring2[128];
+ char *string, response[2800], addressstring2[128];
static char stringbuf[16384]; // server only
qboolean islocal = (LHNETADDRESS_GetAddressType(peeraddress) == LHNETADDRESSTYPE_LOOP);
char senddata[NET_HEADERSIZE+NET_MAXMESSAGE+CRYPTO_HEADERSIZE];
if (length >= 12 && !memcmp(string, "getchallenge", 12) && (islocal || sv_public.integer > -3))
{
- for (i = 0, best = 0, besttime = realtime;i < MAX_CHALLENGES;i++)
+ for (i = 0, best = 0, besttime = host.realtime;i < MAX_CHALLENGES;i++)
{
if(challenges[i].time > 0)
if (!LHNETADDRESS_Compare(peeraddress, &challenges[i].address))
else
{
// flood control: drop if requesting challenge too often
- if(challenges[i].time > realtime - net_challengefloodblockingtimeout.value)
+ if(challenges[i].time > host.realtime - net_challengefloodblockingtimeout.value)
return true;
}
- challenges[i].time = realtime;
+ challenges[i].time = host.realtime;
// send the challenge
memcpy(response, "\377\377\377\377", 4);
dpsnprintf(response+4, sizeof(response)-4, "challenge %s", challenges[i].string);
MSG_WriteString(&sv_message, client->name);
MSG_WriteLong(&sv_message, client->colors);
MSG_WriteLong(&sv_message, client->frags);
- MSG_WriteLong(&sv_message, (int)(realtime - client->connecttime));
+ MSG_WriteLong(&sv_message, (int)(host.realtime - client->connecttime));
if(sv_status_privacy.integer)
MSG_WriteString(&sv_message, client->netconnection ? "hidden" : "botclient");
else
for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
{
// never timeout loopback connections
- if (host_client->netconnection && realtime > host_client->netconnection->timeout && LHNETADDRESS_GetAddressType(&host_client->netconnection->peeraddress) != LHNETADDRESSTYPE_LOOP)
+ if (host_client->netconnection && host.realtime > host_client->netconnection->timeout && LHNETADDRESS_GetAddressType(&host_client->netconnection->peeraddress) != LHNETADDRESSTYPE_LOOP)
{
Con_Printf("Client \"%s\" connection timed out\n", host_client->name);
SV_DropClient(false);
}
if (!masterquerycount)
{
- Con_Print("Unable to query master servers, no suitable network sockets active.\n");
+ Con_Error("Unable to query master servers, no suitable network sockets active.\n");
M_Update_Return_Reason("No network");
}
}
// if it's a state change (client connected), limit next heartbeat to no
// more than 30 sec in the future
- if (priority == 1 && nextheartbeattime > realtime + 30.0)
- nextheartbeattime = realtime + 30.0;
+ if (priority == 1 && nextheartbeattime > host.realtime + 30.0)
+ nextheartbeattime = host.realtime + 30.0;
// limit heartbeatperiod to 30 to 270 second range,
// lower limit is to avoid abusing master servers with excess traffic,
// make advertising optional and don't advertise singleplayer games, and
// only send a heartbeat as often as the admin wants
- if (sv.active && sv_public.integer > 0 && svs.maxclients >= 2 && (priority > 1 || realtime > nextheartbeattime))
+ if (sv.active && sv_public.integer > 0 && svs.maxclients >= 2 && (priority > 1 || host.realtime > nextheartbeattime))
{
- nextheartbeattime = realtime + sv_heartbeatperiod.value;
+ nextheartbeattime = host.realtime + sv_heartbeatperiod.value;
for (masternum = 0;sv_masters[masternum].name;masternum++)
if (sv_masters[masternum].string && sv_masters[masternum].string[0] && LHNETADDRESS_FromString(&masteraddress, sv_masters[masternum].string, DPMASTER_PORT) && (mysocket = NetConn_ChooseServerSocketForAddress(&masteraddress)))
NetConn_WriteString(mysocket, "\377\377\377\377heartbeat DarkPlaces\x0A", &masteraddress);
int i;
lhnetaddress_t tempaddress;
netconn_mempool = Mem_AllocPool("network connections", 0, NULL);
- Cmd_AddCommand(&cmd_client, "net_stats", Net_Stats_f, "print network statistics");
- Cmd_AddCommand(&cmd_server, "net_stats", Net_Stats_f, "print network statistics");
+ Cmd_AddCommand(CMD_SHARED, "net_stats", Net_Stats_f, "print network statistics");
#ifdef CONFIG_MENU
- Cmd_AddCommand(&cmd_client, "net_slist", Net_Slist_f, "query dp master servers and print all server information");
- Cmd_AddCommand(&cmd_client, "net_slistqw", Net_SlistQW_f, "query qw master servers and print all server information");
- Cmd_AddCommand(&cmd_client, "net_refresh", Net_Refresh_f, "query dp master servers and refresh all server information");
+ Cmd_AddCommand(CMD_CLIENT, "net_slist", Net_Slist_f, "query dp master servers and print all server information");
+ Cmd_AddCommand(CMD_CLIENT, "net_slistqw", Net_SlistQW_f, "query qw master servers and print all server information");
+ Cmd_AddCommand(CMD_CLIENT, "net_refresh", Net_Refresh_f, "query dp master servers and refresh all server information");
#endif
- Cmd_AddCommand(&cmd_server, "heartbeat", Net_Heartbeat_f, "send a heartbeat to the master server (updates your server information)");
+ Cmd_AddCommand(CMD_SERVER, "heartbeat", Net_Heartbeat_f, "send a heartbeat to the master server (updates your server information)");
Cvar_RegisterVariable(&net_test);
Cvar_RegisterVariable(&net_usesizelimit);
Cvar_RegisterVariable(&net_burstreserve);
Cvar_RegisterVariable(&net_challengefloodblockingtimeout);
Cvar_RegisterVariable(&net_getstatusfloodblockingtimeout);
Cvar_RegisterVariable(&net_sourceaddresscheck);
- Cvar_RegisterVariable(&cl_netlocalping);
- Cvar_RegisterVariable(&cl_netpacketloss_send);
- Cvar_RegisterVariable(&cl_netpacketloss_receive);
+ Cvar_RegisterVariable(&net_fakelag);
+ Cvar_RegisterVariable(&net_fakeloss_send);
+ Cvar_RegisterVariable(&net_fakeloss_receive);
+ Cvar_RegisterAlias(&net_fakelag, "cl_netlocalping");
+ Cvar_RegisterAlias(&net_fakeloss_send, "cl_netpacketloss_send");
+ Cvar_RegisterAlias(&net_fakeloss_receive, "cl_netpacketloss_receive");
Cvar_RegisterVariable(&hostname);
Cvar_RegisterVariable(&developer_networking);
Cvar_RegisterVariable(&cl_netport);
Cvar_RegisterVariable(&gameversion_min);
Cvar_RegisterVariable(&gameversion_max);
// COMMANDLINEOPTION: Server: -ip <ipaddress> sets the ip address of this machine for purposes of networking (default 0.0.0.0 also known as INADDR_ANY), use only if you have multiple network adapters and need to choose one specifically.
- if ((i = COM_CheckParm("-ip")) && i + 1 < com_argc)
+ if ((i = COM_CheckParm("-ip")) && i + 1 < sys.argc)
{
- if (LHNETADDRESS_FromString(&tempaddress, com_argv[i + 1], 0) == 1)
+ if (LHNETADDRESS_FromString(&tempaddress, sys.argv[i + 1], 0) == 1)
{
- Con_Printf("-ip option used, setting net_address to \"%s\"\n", com_argv[i + 1]);
- Cvar_SetQuick(&net_address, com_argv[i + 1]);
+ Con_Printf("-ip option used, setting net_address to \"%s\"\n", sys.argv[i + 1]);
+ Cvar_SetQuick(&net_address, sys.argv[i + 1]);
}
else
- Con_Printf("-ip option used, but unable to parse the address \"%s\"\n", com_argv[i + 1]);
+ Con_Errorf("-ip option used, but unable to parse the address \"%s\"\n", sys.argv[i + 1]);
}
// COMMANDLINEOPTION: Server: -port <portnumber> sets the port to use for a server (default 26000, the same port as QUAKE itself), useful if you host multiple servers on your machine
- if (((i = COM_CheckParm("-port")) || (i = COM_CheckParm("-ipport")) || (i = COM_CheckParm("-udpport"))) && i + 1 < com_argc)
+ if (((i = COM_CheckParm("-port")) || (i = COM_CheckParm("-ipport")) || (i = COM_CheckParm("-udpport"))) && i + 1 < sys.argc)
{
- i = atoi(com_argv[i + 1]);
+ i = atoi(sys.argv[i + 1]);
if (i >= 0 && i < 65536)
{
Con_Printf("-port option used, setting port cvar to %i\n", i);
Cvar_SetValueQuick(&sv_netport, i);
}
else
- Con_Printf("-port option used, but %i is not a valid port number\n", i);
+ Con_Errorf("-port option used, but %i is not a valid port number\n", i);
}
cl_numsockets = 0;
sv_numsockets = 0;