# HG changeset patch # User Adam Kaminski # Date 1615156760 18000 # Sun Mar 07 17:39:20 2021 -0500 # Node ID b473ca9288c3f0af632482aeff926d93ca0e4724 # Parent c078e6238f5abc260e2c49d6768e96d8f519ec41 Further refined the duplicate lump check so that it will list all protected lumps flagged as duplicates before throwing a fatal error instead of only printing the first duplicate lump that was authenticated. diff -r c078e6238f5a -r b473ca9288c3 src/network.cpp --- a/src/network.cpp Sun Mar 07 17:30:07 2021 -0500 +++ b/src/network.cpp Sun Mar 07 17:39:20 2021 -0500 @@ -152,6 +152,9 @@ // [BB] extern int restart; +// [AK] Did we need to authenticate a lump that has a duplicate? +static bool g_bDuplicateLumpAuthenticated = false; + // [TP] Named ACS scripts share the name pool with all other names in the engine, which means named script numbers may // differ wildly between systems, e.g. if the server and client have different vid_renderer values the names will // already be off. So we create a special index of script names here. @@ -165,6 +168,7 @@ static SOCKET network_AllocateSocket( void ); static bool network_BindSocketToPort( SOCKET Socket, ULONG ulInAddr, USHORT usPort, bool bReUse ); static bool network_GenerateLumpMD5HashAndWarnIfNeeded( const int LumpNum, const char *LumpName, FString &MD5Hash ); +static void network_CheckIfDuplicateLump( const int LumpNum ); // [AK] //***************************************************************************** // FUNCTIONS @@ -359,20 +363,6 @@ for ( unsigned int i = 0; i < lumpsToAuthenticate.size(); i++ ) { - // [AK] Check if we're authenticating any duplicate lumps on the server. - if ( NETWORK_GetState() == NETSTATE_SERVER ) - { - for ( unsigned int j = 0; j < DuplicateLumps.Size(); j++ ) - { - // [AK] If there's a match, throw a fatal error instead. - if ( stricmp( DuplicateLumps[j], lumpsToAuthenticate[i].c_str() ) == 0 ) - { - I_Error( "Attempt to authenticate duplicate protected lump '%s'.\n", lumpsToAuthenticate[i].c_str() ); - return; - } - } - } - switch ( lumpsToAuthenticateMode[i] ){ case LAST_LUMP: int lump; @@ -388,6 +378,9 @@ if ( !network_GenerateLumpMD5HashAndWarnIfNeeded( lump, lumpsToAuthenticate[i].c_str(), checksum ) ) noProtectedLumpsAutoloaded = false; + // [AK] Check if we're trying to authenticate a duplicate lump. + network_CheckIfDuplicateLump( lump ); + // [TP] The wad that had this lump is no longer optional. Wads.LumpIsMandatory( lump ); @@ -418,6 +411,9 @@ if ( !network_GenerateLumpMD5HashAndWarnIfNeeded( workingLump, lumpsToAuthenticate[i].c_str(), checksum ) ) noProtectedLumpsAutoloaded = false; + // [AK] Check if we're trying to authenticate a duplicate lump. + network_CheckIfDuplicateLump( workingLump ); + // [BB] To make Doom and Freedoom network compatible, we need to ignore its DEHACKED lump. // Since this lump only changes some strings, this should cause no problems. if ( ( stricmp ( lumpsToAuthenticate[i].c_str(), "DEHACKED" ) == 0 ) @@ -439,6 +435,22 @@ } CMD5Checksum::GetMD5( reinterpret_cast(longChecksum.GetChars()), longChecksum.Len(), g_lumpsAuthenticationChecksum ); + // [AK] If we needed to authenticate any duplicate lumps, either throw a fatal error if we're + // the server, or just print a warning message that urges modders to fix them. + if ( g_bDuplicateLumpAuthenticated ) + { + FString message = "There are files containing duplicate lumps that require authentication. "; + + if ( NETWORK_GetState() == NETSTATE_SERVER ) + { + message.AppendFormat( "Please resolve these issues before hosting again.\n" ); + I_FatalError( message ); + } + + message.AppendFormat( "These issues must be resolved if you plan on hosting these files in online games.\n" ); + Printf( TEXTCOLOR_RED "%s", message ); + } + // [BB] Warn the user about problematic auto-loaded files. if ( noProtectedLumpsAutoloaded == false ) { @@ -1002,23 +1014,8 @@ if ( LumpNumber == -1 ) return; - // [AK] Check if we're trying to authenticate a duplicate lump on the server. - if ( NETWORK_GetState() == NETSTATE_SERVER ) - { - const char *lumpName = Wads.GetLumpFullName( LumpNumber ); - for ( unsigned int i = 0; i < DuplicateLumps.Size(); i++ ) - { - // [AK] If there's a match, throw a fatal error instead. - if ( DuplicateLumps[i].CompareNoCase( lumpName ) == 0 ) - { - FString fullPath = Wads.GetLumpFullPath( LumpNumber ); - const char *fileName = fullPath.Left( fullPath.Len() - strlen( lumpName ) - 1 ); - - I_Error( "Attempt to authenticate duplicate lump '%s' found in '%s'.\n", lumpName, fileName ); - return; - } - } - } + // [AK] Check if we're trying to authenticate a duplicate lump. + network_CheckIfDuplicateLump( LumpNumber ); g_LumpNumsToAuthenticate.Push ( LumpNumber ); } @@ -1059,6 +1056,33 @@ } +void network_CheckIfDuplicateLump( const int LumpNum ) +{ + const char *lumpName = Wads.GetLumpFullName( LumpNum ); + + for ( unsigned int i = 0; i < DuplicateLumps.Size(); i++ ) + { + // [AK] Check if the name of this lump matches that of any duplicate lumps on the list. + // We'll also need to check if these lumps match the same file. + if ( DuplicateLumps[i].CompareNoCase( lumpName ) == 0 ) + { + FString fullPath = Wads.GetLumpFullPath( LumpNum ); + const char *fileName = fullPath.Left( fullPath.Len() - strlen( lumpName ) - 1 ); + + // [AK] If the lumps belong to the same file, print a message into the console and + // remove it from the list. + if ( DuplicateLumpFilenames[i].CompareNoCase( fileName ) == 0 ) + { + Printf( TEXTCOLOR_YELLOW "%s contains duplicate protected lump %s\n", fileName, lumpName ); + g_bDuplicateLumpAuthenticated = true; + + DuplicateLumps.Delete( i ); + DuplicateLumpFilenames.Delete( i-- ); + } + } + } +} + //***************************************************************************** // [Dusk] Gets a checksum of every map loaded. FString NETWORK_MapCollectionChecksum( ) diff -r c078e6238f5a -r b473ca9288c3 src/resourcefiles/file_zip.cpp --- a/src/resourcefiles/file_zip.cpp Sun Mar 07 17:30:07 2021 -0500 +++ b/src/resourcefiles/file_zip.cpp Sun Mar 07 17:39:20 2021 -0500 @@ -299,22 +299,23 @@ { if (oldNames[i].CompareNoCase(name) == 0) { - if (!quiet) Printf(TEXTCOLOR_YELLOW "\n%s: duplicate lump '%s' detected.\n", Filename, name.GetChars()); - // [AK] We only want to keep track of duplicate lumps that may cause authentication // failures if the file is loaded. Therefore, ignore any lumps that aren't part of // the global or ACS namespaces. if ((lump_p->Namespace != -1 ) && (lump_p->Namespace != ns_global) && (lump_p->Namespace != ns_acslibrary)) break; + const char *shortenedFilename = strrchr(Filename, '/'); + if (shortenedFilename != NULL) shortenedFilename++; + + const char *actualFilename = shortenedFilename != NULL ? shortenedFilename : Filename; bool addDuplicate = true; - // [AK] To keep the list of duplicate lumps as small as possible, first check if the - // name of the lump isn't already in the list. If nothing was found, then add the - // full name of the lump to it. + // [AK] To keep the list of duplicate lumps as small as possible, first check if this + // particular lump isn't already on the list. If not, add it to the list then. for (unsigned int j = 0; j < DuplicateLumps.Size(); j++) { - if (DuplicateLumps[j].CompareNoCase(lump_p->FullName) == 0) + if ((DuplicateLumps[j].CompareNoCase(lump_p->FullName) == 0) && (DuplicateLumpFilenames[j].CompareNoCase(actualFilename) == 0 )) { addDuplicate = false; break; @@ -324,6 +325,7 @@ if (addDuplicate) { DuplicateLumps.Push(lump_p->FullName); + DuplicateLumpFilenames.Push(actualFilename); } break; diff -r c078e6238f5a -r b473ca9288c3 src/w_wad.cpp --- a/src/w_wad.cpp Sun Mar 07 17:30:07 2021 -0500 +++ b/src/w_wad.cpp Sun Mar 07 17:39:20 2021 -0500 @@ -95,6 +95,7 @@ // [AK] A list of all duplicate lumps found during startup. TArray DuplicateLumps; +TArray DuplicateLumpFilenames; // PRIVATE DATA DEFINITIONS ------------------------------------------------ diff -r c078e6238f5a -r b473ca9288c3 src/w_wad.h --- a/src/w_wad.h Sun Mar 07 17:30:07 2021 -0500 +++ b/src/w_wad.h Sun Mar 07 17:39:20 2021 -0500 @@ -251,5 +251,6 @@ // [AK] A list of all duplicate lumps found during startup. extern TArray DuplicateLumps; +extern TArray DuplicateLumpFilenames; #endif