mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-12-31 12:13:16 +00:00
Improved round-queue state net communication
- Only send from the server when an update to roundqueue state is relevant - Perform sanity checking on reciept - Initialise when map command is sent with roundqueue size greater than the client's - Correct gametype/encore state on reciept - Only permit from the server, forbid admin clients from providing it on penalty of kick
This commit is contained in:
parent
19ef96351a
commit
a08683e819
4 changed files with 55 additions and 11 deletions
|
|
@ -2578,12 +2578,18 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean pencoremode, boolean p
|
|||
flags |= 1<<2;
|
||||
if (pforcespecialstage)
|
||||
flags |= 1<<3;
|
||||
if (roundqueue.netcommunicate)
|
||||
flags |= 1<<4;
|
||||
WRITEUINT8(buf_p, flags);
|
||||
|
||||
// roundqueue state
|
||||
WRITEUINT8(buf_p, roundqueue.position);
|
||||
WRITEUINT8(buf_p, roundqueue.size);
|
||||
WRITEUINT8(buf_p, roundqueue.roundnum);
|
||||
if (roundqueue.netcommunicate)
|
||||
{
|
||||
// roundqueue state
|
||||
WRITEUINT8(buf_p, roundqueue.position);
|
||||
WRITEUINT8(buf_p, roundqueue.size);
|
||||
WRITEUINT8(buf_p, roundqueue.roundnum);
|
||||
roundqueue.netcommunicate = false;
|
||||
}
|
||||
|
||||
// new gametype value
|
||||
WRITEUINT8(buf_p, newgametype);
|
||||
|
|
@ -3042,7 +3048,7 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum)
|
|||
UINT8 flags;
|
||||
INT32 presetplayer = 1, lastgametype;
|
||||
UINT8 skipprecutscene, pforcespecialstage;
|
||||
boolean pencoremode;
|
||||
boolean pencoremode, hasroundqueuedata;
|
||||
INT16 mapnumber;
|
||||
|
||||
forceresetplayers = deferencoremode = false;
|
||||
|
|
@ -3055,9 +3061,6 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum)
|
|||
return;
|
||||
}
|
||||
|
||||
if (chmappending)
|
||||
chmappending--;
|
||||
|
||||
flags = READUINT8(*cp);
|
||||
|
||||
pencoremode = ((flags & 1) != 0);
|
||||
|
|
@ -3068,9 +3071,38 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum)
|
|||
|
||||
pforcespecialstage = ((flags & (1<<3)) != 0);
|
||||
|
||||
roundqueue.position = READUINT8(*cp);
|
||||
roundqueue.size = READUINT8(*cp);
|
||||
roundqueue.roundnum = READUINT8(*cp);
|
||||
hasroundqueuedata = ((flags & (1<<4)) != 0);
|
||||
|
||||
if (hasroundqueuedata)
|
||||
{
|
||||
UINT8 position = READUINT8(*cp);
|
||||
UINT8 size = READUINT8(*cp);
|
||||
UINT8 roundnum = READUINT8(*cp);
|
||||
|
||||
if (playernum != serverplayer // Clients, even admin clients, don't have full roundqueue data
|
||||
|| position > size // Sanity check A (intentionally not a >= comparison)
|
||||
|| size > ROUNDQUEUE_MAX) // Sanity Check B (ditto)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal round-queue data received from %s\n"), player_names[playernum]);
|
||||
if (server)
|
||||
SendKick(playernum, KICK_MSG_CON_FAIL);
|
||||
return;
|
||||
}
|
||||
|
||||
roundqueue.position = position;
|
||||
while (roundqueue.size < size)
|
||||
{
|
||||
// We wipe rather than provide full data to prevent bloating the packet,
|
||||
// and because only this data is necessary for sync. ~toast 100423
|
||||
memset(&roundqueue.entries[roundqueue.size], 0, sizeof(roundentry_t));
|
||||
roundqueue.size++;
|
||||
}
|
||||
roundqueue.roundnum = roundnum; // no sanity checking required, server is authoriative
|
||||
}
|
||||
|
||||
// No more kicks below this line, we can now start modifying state beyond this function.
|
||||
if (chmappending)
|
||||
chmappending--;
|
||||
|
||||
lastgametype = gametype;
|
||||
gametype = READUINT8(*cp);
|
||||
|
|
@ -3081,6 +3113,13 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum)
|
|||
else if (gametype != lastgametype)
|
||||
D_GameTypeChanged(lastgametype); // emulate consvar_t behavior for gametype
|
||||
|
||||
if (hasroundqueuedata && roundqueue.position > 0 && roundqueue.size > 0)
|
||||
{
|
||||
// ...we can evaluate CURRENT specifics for roundqueue data, though.
|
||||
roundqueue.entries[roundqueue.position-1].gametype = gametype;
|
||||
roundqueue.entries[roundqueue.position-1].encore = pencoremode;
|
||||
}
|
||||
|
||||
if (!(gametyperules & GTR_ENCORE))
|
||||
pencoremode = false;
|
||||
|
||||
|
|
|
|||
|
|
@ -4173,6 +4173,9 @@ static void G_GetNextMap(void)
|
|||
forceresetplayers = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure the next D_MapChange sends updated roundqueue state.
|
||||
roundqueue.netcommunicate = true;
|
||||
}
|
||||
else if (grandprixinfo.gp == true)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ extern struct roundqueue
|
|||
UINT8 roundnum; // Visible number on HUD
|
||||
UINT8 position; // Head position in the round queue
|
||||
UINT8 size; // Number of entries in the round queue
|
||||
boolean netcommunicate; // As server, should we net-communicate this in XD_MAP?
|
||||
roundentry_t entries[ROUNDQUEUE_MAX]; // Entries in the round queue
|
||||
} roundqueue;
|
||||
|
||||
|
|
|
|||
|
|
@ -138,6 +138,7 @@ void M_CupSelectHandler(INT32 choice)
|
|||
memset(&roundqueue, 0, sizeof(struct roundqueue));
|
||||
G_GPCupIntoRoundQueue(newcup, levellist.newgametype, (boolean)cv_dummygpencore.value);
|
||||
roundqueue.position = roundqueue.roundnum = 1;
|
||||
roundqueue.netcommunicate = true; // relevant for future Online GP
|
||||
|
||||
paused = false;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue