diff --git a/src/d_main.cpp b/src/d_main.cpp index 5e21867bb..6491dc3e3 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -214,6 +214,7 @@ bool autostart; FString StoredWarp; bool advancedemo; FILE *debugfile; +FILE *hashfile; event_t events[MAXEVENTS]; int eventhead; int eventtail; @@ -2220,6 +2221,26 @@ void D_DoomMain (void) execLogfile(logfile); } + if (Args->CheckParm("-hashfiles")) + { + FString filename = "fileinfo.txt"; + Printf("Hashing loaded content to: %s\n", filename); + hashfile = fopen(filename, "w"); + if (hashfile) + { + fprintf(hashfile, "%s version %s (%s)\n", GAMENAME, GetVersionString(), GetGitHash()); +#ifdef __VERSION__ + fprintf(hashfile, "Compiler version: %s\n", __VERSION__); +#endif + fprintf(hashfile, "Command line:"); + for (int i = 0; i < Args->NumArgs(); ++i) + { + fprintf(hashfile, " %s", Args->GetArg(i)); + } + fprintf(hashfile, "\n"); + } + } + D_DoomInit(); PClass::StaticInit (); atterm(FinalGC); @@ -2289,6 +2310,11 @@ void D_DoomMain (void) pwads.Clear(); pwads.ShrinkToFit(); + if (hashfile) + { + Printf("Notice: File hashing is incredibly verbose. Expect loading files to take much longer then usual.\n"); + } + Printf ("W_Init: Init WADfiles.\n"); Wads.InitMultipleFiles (allwads); allwads.Clear(); diff --git a/src/doomstat.h b/src/doomstat.h index 565d15bd6..b1784530f 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -172,6 +172,7 @@ extern bool playeringame[/*MAXPLAYERS*/]; // File handling stuff. extern FILE* debugfile; +extern FILE* hashfile; // if true, load all graphics at level load extern bool precache; diff --git a/src/w_wad.cpp b/src/w_wad.cpp index 9455817db..abbac5763 100644 --- a/src/w_wad.cpp +++ b/src/w_wad.cpp @@ -56,6 +56,7 @@ #include "doomerrors.h" #include "resourcefiles/resourcefile.h" #include "md5.h" +#include "doomstat.h" // MACROS ------------------------------------------------------------------ @@ -300,6 +301,56 @@ void FWadCollection::AddFile (const char *filename, FileReader *wadinfo) AddFile(path, embedded); } } + + if (hashfile) + { + BYTE cksum[16]; + char cksumout[33]; + memset(cksumout, 0, sizeof(cksumout)); + + FileReader *reader = wadinfo; + + if (reader != NULL) + { + MD5Context md5; + reader->Seek(0, SEEK_SET); + md5.Update(reader, reader->GetLength()); + md5.Final(cksum); + + for (size_t j = 0; j < sizeof(cksum); ++j) + { + sprintf(cksumout + (j * 2), "%02X", cksum[j]); + } + + fprintf(hashfile, "file: %s, hash: %s, size: %d\n", filename, cksumout, reader->GetLength()); + } + + else + fprintf(hashfile, "file: %s, Directory structure\n", filename); + + for (DWORD i = 0; i < resfile->LumpCount(); i++) + { + FResourceLump *lump = resfile->GetLump(i); + + if (!(lump->Flags & LUMPF_EMBEDDED)) + { + reader = lump->NewReader(); + + MD5Context md5; + md5.Update(reader, lump->LumpSize); + md5.Final(cksum); + + for (size_t j = 0; j < sizeof(cksum); ++j) + { + sprintf(cksumout + (j * 2), "%02X", cksum[j]); + } + + fprintf(hashfile, "file: %s, lump: %s, hash: %s, size: %d\n", filename, lump->FullName ? lump->FullName : lump->Name, cksumout, lump->LumpSize); + + delete reader; + } + } + } return; } }