diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 13b6fa373..725ffd173 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -920,6 +920,8 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime) netbuffer->u.serverinfo.packetversion = PACKETVERSION; netbuffer->u.serverinfo.version = VERSION; netbuffer->u.serverinfo.subversion = SUBVERSION; + memcpy(netbuffer->u.serverinfo.commit, + comprevision_abbrev_bin, GIT_SHA_ABBREV); strncpy(netbuffer->u.serverinfo.application, SRB2APPLICATION, sizeof netbuffer->u.serverinfo.application); // return back the time value so client can compute their ping @@ -1721,6 +1723,33 @@ static boolean CL_ServerConnectionSearchTicker(tic_t *asksent) if (client) { +#ifdef COMMITVERSION + // Commits do not match? Do not connect! + if (memcmp(serverlist[i].info.commit, + comprevision_abbrev_bin, + GIT_SHA_ABBREV)) + { + char theirs[GIT_SHA_ABBREV * 2 + 1]; + UINT8 n; + + for (n = 0; n < GIT_SHA_ABBREV; ++n) + { + sprintf(&theirs[n * 2], "%02hhx", + serverlist[i].info.commit[n]); + } + + D_QuitNetGame(); + CL_Reset(); + D_StartTitle(); + M_StartMessage( + va( + "Connection failed.\n\nYour binary differs from the server.\n" + " Yours: %.*s\n" + "Theirs: %s\n\n\nPress ESC\n", + GIT_SHA_ABBREV * 2, comprevision, theirs), NULL, MM_NOTHING); + return false; + } +#endif #ifdef HAVE_CURL if (serverlist[i].info.httpsource[0]) strncpy(http_source, serverlist[i].info.httpsource, MAX_MIRROR_LENGTH); diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 163900da2..0bcc4a13c 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -33,7 +33,7 @@ The 'packet version' is used to distinguish packet formats. This version is independent of VERSION and SUBVERSION. Different applications may follow different packet versions. */ -#define PACKETVERSION 0 +#define PACKETVERSION 2 // Network play related stuff. // There is a data struct that stores network @@ -272,6 +272,7 @@ struct serverinfo_pak char application[MAXAPPLICATION]; UINT8 version; UINT8 subversion; + UINT8 commit[GIT_SHA_ABBREV]; UINT8 numberofplayer; UINT8 maxplayer; UINT8 refusereason; // 0: joinable, 1: joins disabled, 2: full diff --git a/src/d_main.cpp b/src/d_main.cpp index a60cf1b64..50129edc6 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -111,6 +111,7 @@ // Version numbers for netplay :upside_down_face: int VERSION; int SUBVERSION; +UINT8 comprevision_abbrev_bin[GIT_SHA_ABBREV]; #ifdef HAVE_DISCORDRPC #include "discord.h" diff --git a/src/doomdef.h b/src/doomdef.h index 489302e48..c69a3e0e7 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -123,6 +123,7 @@ extern char logfilename[1024]; /* A mod name to further distinguish versions. */ #define SRB2APPLICATION "SRB2Kart" +#define COMMITVERSION // Enable this to use add commit hash checking to client join checks. //#define DEVELOP // Disable this for release builds to remove excessive cheat commands and enable hash checking and stuff, all in one go. :3 #ifdef DEVELOP #define VERSIONSTRING "Development EXE" @@ -337,6 +338,15 @@ char *sizeu5(size_t num); // d_main.c extern int VERSION; extern int SUBVERSION; + +// 4 bytes handles 8 characters of a git object SHA. At +// around 20k commits, we only need 6 characters for a unique +// abbreviation. Maybe in another 20k commits, more than 8 +// characters will be required! =P +// P.S. 8 is also what comptime generates +#define GIT_SHA_ABBREV (4) +extern UINT8 comprevision_abbrev_bin[GIT_SHA_ABBREV]; + extern boolean devparm; // development mode (-debug) // m_cheat.c diff --git a/src/version.h b/src/version.h index 498986ebd..bc459ac6f 100644 --- a/src/version.h +++ b/src/version.h @@ -12,4 +12,4 @@ #define MODVERSION 11 // Define this as a prerelease version suffix -// #define BETAVERSION "Alpha" + #define BETAVERSION "Test Server"