X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=blobdiff_plain;f=netconn.c;h=08ab2a0cf241240e1b2753386fb9fe94e4bf501d;hp=3c0f53220662d7b18c8098271f0b203b5cca2e30;hb=0db6270f9fdf1da680391fe0389d7ad6cfc48517;hpb=b48a0c5b1a91ce77bef20c9e9f71c745bad2e4dd diff --git a/netconn.c b/netconn.c index 3c0f5322..08ab2a0c 100755 --- a/netconn.c +++ b/netconn.c @@ -49,6 +49,14 @@ cvar_t net_connecttimeout = {0, "net_connecttimeout","10"}; cvar_t hostname = {CVAR_SAVE, "hostname", "UNNAMED"}; cvar_t developer_networking = {0, "developer_networking", "0"}; +cvar_t cl_fakelocalping_min = {0, "cl_fakelocalping_min","0"}; +cvar_t cl_fakelocalping_max = {0, "cl_fakelocalping_max","0"}; +static cvar_t cl_fakepacketloss_receive = {0, "cl_fakepacketloss_receive","0"}; +static cvar_t cl_fakepacketloss_send = {0, "cl_fakepacketloss_send","0"}; +static cvar_t sv_fakepacketloss_receive = {0, "sv_fakepacketloss_receive","0"}; +static cvar_t sv_fakepacketloss_send = {0, "sv_fakepacketloss_send","0"}; + + /* statistic counters */ static int packetsSent = 0; static int packetsReSent = 0; @@ -86,6 +94,15 @@ cvar_t sv_netaddress_ipv6 = {0, "sv_netaddress_ipv6", "[0:0:0:0:0:0:0:0]:26000"} int NetConn_Read(lhnetsocket_t *mysocket, void *data, int maxlength, lhnetaddress_t *peeraddress) { int length = LHNET_Read(mysocket, data, maxlength, peeraddress); + int i; + if (cl_fakepacketloss_receive.integer) + for (i = 0;i < cl_numsockets;i++) + if (cl_sockets[i] == mysocket && (rand() % 100) < cl_fakepacketloss_receive.integer) + return 0; + if (sv_fakepacketloss_receive.integer) + for (i = 0;i < cl_numsockets;i++) + if (sv_sockets[i] == mysocket && (rand() % 100) < sv_fakepacketloss_receive.integer) + return 0; if (developer_networking.integer && length != 0) { char addressstring[128], addressstring2[128]; @@ -104,7 +121,17 @@ int NetConn_Read(lhnetsocket_t *mysocket, void *data, int maxlength, lhnetaddres int NetConn_Write(lhnetsocket_t *mysocket, const void *data, int length, const lhnetaddress_t *peeraddress) { - int ret = LHNET_Write(mysocket, data, length, peeraddress); + int ret; + int i; + if (cl_fakepacketloss_send.integer) + for (i = 0;i < cl_numsockets;i++) + if (cl_sockets[i] == mysocket && (rand() % 100) < cl_fakepacketloss_send.integer) + return length; + if (sv_fakepacketloss_send.integer) + for (i = 0;i < cl_numsockets;i++) + if (sv_sockets[i] == mysocket && (rand() % 100) < sv_fakepacketloss_send.integer) + return length; + ret = LHNET_Write(mysocket, data, length, peeraddress); if (developer_networking.integer) { char addressstring[128], addressstring2[128]; @@ -143,14 +170,14 @@ int NetConn_SendReliableMessage(netconn_t *conn, sizebuf_t *data) memcpy(conn->sendMessage, data->data, data->cursize); conn->sendMessageLength = data->cursize; - if (conn->sendMessageLength <= MAX_DATAGRAM) + if (conn->sendMessageLength <= MAX_PACKETFRAGMENT) { dataLen = conn->sendMessageLength; eom = NETFLAG_EOM; } else { - dataLen = MAX_DATAGRAM; + dataLen = MAX_PACKETFRAGMENT; eom = 0; } @@ -182,14 +209,14 @@ static void NetConn_SendMessageNext(netconn_t *conn) if (conn->sendMessageLength && !conn->canSend && conn->sendNext) { - if (conn->sendMessageLength <= MAX_DATAGRAM) + if (conn->sendMessageLength <= MAX_PACKETFRAGMENT) { dataLen = conn->sendMessageLength; eom = NETFLAG_EOM; } else { - dataLen = MAX_DATAGRAM; + dataLen = MAX_PACKETFRAGMENT; eom = 0; } @@ -220,14 +247,14 @@ static void NetConn_ReSendMessage(netconn_t *conn) if (conn->sendMessageLength && !conn->canSend && (realtime - conn->lastSendTime) > 1.0) { - if (conn->sendMessageLength <= MAX_DATAGRAM) + if (conn->sendMessageLength <= MAX_PACKETFRAGMENT) { dataLen = conn->sendMessageLength; eom = NETFLAG_EOM; } else { - dataLen = MAX_DATAGRAM; + dataLen = MAX_PACKETFRAGMENT; eom = 0; } @@ -290,20 +317,40 @@ void NetConn_CloseClientPorts(void) LHNET_CloseSocket(cl_sockets[cl_numsockets - 1]); } +void NetConn_OpenClientPort(const char *addressstring, int defaultport) +{ + lhnetaddress_t address; + lhnetsocket_t *s; + char addressstring2[1024]; + if (LHNETADDRESS_FromString(&address, addressstring, defaultport)) + { + if ((s = LHNET_OpenSocket_Connectionless(&address))) + { + cl_sockets[cl_numsockets++] = s; + LHNETADDRESS_ToString(LHNET_AddressFromSocket(s), addressstring2, sizeof(addressstring2), true); + Con_Printf("Client opened a socket on address %s\n", addressstring2); + } + else + { + LHNETADDRESS_ToString(&address, addressstring2, sizeof(addressstring2), true); + Con_Printf("Client failed to open a socket on address %s\n", addressstring2); + } + } + else + Con_Printf("Client unable to parse address %s\n", addressstring); +} + void NetConn_OpenClientPorts(void) { int port; - lhnetaddress_t address; NetConn_CloseClientPorts(); port = bound(0, cl_netport.integer, 65535); if (cl_netport.integer != port) Cvar_SetValueQuick(&cl_netport, port); - LHNETADDRESS_FromString(&address, "local", port); - cl_sockets[cl_numsockets++] = LHNET_OpenSocket_Connectionless(&address); - LHNETADDRESS_FromString(&address, cl_netaddress.string, port); - cl_sockets[cl_numsockets++] = LHNET_OpenSocket_Connectionless(&address); - LHNETADDRESS_FromString(&address, cl_netaddress_ipv6.string, port); - cl_sockets[cl_numsockets++] = LHNET_OpenSocket_Connectionless(&address); + Con_Printf("Client using port %i\n", port); + NetConn_OpenClientPort("local", port); + NetConn_OpenClientPort(cl_netaddress.string, port); + NetConn_OpenClientPort(cl_netaddress_ipv6.string, port); } void NetConn_CloseServerPorts(void) @@ -313,32 +360,55 @@ void NetConn_CloseServerPorts(void) LHNET_CloseSocket(sv_sockets[sv_numsockets - 1]); } +void NetConn_OpenServerPort(const char *addressstring, int defaultport) +{ + lhnetaddress_t address; + lhnetsocket_t *s; + char addressstring2[1024]; + if (LHNETADDRESS_FromString(&address, addressstring, defaultport)) + { + if ((s = LHNET_OpenSocket_Connectionless(&address))) + { + sv_sockets[sv_numsockets++] = s; + LHNETADDRESS_ToString(LHNET_AddressFromSocket(s), addressstring2, sizeof(addressstring2), true); + Con_Printf("Server listening on address %s\n", addressstring2); + } + else + { + LHNETADDRESS_ToString(&address, addressstring2, sizeof(addressstring2), true); + Con_Printf("Server failed to open socket on address %s\n", addressstring2); + } + } + else + Con_Printf("Server unable to parse address %s\n", addressstring); +} + void NetConn_OpenServerPorts(int opennetports) { int port; - lhnetaddress_t address; NetConn_CloseServerPorts(); port = bound(0, sv_netport.integer, 65535); if (port == 0) port = 26000; + Con_Printf("Server using port %i\n", port); if (sv_netport.integer != port) Cvar_SetValueQuick(&sv_netport, port); - LHNETADDRESS_FromString(&address, "local", port); - sv_sockets[sv_numsockets++] = LHNET_OpenSocket_Connectionless(&address); + if (cls.state != ca_dedicated) + NetConn_OpenServerPort("local", port); if (opennetports) { - LHNETADDRESS_FromString(&address, sv_netaddress.string, port); - sv_sockets[sv_numsockets++] = LHNET_OpenSocket_Connectionless(&address); - LHNETADDRESS_FromString(&address, sv_netaddress_ipv6.string, port); - sv_sockets[sv_numsockets++] = LHNET_OpenSocket_Connectionless(&address); + NetConn_OpenServerPort(sv_netaddress.string, port); + NetConn_OpenServerPort(sv_netaddress_ipv6.string, port); } + if (sv_numsockets == 0) + Host_Error("NetConn_OpenServerPorts: unable to open any ports!\n"); } lhnetsocket_t *NetConn_ChooseClientSocketForAddress(lhnetaddress_t *address) { int i, a = LHNETADDRESS_GetAddressType(address); for (i = 0;i < cl_numsockets;i++) - if (LHNETADDRESS_GetAddressType(LHNET_AddressFromSocket(cl_sockets[i])) == a) + if (cl_sockets[i] && LHNETADDRESS_GetAddressType(LHNET_AddressFromSocket(cl_sockets[i])) == a) return cl_sockets[i]; return NULL; } @@ -347,7 +417,7 @@ lhnetsocket_t *NetConn_ChooseServerSocketForAddress(lhnetaddress_t *address) { int i, a = LHNETADDRESS_GetAddressType(address); for (i = 0;i < sv_numsockets;i++) - if (LHNETADDRESS_GetAddressType(LHNET_AddressFromSocket(sv_sockets[i])) == a) + if (sv_sockets[i] && LHNETADDRESS_GetAddressType(LHNET_AddressFromSocket(sv_sockets[i])) == a) return sv_sockets[i]; return NULL; } @@ -479,10 +549,10 @@ int NetConn_ReceivedMessage(netconn_t *conn, qbyte *data, int length) Con_DPrintf("ack sequencing error\n"); conn->lastMessageTime = realtime; conn->timeout = realtime + net_messagetimeout.value; - conn->sendMessageLength -= MAX_DATAGRAM; + conn->sendMessageLength -= MAX_PACKETFRAGMENT; if (conn->sendMessageLength > 0) { - memcpy(conn->sendMessage, conn->sendMessage+MAX_DATAGRAM, conn->sendMessageLength); + memcpy(conn->sendMessage, conn->sendMessage+MAX_PACKETFRAGMENT, conn->sendMessageLength); conn->sendNext = true; NetConn_SendMessageNext(conn); } @@ -549,6 +619,20 @@ void NetConn_ConnectionEstablished(lhnetsocket_t *mysocket, lhnetaddress_t *peer Host_Reconnect_f(); } +int NetConn_IsLocalGame(void) +{ + int i; + if (cls.state == ca_connected && sv.active/* && LHNETADDRESS_GetAddressType(cl.netcon->peeraddress) == LHNETADDRESSTYPE_LOOP*/) + { + // make sure there are no other connected clients + for (i = 1;i < MAX_SCOREBOARD;i++) + if (svs.connectedclients[i]) + return false; + return true; + } + return false; +} + static struct { double senttime; @@ -903,7 +987,7 @@ static void NetConn_BuildChallengeString(char *buffer, int bufferlength) extern void SV_ConnectClient(int clientnum, netconn_t *netconnection); int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, qbyte *data, int length, lhnetaddress_t *peeraddress) { - int i, n, ret, clientnum, responselength, best; + int i, n, ret, clientnum, responselength, best, clientcount; double besttime; client_t *client; netconn_t *conn; @@ -973,10 +1057,10 @@ int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, qbyte *data, int length, else { // see if this is a duplicate connection request - for (clientnum = 0, client = svs.clients;clientnum < svs.maxclients;clientnum++, client++) - if (client->active && LHNETADDRESS_Compare(peeraddress, &client->netconnection->peeraddress) == 0) + for (clientnum = 0;clientnum < MAX_SCOREBOARD;clientnum++) + if ((client = svs.connectedclients[clientnum]) && LHNETADDRESS_Compare(peeraddress, &client->netconnection->peeraddress) == 0) break; - if (clientnum < svs.maxclients) + if (clientnum < MAX_SCOREBOARD) { // duplicate connection request if (realtime - client->netconnection->connecttime < 2.0) @@ -997,30 +1081,48 @@ int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, qbyte *data, int length, else { // this is a new client, find a slot - for (clientnum = 0, client = svs.clients;clientnum < svs.maxclients;clientnum++, client++) - if (!client->active) + for (clientcount = 0, clientnum = 0;clientnum < MAX_SCOREBOARD;clientnum++) + if (svs.connectedclients[clientnum]) + clientcount++; + for (clientnum = 0;clientnum < MAX_SCOREBOARD;clientnum++) + if (!svs.connectedclients[clientnum]) break; - if (clientnum == svs.maxclients) + if (clientcount < max(1, sv_maxplayers.integer) && clientnum < MAX_SCOREBOARD) + { + // allocate and prepare the client struct + if ((client = Mem_Alloc(sv_clients_mempool, sizeof(client_t)))) + { + if ((client->entitydatabase4 = EntityFrame4_AllocDatabase(sv_clients_mempool))) + { + if ((conn = NetConn_Open(mysocket, peeraddress))) + { + // allocated connection + LHNETADDRESS_ToString(peeraddress, conn->address, sizeof(conn->address), true); + if (developer.integer) + Con_Printf("Datagram_ParseConnectionless: sending \"accept\" to %s.\n", conn->address); + NetConn_WriteString(mysocket, "\377\377\377\377accept", peeraddress); + // now set up the client struct + svs.connectedclients[clientnum] = client; + SV_ConnectClient(clientnum, conn); + NetConn_Heartbeat(1); + } + else + { + EntityFrame4_FreeDatabase(client->entitydatabase4); + Mem_Free(client); + } + } + else + Mem_Free(client); + } + } + else { // server is full if (developer.integer) Con_Printf("Datagram_ParseConnectionless: sending \"reject Server is full.\" to %s.\n", addressstring2); NetConn_WriteString(mysocket, "\377\377\377\377reject Server is full.", peeraddress); } - else - { - if ((conn = NetConn_Open(mysocket, peeraddress))) - { - // allocated connection - strcpy(conn->address, addressstring2); - if (developer.integer) - Con_Printf("Datagram_ParseConnectionless: sending \"accept\" to %s.\n", addressstring2); - NetConn_WriteString(mysocket, "\377\377\377\377accept", peeraddress); - // now set up the client struct - SV_ConnectClient(clientnum, conn); - NetConn_Heartbeat(1); - } - } } } } @@ -1033,13 +1135,13 @@ int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, qbyte *data, int length, // If there was a challenge in the getinfo message if (length > 8 && string[7] == ' ') challenge = string + 8; - for (i = 0, n = 0;i < svs.maxclients;i++) - if (svs.clients[i].active) + for (i = 0, n = 0;i < MAX_SCOREBOARD;i++) + if (svs.connectedclients[i]) n++; responselength = snprintf(response, sizeof(response), "\377\377\377\377infoResponse\x0A" "\\gamename\\%s\\modname\\%s\\sv_maxclients\\%d" "\\clients\\%d\\mapname\\%s\\hostname\\%s\\protocol\\%d%s%s", - gamename, com_modname, svs.maxclients, n, + gamename, com_modname, min(sv_maxplayers.integer, MAX_SCOREBOARD), n, sv.name, hostname.string, NET_PROTOCOL_VERSION, challenge ? "\\challenge\\" : "", challenge ? challenge : ""); // does it fit in the buffer? if (responselength < (int)sizeof(response)) @@ -1099,10 +1201,10 @@ int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, qbyte *data, int length, else { // see if this is a duplicate connection request - for (clientnum = 0, client = svs.clients;clientnum < svs.maxclients;clientnum++, client++) - if (client->active && LHNETADDRESS_Compare(peeraddress, &client->netconnection->peeraddress) == 0) + for (clientnum = 0;clientnum < MAX_SCOREBOARD;clientnum++) + if ((client = svs.connectedclients[clientnum]) && LHNETADDRESS_Compare(peeraddress, &client->netconnection->peeraddress) == 0) break; - if (clientnum < svs.maxclients) + if (clientnum < MAX_SCOREBOARD) { // duplicate connection request if (realtime - client->netconnection->connecttime < 2.0) @@ -1131,10 +1233,11 @@ int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, qbyte *data, int length, else { // this is a new client, find a slot - for (clientnum = 0, client = svs.clients;clientnum < svs.maxclients;clientnum++, client++) - if (!client->active) + for (clientnum = 0;clientnum < MAX_SCOREBOARD;clientnum++) + if (!(client = svs.connectedclients[clientnum])) break; - if (clientnum < svs.maxclients && (client->netconnection = conn = NetConn_Open(mysocket, peeraddress)) != NULL) + // WARNING: this is broken code + if (clientnum < MAX_SCOREBOARD && (client->netconnection = conn = NetConn_Open(mysocket, peeraddress)) != NULL) { // connect to the client // everything is allocated, just fill in the details @@ -1189,7 +1292,7 @@ int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, qbyte *data, int length, MSG_WriteString(&net_message, hostname.string); MSG_WriteString(&net_message, sv.name); MSG_WriteByte(&net_message, net_activeconnections); - MSG_WriteByte(&net_message, svs.maxclients); + MSG_WriteByte(&net_message, min(sv_maxplayers.integer, MAX_SCOREBOARD)); MSG_WriteByte(&net_message, NET_PROTOCOL_VERSION); *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK)); NetConn_Write(mysocket, net_message.data, net_message.cursize, peeraddress); @@ -1264,14 +1367,25 @@ int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, qbyte *data, int length, } } #endif - for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++) + for (i = 0;i < MAX_SCOREBOARD;i++) { - if (host_client->active && host_client->netconnection && host_client->netconnection->mysocket == mysocket && !LHNETADDRESS_Compare(&host_client->netconnection->peeraddress, peeraddress)) + if ((host_client = svs.connectedclients[i])) { - sv_player = host_client->edict; - if ((ret = NetConn_ReceivedMessage(host_client->netconnection, data, length)) == 2) - SV_ReadClientMessage(); - return ret; + if (host_client->netconnection) + { + if (host_client->netconnection->mysocket == mysocket && !LHNETADDRESS_Compare(&host_client->netconnection->peeraddress, peeraddress)) + { + sv_player = host_client->edict; + if ((ret = NetConn_ReceivedMessage(host_client->netconnection, data, length)) == 2) + SV_ReadClientMessage(); + return ret; + } + } + else + { + Con_Printf("Removing client with no netconnection!\n"); + SV_DropClient(true); + } } } } @@ -1287,9 +1401,9 @@ void NetConn_ServerFrame(void) for (i = 0;i < sv_numsockets;i++) while (sv_sockets[i] && (length = NetConn_Read(sv_sockets[i], readbuffer, sizeof(readbuffer), &peeraddress)) > 0) NetConn_ServerParsePacket(sv_sockets[i], readbuffer, length, &peeraddress); - for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++) + for (i = 0;i < MAX_SCOREBOARD;i++) { - if (host_client->active && realtime > host_client->netconnection->timeout) + if ((host_client = svs.connectedclients[i]) && realtime > host_client->netconnection->timeout) { Con_Printf("Client \"%s\" connection timed out\n", host_client->name); sv_player = host_client->edict; @@ -1364,7 +1478,7 @@ void NetConn_Heartbeat(int priority) // 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 && svs.maxclients >= 2 && (priority > 1 || realtime > nextheartbeattime)) + if (sv.active && sv_public.integer && (!cl.islocalgame || sv_maxplayers.integer >= 2) && (priority > 1 || realtime > nextheartbeattime)) { nextheartbeattime = realtime + sv_heartbeatperiod.value; for (masternum = 0;sv_masters[masternum].name;masternum++) @@ -1391,9 +1505,9 @@ int NetConn_SendToAll(sizebuf_t *data, double blocktime) count = 0; NetConn_ClientFrame(); NetConn_ServerFrame(); - for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++) + for (i = 0;i < MAX_SCOREBOARD;i++) { - if (host_client->active) + if ((host_client = svs.connectedclients[i])) { if (NetConn_CanSendMessage(host_client->netconnection)) { @@ -1410,30 +1524,6 @@ int NetConn_SendToAll(sizebuf_t *data, double blocktime) return count; } -static void MaxPlayers_f(void) -{ - int n; - - if (Cmd_Argc() != 2) - { - Con_Printf("\"maxplayers\" is \"%u\"\n", svs.maxclients); - return; - } - - if (sv.active) - { - Con_Printf("maxplayers can not be changed while a server is running.\n"); - return; - } - - n = atoi(Cmd_Argv(1)); - n = bound(1, n, MAX_SCOREBOARD); - if (svs.maxclients != n) - Con_Printf("\"maxplayers\" set to \"%u\"\n", n); - - SV_SetMaxClients(n); -} - static void Net_Heartbeat_f(void) { NetConn_Heartbeat(2); @@ -1474,15 +1564,21 @@ void Net_Slist_f(void) void NetConn_Init(void) { - int masternum; + int i; + lhnetaddress_t tempaddress; netconn_mempool = Mem_AllocPool("Networking"); Cmd_AddCommand("net_stats", Net_Stats_f); Cmd_AddCommand("net_slist", Net_Slist_f); - Cmd_AddCommand("maxplayers", MaxPlayers_f); Cmd_AddCommand("heartbeat", Net_Heartbeat_f); Cvar_RegisterVariable(&net_messagetimeout); Cvar_RegisterVariable(&net_messagerejointimeout); Cvar_RegisterVariable(&net_connecttimeout); + Cvar_RegisterVariable(&cl_fakelocalping_min); + Cvar_RegisterVariable(&cl_fakelocalping_max); + Cvar_RegisterVariable(&cl_fakepacketloss_receive); + Cvar_RegisterVariable(&cl_fakepacketloss_send); + Cvar_RegisterVariable(&sv_fakepacketloss_receive); + Cvar_RegisterVariable(&sv_fakepacketloss_send); Cvar_RegisterVariable(&hostname); Cvar_RegisterVariable(&developer_networking); Cvar_RegisterVariable(&cl_netport); @@ -1493,8 +1589,30 @@ void NetConn_Init(void) Cvar_RegisterVariable(&sv_netaddress_ipv6); Cvar_RegisterVariable(&sv_public); Cvar_RegisterVariable(&sv_heartbeatperiod); - for (masternum = 0;sv_masters[masternum].name;masternum++) - Cvar_RegisterVariable(&sv_masters[masternum]); + for (i = 0;sv_masters[i].name;i++) + Cvar_RegisterVariable(&sv_masters[i]); + if ((i = COM_CheckParm("-ip")) && i + 1 < com_argc) + { + if (LHNETADDRESS_FromString(&tempaddress, com_argv[i + 1], 0) == 1) + { + Con_Printf("-ip option used, setting cl_netaddress and sv_netaddress to address \"%s\"\n"); + Cvar_SetQuick(&cl_netaddress, com_argv[i + 1]); + Cvar_SetQuick(&sv_netaddress, com_argv[i + 1]); + } + else + Con_Printf("-ip option used, but unable to parse the address \"%s\"\n", com_argv[i + 1]); + } + if (((i = COM_CheckParm("-port")) || (i = COM_CheckParm("-ipport")) || (i = COM_CheckParm("-udpport"))) && i + 1 < com_argc) + { + i = atoi(com_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); + } cl_numsockets = 0; sv_numsockets = 0; memset(&pingcache, 0, sizeof(pingcache));