X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=netconn.c;h=7d46e1c375697d179e9622b347adfb570356aec1;hb=8be49ec5ac5c9ed9203b8a2882fce57904285096;hp=0b7e0eb1148f07c879afa344c4edce42fad2f385;hpb=18ccad34785dd40794a2198ac79d05694b2f1a40;p=xonotic%2Fdarkplaces.git diff --git a/netconn.c b/netconn.c index 0b7e0eb1..7d46e1c3 100755 --- a/netconn.c +++ b/netconn.c @@ -25,7 +25,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define MASTER_PORT 27950 -cvar_t sv_public = {0, "sv_public", "1"}; +// note this defaults on for dedicated servers, off for listen servers +cvar_t sv_public = {0, "sv_public", "0"}; static cvar_t sv_heartbeatperiod = {CVAR_SAVE, "sv_heartbeatperiod", "120"}; // FIXME: resolve DNS on masters whenever their value changes and cache it (to avoid major delays in active servers when they heartbeat) @@ -36,7 +37,7 @@ static cvar_t sv_masters [] = {CVAR_SAVE, "sv_master3", ""}, {CVAR_SAVE, "sv_master4", ""}, {0, "sv_masterextra1", "ghdigital.com"}, //69.59.212.88 - {0, "sv_masterextra2", "dpmaster.deathmask.net"}, //209.164.24.243 + {0, "sv_masterextra2", "dpmaster.deathmask.net"}, //66.169.205.20 {0, "sv_masterextra3", "12.166.196.192"}, //blaze.mindphukd.org (doesn't resolve currently but works as an ip) {0, NULL, NULL} }; @@ -205,25 +206,34 @@ static qboolean _ServerList_CompareInt( int A, serverlist_maskop_t op, int B ) static qboolean _ServerList_CompareStr( const char *A, serverlist_maskop_t op, const char *B ) { + int i; + char bufferA[ 256 ], bufferB[ 256 ]; // should be more than enough + for (i = 0;i < (int)sizeof(bufferA)-1 && A[i];i++) + bufferA[i] = (A[i] >= 'A' && A[i] <= 'Z') ? (A[i] + 'a' - 'A') : A[i]; + bufferA[i] = 0; + for (i = 0;i < (int)sizeof(bufferB)-1 && B[i];i++) + bufferB[i] = (B[i] >= 'A' && B[i] <= 'Z') ? (B[i] + 'a' - 'A') : B[i]; + bufferB[i] = 0; + // Same here, also using an intermediate & final return would be more appropriate // A info B mask switch( op ) { case SLMO_CONTAINS: - return *B && !!strstr( A, B ); // we want a real bool + return *bufferB && !!strstr( bufferA, bufferB ); // we want a real bool case SLMO_NOTCONTAIN: - return !*B || !strstr( A, B ); + return !*bufferB || !strstr( bufferA, bufferB ); case SLMO_LESS: - return strcmp( A, B ) < 0; + return strcmp( bufferA, bufferB ) < 0; case SLMO_LESSEQUAL: - return strcmp( A, B ) <= 0; + return strcmp( bufferA, bufferB ) <= 0; case SLMO_EQUAL: - return strcmp( A, B ) == 0; + return strcmp( bufferA, bufferB ) == 0; case SLMO_GREATER: - return strcmp( A, B ) > 0; + return strcmp( bufferA, bufferB ) > 0; case SLMO_NOTEQUAL: - return strcmp( A, B ) != 0; + return strcmp( bufferA, bufferB ) != 0; case SLMO_GREATEREQUAL: - return strcmp( A, B ) >= 0; + return strcmp( bufferA, bufferB ) >= 0; default: Con_DPrint( "_ServerList_CompareStr: Bad op!\n" ); return false; @@ -387,7 +397,7 @@ int NetConn_Read(lhnetsocket_t *mysocket, void *data, int maxlength, lhnetaddres { LHNETADDRESS_ToString(peeraddress, addressstring2, sizeof(addressstring2), true); Con_Printf("LHNET_Read(%p (%s), %p, %i, %p) = %i from %s:\n", mysocket, addressstring, data, maxlength, peeraddress, length, addressstring2); - Com_HexDumpToConsole(data, length); + Com_HexDumpToConsole((qbyte *)data, length); } else Con_Printf("LHNET_Read(%p (%s), %p, %i, %p) = %i\n", mysocket, addressstring, data, maxlength, peeraddress, length); @@ -410,7 +420,7 @@ int NetConn_Write(lhnetsocket_t *mysocket, const void *data, int length, const l LHNETADDRESS_ToString(LHNET_AddressFromSocket(mysocket), addressstring, sizeof(addressstring), true); LHNETADDRESS_ToString(peeraddress, addressstring2, sizeof(addressstring2), true); Con_Printf("LHNET_Write(%p (%s), %p, %i, %p (%s)) = %i%s\n", mysocket, addressstring, data, length, peeraddress, addressstring2, length, ret == length ? "" : " (ERROR)"); - Com_HexDumpToConsole(data, length); + Com_HexDumpToConsole((qbyte *)data, length); } return ret; } @@ -418,7 +428,7 @@ int NetConn_Write(lhnetsocket_t *mysocket, const void *data, int length, const l int NetConn_WriteString(lhnetsocket_t *mysocket, const char *string, const lhnetaddress_t *peeraddress) { // note this does not include the trailing NULL because we add that in the parser - return NetConn_Write(mysocket, string, strlen(string), peeraddress); + return NetConn_Write(mysocket, string, (int)strlen(string), peeraddress); } int NetConn_SendReliableMessage(netconn_t *conn, sizebuf_t *data) @@ -430,13 +440,22 @@ int NetConn_SendReliableMessage(netconn_t *conn, sizebuf_t *data) //#ifdef DEBUG if (data->cursize == 0) - Sys_Error("Datagram_SendMessage: zero length message\n"); + { + Con_Printf ("Datagram_SendMessage: zero length message\n"); + return -1; + } if (data->cursize > (int)sizeof(conn->sendMessage)) - Sys_Error("Datagram_SendMessage: message too big (%u > %u)\n", data->cursize, sizeof(conn->sendMessage)); + { + Con_Printf ("Datagram_SendMessage: message too big (%u > %u)\n", data->cursize, sizeof(conn->sendMessage)); + return -1; + } if (conn->canSend == false) - Sys_Error("SendMessage: called with canSend == false\n"); + { + Con_Printf ("SendMessage: called with canSend == false\n"); + return -1; + } //#endif memcpy(conn->sendMessage, data->data, data->cursize); @@ -455,7 +474,7 @@ int NetConn_SendReliableMessage(netconn_t *conn, sizebuf_t *data) packetLen = NET_HEADERSIZE + dataLen; - header = (void *)sendbuffer; + header = (unsigned int *)sendbuffer; header[0] = BigLong(packetLen | (NETFLAG_DATA | eom)); header[1] = BigLong(conn->sendSequence); memcpy(sendbuffer + NET_HEADERSIZE, conn->sendMessage, dataLen); @@ -494,7 +513,7 @@ static void NetConn_SendMessageNext(netconn_t *conn) packetLen = NET_HEADERSIZE + dataLen; - header = (void *)sendbuffer; + header = (unsigned int *)sendbuffer; header[0] = BigLong(packetLen | (NETFLAG_DATA | eom)); header[1] = BigLong(conn->sendSequence); memcpy(sendbuffer + NET_HEADERSIZE, conn->sendMessage, dataLen); @@ -532,7 +551,7 @@ static void NetConn_ReSendMessage(netconn_t *conn) packetLen = NET_HEADERSIZE + dataLen; - header = (void *)sendbuffer; + header = (unsigned int *)sendbuffer; header[0] = BigLong(packetLen | (NETFLAG_DATA | eom)); header[1] = BigLong(conn->sendSequence - 1); memcpy(sendbuffer + NET_HEADERSIZE, conn->sendMessage, dataLen); @@ -555,19 +574,25 @@ qboolean NetConn_CanSendMessage(netconn_t *conn) int NetConn_SendUnreliableMessage(netconn_t *conn, sizebuf_t *data) { int packetLen; - int *header; + unsigned int *header; packetLen = NET_HEADERSIZE + data->cursize; //#ifdef DEBUG if (data->cursize == 0) - Sys_Error("Datagram_SendUnreliableMessage: zero length message\n"); + { + Con_Printf ("Datagram_SendUnreliableMessage: zero length message\n"); + return -1; + } if (packetLen > (int)sizeof(sendbuffer)) - Sys_Error("Datagram_SendUnreliableMessage: message too big %u\n", data->cursize); + { + Con_Printf ("Datagram_SendUnreliableMessage: message too big %u\n", data->cursize); + return -1; + } //#endif - header = (void *)sendbuffer; + header = (unsigned int *)sendbuffer; header[0] = BigLong(packetLen | NETFLAG_UNRELIABLE); header[1] = BigLong(conn->unreliableSendSequence); memcpy(sendbuffer + NET_HEADERSIZE, data->data, data->cursize); @@ -636,23 +661,33 @@ void NetConn_OpenServerPort(const char *addressstring, int defaultport) { lhnetaddress_t address; lhnetsocket_t *s; + int port; char addressstring2[1024]; - if (LHNETADDRESS_FromString(&address, addressstring, defaultport)) + + for (port = defaultport; port <= defaultport + 100; port++) { - if ((s = LHNET_OpenSocket_Connectionless(&address))) + if (LHNETADDRESS_FromString(&address, addressstring, port)) { - sv_sockets[sv_numsockets++] = s; - LHNETADDRESS_ToString(LHNET_AddressFromSocket(s), addressstring2, sizeof(addressstring2), true); - Con_Printf("Server listening on address %s\n", addressstring2); + 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); + break; + } + else + { + LHNETADDRESS_ToString(&address, addressstring2, sizeof(addressstring2), true); + Con_Printf("Server failed to open socket 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); + Con_Printf("Server unable to parse address %s\n", addressstring); + // if it cant parse one address, it wont be able to parse another for sure + break; } } - else - Con_Printf("Server unable to parse address %s\n", addressstring); } void NetConn_OpenServerPorts(int opennetports) @@ -697,7 +732,7 @@ lhnetsocket_t *NetConn_ChooseServerSocketForAddress(lhnetaddress_t *address) netconn_t *NetConn_Open(lhnetsocket_t *mysocket, lhnetaddress_t *peeraddress) { netconn_t *conn; - conn = Mem_Alloc(netconn_mempool, sizeof(*conn)); + conn = (netconn_t *)Mem_Alloc(netconn_mempool, sizeof(*conn)); conn->mysocket = mysocket; conn->peeraddress = *peeraddress; conn->canSend = true; @@ -852,7 +887,7 @@ int NetConn_ReceivedMessage(netconn_t *conn, qbyte *data, int length) conn->lastMessageTime = realtime; conn->timeout = realtime + net_messagetimeout.value; conn->receiveSequence++; - if( conn->receiveMessageLength + length <= sizeof( conn->receiveMessage ) ) { + if( conn->receiveMessageLength + length <= (int)sizeof( conn->receiveMessage ) ) { memcpy(conn->receiveMessage + conn->receiveMessageLength, data, length); conn->receiveMessageLength += length; } else { @@ -1134,7 +1169,7 @@ int NetConn_ClientParsePacket(lhnetsocket_t *mysocket, qbyte *data, int length, if (developer.integer) Con_Printf("Datagram_ParseConnectionless: received CCREP_REJECT from %s.\n", addressstring2); cls.connect_trying = false; - M_Update_Return_Reason(data); + M_Update_Return_Reason((char *)data); break; #if 0 case CCREP_SERVER_INFO: @@ -1223,7 +1258,7 @@ void NetConn_QueryQueueFrame(void) for( index = 0, queries = 0 ; index < serverlist_cachecount && queries < maxqueries ; index++ ) { serverlist_entry_t *entry = &serverlist_cache[ index ]; - if( entry->query != SQS_QUERYING ) + if( entry->query != SQS_QUERYING ) { continue; } @@ -1234,7 +1269,7 @@ void NetConn_QueryQueueFrame(void) continue; } - if( entry->querycounter != (unsigned) net_slist_maxtries.integer ) + if( entry->querycounter != (unsigned) net_slist_maxtries.integer ) { lhnetaddress_t address; int socket; @@ -1252,8 +1287,8 @@ void NetConn_QueryQueueFrame(void) Con_Printf("querying %25s (%i. try)\n", entry->info.cname, entry->querycounter); queries++; - } - else + } + else { entry->query = SQS_TIMEDOUT; } @@ -1308,7 +1343,7 @@ void NetConn_ClientFrame(void) } #define MAX_CHALLENGES 128 -struct +struct challenge_s { lhnetaddress_t address; double time; @@ -1331,10 +1366,83 @@ static void NetConn_BuildChallengeString(char *buffer, int bufferlength) buffer[i] = 0; } +static qboolean NetConn_BuildStatusResponse(const char* challenge, char* out_msg, size_t out_size, qboolean fullstatus) +{ + unsigned int nb_clients = 0, i; + int length; + + // How many clients are there? + for (i = 0;i < (unsigned int)svs.maxclients;i++) + if (svs.clients[i].active) + nb_clients++; + + // TODO: we should add more information for the full status string + length = dpsnprintf(out_msg, out_size, + "\377\377\377\377%s\x0A" + "\\gamename\\%s\\modname\\%s\\sv_maxclients\\%d" + "\\clients\\%d\\mapname\\%s\\hostname\\%s""\\protocol\\%d" + "%s%s" + "%s", + fullstatus ? "statusResponse" : "infoResponse", + gamename, com_modname, svs.maxclients, + nb_clients, sv.name, hostname.string, NET_PROTOCOL_VERSION, + challenge ? "\\challenge\\" : "", challenge ? challenge : "", + fullstatus ? "\n" : ""); + + // Make sure it fits in the buffer + if (length < 0) + return false; + + if (fullstatus) + { + char *ptr; + int left; + + ptr = out_msg + length; + left = (int)out_size - length; + + for (i = 0;i < (unsigned int)svs.maxclients;i++) + { + client_t *cl = &svs.clients[i]; + if (cl->active) + { + int nameind, cleanind; + char curchar; + char cleanname [sizeof(cl->name)]; + + // Remove all characters '"' and '\' in the player name + nameind = 0; + cleanind = 0; + do + { + curchar = cl->name[nameind++]; + if (curchar != '"' && curchar != '\\') + { + cleanname[cleanind++] = curchar; + if (cleanind == sizeof(cleanname) - 1) + break; + } + } while (curchar != '\0'); + + length = dpsnprintf(ptr, left, "%d %d \"%s\"\n", + cl->frags, + (int)(cl->ping * 1000.0f), + cleanname); + if(length < 0) + return false; + left -= length; + ptr += length; + } + } + } + + return true; +} + extern void SV_SendServerinfo (client_t *client); int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, qbyte *data, int length, lhnetaddress_t *peeraddress) { - int i, n, ret, clientnum, responselength, best; + int i, ret, clientnum, best; double besttime; client_t *client; netconn_t *conn; @@ -1465,19 +1573,12 @@ int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, qbyte *data, int length, if (length >= 7 && !memcmp(string, "getinfo", 7)) { const char *challenge = NULL; + // 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) - n++; - responselength = dpsnprintf(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, - sv.name, hostname.string, NET_PROTOCOL_VERSION, challenge ? "\\challenge\\" : "", challenge ? challenge : ""); - // does it fit in the buffer? - if (responselength >= 0) + + if (NetConn_BuildStatusResponse(challenge, response, sizeof(response), false)) { if (developer.integer) Con_Printf("Sending reply to master %s - %s\n", addressstring2, response); @@ -1485,6 +1586,22 @@ int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, qbyte *data, int length, } return true; } + if (length >= 9 && !memcmp(string, "getstatus", 9)) + { + const char *challenge = NULL; + + // If there was a challenge in the getinfo message + if (length > 10 && string[9] == ' ') + challenge = string + 10; + + if (NetConn_BuildStatusResponse(challenge, response, sizeof(response), true)) + { + if (developer.integer) + Con_Printf("Sending reply to client %s - %s\n", addressstring2, response); + NetConn_WriteString(mysocket, response, peeraddress); + } + return true; + } /* if (!strncmp(string, "ping", 4)) {