From dcd0fe7feb4ae94695a5df782e009cb231c6f0cf Mon Sep 17 00:00:00 2001 From: toaster Date: Wed, 1 May 2024 18:08:36 +0100 Subject: [PATCH 1/3] G_SaveDemo: Defer save for eversavedreplay event Prevents challenge success noise from being eaten by gamestate transition --- src/g_demo.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/g_demo.cpp b/src/g_demo.cpp index 4e0bfd437..bb6aff69b 100644 --- a/src/g_demo.cpp +++ b/src/g_demo.cpp @@ -4174,8 +4174,11 @@ void G_SaveDemo(void) if (gamedata->eversavedreplay == false) { gamedata->eversavedreplay = true; - M_UpdateUnlockablesAndExtraEmblems(true, true); - G_SaveGameData(); + // The following will IMMEDIATELY happen on either next level load + // or returning to menu, so don't make the sound just to get cut off + //M_UpdateUnlockablesAndExtraEmblems(true, true); + //G_SaveGameData(); + gamedata->deferredsave = true; } } else From 7390ee54427327467787d94d1d5935d8b36107c4 Mon Sep 17 00:00:00 2001 From: toaster Date: Wed, 1 May 2024 19:54:09 +0100 Subject: [PATCH 2/3] G_SaveDemo: Resolve memory errors that could result in crashes - Empty `demo.titlename` case - Don't try to save demo of name `.lmp` - Doesn't fall back to anything, because emptying out the name field can be reasonably treated as not wanting to save - `demo.titlename` consists only of invalid characters - Don't try to save demo of name `-.lmp` - Falls back to the default demo title, because the user clearly wanted to save and just happened to provide invalid text --- src/g_demo.cpp | 31 +++++++++++++++++++++++++------ src/st_stuff.c | 2 +- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/g_demo.cpp b/src/g_demo.cpp index bb6aff69b..310510ae5 100644 --- a/src/g_demo.cpp +++ b/src/g_demo.cpp @@ -4135,7 +4135,7 @@ void G_SaveDemo(void) strindex++; dash = false; } - else if (!dash) + else if (strindex && !dash) { demo_slug[strindex] = '-'; strindex++; @@ -4143,12 +4143,31 @@ void G_SaveDemo(void) } } - demo_slug[strindex] = 0; - if (dash) demo_slug[strindex-1] = 0; + if (dash && strindex) + { + strindex--; + } + demo_slug[strindex] = '\0'; - writepoint = strstr(strrchr(demoname, *PATHSEP), "-") + 1; - demo_slug[128 - (writepoint - demoname) - 4] = 0; - sprintf(writepoint, "%s.lmp", demo_slug); + if (demo_slug[0] != '\0') + { + // Slug is valid, write the chosen filename. + writepoint = strstr(strrchr(demoname, *PATHSEP), "-") + 1; + demo_slug[128 - (writepoint - demoname) - 4] = 0; + sprintf(writepoint, "%s.lmp", demo_slug); + } + else if (demo.titlename[0] == '\0') + { + // Slug is completely blank? Will crash if we attempt to save + // No bailout because empty seems like a good "no thanks" choice + G_ResetDemoRecording(); + return; + } + // If a title that is invalid is provided, the user clearly wanted + // to save. But we can't do so at that name, so we only apply the + // title INSIDE the file, not in the naked filesystem. + // (A hypothetical example is bamboozling bot behaviour causing + // a player to write "?????????".) ~toast 010524 } length = *(UINT32 *)demoinfo_p; diff --git a/src/st_stuff.c b/src/st_stuff.c index 21e0669b1..69e0b4d34 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -1490,7 +1490,7 @@ void ST_DrawSaveReplayHint(INT32 flags) V_DrawRightAlignedThinString( BASEVIDWIDTH - 2, 2, flags|V_YELLOWMAP, - demo.willsave ? "Replay will be saved. \xAB Change title" : "\xAB or \xAD Save replay" + (demo.willsave && demo.titlename[0]) ? "Replay will be saved. \xAB Change title" : "\xAB or \xAD Save replay" ); } From 9d0c9ece4b4d2fdb08bb52395f4a3fcab2665327 Mon Sep 17 00:00:00 2001 From: toaster Date: Wed, 1 May 2024 19:55:30 +0100 Subject: [PATCH 3/3] Demos: Use long lumpname when handling staff ghost information Implements new W_CheckLongNameForNum funcs, which are broadly copypasted from W_CheckNameForNum --- src/k_credits.cpp | 1 - src/p_setup.cpp | 2 +- src/w_wad.cpp | 13 +++++++++++++ src/w_wad.h | 2 ++ 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/k_credits.cpp b/src/k_credits.cpp index d867e2b6e..6c14f4dc1 100644 --- a/src/k_credits.cpp +++ b/src/k_credits.cpp @@ -555,7 +555,6 @@ static boolean F_CreditsPlayDemo(void) UINT8 ghost_id = M_RandomKey( mapheaderinfo[map_id]->ghostCount ); brief = mapheaderinfo[map_id]->ghostBrief[ghost_id]; - std::string demo_name = static_cast(W_CheckNameForNumPwad(brief->wad, brief->lump)); demo.attract = DEMO_ATTRACT_CREDITS; demo.ignorefiles = true; diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 058f4a792..b1d011b07 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -7901,7 +7901,7 @@ static void P_LoadRecordGhosts(void) savebuffer_t buf = {0}; staffbrief_t* ghostbrief = mapheaderinfo[gamemap-1]->ghostBrief[i - 1]; - const char* lumpname = W_CheckNameForNumPwad(ghostbrief->wad, ghostbrief->lump); + const char* lumpname = W_CheckLongNameForNumPwad(ghostbrief->wad, ghostbrief->lump); size_t lumplength = W_LumpLengthPwad(ghostbrief->wad, ghostbrief->lump); if (lumplength == 0) { diff --git a/src/w_wad.cpp b/src/w_wad.cpp index 604ed203e..8d31c97a1 100644 --- a/src/w_wad.cpp +++ b/src/w_wad.cpp @@ -1021,6 +1021,19 @@ const char *W_CheckNameForNum(lumpnum_t lumpnum) return W_CheckNameForNumPwad(WADFILENUM(lumpnum),LUMPNUM(lumpnum)); } +const char *W_CheckLongNameForNumPwad(UINT16 wad, UINT16 lump) +{ + if (lump >= wadfiles[wad]->numlumps || !TestValidLump(wad, 0)) + return NULL; + + return wadfiles[wad]->lumpinfo[lump].longname; +} + +const char *W_CheckLongNameForNum(lumpnum_t lumpnum) +{ + return W_CheckLongNameForNumPwad(WADFILENUM(lumpnum),LUMPNUM(lumpnum)); +} + // // wadid is a wad number // (Used for sprites loading) diff --git a/src/w_wad.h b/src/w_wad.h index d224475d9..a928ffc44 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -154,6 +154,8 @@ INT32 W_InitMultipleFiles(char **filenames, boolean addons); const char *W_CheckNameForNumPwad(UINT16 wad, UINT16 lump); const char *W_CheckNameForNum(lumpnum_t lumpnum); +const char *W_CheckLongNameForNumPwad(UINT16 wad, UINT16 lump); +const char *W_CheckLongNameForNum(lumpnum_t lumpnum); UINT16 W_FindNextEmptyInPwad(UINT16 wad, UINT16 startlump); // checks only in one pwad