Port pubkey validation from RR and make it optional

For more competitve servers they can enable this to prevent unfair play while letting casual servers still have flexibility
This commit is contained in:
NepDisk 2026-03-29 21:28:46 -04:00
parent a81aef27e2
commit 13a82ca079
3 changed files with 42 additions and 1 deletions

View file

@ -4574,7 +4574,7 @@ static void HandleConnect(SINT8 node)
{
doomdata_t *netbuffer = DOOMCOM_DATA(doomcom);
char names[MAXSPLITSCREENPLAYERS][MAXPLAYERNAME + 1];
INT32 i;
INT32 i, j;
UINT8 availabilitiesbuffer[MAXAVAILABILITY];
// Sal: Dedicated mode is INCREDIBLY hacked together.
@ -4690,6 +4690,8 @@ static void HandleConnect(SINT8 node)
{
int sigcheck;
boolean newnode = false;
char allZero[PUBKEYLENGTH];
memset(allZero, 0, sizeof(allZero));
for (i = 0; i < netbuffer->u.clientcfg.localplayers - playerpernode[node]; i++)
{
@ -4714,6 +4716,40 @@ static void HandleConnect(SINT8 node)
return;
}
}
if (cv_validate_pubkey.value)
{
// Check non-GUESTS for duplicate pubkeys, they'll create nonsense stats
if (memcmp(lastReceivedKey[node][i], allZero, PUBKEYLENGTH) != 0)
{
// Players already here
for (j = 0; j < MAXPLAYERS; j++)
{
if (!playeringame[j])
continue;
if (memcmp(lastReceivedKey[node][i], players[j].public_key, PUBKEYLENGTH) == 0)
{
SV_SendRefuse(node, M_GetText("This server disallows\nduplicate pubkeys,\n(Did you share your keys?)"));
return;
}
}
// Players we're trying to add
for (j = 0; j < netbuffer->u.clientcfg.localplayers - playerpernode[node]; j++)
{
if (memcmp(lastReceivedKey[node][i], allZero, PUBKEYLENGTH) == 0)
continue;
if (i == j)
continue;
if (memcmp(lastReceivedKey[node][i], lastReceivedKey[node][j], PUBKEYLENGTH) == 0)
{
SV_SendRefuse(node, M_GetText("Duplicate pubkey in local party.\n(How did you even do this?)"));
return;
}
}
}
}
}
memcpy(availabilitiesbuffer, netbuffer->u.clientcfg.availabilities, sizeof(availabilitiesbuffer));

View file

@ -791,6 +791,9 @@ consvar_t cv_nettimeout = CVAR_INIT ("nettimeout", "210", CV_CALL|CV_SAVE, netti
consvar_t cv_jointimeout = CVAR_INIT ("jointimeout", "210", CV_CALL|CV_SAVE, nettimeout_cons_t, JoinTimeout_OnChange);
consvar_t cv_maxping = CVAR_INIT ("maxdelay", "20", CV_SAVE, CV_Unsigned, NULL);
consvar_t cv_validate_pubkey= CVAR_INIT ("validate_pubkey", "Off", 0, CV_OnOff, NULL); // Validate for duplicate players on Join.
static CV_PossibleValue_t lagless_cons_t[] = {{-1, "Worst"}, {0, "Best"}, {1, "Lagless"}, {0, NULL}};
consvar_t cv_lagless = CVAR_INIT ("lagless", "Lagless", CV_SAVE|CV_NETVAR|CV_CALL, lagless_cons_t, Lagless_OnChange);
@ -1146,6 +1149,7 @@ void D_RegisterServerCommands(void)
COM_AddCommand("ping", Command_Ping_f);
CV_RegisterVar(&cv_nettimeout);
CV_RegisterVar(&cv_jointimeout);
CV_RegisterVar(&cv_validate_pubkey);
CV_RegisterVar(&cv_kicktime);
CV_RegisterVar(&cv_skipmapcheck);
CV_RegisterVar(&cv_sleep);

View file

@ -778,6 +778,7 @@ extern consvar_t cv_forceskin; // force clients to use the server's skin
extern consvar_t cv_downloading; // allow clients to downloading WADs.
extern consvar_t cv_nettimeout; // SRB2Kart: Advanced server options menu
extern consvar_t cv_jointimeout;
extern consvar_t cv_validate_pubkey;
extern ticcmd_t netcmds[BACKUPTICS][MAXPLAYERS];
extern INT32 serverplayer;
extern INT32 adminplayers[MAXPLAYERS];