mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-26 06:11:01 +00:00
Big textcmd refactor
Give a length byte for each netcmd to avoid buffer overflow. Send multiple PT_TEXTCMD if localtextcmd is bigger large. Code may be cleaner too I guess. :v
This commit is contained in:
parent
a98b0834a6
commit
5e91c1a5e6
6 changed files with 314 additions and 136 deletions
|
@ -1893,7 +1893,7 @@ static void CV_SetCVar(consvar_t *var, const char *value, boolean stealth)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only add to netcmd buffer if in a netgame, otherwise, just change it.
|
// Only add to netcmd buffer if in a netgame, otherwise, just change it.
|
||||||
if (netgame || multiplayer)
|
if (netgame && Playing())
|
||||||
{
|
{
|
||||||
WRITEUINT16(p, var->netid);
|
WRITEUINT16(p, var->netid);
|
||||||
WRITESTRING(p, value);
|
WRITESTRING(p, value);
|
||||||
|
|
417
src/d_clisrv.c
417
src/d_clisrv.c
|
@ -116,15 +116,33 @@ UINT8 adminpassmd5[16];
|
||||||
boolean adminpasswordset = false;
|
boolean adminpasswordset = false;
|
||||||
|
|
||||||
// Client specific
|
// Client specific
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
netcmd_type,
|
||||||
|
netcmd_length,
|
||||||
|
|
||||||
|
NETCMD_HEADER_SIZE
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
UINT8 * buffer;
|
||||||
|
size_t length;
|
||||||
|
size_t size;/* allocated size */
|
||||||
|
} localtextcmd_t;
|
||||||
|
|
||||||
|
static localtextcmd_t localtextcmd;
|
||||||
|
static localtextcmd_t localtextcmd2; // that's tails
|
||||||
|
|
||||||
static ticcmd_t localcmds;
|
static ticcmd_t localcmds;
|
||||||
static ticcmd_t localcmds2;
|
static ticcmd_t localcmds2;
|
||||||
|
|
||||||
static boolean cl_packetmissed;
|
static boolean cl_packetmissed;
|
||||||
// here it is for the secondary local player (splitscreen)
|
// here it is for the secondary local player (splitscreen)
|
||||||
static UINT8 mynode; // my address pointofview server
|
static UINT8 mynode; // my address pointofview server
|
||||||
static boolean cl_redownloadinggamestate = false;
|
static boolean cl_redownloadinggamestate = false;
|
||||||
|
|
||||||
static UINT8 localtextcmd[MAXTEXTCMD];
|
|
||||||
static UINT8 localtextcmd2[MAXTEXTCMD]; // splitscreen
|
|
||||||
static tic_t neededtic;
|
static tic_t neededtic;
|
||||||
SINT8 servernode = 0; // the number of the server node
|
SINT8 servernode = 0; // the number of the server node
|
||||||
/// \brief do we accept new players?
|
/// \brief do we accept new players?
|
||||||
|
@ -139,6 +157,7 @@ boolean acceptnewnode = true;
|
||||||
typedef struct textcmdplayer_s
|
typedef struct textcmdplayer_s
|
||||||
{
|
{
|
||||||
INT32 playernum;
|
INT32 playernum;
|
||||||
|
UINT8 length;
|
||||||
UINT8 cmd[MAXTEXTCMD];
|
UINT8 cmd[MAXTEXTCMD];
|
||||||
struct textcmdplayer_s *next;
|
struct textcmdplayer_s *next;
|
||||||
} textcmdplayer_t;
|
} textcmdplayer_t;
|
||||||
|
@ -230,44 +249,85 @@ void RegisterNetXCmd(netxcmd_t id, void (*cmd_f)(UINT8 **p, INT32 playernum))
|
||||||
listnetxcmd[id] = cmd_f;
|
listnetxcmd[id] = cmd_f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static UINT8 * ResizeTextcmd (localtextcmd_t * textcmd, size_t extra)
|
||||||
|
{
|
||||||
|
extra = textcmd->length + extra;
|
||||||
|
|
||||||
|
if (extra > textcmd->size)
|
||||||
|
{
|
||||||
|
Z_Realloc
|
||||||
|
(
|
||||||
|
textcmd->buffer,
|
||||||
|
( textcmd->size = extra ),
|
||||||
|
PU_STATIC,
|
||||||
|
&textcmd->buffer
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return &textcmd->buffer[textcmd->length];
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SendNetXCmdInternal
|
||||||
|
(
|
||||||
|
localtextcmd_t * textcmd,
|
||||||
|
netxcmd_t id,
|
||||||
|
const void * payload,
|
||||||
|
size_t length
|
||||||
|
){
|
||||||
|
const size_t total = NETCMD_HEADER_SIZE + length;
|
||||||
|
|
||||||
|
UINT8 * next;
|
||||||
|
|
||||||
|
I_Assert(payload != NULL && length > 0);
|
||||||
|
|
||||||
|
if (textcmd->length + total > textcmd->size)
|
||||||
|
{
|
||||||
|
CONS_Debug(DBG_NETPLAY,
|
||||||
|
"NetXCmd buffer full, allocating extra buffer for netcmd %d!"
|
||||||
|
"(size: %s, needed: %s)\n",
|
||||||
|
id, sizeu1(textcmd->length), sizeu2(total));
|
||||||
|
|
||||||
|
ResizeTextcmd(textcmd, total);
|
||||||
|
}
|
||||||
|
|
||||||
|
next = &textcmd->buffer[textcmd->length];
|
||||||
|
|
||||||
|
textcmd->length += total;
|
||||||
|
|
||||||
|
next[netcmd_type] = id;
|
||||||
|
next[netcmd_length] = length;
|
||||||
|
|
||||||
|
memcpy(&next[NETCMD_HEADER_SIZE], payload, length);
|
||||||
|
}
|
||||||
|
|
||||||
void SendNetXCmd(netxcmd_t id, const void *param, size_t nparam)
|
void SendNetXCmd(netxcmd_t id, const void *param, size_t nparam)
|
||||||
{
|
{
|
||||||
if (localtextcmd[0]+2+nparam > MAXTEXTCMD)
|
SendNetXCmdInternal(&localtextcmd, id, param, nparam);
|
||||||
{
|
|
||||||
// for future reference: if (cv_debug) != debug disabled.
|
|
||||||
CONS_Alert(CONS_ERROR, M_GetText("NetXCmd buffer full, cannot add netcmd %d! (size: %d, needed: %s)\n"), id, localtextcmd[0], sizeu1(nparam));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
localtextcmd[0]++;
|
|
||||||
localtextcmd[localtextcmd[0]] = (UINT8)id;
|
|
||||||
if (param && nparam)
|
|
||||||
{
|
|
||||||
M_Memcpy(&localtextcmd[localtextcmd[0]+1], param, nparam);
|
|
||||||
localtextcmd[0] = (UINT8)(localtextcmd[0] + (UINT8)nparam);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// splitscreen player
|
// splitscreen player
|
||||||
void SendNetXCmd2(netxcmd_t id, const void *param, size_t nparam)
|
void SendNetXCmd2(netxcmd_t id, const void *param, size_t nparam)
|
||||||
{
|
{
|
||||||
if (localtextcmd2[0]+2+nparam > MAXTEXTCMD)
|
SendNetXCmdInternal(&localtextcmd2, id, param, nparam);
|
||||||
{
|
|
||||||
I_Error("No more place in the buffer for netcmd %d\n",id);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
localtextcmd2[0]++;
|
|
||||||
localtextcmd2[localtextcmd2[0]] = (UINT8)id;
|
|
||||||
if (param && nparam)
|
|
||||||
{
|
|
||||||
M_Memcpy(&localtextcmd2[localtextcmd2[0]+1], param, nparam);
|
|
||||||
localtextcmd2[0] = (UINT8)(localtextcmd2[0] + (UINT8)nparam);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT8 GetFreeXCmdSize(void)
|
static void ResetLocalTextcmd (localtextcmd_t * textcmd)
|
||||||
{
|
{
|
||||||
// -1 for the size and another -1 for the ID.
|
if (textcmd->size > MAXTEXTCMD)
|
||||||
return (UINT8)(localtextcmd[0] - 2);
|
{
|
||||||
|
if (textcmd->length < textcmd->size)
|
||||||
|
{
|
||||||
|
Z_Realloc(textcmd->buffer, MAXTEXTCMD, PU_STATIC, &textcmd->buffer);
|
||||||
|
textcmd->size = MAXTEXTCMD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (textcmd->size < MAXTEXTCMD)
|
||||||
|
{
|
||||||
|
Z_Malloc(MAXTEXTCMD, PU_STATIC, &textcmd->buffer);
|
||||||
|
textcmd->size = MAXTEXTCMD;
|
||||||
|
}
|
||||||
|
|
||||||
|
textcmd->length = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Frees all textcmd memory for the specified tic
|
// Frees all textcmd memory for the specified tic
|
||||||
|
@ -308,7 +368,7 @@ static void D_FreeTextcmd(tic_t tic)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets the buffer for the specified ticcmd, or NULL if there isn't one
|
// Gets the buffer for the specified ticcmd, or NULL if there isn't one
|
||||||
static UINT8* D_GetExistingTextcmd(tic_t tic, INT32 playernum)
|
static textcmdplayer_t * D_GetExistingTextcmd(tic_t tic, INT32 playernum)
|
||||||
{
|
{
|
||||||
textcmdtic_t *textcmdtic = textcmds[tic & (TEXTCMD_HASH_SIZE - 1)];
|
textcmdtic_t *textcmdtic = textcmds[tic & (TEXTCMD_HASH_SIZE - 1)];
|
||||||
while (textcmdtic && textcmdtic->tic != tic) textcmdtic = textcmdtic->next;
|
while (textcmdtic && textcmdtic->tic != tic) textcmdtic = textcmdtic->next;
|
||||||
|
@ -319,14 +379,14 @@ static UINT8* D_GetExistingTextcmd(tic_t tic, INT32 playernum)
|
||||||
textcmdplayer_t *textcmdplayer = textcmdtic->playercmds[playernum & (TEXTCMD_HASH_SIZE - 1)];
|
textcmdplayer_t *textcmdplayer = textcmdtic->playercmds[playernum & (TEXTCMD_HASH_SIZE - 1)];
|
||||||
while (textcmdplayer && textcmdplayer->playernum != playernum) textcmdplayer = textcmdplayer->next;
|
while (textcmdplayer && textcmdplayer->playernum != playernum) textcmdplayer = textcmdplayer->next;
|
||||||
|
|
||||||
if (textcmdplayer) return textcmdplayer->cmd;
|
return textcmdplayer;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets the buffer for the specified ticcmd, creating one if necessary
|
// Gets the buffer for the specified ticcmd, creating one if necessary
|
||||||
static UINT8* D_GetTextcmd(tic_t tic, INT32 playernum)
|
static textcmdplayer_t * D_GetTextcmd(tic_t tic, INT32 playernum)
|
||||||
{
|
{
|
||||||
textcmdtic_t *textcmdtic = textcmds[tic & (TEXTCMD_HASH_SIZE - 1)];
|
textcmdtic_t *textcmdtic = textcmds[tic & (TEXTCMD_HASH_SIZE - 1)];
|
||||||
textcmdtic_t **tctprev = &textcmds[tic & (TEXTCMD_HASH_SIZE - 1)];
|
textcmdtic_t **tctprev = &textcmds[tic & (TEXTCMD_HASH_SIZE - 1)];
|
||||||
|
@ -363,45 +423,79 @@ static UINT8* D_GetTextcmd(tic_t tic, INT32 playernum)
|
||||||
textcmdplayer->playernum = playernum;
|
textcmdplayer->playernum = playernum;
|
||||||
}
|
}
|
||||||
|
|
||||||
return textcmdplayer->cmd;
|
return textcmdplayer;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ConsistencyKick(UINT8 player)
|
||||||
|
{
|
||||||
|
if (server)
|
||||||
|
{
|
||||||
|
SendKick(player, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ExtraDataTicker(void)
|
static void ExtraDataTicker(void)
|
||||||
{
|
{
|
||||||
INT32 i;
|
INT32 player;
|
||||||
|
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
for (player = 0; player < MAXPLAYERS; player++)
|
||||||
if (playeringame[i] || i == 0)
|
if (playeringame[player] || player == 0)
|
||||||
{
|
{
|
||||||
UINT8 *bufferstart = D_GetExistingTextcmd(gametic, i);
|
textcmdplayer_t * textcmd = D_GetExistingTextcmd(gametic, player);
|
||||||
|
|
||||||
if (bufferstart)
|
if (textcmd != NULL)
|
||||||
{
|
{
|
||||||
UINT8 *curpos = bufferstart;
|
UINT8 *curpos = textcmd->cmd;
|
||||||
UINT8 *bufferend = &curpos[curpos[0]+1];
|
UINT8 *bufferend = &curpos[textcmd->length];
|
||||||
|
|
||||||
curpos++;
|
while (curpos + NETCMD_HEADER_SIZE < bufferend)
|
||||||
while (curpos < bufferend)
|
|
||||||
{
|
{
|
||||||
if (*curpos < MAXNETXCMD && listnetxcmd[*curpos])
|
const UINT8 id = curpos[netcmd_type];
|
||||||
|
const UINT8 length = curpos[netcmd_length];
|
||||||
|
|
||||||
|
if (id < MAXNETXCMD && listnetxcmd[id])
|
||||||
{
|
{
|
||||||
const UINT8 id = *curpos;
|
curpos += NETCMD_HEADER_SIZE + length;
|
||||||
curpos++;
|
|
||||||
DEBFILE(va("executing x_cmd %s ply %u ", netxcmdnames[id - 1], i));
|
if (curpos > bufferend)
|
||||||
(listnetxcmd[id])(&curpos, i);
|
{
|
||||||
|
CONS_Alert(CONS_WARNING,
|
||||||
|
"Net command from player %d reports larger"
|
||||||
|
" payload than is present (%d > %s)\n",
|
||||||
|
player, length, sizeu1( bufferend - curpos ));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBFILE(va("executing x_cmd %s ply %u ", netxcmdnames[id - 1], player));
|
||||||
|
|
||||||
|
// TODO: bounds check in netcmd handler
|
||||||
|
#if 0
|
||||||
|
if ((listnetxcmd[id])(&curpos[-(length)], length, player))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
UINT8 * poopoopeepee = &curpos[-(length)];
|
||||||
|
(listnetxcmd[id])(&poopoopeepee, player);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
DEBFILE("done\n");
|
DEBFILE("done\n");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (server)
|
CONS_Alert(CONS_WARNING,
|
||||||
{
|
"Got unknown net command %d from player %d\n",
|
||||||
SendKick(i, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
id, player);
|
||||||
DEBFILE(va("player %d kicked [gametic=%u] reason as follows:\n", i, gametic));
|
|
||||||
}
|
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("Got unknown net command [%s]=%d (max %d)\n"), sizeu1(curpos - bufferstart), *curpos, bufferstart[0]);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (curpos < bufferend)
|
||||||
|
{
|
||||||
|
ConsistencyKick(player);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3567,8 +3661,8 @@ void SV_StopServer(void)
|
||||||
Y_EndIntermission();
|
Y_EndIntermission();
|
||||||
gamestate = wipegamestate = GS_NULL;
|
gamestate = wipegamestate = GS_NULL;
|
||||||
|
|
||||||
localtextcmd[0] = 0;
|
ResetLocalTextcmd(&localtextcmd);
|
||||||
localtextcmd2[0] = 0;
|
ResetLocalTextcmd(&localtextcmd2);
|
||||||
|
|
||||||
for (i = firstticstosend; i < firstticstosend + BACKUPTICS; i++)
|
for (i = firstticstosend; i < firstticstosend + BACKUPTICS; i++)
|
||||||
D_Clearticcmd(i);
|
D_Clearticcmd(i);
|
||||||
|
@ -3604,17 +3698,17 @@ static void SV_SendRefuse(INT32 node, const char *reason)
|
||||||
Net_CloseConnection(node);
|
Net_CloseConnection(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
// used at txtcmds received to check packetsize bound
|
// used at textcmds received to check packetsize bound
|
||||||
static size_t TotalTextCmdPerTic(tic_t tic)
|
static size_t TotalTextCmdPerTic(tic_t tic)
|
||||||
{
|
{
|
||||||
INT32 i;
|
INT32 i;
|
||||||
size_t total = 1; // num of textcmds in the tic (ntextcmd byte)
|
size_t total = 0; // length of textcmds in the tic
|
||||||
|
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
{
|
{
|
||||||
UINT8 *textcmd = D_GetExistingTextcmd(tic, i);
|
const textcmdplayer_t * textcmd = D_GetExistingTextcmd(tic, i);
|
||||||
if ((!i || playeringame[i]) && textcmd)
|
if ((!i || playeringame[i]) && textcmd)
|
||||||
total += 2 + textcmd[0]; // "+2" for size and playernum
|
total += textcmd->length;
|
||||||
}
|
}
|
||||||
|
|
||||||
return total;
|
return total;
|
||||||
|
@ -4009,13 +4103,11 @@ static void HandlePacketFromPlayer(SINT8 node)
|
||||||
{
|
{
|
||||||
INT32 netconsole;
|
INT32 netconsole;
|
||||||
tic_t realend, realstart;
|
tic_t realend, realstart;
|
||||||
UINT8 *pak, *txtpak, numtxtpak;
|
UINT8 *pak, *txtpak, *endtxtpak;
|
||||||
#ifndef NOMD5
|
#ifndef NOMD5
|
||||||
UINT8 finalmd5[16];/* Well, it's the cool thing to do? */
|
UINT8 finalmd5[16];/* Well, it's the cool thing to do? */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
txtpak = NULL;
|
|
||||||
|
|
||||||
if (dedicated && node == 0)
|
if (dedicated && node == 0)
|
||||||
netconsole = 0;
|
netconsole = 0;
|
||||||
else
|
else
|
||||||
|
@ -4134,11 +4226,13 @@ static void HandlePacketFromPlayer(SINT8 node)
|
||||||
{
|
{
|
||||||
size_t j;
|
size_t j;
|
||||||
tic_t tic = maketic;
|
tic_t tic = maketic;
|
||||||
UINT8 *textcmd;
|
textcmdplayer_t * textcmd;
|
||||||
|
|
||||||
|
const int length = ( doomcom->datalength - BASEPACKETSIZE );
|
||||||
|
|
||||||
// ignore if the textcmd has a reported size of zero
|
// ignore if the textcmd has a reported size of zero
|
||||||
// this shouldn't be sent at all
|
// this shouldn't be sent at all
|
||||||
if (!netbuffer->u.textcmd[0])
|
if (! length)
|
||||||
{
|
{
|
||||||
DEBFILE(va("GetPacket: Textcmd with size 0 detected! (node %u, player %d)\n",
|
DEBFILE(va("GetPacket: Textcmd with size 0 detected! (node %u, player %d)\n",
|
||||||
node, netconsole));
|
node, netconsole));
|
||||||
|
@ -4146,26 +4240,15 @@ static void HandlePacketFromPlayer(SINT8 node)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ignore if the textcmd size var is actually larger than it should be
|
|
||||||
// BASEPACKETSIZE + 1 (for size) + textcmd[0] should == datalength
|
|
||||||
if (netbuffer->u.textcmd[0] > (size_t)doomcom->datalength-BASEPACKETSIZE-1)
|
|
||||||
{
|
|
||||||
DEBFILE(va("GetPacket: Bad Textcmd packet size! (expected %d, actual %s, node %u, player %d)\n",
|
|
||||||
netbuffer->u.textcmd[0], sizeu1((size_t)doomcom->datalength-BASEPACKETSIZE-1),
|
|
||||||
node, netconsole));
|
|
||||||
Net_UnAcknowledgePacket(node);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if tic that we are making isn't too large else we cannot send it :(
|
// check if tic that we are making isn't too large else we cannot send it :(
|
||||||
// doomcom->numslots+1 "+1" since doomcom->numslots can change within this time and sent time
|
// doomcom->numslots+1 "+1" since doomcom->numslots can change within this time and sent time
|
||||||
j = software_MAXPACKETLENGTH
|
j = software_MAXPACKETLENGTH
|
||||||
- (netbuffer->u.textcmd[0]+2+BASESERVERTICSSIZE
|
- (length + BASESERVERTICSSIZE
|
||||||
+ (doomcom->numslots+1)*sizeof(ticcmd_t));
|
+ (doomcom->numslots +1 ) * sizeof(ticcmd_t));
|
||||||
|
|
||||||
// search a tic that have enougth space in the ticcmd
|
// search a tic that have enougth space in the ticcmd
|
||||||
while ((textcmd = D_GetExistingTextcmd(tic, netconsole)),
|
while ((textcmd = D_GetExistingTextcmd(tic, netconsole)),
|
||||||
(TotalTextCmdPerTic(tic) > j || netbuffer->u.textcmd[0] + (textcmd ? textcmd[0] : 0) > MAXTEXTCMD)
|
(TotalTextCmdPerTic(tic) > j || length + (textcmd ? textcmd->length : 0) > MAXTEXTCMD)
|
||||||
&& tic < firstticstosend + BACKUPTICS)
|
&& tic < firstticstosend + BACKUPTICS)
|
||||||
tic++;
|
tic++;
|
||||||
|
|
||||||
|
@ -4181,11 +4264,17 @@ static void HandlePacketFromPlayer(SINT8 node)
|
||||||
// Make sure we have a buffer
|
// Make sure we have a buffer
|
||||||
if (!textcmd) textcmd = D_GetTextcmd(tic, netconsole);
|
if (!textcmd) textcmd = D_GetTextcmd(tic, netconsole);
|
||||||
|
|
||||||
DEBFILE(va("textcmd put in tic %u at position %d (player %d) ftts %u mk %u\n",
|
DEBFILE(va("textcmd put in tic %u at position %s (player %d) ftts %u mk %u\n",
|
||||||
tic, textcmd[0]+1, netconsole, firstticstosend, maketic));
|
tic, sizeu1(textcmd->length), netconsole, firstticstosend, maketic));
|
||||||
|
|
||||||
M_Memcpy(&textcmd[textcmd[0]+1], netbuffer->u.textcmd+1, netbuffer->u.textcmd[0]);
|
memcpy
|
||||||
textcmd[0] += (UINT8)netbuffer->u.textcmd[0];
|
(
|
||||||
|
&textcmd->cmd[textcmd->length],
|
||||||
|
netbuffer->u.textcmd,
|
||||||
|
length
|
||||||
|
);
|
||||||
|
|
||||||
|
textcmd->length += length;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PT_LOGIN:
|
case PT_LOGIN:
|
||||||
|
@ -4275,9 +4364,8 @@ static void HandlePacketFromPlayer(SINT8 node)
|
||||||
realstart = netbuffer->u.serverpak.starttic;
|
realstart = netbuffer->u.serverpak.starttic;
|
||||||
realend = realstart + netbuffer->u.serverpak.numtics;
|
realend = realstart + netbuffer->u.serverpak.numtics;
|
||||||
|
|
||||||
if (!txtpak)
|
txtpak = (UINT8 *)&netbuffer->u.serverpak.cmds[netbuffer->u.serverpak.numslots
|
||||||
txtpak = (UINT8 *)&netbuffer->u.serverpak.cmds[netbuffer->u.serverpak.numslots
|
* netbuffer->u.serverpak.numtics];
|
||||||
* netbuffer->u.serverpak.numtics];
|
|
||||||
|
|
||||||
if (realend > gametic + CLIENTBACKUPTICS)
|
if (realend > gametic + CLIENTBACKUPTICS)
|
||||||
realend = gametic + CLIENTBACKUPTICS;
|
realend = gametic + CLIENTBACKUPTICS;
|
||||||
|
@ -4285,7 +4373,7 @@ static void HandlePacketFromPlayer(SINT8 node)
|
||||||
|
|
||||||
if (realstart <= neededtic && realend > neededtic)
|
if (realstart <= neededtic && realend > neededtic)
|
||||||
{
|
{
|
||||||
tic_t i, j;
|
tic_t i;
|
||||||
pak = (UINT8 *)&netbuffer->u.serverpak.cmds;
|
pak = (UINT8 *)&netbuffer->u.serverpak.cmds;
|
||||||
|
|
||||||
for (i = realstart; i < realend; i++)
|
for (i = realstart; i < realend; i++)
|
||||||
|
@ -4298,15 +4386,26 @@ static void HandlePacketFromPlayer(SINT8 node)
|
||||||
netbuffer->u.serverpak.numslots*sizeof (ticcmd_t));
|
netbuffer->u.serverpak.numslots*sizeof (ticcmd_t));
|
||||||
|
|
||||||
// copy the textcmds
|
// copy the textcmds
|
||||||
numtxtpak = *txtpak++;
|
endtxtpak = txtpak;
|
||||||
for (j = 0; j < numtxtpak; j++)
|
endtxtpak += READUINT16 (txtpak);
|
||||||
{
|
|
||||||
INT32 k = *txtpak++; // playernum
|
|
||||||
const size_t txtsize = txtpak[0]+1;
|
|
||||||
|
|
||||||
if (i >= gametic) // Don't copy old net commands
|
if (i < gametic) // Don't copy old net commands
|
||||||
M_Memcpy(D_GetTextcmd(i, k), txtpak, txtsize);
|
{
|
||||||
txtpak += txtsize;
|
txtpak = endtxtpak;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while (txtpak < endtxtpak)
|
||||||
|
{
|
||||||
|
INT32 k = *txtpak++; // playernum
|
||||||
|
const size_t txtsize = READUINT16(txtpak);
|
||||||
|
textcmdplayer_t * textcmd = D_GetTextcmd(i, k);
|
||||||
|
|
||||||
|
memcpy(textcmd->cmd, txtpak, txtsize);
|
||||||
|
textcmd->length = txtsize;
|
||||||
|
|
||||||
|
txtpak += txtsize;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4547,6 +4646,98 @@ static INT16 Consistancy(void)
|
||||||
return (INT16)(ret & 0xFFFF);
|
return (INT16)(ret & 0xFFFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int NetxcmdLength(const UINT8 *netcmd)
|
||||||
|
{
|
||||||
|
return NETCMD_HEADER_SIZE + netcmd[netcmd_length];
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean
|
||||||
|
SendTextcmdPacket
|
||||||
|
(
|
||||||
|
localtextcmd_t * textcmd,
|
||||||
|
const size_t start,
|
||||||
|
const int length
|
||||||
|
){
|
||||||
|
memcpy(netbuffer->u.textcmd, &textcmd->buffer[start], length);
|
||||||
|
|
||||||
|
if (HSendPacket(servernode, true, 0, length))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (start > 0)
|
||||||
|
{
|
||||||
|
memmove
|
||||||
|
(
|
||||||
|
textcmd->buffer,
|
||||||
|
&textcmd->buffer[start],
|
||||||
|
( textcmd->length -= start )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
CL_SendTextcmd
|
||||||
|
(
|
||||||
|
int packettype,
|
||||||
|
localtextcmd_t * textcmd
|
||||||
|
){
|
||||||
|
size_t s;
|
||||||
|
size_t t;
|
||||||
|
|
||||||
|
int textcmdlength;
|
||||||
|
int netcmdlength;
|
||||||
|
|
||||||
|
if (textcmd->length > 0)
|
||||||
|
{
|
||||||
|
netbuffer->packettype = packettype;
|
||||||
|
|
||||||
|
if (textcmd->length > MAXTEXTCMD)
|
||||||
|
{
|
||||||
|
for (s = t = 0U, textcmdlength = 0 ;; )
|
||||||
|
{
|
||||||
|
netcmdlength = NetxcmdLength(&textcmd->buffer[t]);
|
||||||
|
|
||||||
|
if (textcmdlength + netcmdlength > MAXTEXTCMD)
|
||||||
|
{
|
||||||
|
if (SendTextcmdPacket(textcmd, s, textcmdlength))
|
||||||
|
{
|
||||||
|
textcmdlength = 0;
|
||||||
|
s = t;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
textcmdlength += netcmdlength;
|
||||||
|
t += netcmdlength;
|
||||||
|
|
||||||
|
if (t >= textcmd->length)
|
||||||
|
{
|
||||||
|
if (SendTextcmdPacket(textcmd, s, textcmdlength))
|
||||||
|
{
|
||||||
|
ResetLocalTextcmd(textcmd);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (SendTextcmdPacket(textcmd, 0, textcmd->length))
|
||||||
|
{
|
||||||
|
ResetLocalTextcmd(textcmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// send the client packet to the server
|
// send the client packet to the server
|
||||||
static void CL_SendClientCmd(void)
|
static void CL_SendClientCmd(void)
|
||||||
{
|
{
|
||||||
|
@ -4587,24 +4778,10 @@ static void CL_SendClientCmd(void)
|
||||||
if (cl_mode == CL_CONNECTED || dedicated)
|
if (cl_mode == CL_CONNECTED || dedicated)
|
||||||
{
|
{
|
||||||
// Send extra data if needed
|
// Send extra data if needed
|
||||||
if (localtextcmd[0])
|
CL_SendTextcmd(PT_TEXTCMD, &localtextcmd);
|
||||||
{
|
|
||||||
netbuffer->packettype = PT_TEXTCMD;
|
|
||||||
M_Memcpy(netbuffer->u.textcmd,localtextcmd, localtextcmd[0]+1);
|
|
||||||
// All extra data have been sent
|
|
||||||
if (HSendPacket(servernode, true, 0, localtextcmd[0]+1)) // Send can fail...
|
|
||||||
localtextcmd[0] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send extra data if needed for player 2 (splitscreen)
|
// Send extra data if needed for player 2 (splitscreen)
|
||||||
if (localtextcmd2[0])
|
CL_SendTextcmd(PT_TEXTCMD2, &localtextcmd2);
|
||||||
{
|
|
||||||
netbuffer->packettype = PT_TEXTCMD2;
|
|
||||||
M_Memcpy(netbuffer->u.textcmd, localtextcmd2, localtextcmd2[0]+1);
|
|
||||||
// All extra data have been sent
|
|
||||||
if (HSendPacket(servernode, true, 0, localtextcmd2[0]+1)) // Send can fail...
|
|
||||||
localtextcmd2[0] = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4617,7 +4794,7 @@ static void SV_SendTics(void)
|
||||||
INT32 j;
|
INT32 j;
|
||||||
size_t packsize;
|
size_t packsize;
|
||||||
UINT8 *bufpos;
|
UINT8 *bufpos;
|
||||||
UINT8 *ntextcmd;
|
UINT16 *ntextcmd;
|
||||||
|
|
||||||
// send to all client but not to me
|
// send to all client but not to me
|
||||||
// for each node create a packet with x tics and send it
|
// for each node create a packet with x tics and send it
|
||||||
|
@ -4694,19 +4871,23 @@ static void SV_SendTics(void)
|
||||||
// add textcmds
|
// add textcmds
|
||||||
for (i = realfirsttic; i < lasttictosend; i++)
|
for (i = realfirsttic; i < lasttictosend; i++)
|
||||||
{
|
{
|
||||||
ntextcmd = bufpos++;
|
ntextcmd = (UINT16 *)bufpos;
|
||||||
*ntextcmd = 0;
|
*ntextcmd = 0;
|
||||||
|
|
||||||
|
bufpos += sizeof (UINT16);
|
||||||
|
|
||||||
for (j = 0; j < MAXPLAYERS; j++)
|
for (j = 0; j < MAXPLAYERS; j++)
|
||||||
{
|
{
|
||||||
UINT8 *textcmd = D_GetExistingTextcmd(i, j);
|
const textcmdplayer_t * textcmd = D_GetExistingTextcmd(i, j);
|
||||||
INT32 size = textcmd ? textcmd[0] : 0;
|
INT32 size = textcmd ? textcmd->length : 0;
|
||||||
|
|
||||||
if ((!j || playeringame[j]) && size)
|
if ((!j || playeringame[j]) && size)
|
||||||
{
|
{
|
||||||
(*ntextcmd)++;
|
(*ntextcmd) += 3 + size;
|
||||||
WRITEUINT8(bufpos, j);
|
WRITEUINT8(bufpos, j);
|
||||||
M_Memcpy(bufpos, textcmd, size + 1);
|
WRITEUINT16(bufpos, size);
|
||||||
bufpos += size + 1;
|
memcpy(bufpos, textcmd->cmd, size);
|
||||||
|
bufpos += size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -292,7 +292,7 @@ typedef struct
|
||||||
client2cmd_pak client2pak; // 200 bytes
|
client2cmd_pak client2pak; // 200 bytes
|
||||||
servertics_pak serverpak; // 132495 bytes (more around 360, no?)
|
servertics_pak serverpak; // 132495 bytes (more around 360, no?)
|
||||||
serverconfig_pak servercfg; // 773 bytes
|
serverconfig_pak servercfg; // 773 bytes
|
||||||
UINT8 textcmd[MAXTEXTCMD+1]; // 66049 bytes (wut??? 64k??? More like 257 bytes...)
|
UINT8 textcmd[MAXTEXTCMD]; // use sizeof
|
||||||
filetx_pak filetxpak; // 139 bytes
|
filetx_pak filetxpak; // 139 bytes
|
||||||
fileack_pak fileack;
|
fileack_pak fileack;
|
||||||
UINT8 filereceived;
|
UINT8 filereceived;
|
||||||
|
@ -429,7 +429,6 @@ INT32 D_NumPlayers(void);
|
||||||
void D_ResetTiccmds(void);
|
void D_ResetTiccmds(void);
|
||||||
|
|
||||||
tic_t GetLag(INT32 node);
|
tic_t GetLag(INT32 node);
|
||||||
UINT8 GetFreeXCmdSize(void);
|
|
||||||
|
|
||||||
void D_MD5PasswordPass(const UINT8 *buffer, size_t len, const char *salt, void *dest);
|
void D_MD5PasswordPass(const UINT8 *buffer, size_t len, const char *salt, void *dest);
|
||||||
|
|
||||||
|
|
|
@ -402,14 +402,15 @@ const char *netxcmdnames[MAXNETXCMD - 1] =
|
||||||
"ADDPLAYER",
|
"ADDPLAYER",
|
||||||
"TEAMCHANGE",
|
"TEAMCHANGE",
|
||||||
"CLEARSCORES",
|
"CLEARSCORES",
|
||||||
"LOGIN",
|
"",
|
||||||
"VERIFIED",
|
"VERIFIED",
|
||||||
"RANDOMSEED",
|
"RANDOMSEED",
|
||||||
"RUNSOC",
|
"RUNSOC",
|
||||||
"REQADDFILE",
|
"REQADDFILE",
|
||||||
"DELFILE", // replace next time we add an XD
|
"",
|
||||||
"SETMOTD",
|
"SETMOTD",
|
||||||
"SUICIDE",
|
"SUICIDE",
|
||||||
|
"DEMOTED",
|
||||||
"LUACMD",
|
"LUACMD",
|
||||||
"LUAVAR",
|
"LUAVAR",
|
||||||
"LUAFILE"
|
"LUAFILE"
|
||||||
|
@ -1527,6 +1528,9 @@ void SendWeaponPref(void)
|
||||||
{
|
{
|
||||||
UINT8 buf[1];
|
UINT8 buf[1];
|
||||||
|
|
||||||
|
if (!Playing())
|
||||||
|
return;
|
||||||
|
|
||||||
buf[0] = 0;
|
buf[0] = 0;
|
||||||
if (cv_flipcam.value)
|
if (cv_flipcam.value)
|
||||||
buf[0] |= 1;
|
buf[0] |= 1;
|
||||||
|
@ -1543,6 +1547,9 @@ void SendWeaponPref2(void)
|
||||||
{
|
{
|
||||||
UINT8 buf[1];
|
UINT8 buf[1];
|
||||||
|
|
||||||
|
if (!Playing())
|
||||||
|
return;
|
||||||
|
|
||||||
buf[0] = 0;
|
buf[0] = 0;
|
||||||
if (cv_flipcam2.value)
|
if (cv_flipcam2.value)
|
||||||
buf[0] |= 1;
|
buf[0] |= 1;
|
||||||
|
|
|
@ -118,6 +118,7 @@ extern boolean timedemo_quit;
|
||||||
|
|
||||||
extern consvar_t cv_freedemocamera;
|
extern consvar_t cv_freedemocamera;
|
||||||
|
|
||||||
|
/* there is a netxcmdnames array to keep updated too if you weren't aware! */
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
XD_NAMEANDCOLOR = 1,
|
XD_NAMEANDCOLOR = 1,
|
||||||
|
@ -132,13 +133,13 @@ typedef enum
|
||||||
XD_ADDPLAYER, // 10
|
XD_ADDPLAYER, // 10
|
||||||
XD_TEAMCHANGE, // 11
|
XD_TEAMCHANGE, // 11
|
||||||
XD_CLEARSCORES, // 12
|
XD_CLEARSCORES, // 12
|
||||||
// UNUSED 13 (Because I don't want to change these comments)
|
// UNUSED 13 (new netcmd goes here)
|
||||||
XD_VERIFIED = 14,//14
|
XD_VERIFIED = 14,//14
|
||||||
XD_RANDOMSEED, // 15
|
XD_RANDOMSEED, // 15
|
||||||
XD_RUNSOC, // 16
|
XD_RUNSOC, // 16
|
||||||
XD_REQADDFILE, // 17
|
XD_REQADDFILE, // 17
|
||||||
XD_DELFILE, // 18 - replace next time we add an XD
|
// UNUSED 18 (new netcmd goes here)
|
||||||
XD_SETMOTD, // 19
|
XD_SETMOTD = 19,// 19
|
||||||
XD_SUICIDE, // 20
|
XD_SUICIDE, // 20
|
||||||
XD_DEMOTED, // 21
|
XD_DEMOTED, // 21
|
||||||
XD_LUACMD, // 22
|
XD_LUACMD, // 22
|
||||||
|
|
10
src/p_tick.c
10
src/p_tick.c
|
@ -355,11 +355,6 @@ static void P_DoAutobalanceTeams(void)
|
||||||
memset(redarray, 0, sizeof(redarray));
|
memset(redarray, 0, sizeof(redarray));
|
||||||
memset(bluearray, 0, sizeof(bluearray));
|
memset(bluearray, 0, sizeof(bluearray));
|
||||||
|
|
||||||
// Only do it if we have enough room in the net buffer to send it.
|
|
||||||
// Otherwise, come back next time and try again.
|
|
||||||
if (sizeof(usvalue) > GetFreeXCmdSize())
|
|
||||||
return;
|
|
||||||
|
|
||||||
//We have to store the players in an array with the rest of their team.
|
//We have to store the players in an array with the rest of their team.
|
||||||
//We can then pick a random player to be forced to change teams.
|
//We can then pick a random player to be forced to change teams.
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
|
@ -431,11 +426,6 @@ void P_DoTeamscrambling(void)
|
||||||
UINT16 usvalue;
|
UINT16 usvalue;
|
||||||
NetPacket.value.l = NetPacket.value.b = 0;
|
NetPacket.value.l = NetPacket.value.b = 0;
|
||||||
|
|
||||||
// Only do it if we have enough room in the net buffer to send it.
|
|
||||||
// Otherwise, come back next time and try again.
|
|
||||||
if (sizeof(usvalue) > GetFreeXCmdSize())
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (scramblecount < scrambletotal)
|
if (scramblecount < scrambletotal)
|
||||||
{
|
{
|
||||||
if (players[scrambleplayers[scramblecount]].ctfteam != scrambleteams[scramblecount])
|
if (players[scrambleplayers[scramblecount]].ctfteam != scrambleteams[scramblecount])
|
||||||
|
|
Loading…
Reference in a new issue