Merge remote-tracking branch 'origin/fix-playernode-crash' into netcode-tests

This commit is contained in:
Steel Titanium 2020-03-08 13:57:28 -04:00
commit 9b42bb132e
4 changed files with 65 additions and 56 deletions

View file

@ -1289,6 +1289,37 @@ static boolean CL_SendJoin(void)
return HSendPacket(servernode, true, 0, sizeof (clientconfig_pak)); return HSendPacket(servernode, true, 0, sizeof (clientconfig_pak));
} }
static INT32 FindRejoinerNum(SINT8 node)
{
char strippednodeaddress[64];
const char *nodeaddress;
char *port;
INT32 i;
// Make sure there is no dead dress before proceeding to the stripping
if (!I_GetNodeAddress)
return -1;
nodeaddress = I_GetNodeAddress(node);
if (!nodeaddress)
return -1;
// Strip the address of its port
strcpy(strippednodeaddress, nodeaddress);
port = strchr(strippednodeaddress, ':');
if (port)
*port = '\0';
// Check if any player matches the stripped address
for (i = 0; i < MAXPLAYERS; i++)
{
if (playeringame[i] && playeraddress[i][0] && playernode[i] == UINT8_MAX
&& !strcmp(playeraddress[i], strippednodeaddress))
return i;
}
return -1;
}
static void SV_SendServerInfo(INT32 node, tic_t servertime) static void SV_SendServerInfo(INT32 node, tic_t servertime)
{ {
UINT8 *p; UINT8 *p;
@ -1306,6 +1337,16 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime)
netbuffer->u.serverinfo.numberofplayer = (UINT8)D_NumPlayers(); netbuffer->u.serverinfo.numberofplayer = (UINT8)D_NumPlayers();
netbuffer->u.serverinfo.maxplayer = (UINT8)cv_maxplayers.value; netbuffer->u.serverinfo.maxplayer = (UINT8)cv_maxplayers.value;
if (FindRejoinerNum(node) != -1)
netbuffer->u.serverinfo.refusereason = 0;
else if (!cv_allownewplayer.value)
netbuffer->u.serverinfo.refusereason = 1;
else if (D_NumPlayers() >= cv_maxplayers.value)
netbuffer->u.serverinfo.refusereason = 2;
else
netbuffer->u.serverinfo.refusereason = 0;
strncpy(netbuffer->u.serverinfo.gametypename, Gametype_Names[gametype], strncpy(netbuffer->u.serverinfo.gametypename, Gametype_Names[gametype],
sizeof netbuffer->u.serverinfo.gametypename); sizeof netbuffer->u.serverinfo.gametypename);
netbuffer->u.serverinfo.modifiedgame = (UINT8)modifiedgame; netbuffer->u.serverinfo.modifiedgame = (UINT8)modifiedgame;
@ -1863,12 +1904,17 @@ static boolean CL_ServerConnectionSearchTicker(boolean viams, tic_t *asksent)
} }
// Quit here rather than downloading files and being refused later. // Quit here rather than downloading files and being refused later.
if (serverlist[i].info.numberofplayer >= serverlist[i].info.maxplayer) if (serverlist[i].info.refusereason)
{ {
D_QuitNetGame(); D_QuitNetGame();
CL_Reset(); CL_Reset();
D_StartTitle(); D_StartTitle();
M_StartMessage(va(M_GetText("Maximum players reached: %d\n\nPress ESC\n"), serverlist[i].info.maxplayer), NULL, MM_NOTHING); if (serverlist[i].info.refusereason == 1)
M_StartMessage(M_GetText("The server is not accepting\njoins for the moment.\n\nPress ESC\n"), NULL, MM_NOTHING);
else if (serverlist[i].info.refusereason == 2)
M_StartMessage(va(M_GetText("Maximum players reached: %d\n\nPress ESC\n"), serverlist[i].info.maxplayer), NULL, MM_NOTHING);
else
M_StartMessage(M_GetText("You can't join.\nI don't know why,\nbut you can't join.\n\nPress ESC\n"), NULL, MM_NOTHING);
return false; return false;
} }
@ -2439,14 +2485,14 @@ static void CL_RemovePlayer(INT32 playernum, kickreason_t reason)
if (!playeringame[playernum]) if (!playeringame[playernum])
return; return;
if (server && !demoplayback) if (server && !demoplayback && playernode[playernum] != UINT8_MAX)
{ {
INT32 node = playernode[playernum]; INT32 node = playernode[playernum];
playerpernode[node]--; playerpernode[node]--;
if (playerpernode[node] <= 0) if (playerpernode[node] <= 0)
{ {
nodeingame[playernode[playernum]] = false; nodeingame[node] = false;
Net_CloseConnection(playernode[playernum]); Net_CloseConnection(node);
ResetNode(node); ResetNode(node);
} }
} }
@ -2792,16 +2838,13 @@ static void Command_Kick(void)
if (pn == -1 || pn == 0) if (pn == -1 || pn == 0)
return; return;
if (server) // Special case if we are trying to kick a player who is downloading the game state:
// trigger a timeout instead of kicking them, because a kick would only
// take effect after they have finished downloading
if (server && playernode[pn] != UINT8_MAX && sendingsavegame[playernode[pn]])
{ {
// Special case if we are trying to kick a player who is downloading the game state: Net_ConnectionTimeout(playernode[pn]);
// trigger a timeout instead of kicking them, because a kick would only return;
// take effect after they have finished downloading
if (sendingsavegame[playernode[pn]])
{
Net_ConnectionTimeout(playernode[pn]);
return;
}
} }
WRITESINT8(p, pn); WRITESINT8(p, pn);
@ -2859,7 +2902,7 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
// Is playernum authorized to make this kick? // Is playernum authorized to make this kick?
if (playernum != serverplayer && !IsPlayerAdmin(playernum) if (playernum != serverplayer && !IsPlayerAdmin(playernum)
&& !(playerpernode[playernode[playernum]] == 2 && !(playernode[playernum] != UINT8_MAX && playerpernode[playernode[playernum]] == 2
&& nodetoplayer2[playernode[playernum]] == pnum)) && nodetoplayer2[playernode[playernum]] == pnum))
{ {
// We received a kick command from someone who isn't the // We received a kick command from someone who isn't the
@ -3018,7 +3061,7 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
} }
else if (keepbody) else if (keepbody)
{ {
if (server && !demoplayback) if (server && !demoplayback && playernode[pnum] != UINT8_MAX)
{ {
INT32 node = playernode[pnum]; INT32 node = playernode[pnum];
playerpernode[node]--; playerpernode[node]--;
@ -3234,37 +3277,6 @@ void D_QuitNetGame(void)
#endif #endif
} }
static INT32 FindRejoinerNum(SINT8 node)
{
char strippednodeaddress[64];
const char *nodeaddress;
char *port;
INT32 i;
// Make sure there is no dead dress before proceeding to the stripping
if (!I_GetNodeAddress)
return -1;
nodeaddress = I_GetNodeAddress(node);
if (!nodeaddress)
return -1;
// Strip the address of its port
strcpy(strippednodeaddress, nodeaddress);
port = strchr(strippednodeaddress, ':');
if (port)
*port = '\0';
// Check if any player matches the stripped address
for (i = 0; i < MAXPLAYERS; i++)
{
if (playeringame[i] && playeraddress[i][0] && playernode[i] == UINT8_MAX
&& !strcmp(playeraddress[i], strippednodeaddress))
return i;
}
return -1;
}
// Adds a node to the game (player will follow at map change or at savegame....) // Adds a node to the game (player will follow at map change or at savegame....)
static inline void SV_AddNode(INT32 node) static inline void SV_AddNode(INT32 node)
{ {
@ -3595,7 +3607,7 @@ static void HandleConnect(SINT8 node)
rejoinernum = FindRejoinerNum(node); rejoinernum = FindRejoinerNum(node);
if (bannednode && bannednode[node]) if (bannednode && bannednode[node])
SV_SendRefuse(node, M_GetText("You have been banned\nfrom the server")); SV_SendRefuse(node, M_GetText("You have been banned\nfrom the server."));
else if (netbuffer->u.clientcfg._255 != 255 || else if (netbuffer->u.clientcfg._255 != 255 ||
netbuffer->u.clientcfg.packetversion != PACKETVERSION) netbuffer->u.clientcfg.packetversion != PACKETVERSION)
SV_SendRefuse(node, "Incompatible packet formats."); SV_SendRefuse(node, "Incompatible packet formats.");
@ -3606,7 +3618,7 @@ static void HandleConnect(SINT8 node)
|| netbuffer->u.clientcfg.subversion != SUBVERSION) || netbuffer->u.clientcfg.subversion != SUBVERSION)
SV_SendRefuse(node, va(M_GetText("Different SRB2 versions cannot\nplay a netgame!\n(server version %d.%d.%d)"), VERSION/100, VERSION%100, SUBVERSION)); SV_SendRefuse(node, va(M_GetText("Different SRB2 versions cannot\nplay a netgame!\n(server version %d.%d.%d)"), VERSION/100, VERSION%100, SUBVERSION));
else if (!cv_allownewplayer.value && node && rejoinernum == -1) else if (!cv_allownewplayer.value && node && rejoinernum == -1)
SV_SendRefuse(node, M_GetText("The server is not accepting\njoins for the moment")); SV_SendRefuse(node, M_GetText("The server is not accepting\njoins for the moment."));
else if (D_NumPlayers() >= cv_maxplayers.value && rejoinernum == -1) else if (D_NumPlayers() >= cv_maxplayers.value && rejoinernum == -1)
SV_SendRefuse(node, va(M_GetText("Maximum players reached: %d"), cv_maxplayers.value)); SV_SendRefuse(node, va(M_GetText("Maximum players reached: %d"), cv_maxplayers.value));
else if (netgame && netbuffer->u.clientcfg.localplayers > 1) // Hacked client? else if (netgame && netbuffer->u.clientcfg.localplayers > 1) // Hacked client?
@ -4971,7 +4983,7 @@ void NetUpdate(void)
PingUpdate(); PingUpdate();
// update node latency values so we can take an average later. // update node latency values so we can take an average later.
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
if (playeringame[i]) if (playeringame[i] && playernode[i] != UINT8_MAX)
realpingtable[i] += G_TicsToMilliseconds(GetLag(playernode[i])); realpingtable[i] += G_TicsToMilliseconds(GetLag(playernode[i]));
pingmeasurecount++; pingmeasurecount++;
} }

View file

@ -27,7 +27,7 @@ This version is independent of the mod name, and standard
version and subversion. It should only account for the version and subversion. It should only account for the
basic fields of the packet, and change infrequently. basic fields of the packet, and change infrequently.
*/ */
#define PACKETVERSION 2 #define PACKETVERSION 3
// Network play related stuff. // Network play related stuff.
// There is a data struct that stores network // There is a data struct that stores network
@ -367,6 +367,7 @@ typedef struct
UINT8 subversion; UINT8 subversion;
UINT8 numberofplayer; UINT8 numberofplayer;
UINT8 maxplayer; UINT8 maxplayer;
UINT8 refusereason; // 0: joinable, 1: joins disabled, 2: full
char gametypename[24]; char gametypename[24];
UINT8 modifiedgame; UINT8 modifiedgame;
UINT8 cheatsenabled; UINT8 cheatsenabled;

View file

@ -3344,10 +3344,6 @@ static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum)
boolean kick = false; boolean kick = false;
boolean toomany = false; boolean toomany = false;
INT32 i,j; INT32 i,j;
serverinfo_pak *dummycheck = NULL;
// Shut the compiler up.
(void)dummycheck;
READSTRINGN(*cp, filename, 240); READSTRINGN(*cp, filename, 240);
READMEM(*cp, md5sum, 16); READMEM(*cp, md5sum, 16);

View file

@ -10395,7 +10395,7 @@ static void M_DrawConnectMenu(void)
for (i = 0; i < min(serverlistcount - serverlistpage * SERVERS_PER_PAGE, SERVERS_PER_PAGE); i++) for (i = 0; i < min(serverlistcount - serverlistpage * SERVERS_PER_PAGE, SERVERS_PER_PAGE); i++)
{ {
INT32 slindex = i + serverlistpage * SERVERS_PER_PAGE; INT32 slindex = i + serverlistpage * SERVERS_PER_PAGE;
UINT32 globalflags = ((serverlist[slindex].info.numberofplayer >= serverlist[slindex].info.maxplayer) ? V_TRANSLUCENT : 0) UINT32 globalflags = (serverlist[slindex].info.refusereason ? V_TRANSLUCENT : 0)
|((itemOn == FIRSTSERVERLINE+i) ? V_YELLOWMAP : 0)|V_ALLOWLOWERCASE; |((itemOn == FIRSTSERVERLINE+i) ? V_YELLOWMAP : 0)|V_ALLOWLOWERCASE;
V_DrawString(currentMenu->x, S_LINEY(i), globalflags, serverlist[slindex].info.servername); V_DrawString(currentMenu->x, S_LINEY(i), globalflags, serverlist[slindex].info.servername);