]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - netconn.c
dynamically grow maxtempentities
[xonotic/darkplaces.git] / netconn.c
index dde22c22c34c28f1a28fe65349ec367bcb705f73..e2095d9197bc82c13ca13c6f2d7a9da77ba5e6b5 100755 (executable)
--- a/netconn.c
+++ b/netconn.c
@@ -35,6 +35,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 cvar_t sv_public = {0, "sv_public", "0", "1: advertises this server on the master server (so that players can find it in the server browser); 0: allow direct queries only; -1: do not respond to direct queries; -2: do not allow anyone to connect; -3: already block at getchallenge level"};
 cvar_t sv_public_rejectreason = {0, "sv_public_rejectreason", "The server is closing.", "Rejection reason for connects when sv_public is -2"};
 static cvar_t sv_heartbeatperiod = {CVAR_SAVE, "sv_heartbeatperiod", "120", "how often to send heartbeat in seconds (only used if sv_public is 1)"};
+extern cvar_t sv_status_privacy;
 
 static cvar_t sv_masters [] =
 {
@@ -2037,6 +2038,21 @@ static int NetConn_ClientParsePacket(lhnetsocket_t *mysocket, unsigned char *dat
                                lhnetaddress_t clientportaddress;
                                clientportaddress = *peeraddress;
                                LHNETADDRESS_SetPort(&clientportaddress, MSG_ReadLong());
+                               // extra ProQuake stuff
+                               if (length >= 6)
+                                       cls.proquake_servermod = MSG_ReadByte(); // MOD_PROQUAKE
+                               else
+                                       cls.proquake_servermod = 0;
+                               if (length >= 7)
+                                       cls.proquake_serverversion = MSG_ReadByte(); // version * 10
+                               else
+                                       cls.proquake_serverversion = 0;
+                               if (length >= 8)
+                                       cls.proquake_serverflags = MSG_ReadByte(); // flags (mainly PQF_CHEATFREE)
+                               else
+                                       cls.proquake_serverflags = 0;
+                               if (cls.proquake_servermod == 1)
+                                       Con_Printf("Connected to ProQuake %.1f server, enabling precise aim\n", cls.proquake_serverversion / 10.0f);
                                // update the server IP in the userinfo (QW servers expect this, and it is used by the reconnect command)
                                InfoString_SetValue(cls.userinfo, sizeof(cls.userinfo), "*ip", addressstring2);
                                M_Update_Return_Reason("Accepted");
@@ -2217,6 +2233,15 @@ void NetConn_ClientFrame(void)
                MSG_WriteByte(&net_message, CCREQ_CONNECT);
                MSG_WriteString(&net_message, "QUAKE");
                MSG_WriteByte(&net_message, NET_PROTOCOL_VERSION);
+               // extended proquake stuff
+               MSG_WriteByte(&net_message, 1); // mod = MOD_PROQUAKE
+               // this version matches ProQuake 3.40, the first version to support
+               // the NAT fix, and it only supports the NAT fix for ProQuake 3.40 or
+               // higher clients, so we pretend we are that version...
+               MSG_WriteByte(&net_message, 34); // version * 10
+               MSG_WriteByte(&net_message, 0); // flags
+               MSG_WriteLong(&net_message, 0); // password
+               // write the packetsize now...
                StoreBigLong(net_message.data, NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
                NetConn_Write(cls.connect_mysocket, net_message.data, net_message.cursize, &cls.connect_address);
                SZ_Clear(&net_message);
@@ -2636,7 +2661,7 @@ allow:
        return va("%srcon", restricted ? "restricted " : "");
 }
 
-void RCon_Execute(lhnetsocket_t *mysocket, lhnetaddress_t *peeraddress, const char *addressstring2, const char *userlevel, const char *s, const char *endpos)
+void RCon_Execute(lhnetsocket_t *mysocket, lhnetaddress_t *peeraddress, const char *addressstring2, const char *userlevel, const char *s, const char *endpos, qboolean proquakeprotocol)
 {
        if(userlevel)
        {
@@ -2653,7 +2678,7 @@ void RCon_Execute(lhnetsocket_t *mysocket, lhnetaddress_t *peeraddress, const ch
                Con_Printf("\n");
 
                if (!host_client || !host_client->netconnection || LHNETADDRESS_GetAddressType(&host_client->netconnection->peeraddress) != LHNETADDRESSTYPE_LOOP)
-                       Con_Rcon_Redirect_Init(mysocket, peeraddress);
+                       Con_Rcon_Redirect_Init(mysocket, peeraddress, proquakeprotocol);
                while(s != endpos)
                {
                        size_t l = strlen(s);
@@ -2973,7 +2998,7 @@ static int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, unsigned char *dat
                        ++s;
 
                        userlevel = RCon_Authenticate(peeraddress, password, s, endpos, hmac_mdfour_time_matching, timeval, endpos - timeval - 1); // not including the appended \0 into the HMAC
-                       RCon_Execute(mysocket, peeraddress, addressstring2, userlevel, s, endpos);
+                       RCon_Execute(mysocket, peeraddress, addressstring2, userlevel, s, endpos, false);
                        return true;
                }
                if (length >= 42 && !memcmp(string, "srcon HMAC-MD4 CHALLENGE ", 25))
@@ -2988,7 +3013,7 @@ static int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, unsigned char *dat
                        ++s;
 
                        userlevel = RCon_Authenticate(peeraddress, password, s, endpos, hmac_mdfour_challenge_matching, challenge, endpos - challenge - 1); // not including the appended \0 into the HMAC
-                       RCon_Execute(mysocket, peeraddress, addressstring2, userlevel, s, endpos);
+                       RCon_Execute(mysocket, peeraddress, addressstring2, userlevel, s, endpos, false);
                        return true;
                }
                if (length >= 5 && !memcmp(string, "rcon ", 5))
@@ -3010,7 +3035,7 @@ static int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, unsigned char *dat
                        if (!ISWHITESPACE(password[0]))
                        {
                                const char *userlevel = RCon_Authenticate(peeraddress, password, s, endpos, plaintext_matching, NULL, 0);
-                               RCon_Execute(mysocket, peeraddress, addressstring2, userlevel, s, endpos);
+                               RCon_Execute(mysocket, peeraddress, addressstring2, userlevel, s, endpos, false);
                        }
                        return true;
                }
@@ -3224,7 +3249,10 @@ static int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, unsigned char *dat
                                        MSG_WriteLong(&net_message, client->colors);
                                        MSG_WriteLong(&net_message, client->frags);
                                        MSG_WriteLong(&net_message, (int)(realtime - client->connecttime));
-                                       MSG_WriteString(&net_message, client->netconnection ? client->netconnection->address : "botclient");
+                                       if(sv_status_privacy.integer)
+                                               MSG_WriteString(&net_message, client->netconnection ? "hidden" : "botclient");
+                                       else
+                                               MSG_WriteString(&net_message, client->netconnection ? client->netconnection->address : "botclient");
                                        StoreBigLong(net_message.data, NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
                                        NetConn_Write(mysocket, net_message.data, net_message.cursize, peeraddress);
                                        SZ_Clear(&net_message);
@@ -3260,6 +3288,25 @@ static int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, unsigned char *dat
                                SZ_Clear(&net_message);
                        }
                        break;
+               case CCREQ_RCON:
+                       if (developer_extra.integer)
+                               Con_DPrintf("Datagram_ParseConnectionless: received CCREQ_RCON from %s.\n", addressstring2);
+                       if (sv.active && !rcon_secure.integer)
+                       {
+                               char password[2048];
+                               char cmd[2048];
+                               char *s;
+                               char *endpos;
+                               const char *userlevel;
+                               strlcpy(password, MSG_ReadString(), sizeof(password));
+                               strlcpy(cmd, MSG_ReadString(), sizeof(cmd));
+                               s = cmd;
+                               endpos = cmd + strlen(cmd) + 1; // one behind the NUL, so adding strlen+1 will eventually reach it
+                               userlevel = RCon_Authenticate(peeraddress, password, s, endpos, plaintext_matching, NULL, 0);
+                               RCon_Execute(mysocket, peeraddress, addressstring2, userlevel, s, endpos, true);
+                               return true;
+                       }
+                       break;
                default:
                        break;
                }