mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-02-02 06:23:03 +00:00
Merge branch 'working-server-incompatibility-checks' into 'next'
Actually tell you if the server is running an incompatible version See merge request STJr/SRB2!1509
This commit is contained in:
commit
6d76d05d62
2 changed files with 209 additions and 78 deletions
259
src/d_clisrv.c
259
src/d_clisrv.c
|
@ -1150,15 +1150,14 @@ static boolean CL_SendJoin(void)
|
|||
CONS_Printf(M_GetText("Sending join request...\n"));
|
||||
netbuffer->packettype = PT_CLIENTJOIN;
|
||||
|
||||
netbuffer->u.clientcfg.modversion = MODVERSION;
|
||||
strncpy(netbuffer->u.clientcfg.application,
|
||||
SRB2APPLICATION,
|
||||
sizeof netbuffer->u.clientcfg.application);
|
||||
|
||||
if (splitscreen || botingame)
|
||||
localplayers++;
|
||||
netbuffer->u.clientcfg.localplayers = localplayers;
|
||||
netbuffer->u.clientcfg._255 = 255;
|
||||
netbuffer->u.clientcfg.packetversion = PACKETVERSION;
|
||||
netbuffer->u.clientcfg.version = VERSION;
|
||||
netbuffer->u.clientcfg.subversion = SUBVERSION;
|
||||
strncpy(netbuffer->u.clientcfg.application, SRB2APPLICATION,
|
||||
sizeof netbuffer->u.clientcfg.application);
|
||||
|
||||
CleanupPlayerName(consoleplayer, cv_playername.zstring);
|
||||
if (splitscreen)
|
||||
|
@ -1201,6 +1200,21 @@ static INT32 FindRejoinerNum(SINT8 node)
|
|||
return -1;
|
||||
}
|
||||
|
||||
static UINT8
|
||||
GetRefuseReason (INT32 node)
|
||||
{
|
||||
if (!node || FindRejoinerNum(node) != -1)
|
||||
return 0;
|
||||
else if (bannednode && bannednode[node])
|
||||
return REFUSE_BANNED;
|
||||
else if (!cv_allownewplayer.value)
|
||||
return REFUSE_JOINS_DISABLED;
|
||||
else if (D_NumPlayers() >= cv_maxplayers.value)
|
||||
return REFUSE_SLOTS_FULL;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void SV_SendServerInfo(INT32 node, tic_t servertime)
|
||||
{
|
||||
UINT8 *p;
|
||||
|
@ -1219,14 +1233,7 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime)
|
|||
netbuffer->u.serverinfo.numberofplayer = (UINT8)D_NumPlayers();
|
||||
netbuffer->u.serverinfo.maxplayer = (UINT8)cv_maxplayers.value;
|
||||
|
||||
if (!node || 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;
|
||||
netbuffer->u.serverinfo.refusereason = GetRefuseReason(node);
|
||||
|
||||
strncpy(netbuffer->u.serverinfo.gametypename, Gametype_Names[gametype],
|
||||
sizeof netbuffer->u.serverinfo.gametypename);
|
||||
|
@ -1344,9 +1351,6 @@ static boolean SV_SendServerConfig(INT32 node)
|
|||
|
||||
netbuffer->packettype = PT_SERVERCFG;
|
||||
|
||||
netbuffer->u.servercfg.version = VERSION;
|
||||
netbuffer->u.servercfg.subversion = SUBVERSION;
|
||||
|
||||
netbuffer->u.servercfg.serverplayer = (UINT8)serverplayer;
|
||||
netbuffer->u.servercfg.totalslotnum = (UINT8)(doomcom->numslots);
|
||||
netbuffer->u.servercfg.gametic = (tic_t)LONG(gametic);
|
||||
|
@ -1667,20 +1671,24 @@ static void SL_InsertServer(serverinfo_pak* info, SINT8 node)
|
|||
if (serverlistcount >= MAXSERVERLIST)
|
||||
return; // list full
|
||||
|
||||
if (info->_255 != 255)
|
||||
return;/* old packet format */
|
||||
/* check it later if connecting to this one */
|
||||
if (node != servernode)
|
||||
{
|
||||
if (info->_255 != 255)
|
||||
return;/* old packet format */
|
||||
|
||||
if (info->packetversion != PACKETVERSION)
|
||||
return;/* old new packet format */
|
||||
if (info->packetversion != PACKETVERSION)
|
||||
return;/* old new packet format */
|
||||
|
||||
if (info->version != VERSION)
|
||||
return; // Not same version.
|
||||
if (info->version != VERSION)
|
||||
return; // Not same version.
|
||||
|
||||
if (info->subversion != SUBVERSION)
|
||||
return; // Close, but no cigar.
|
||||
if (info->subversion != SUBVERSION)
|
||||
return; // Close, but no cigar.
|
||||
|
||||
if (strcmp(info->application, SRB2APPLICATION))
|
||||
return;/* that's a different mod */
|
||||
if (strcmp(info->application, SRB2APPLICATION))
|
||||
return;/* that's a different mod */
|
||||
}
|
||||
|
||||
i = serverlistcount++;
|
||||
}
|
||||
|
@ -1829,6 +1837,72 @@ void CL_UpdateServerList(boolean internetsearch, INT32 room)
|
|||
|
||||
#endif // ifndef NONET
|
||||
|
||||
static const char * InvalidServerReason (INT32 i)
|
||||
{
|
||||
#define EOT "\nPress ESC\n"
|
||||
|
||||
serverinfo_pak *info = &serverlist[i].info;
|
||||
|
||||
/* magic number for new packet format */
|
||||
if (info->_255 != 255)
|
||||
{
|
||||
return
|
||||
"Outdated server (version unknown).\n" EOT;
|
||||
}
|
||||
|
||||
if (strncmp(info->application, SRB2APPLICATION, sizeof
|
||||
info->application))
|
||||
{
|
||||
return va(
|
||||
"%s cannot connect\n"
|
||||
"to %s servers.\n" EOT,
|
||||
SRB2APPLICATION,
|
||||
info->application);
|
||||
}
|
||||
|
||||
if (
|
||||
info->packetversion != PACKETVERSION ||
|
||||
info->version != VERSION ||
|
||||
info->subversion != SUBVERSION
|
||||
){
|
||||
return va(
|
||||
"Incompatible %s versions.\n"
|
||||
"(server version %d.%d.%d)\n" EOT,
|
||||
SRB2APPLICATION,
|
||||
info->version / 100,
|
||||
info->version % 100,
|
||||
info->subversion);
|
||||
}
|
||||
|
||||
switch (info->refusereason)
|
||||
{
|
||||
case REFUSE_BANNED:
|
||||
return
|
||||
"You have been banned\n"
|
||||
"from the server.\n" EOT;
|
||||
case REFUSE_JOINS_DISABLED:
|
||||
return
|
||||
"The server is not accepting\n"
|
||||
"joins for the moment.\n" EOT;
|
||||
case REFUSE_SLOTS_FULL:
|
||||
return va(
|
||||
"Maximum players reached: %d\n" EOT,
|
||||
info->maxplayer);
|
||||
default:
|
||||
if (info->refusereason)
|
||||
{
|
||||
return
|
||||
"You can't join.\n"
|
||||
"I don't know why,\n"
|
||||
"but you can't join.\n" EOT;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
#undef EOT
|
||||
}
|
||||
|
||||
/** Called by CL_ServerConnectionTicker
|
||||
*
|
||||
* \param asksent The last time we asked the server to join. We re-ask every second in case our request got lost in transmit.
|
||||
|
@ -1859,23 +1933,23 @@ static boolean CL_ServerConnectionSearchTicker(tic_t *asksent)
|
|||
return true;
|
||||
}
|
||||
|
||||
// Quit here rather than downloading files and being refused later.
|
||||
if (serverlist[i].info.refusereason)
|
||||
{
|
||||
D_QuitNetGame();
|
||||
CL_Reset();
|
||||
D_StartTitle();
|
||||
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;
|
||||
}
|
||||
|
||||
if (client)
|
||||
{
|
||||
const char *reason = InvalidServerReason(i);
|
||||
|
||||
// Quit here rather than downloading files
|
||||
// and being refused later.
|
||||
if (reason)
|
||||
{
|
||||
char *message = Z_StrDup(reason);
|
||||
D_QuitNetGame();
|
||||
CL_Reset();
|
||||
D_StartTitle();
|
||||
M_StartMessage(message, NULL, MM_NOTHING);
|
||||
Z_Free(message);
|
||||
return false;
|
||||
}
|
||||
|
||||
D_ParseFileneeded(serverlist[i].info.fileneedednum,
|
||||
serverlist[i].info.fileneeded);
|
||||
CONS_Printf(M_GetText("Checking files...\n"));
|
||||
|
@ -3620,6 +3694,78 @@ static size_t TotalTextCmdPerTic(tic_t tic)
|
|||
return total;
|
||||
}
|
||||
|
||||
static const char *
|
||||
ConnectionRefused (SINT8 node, INT32 rejoinernum)
|
||||
{
|
||||
clientconfig_pak *cc = &netbuffer->u.clientcfg;
|
||||
|
||||
boolean rejoining = (rejoinernum != -1);
|
||||
|
||||
if (!node)/* server connecting to itself */
|
||||
return NULL;
|
||||
|
||||
if (
|
||||
cc->modversion != MODVERSION ||
|
||||
strncmp(cc->application, SRB2APPLICATION,
|
||||
sizeof cc->application)
|
||||
){
|
||||
return/* this is probably client's fault */
|
||||
"Incompatible.";
|
||||
}
|
||||
else if (bannednode && bannednode[node])
|
||||
{
|
||||
return
|
||||
"You have been banned\n"
|
||||
"from the server.";
|
||||
}
|
||||
else if (cc->localplayers != 1)
|
||||
{
|
||||
return
|
||||
"Wrong player count.";
|
||||
}
|
||||
|
||||
if (!rejoining)
|
||||
{
|
||||
if (!cv_allownewplayer.value)
|
||||
{
|
||||
return
|
||||
"The server is not accepting\n"
|
||||
"joins for the moment.";
|
||||
}
|
||||
else if (D_NumPlayers() >= cv_maxplayers.value)
|
||||
{
|
||||
return va(
|
||||
"Maximum players reached: %d",
|
||||
cv_maxplayers.value);
|
||||
}
|
||||
}
|
||||
|
||||
if (luafiletransfers)
|
||||
{
|
||||
return
|
||||
"The serveris broadcasting a file\n"
|
||||
"requested by a Lua script.\n"
|
||||
"Please wait a bit and then\n"
|
||||
"try rejoining.";
|
||||
}
|
||||
|
||||
if (netgame)
|
||||
{
|
||||
const tic_t th = 2 * cv_joindelay.value * TICRATE;
|
||||
|
||||
if (joindelay > th)
|
||||
{
|
||||
return va(
|
||||
"Too many people are connecting.\n"
|
||||
"Please wait %d seconds and then\n"
|
||||
"try rejoining.",
|
||||
(joindelay - th) / TICRATE);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** Called when a PT_CLIENTJOIN packet is received
|
||||
*
|
||||
* \param node The packet sender
|
||||
|
@ -3630,33 +3776,14 @@ static void HandleConnect(SINT8 node)
|
|||
char names[MAXSPLITSCREENPLAYERS][MAXPLAYERNAME + 1];
|
||||
INT32 rejoinernum;
|
||||
INT32 i;
|
||||
const char *refuse;
|
||||
|
||||
rejoinernum = FindRejoinerNum(node);
|
||||
|
||||
if (bannednode && bannednode[node])
|
||||
SV_SendRefuse(node, M_GetText("You have been banned\nfrom the server."));
|
||||
else if (netbuffer->u.clientcfg._255 != 255 ||
|
||||
netbuffer->u.clientcfg.packetversion != PACKETVERSION)
|
||||
SV_SendRefuse(node, "Incompatible packet formats.");
|
||||
else if (strncmp(netbuffer->u.clientcfg.application, SRB2APPLICATION,
|
||||
sizeof netbuffer->u.clientcfg.application))
|
||||
SV_SendRefuse(node, "Different SRB2 modifications\nare not compatible.");
|
||||
else if (netbuffer->u.clientcfg.version != VERSION
|
||||
|| 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));
|
||||
else if (!cv_allownewplayer.value && node && rejoinernum == -1)
|
||||
SV_SendRefuse(node, M_GetText("The server is not accepting\njoins for the moment."));
|
||||
else if (D_NumPlayers() >= cv_maxplayers.value && rejoinernum == -1)
|
||||
SV_SendRefuse(node, va(M_GetText("Maximum players reached: %d"), cv_maxplayers.value));
|
||||
else if (netgame && netbuffer->u.clientcfg.localplayers > 1) // Hacked client?
|
||||
SV_SendRefuse(node, M_GetText("Too many players from\nthis node."));
|
||||
else if (netgame && !netbuffer->u.clientcfg.localplayers) // Stealth join?
|
||||
SV_SendRefuse(node, M_GetText("No players from\nthis node."));
|
||||
else if (luafiletransfers)
|
||||
SV_SendRefuse(node, M_GetText("The server is broadcasting a file\nrequested by a Lua script.\nPlease wait a bit and then\ntry rejoining."));
|
||||
else if (netgame && joindelay > 2 * (tic_t)cv_joindelay.value * TICRATE)
|
||||
SV_SendRefuse(node, va(M_GetText("Too many people are connecting.\nPlease wait %d seconds and then\ntry rejoining."),
|
||||
(joindelay - 2 * cv_joindelay.value * TICRATE) / TICRATE));
|
||||
refuse = ConnectionRefused(node, rejoinernum);
|
||||
|
||||
if (refuse)
|
||||
SV_SendRefuse(node, refuse);
|
||||
else
|
||||
{
|
||||
#ifndef NONET
|
||||
|
|
|
@ -22,11 +22,15 @@
|
|||
#include "mserv.h"
|
||||
|
||||
/*
|
||||
The 'packet version' is used to distinguish packet formats.
|
||||
This version is independent of VERSION and SUBVERSION. Different
|
||||
applications may follow different packet versions.
|
||||
The 'packet version' is used to distinguish packet
|
||||
formats. This version is independent of VERSION and
|
||||
SUBVERSION. Different applications may follow different
|
||||
packet versions.
|
||||
|
||||
If you change the struct or the meaning of a field
|
||||
therein, increment this number.
|
||||
*/
|
||||
#define PACKETVERSION 3
|
||||
#define PACKETVERSION 4
|
||||
|
||||
// Network play related stuff.
|
||||
// There is a data struct that stores network
|
||||
|
@ -141,9 +145,6 @@ typedef struct
|
|||
|
||||
typedef struct
|
||||
{
|
||||
UINT8 version; // Different versions don't work
|
||||
UINT8 subversion; // Contains build version
|
||||
|
||||
// Server launch stuffs
|
||||
UINT8 serverplayer;
|
||||
UINT8 totalslotnum; // "Slots": highest player number in use plus one.
|
||||
|
@ -190,16 +191,19 @@ typedef struct
|
|||
|
||||
typedef struct
|
||||
{
|
||||
UINT8 _255;/* see serverinfo_pak */
|
||||
UINT8 packetversion;
|
||||
UINT8 modversion;
|
||||
char application[MAXAPPLICATION];
|
||||
UINT8 version; // Different versions don't work
|
||||
UINT8 subversion; // Contains build version
|
||||
UINT8 localplayers;
|
||||
UINT8 mode;
|
||||
char names[MAXSPLITSCREENPLAYERS][MAXPLAYERNAME];
|
||||
} ATTRPACK clientconfig_pak;
|
||||
|
||||
enum {
|
||||
REFUSE_JOINS_DISABLED = 1,
|
||||
REFUSE_SLOTS_FULL,
|
||||
REFUSE_BANNED,
|
||||
};
|
||||
|
||||
#define MAXSERVERNAME 32
|
||||
#define MAXFILENEEDED 915
|
||||
// This packet is too large
|
||||
|
@ -217,7 +221,7 @@ typedef struct
|
|||
UINT8 subversion;
|
||||
UINT8 numberofplayer;
|
||||
UINT8 maxplayer;
|
||||
UINT8 refusereason; // 0: joinable, 1: joins disabled, 2: full
|
||||
UINT8 refusereason; // 0: joinable, REFUSE enum
|
||||
char gametypename[24];
|
||||
UINT8 modifiedgame;
|
||||
UINT8 cheatsenabled;
|
||||
|
|
Loading…
Reference in a new issue