mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
XD_REQMAPQUEUE --> PT_REQMAPQUEUE
It was technically possible for custom clients to spoil future rounds of a tournament queued while they are connected to a server. Making it a PT direct packet to the servernode both solves this problem AND reduces irrelevant NetXCmd traffic for clients.
This commit is contained in:
parent
8bd50ddb65
commit
512ec6c2eb
5 changed files with 106 additions and 74 deletions
|
|
@ -4772,6 +4772,86 @@ static void PT_Say(int node)
|
|||
DoSayCommand(say.message, say.target, say.flags, say.source);
|
||||
}
|
||||
|
||||
static void PT_ReqMapQueue(int node)
|
||||
{
|
||||
if (client)
|
||||
return; // Only sent to servers, why are we receiving this?
|
||||
|
||||
reqmapqueue_pak reqmapqueue = netbuffer->u.reqmapqueue;
|
||||
|
||||
// Check for a spoofed source.
|
||||
if (reqmapqueue.source == serverplayer)
|
||||
{
|
||||
// Servers aren't guaranteed to have a playernode, dedis exist.
|
||||
if (node != servernode)
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (playernode[reqmapqueue.source] != node)
|
||||
return;
|
||||
|
||||
if (!IsPlayerAdmin(reqmapqueue.source))
|
||||
{
|
||||
CONS_Debug(DBG_NETPLAY,"Received illegal request map queue cmd from Player %d (%s).\n", reqmapqueue.source+1, player_names[reqmapqueue.source]);
|
||||
SendKick(reqmapqueue.source, KICK_MSG_CON_FAIL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const boolean doclear = (reqmapqueue.newgametype == ROUNDQUEUE_CLEAR);
|
||||
|
||||
// The following prints will only appear when multiple clients
|
||||
// attempt to affect the round queue at similar time increments
|
||||
if (doclear == true)
|
||||
{
|
||||
if (roundqueue.size == 0)
|
||||
{
|
||||
// therefore this one doesn't really need a error print
|
||||
// because what both players wanted was done anyways
|
||||
//CONS_Alert(CONS_ERROR, "queuemap: Queue is already empty!\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (roundqueue.size >= ROUNDQUEUE_MAX)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, "Recieved REQMAPQUEUE, but unable to add map beyond %u\n", roundqueue.size);
|
||||
|
||||
// But this one does, because otherwise it's silent failure!
|
||||
// Todo print the map's name, maybe?
|
||||
char rejectmsg[256];
|
||||
strlcpy(rejectmsg, "The server couldn't queue your chosen map.", 256);
|
||||
SendServerNotice(reqmapqueue.source, rejectmsg);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
UINT8 buf[1+2+1];
|
||||
UINT8 *buf_p = buf;
|
||||
|
||||
WRITEUINT8(buf_p, reqmapqueue.flags);
|
||||
WRITEUINT16(buf_p, reqmapqueue.newgametype);
|
||||
|
||||
WRITEUINT8(buf_p, roundqueue.size);
|
||||
|
||||
// Match Got_MapQueuecmd, but with the addition of reqmapqueue.newmapnum available to us
|
||||
if (doclear == true)
|
||||
{
|
||||
memset(&roundqueue, 0, sizeof(struct roundqueue));
|
||||
}
|
||||
else
|
||||
{
|
||||
G_MapIntoRoundQueue(
|
||||
reqmapqueue.newmapnum,
|
||||
reqmapqueue.newgametype,
|
||||
((reqmapqueue.flags & 1) != 0),
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
SendNetXCmd(XD_MAPQUEUE, buf, buf_p - buf);
|
||||
}
|
||||
|
||||
static char NodeToSplitPlayer(int node, int split)
|
||||
{
|
||||
if (split == 0)
|
||||
|
|
@ -5117,6 +5197,9 @@ static void HandlePacketFromPlayer(SINT8 node)
|
|||
case PT_SAY:
|
||||
PT_Say(node);
|
||||
break;
|
||||
case PT_REQMAPQUEUE:
|
||||
PT_ReqMapQueue(node);
|
||||
break;
|
||||
case PT_LOGIN:
|
||||
if (client)
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -135,6 +135,8 @@ typedef enum
|
|||
|
||||
PT_SAY, // "Hey server, please send this chat message to everyone via XD_SAY"
|
||||
|
||||
PT_REQMAPQUEUE, // Client requesting a roundqueue operation
|
||||
|
||||
NUMPACKETTYPE
|
||||
} packettype_t;
|
||||
|
||||
|
|
@ -401,6 +403,14 @@ struct say_pak
|
|||
UINT8 source;
|
||||
} ATTRPACK;
|
||||
|
||||
struct reqmapqueue_pak
|
||||
{
|
||||
UINT16 newmapnum;
|
||||
UINT16 newgametype;
|
||||
UINT8 flags;
|
||||
UINT8 source;
|
||||
} ATTRPACK;
|
||||
|
||||
struct netinfo_pak
|
||||
{
|
||||
UINT32 pingtable[MAXPLAYERS+1];
|
||||
|
|
@ -451,6 +461,7 @@ struct doomdata_t
|
|||
responseall_pak responseall; // 256 bytes
|
||||
resultsall_pak resultsall; // 1024 bytes. Also, you really shouldn't trust anything here.
|
||||
say_pak say; // I don't care anymore.
|
||||
reqmapqueue_pak reqmapqueue; // Formerly XD_REQMAPQUEUE
|
||||
} u; // This is needed to pack diff packet types data together
|
||||
} ATTRPACK;
|
||||
|
||||
|
|
|
|||
|
|
@ -109,7 +109,6 @@ static void Got_DiscordInfo(const UINT8 **cp, INT32 playernum);
|
|||
static void Got_ScheduleTaskcmd(const UINT8 **cp, INT32 playernum);
|
||||
static void Got_ScheduleClearcmd(const UINT8 **cp, INT32 playernum);
|
||||
static void Got_Automatecmd(const UINT8 **cp, INT32 playernum);
|
||||
static void Got_RequestMapQueuecmd(const UINT8 **cp, INT32 playernum);
|
||||
static void Got_MapQueuecmd(const UINT8 **cp, INT32 playernum);
|
||||
static void Got_Cheat(const UINT8 **cp, INT32 playernum);
|
||||
|
||||
|
|
@ -317,7 +316,7 @@ const char *netxcmdnames[MAXNETXCMD - 1] =
|
|||
"SCHEDULETASK", // XD_SCHEDULETASK
|
||||
"SCHEDULECLEAR", // XD_SCHEDULECLEAR
|
||||
"AUTOMATE", // XD_AUTOMATE
|
||||
"REQMAPQUEUE", // XD_REQMAPQUEUE
|
||||
"",
|
||||
"MAPQUEUE", // XD_MAPQUEUE
|
||||
"CALLZVOTE", // XD_CALLZVOTE
|
||||
"SETZVOTE", // XD_SETZVOTE
|
||||
|
|
@ -369,7 +368,6 @@ void D_RegisterServerCommands(void)
|
|||
RegisterNetXCmd(XD_SCHEDULETASK, Got_ScheduleTaskcmd);
|
||||
RegisterNetXCmd(XD_SCHEDULECLEAR, Got_ScheduleClearcmd);
|
||||
RegisterNetXCmd(XD_AUTOMATE, Got_Automatecmd);
|
||||
RegisterNetXCmd(XD_REQMAPQUEUE, Got_RequestMapQueuecmd);
|
||||
RegisterNetXCmd(XD_MAPQUEUE, Got_MapQueuecmd);
|
||||
|
||||
RegisterNetXCmd(XD_CHEAT, Got_Cheat);
|
||||
|
|
@ -2937,42 +2935,26 @@ static void Command_RestartLevel(void)
|
|||
|
||||
static void Handle_MapQueueSend(UINT16 newmapnum, UINT16 newgametype, boolean newencoremode)
|
||||
{
|
||||
static char buf[1+2+2];
|
||||
static char *buf_p = buf;
|
||||
|
||||
UINT8 flags = 0;
|
||||
boolean doclear = (newgametype == ROUNDQUEUE_CLEAR);
|
||||
|
||||
CONS_Debug(DBG_GAMELOGIC, "Map queue: mapnum=%d newgametype=%d newencoremode=%d\n",
|
||||
newmapnum, newgametype, newencoremode);
|
||||
|
||||
buf_p = buf;
|
||||
|
||||
if (newencoremode)
|
||||
flags |= 1;
|
||||
|
||||
WRITEUINT8(buf_p, flags);
|
||||
WRITEUINT16(buf_p, newgametype);
|
||||
netbuffer->packettype = PT_REQMAPQUEUE;
|
||||
|
||||
if (client)
|
||||
{
|
||||
WRITEUINT16(buf_p, newmapnum);
|
||||
SendNetXCmd(XD_REQMAPQUEUE, buf, buf_p - buf);
|
||||
return;
|
||||
}
|
||||
reqmapqueue_pak *reqmapqueue = &netbuffer->u.reqmapqueue;
|
||||
|
||||
WRITEUINT8(buf_p, roundqueue.size);
|
||||
reqmapqueue->newmapnum = newmapnum;
|
||||
reqmapqueue->flags = flags;
|
||||
reqmapqueue->newgametype = newgametype;
|
||||
reqmapqueue->source = consoleplayer;
|
||||
|
||||
if (doclear == true)
|
||||
{
|
||||
memset(&roundqueue, 0, sizeof(struct roundqueue));
|
||||
}
|
||||
else
|
||||
{
|
||||
G_MapIntoRoundQueue(newmapnum, newgametype, newencoremode, false);
|
||||
}
|
||||
HSendPacket(servernode, false, 0, sizeof(reqmapqueue_pak));
|
||||
|
||||
SendNetXCmd(XD_MAPQUEUE, buf, buf_p - buf);
|
||||
// See PT_ReqMapQueue and Got_MapQueuecmd for the next stages
|
||||
}
|
||||
|
||||
static void Command_QueueMap_f(void)
|
||||
|
|
@ -3129,51 +3111,6 @@ static void Command_QueueMap_f(void)
|
|||
Z_Free(mapname);
|
||||
}
|
||||
|
||||
static void Got_RequestMapQueuecmd(const UINT8 **cp, INT32 playernum)
|
||||
{
|
||||
UINT8 flags;
|
||||
boolean setencore;
|
||||
UINT16 mapnumber, setgametype;
|
||||
boolean doclear = false;
|
||||
|
||||
flags = READUINT8(*cp);
|
||||
|
||||
setencore = ((flags & 1) != 0);
|
||||
|
||||
setgametype = READUINT16(*cp);
|
||||
|
||||
mapnumber = READUINT16(*cp);
|
||||
|
||||
if (!IsPlayerAdmin(playernum))
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal request map queue command received from %s\n"), player_names[playernum]);
|
||||
if (server && playernum != serverplayer)
|
||||
SendKick(playernum, KICK_MSG_CON_FAIL);
|
||||
return;
|
||||
}
|
||||
|
||||
doclear = (setgametype == ROUNDQUEUE_CLEAR);
|
||||
|
||||
if (doclear == true)
|
||||
{
|
||||
if (roundqueue.size == 0)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, "queuemap: Queue is already empty!\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (roundqueue.size >= ROUNDQUEUE_MAX)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, "queuemap: Unable to add map beyond %u\n", roundqueue.size);
|
||||
return;
|
||||
}
|
||||
|
||||
if (client)
|
||||
return;
|
||||
|
||||
Handle_MapQueueSend(mapnumber, setgametype, setencore);
|
||||
}
|
||||
|
||||
static void Got_MapQueuecmd(const UINT8 **cp, INT32 playernum)
|
||||
{
|
||||
UINT8 flags, queueposition, i;
|
||||
|
|
|
|||
|
|
@ -180,8 +180,8 @@ typedef enum
|
|||
XD_SCHEDULETASK, // 34
|
||||
XD_SCHEDULECLEAR, // 35
|
||||
XD_AUTOMATE, // 36
|
||||
XD_REQMAPQUEUE, // 37
|
||||
XD_MAPQUEUE, // 38
|
||||
// 37 is free
|
||||
XD_MAPQUEUE = XD_AUTOMATE+2, // 38
|
||||
XD_CALLZVOTE, // 39
|
||||
XD_SETZVOTE, // 40
|
||||
XD_TEAMCHANGE, // 41
|
||||
|
|
|
|||
|
|
@ -83,6 +83,7 @@ TYPEDEF (challengeall_pak);
|
|||
TYPEDEF (responseall_pak);
|
||||
TYPEDEF (resultsall_pak);
|
||||
TYPEDEF (say_pak);
|
||||
TYPEDEF (reqmapqueue_pak);
|
||||
TYPEDEF (netinfo_pak);
|
||||
|
||||
// d_event.h
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue