#define DPMASTER_PORT 27950
// note this defaults on for dedicated servers, off for listen servers
-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"};
+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)"};
static cvar_t sv_masters [] =
// 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);
// TODO: add userinfo stuff here instead of using NQ commands?
- NetConn_WriteString(mysocket, va("\377\377\377\377connect\\protocol\\darkplaces 3\\protocols\\%s\\challenge\\%s", protocolnames, string + 10), peeraddress);
+ NetConn_WriteString(mysocket, va("\377\377\377\377connect\\protocol\\darkplaces 3\\protocols\\%s%s\\challenge\\%s", protocolnames, cls.connect_userinfo, string + 10), peeraddress);
return true;
}
if (length == 6 && !memcmp(string, "accept", 6) && cls.connect_trying)
cls.qw_qport = qport.integer;
// 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);
- NetConn_WriteString(mysocket, va("\377\377\377\377connect %i %i %i \"%s\"\n", 28, cls.qw_qport, atoi(string + 1), cls.userinfo), peeraddress);
+ NetConn_WriteString(mysocket, va("\377\377\377\377connect %i %i %i \"%s%s\"\n", 28, cls.qw_qport, atoi(string + 1), cls.userinfo, cls.connect_userinfo), peeraddress);
return true;
}
if (length >= 1 && string[0] == 'j' && cls.connect_trying)
SZ_Clear(&net_message);
}
for (i = 0;i < cl_numsockets;i++)
+ {
while (cl_sockets[i] && (length = NetConn_Read(cl_sockets[i], readbuffer, sizeof(readbuffer), &peeraddress)) > 0)
+ {
+// R_TimeReport("clientreadnetwork");
NetConn_ClientParsePacket(cl_sockets[i], readbuffer, length, &peeraddress);
+// R_TimeReport("clientparsepacket");
+ }
+ }
NetConn_QueryQueueFrame();
if (cls.netcon && realtime > cls.netcon->timeout && !sv.active)
{
"%s",
fullstatus ? "statusResponse" : "infoResponse",
gamename, com_modname, gameversion.integer, svs.maxclients,
- nb_clients, nb_bots, sv.name, hostname.string, NET_PROTOCOL_VERSION,
+ nb_clients, nb_bots, sv.worldbasename, hostname.string, NET_PROTOCOL_VERSION,
*qcstatus ? "\\qcstatus\\" : "", qcstatus,
challenge ? "\\challenge\\" : "", challenge ? challenge : "",
fullstatus ? "\n" : "");
}
}
- if ((gamemode == GAME_NEXUIZ) && (teamplay.integer > 0))
+ if ((gamemode == GAME_NEXUIZ || gamemode == GAME_XONOTIC) && (teamplay.integer > 0))
{
if(cl->frags == -666) // spectator
strlcpy(teambuf, " 0", sizeof(teambuf));
Com_HexDumpToConsole(data, length);
}
- if (length >= 12 && !memcmp(string, "getchallenge", 12) && (islocal || sv_public.integer > -2))
+ if (length >= 12 && !memcmp(string, "getchallenge", 12) && (islocal || sv_public.integer > -3))
{
for (i = 0, best = 0, besttime = realtime;i < MAX_CHALLENGES;i++)
{
NetConn_WriteString(mysocket, va("\377\377\377\377challenge %s", challenge[i].string), peeraddress);
return true;
}
- if (length > 8 && !memcmp(string, "connect\\", 8) && (islocal || sv_public.integer > -2))
+ if (length > 8 && !memcmp(string, "connect\\", 8))
{
string += 7;
length -= 7;
if (i == MAX_CHALLENGES)
return true;
+ if(!(islocal || sv_public.integer > -2))
+ {
+ if (developer_extra.integer)
+ Con_Printf("Datagram_ParseConnectionless: sending \"reject %s\" to %s.\n", sv_public_rejectreason.string, addressstring2);
+ NetConn_WriteString(mysocket, va("\377\377\377\377reject %s", sv_public_rejectreason.string), peeraddress);
+ return true;
+ }
+
// check engine protocol
if(!(s = SearchInfostring(string, "protocol")) || strcmp(s, "darkplaces 3"))
{
case CCREQ_CONNECT:
if (developer_extra.integer)
Con_DPrintf("Datagram_ParseConnectionless: received CCREQ_CONNECT from %s.\n", addressstring2);
- if(!islocal && sv_public.integer <= -2)
+ if(!(islocal || sv_public.integer > -2))
+ {
+ if (developer_extra.integer)
+ Con_DPrintf("Datagram_ParseConnectionless: sending CCREP_REJECT \"%s\" to %s.\n", sv_public_rejectreason.string, addressstring2);
+ SZ_Clear(&net_message);
+ // save space for the header, filled in later
+ MSG_WriteLong(&net_message, 0);
+ MSG_WriteByte(&net_message, CCREP_REJECT);
+ MSG_WriteString(&net_message, va("%s\n", sv_public_rejectreason.string));
+ 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);
break;
+ }
protocolname = MSG_ReadString();
protocolnumber = MSG_ReadByte();
case CCREQ_SERVER_INFO:
if (developer_extra.integer)
Con_DPrintf("Datagram_ParseConnectionless: received CCREQ_SERVER_INFO from %s.\n", addressstring2);
- if(!islocal && sv_public.integer <= -1)
+ if(!(islocal || sv_public.integer > -1))
break;
if (sv.active && !strcmp(MSG_ReadString(), "QUAKE"))
{
case CCREQ_PLAYER_INFO:
if (developer_extra.integer)
Con_DPrintf("Datagram_ParseConnectionless: received CCREQ_PLAYER_INFO from %s.\n", addressstring2);
- if(!islocal && sv_public.integer <= -1)
+ if(!(islocal || sv_public.integer > -1))
break;
if (sv.active)
{
case CCREQ_RULE_INFO:
if (developer_extra.integer)
Con_DPrintf("Datagram_ParseConnectionless: received CCREQ_RULE_INFO from %s.\n", addressstring2);
- if(!islocal && sv_public.integer <= -1)
+ if(!(islocal || sv_public.integer > -1))
break;
if (sv.active)
{
Cvar_RegisterVariable(&net_address);
Cvar_RegisterVariable(&net_address_ipv6);
Cvar_RegisterVariable(&sv_public);
+ Cvar_RegisterVariable(&sv_public_rejectreason);
Cvar_RegisterVariable(&sv_heartbeatperiod);
for (i = 0;sv_masters[i].name;i++)
Cvar_RegisterVariable(&sv_masters[i]);