From e1cab3a62e5bcf98e03e471f2daa23f557b85787 Mon Sep 17 00:00:00 2001 From: toaster Date: Mon, 26 May 2025 21:21:29 +0100 Subject: [PATCH 1/3] Undo over-optimisation and don't drop the visited status of unloaded custom courses Fixes everyone having to NoVisitNeeded their SP-intended stuff --- src/g_gamedata.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/g_gamedata.cpp b/src/g_gamedata.cpp index 556def12a..1fd9e3ab3 100644 --- a/src/g_gamedata.cpp +++ b/src/g_gamedata.cpp @@ -655,7 +655,7 @@ void srb2::load_ng_gamedata() mapheaderinfo[mapnum]->records = dummyrecord; } - else if (dummyrecord.mapvisited & MV_BEATEN + else if (dummyrecord.mapvisited & (MV_VISITED|MV_BEATEN) || dummyrecord.timeattack.time != 0 || dummyrecord.timeattack.lap != 0 || dummyrecord.spbattack.time != 0 || dummyrecord.spbattack.lap != 0 || dummyrecord.spraycan != MCAN_INVALID) From b4bb4db12bf9a6bdc12246e82c8fc54337f98e6a Mon Sep 17 00:00:00 2001 From: toaster Date: Mon, 26 May 2025 21:25:06 +0100 Subject: [PATCH 2/3] skinref_t: Don't dereference out-of-range - Misjudged the boundary conditions as `numskins == MAXSKINS` is valid - Internal version of public MR !113, credit Alu Folie for bringing attention to the area of error --- src/g_gamedata.cpp | 2 +- src/k_menudraw.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/g_gamedata.cpp b/src/g_gamedata.cpp index 1fd9e3ab3..be218c5ca 100644 --- a/src/g_gamedata.cpp +++ b/src/g_gamedata.cpp @@ -214,7 +214,7 @@ void srb2::save_ng_gamedata() { newrecords.bestskin = String(skinref.unloaded->name); } - else + else if (skinref.id < numskins) { newrecords.bestskin = String(skins[skinref.id].name); } diff --git a/src/k_menudraw.c b/src/k_menudraw.c index 61853ece5..45465504a 100644 --- a/src/k_menudraw.c +++ b/src/k_menudraw.c @@ -3029,7 +3029,7 @@ fixed_t M_DrawCupWinData(INT32 rankx, INT32 ranky, cupheader_t *cup, UINT8 diffi patch_t *charPat = NULL; if ((windata->best_skin.unloaded != NULL) - || (windata->best_skin.id > numskins)) + || (windata->best_skin.id >= numskins)) { colormap = NULL; From afab1eebd0ef0ca321dc7ee4d79bd6b01c0f3c74 Mon Sep 17 00:00:00 2001 From: toaster Date: Mon, 26 May 2025 21:33:01 +0100 Subject: [PATCH 3/3] Drop time attack 1.0 records entirely on gamedata conversion - We keep medals, but times are invalid due to the massive overhaul! - To avoid double increment of minorversion, this will not fire on current internal, only 2.3 gamedatas --- src/g_gamedata.cpp | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/g_gamedata.cpp b/src/g_gamedata.cpp index be218c5ca..077eb0b81 100644 --- a/src/g_gamedata.cpp +++ b/src/g_gamedata.cpp @@ -32,6 +32,7 @@ namespace fs = std::filesystem; #define GD_VERSION_MINOR (2) #define GD_MINIMUM_SPRAYCANSV2 (2) +#define GD_MINIMUM_TIMEATTACKV2 (2) void srb2::save_ng_gamedata() { @@ -614,10 +615,22 @@ void srb2::load_ng_gamedata() dummyrecord.mapvisited |= mappair.second.visited.encore ? MV_ENCORE : 0; dummyrecord.mapvisited |= mappair.second.visited.spbattack ? MV_SPBATTACK : 0; dummyrecord.mapvisited |= mappair.second.visited.mysticmelody ? MV_MYSTICMELODY : 0; - dummyrecord.timeattack.time = mappair.second.stats.timeattack.besttime; - dummyrecord.timeattack.lap = mappair.second.stats.timeattack.bestlap; - dummyrecord.spbattack.time = mappair.second.stats.spbattack.besttime; - dummyrecord.spbattack.lap = mappair.second.stats.spbattack.bestlap; + + if (minorversion >= GD_MINIMUM_TIMEATTACKV2) + { + dummyrecord.timeattack.time = mappair.second.stats.timeattack.besttime; + dummyrecord.timeattack.lap = mappair.second.stats.timeattack.bestlap; + dummyrecord.spbattack.time = mappair.second.stats.spbattack.besttime; + dummyrecord.spbattack.lap = mappair.second.stats.spbattack.bestlap; + } + else + { + converted = true; + + dummyrecord.timeattack.time = dummyrecord.timeattack.lap = \ + dummyrecord.spbattack.time = dummyrecord.spbattack.lap = 0; + } + dummyrecord.timeplayed = mappair.second.stats.time.total; dummyrecord.netgametimeplayed = mappair.second.stats.time.netgame; dummyrecord.modetimeplayed[GDGT_RACE] = mappair.second.stats.time.race;