From 6c0118d49179cc65f42c0917621b1cb127934c04 Mon Sep 17 00:00:00 2001 From: toaster Date: Fri, 12 Apr 2024 14:01:24 +0100 Subject: [PATCH 1/4] Fix dedicated server Encore warp getting ahead of non-dedicated clients There was new waiting time added to the non-dedicated behaviour that was not added for the other case --- src/p_setup.cpp | 53 ++++++++++++++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 23 deletions(-) diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 548bdf914..e8ce43e49 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -8373,30 +8373,9 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate) // will be set by player think. players[consoleplayer].viewz = 1; - // Cancel all d_main.c fadeouts (keep fade in though). - if (reloadinggamestate) - wipegamestate = gamestate; // Don't fade if reloading the gamestate - // Encore mode fade to pink to white - // This is handled BEFORE sounds are stopped. - else if (encoremode && !prevencoremode && modeattacking == ATTACKING_NONE && !demo.rewinding) - { - if (rendermode != render_none) - { - tic_t locstarttime, endtime, nowtime; + // (This define might be useful for other areas of code? Not sure) + tic_t locstarttime, endtime, nowtime; - Music_StopAll(); // er, about that... - - // Fade to an inverted screen, with a circle fade... - F_WipeStartScreen(); - - V_EncoreInvertScreen(); - F_WipeEndScreen(); - - S_StartSound(NULL, sfx_ruby1); - F_RunWipe(wipe_encore_toinvert, wipedefs[wipe_encore_toinvert], false, NULL, false, false); - - // Hold on invert for extra effect. - // (This define might be useful for other areas of code? Not sure) #define WAIT(timetowait) \ locstarttime = nowtime = lastwipetic; \ endtime = locstarttime + timetowait; \ @@ -8415,6 +8394,28 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate) NetKeepAlive(); \ } \ + // Cancel all d_main.c fadeouts (keep fade in though). + if (reloadinggamestate) + wipegamestate = gamestate; // Don't fade if reloading the gamestate + // Encore mode fade to pink to white + // This is handled BEFORE sounds are stopped. + else if (encoremode && !prevencoremode && modeattacking == ATTACKING_NONE && !demo.rewinding) + { + if (rendermode != render_none) + { + Music_StopAll(); // er, about that... + + // Fade to an inverted screen, with a circle fade... + F_WipeStartScreen(); + + V_EncoreInvertScreen(); + F_WipeEndScreen(); + + S_StartSound(NULL, sfx_ruby1); + F_RunWipe(wipe_encore_toinvert, wipedefs[wipe_encore_toinvert], false, NULL, false, false); + + // Hold on invert for extra effect. + WAIT((3*TICRATE)/2); S_StartSound(NULL, sfx_ruby2); @@ -8441,9 +8442,15 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate) { // dedicated servers can call this now, to wait the appropriate amount of time for clients to wipe F_RunWipe(wipe_encore_towhite, wipedefs[wipe_encore_towhite], false, "FADEMAP1", false, true); + + WAIT((3*TICRATE)/2); + F_RunWipe(wipe_level_toblack, wipedefs[wipe_level_toblack], false, "FADEMAP0", false, false); + + WAIT((3*TICRATE)/4); } } +#undef WAIT // Special stage & record attack retry fade to white // This is handled BEFORE sounds are stopped. From 54d6914b5049042a76029d34d082d1e10081ad66 Mon Sep 17 00:00:00 2001 From: toaster Date: Fri, 12 Apr 2024 14:05:15 +0100 Subject: [PATCH 2/4] Add M_TryExactPassword Single-use password technology that exists outside of the enumerated list --- src/m_pw.cpp | 33 +++++++++++++++++++++++---------- src/m_pw.h | 1 + 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/m_pw.cpp b/src/m_pw.cpp index 894492932..11b95e4d6 100644 --- a/src/m_pw.cpp +++ b/src/m_pw.cpp @@ -43,22 +43,21 @@ namespace constexpr const UINT8 kRRSalt[17] = "0L4rlK}{9ay6'VJS"; +std::array decode_hash(std::string encoded) +{ + std::array decoded; + if (modp::b64_decode(encoded).size() != decoded.size()) + throw std::invalid_argument("hash is incorrectly sized"); + std::copy(encoded.begin(), encoded.end(), decoded.begin()); + return decoded; +} + struct Pw { Pw(void (*cb)(), const char *encoded_hash) : cb_(cb), hash_(decode_hash(encoded_hash)) {} void (*cb_)(); const std::array hash_; - -private: - static std::array decode_hash(std::string encoded) - { - std::array decoded; - if (modp::b64_decode(encoded).size() != decoded.size()) - throw std::invalid_argument("hash is incorrectly sized"); - std::copy(encoded.begin(), encoded.end(), decoded.begin()); - return decoded; - } }; std::vector passwords; @@ -342,6 +341,20 @@ try_password_e M_TryPassword(const char *password, boolean conditions) return return_code; } +boolean M_TryExactPassword(const char *password, const char *encodedhash) +{ + // Normalize input casing + std::string key = password; + strlwr(key.data()); + + UINT8 key_hash[M_PW_HASH_SIZE]; + M_HashPassword(key_hash, key.c_str(), kRRSalt); + + auto hash = decode_hash(encodedhash); + + return (memcmp(key_hash, hash.data(), M_PW_HASH_SIZE) == 0); +} + #ifdef DEVELOP void Command_Crypt_f(void) { diff --git a/src/m_pw.h b/src/m_pw.h index ec01f0b67..87efd98aa 100644 --- a/src/m_pw.h +++ b/src/m_pw.h @@ -27,6 +27,7 @@ try_password_e; void M_PasswordInit(void); try_password_e M_TryPassword(const char *password, boolean challenges); +boolean M_TryExactPassword(const char *password, const char *encodedhash); #ifdef __cplusplus } // extern "C" From 2caa5ff01856a925c4a4385b8a2b40c1a8a536dc Mon Sep 17 00:00:00 2001 From: toaster Date: Fri, 12 Apr 2024 14:17:33 +0100 Subject: [PATCH 3/4] Dedicated server -spoilers startup parameter Servers should get enough free for a healthy launch ecosystem, but not everything. We'll give the relevant password out after, like, the first week probably? Please be patient, commit-diver --- src/d_clisrv.c | 3 +-- src/d_main.cpp | 15 ++++++++++- src/g_game.c | 40 +++++++++++++-------------- src/m_cond.c | 73 +++++++++++++++++++++++++++++++++++++++++--------- src/m_cond.h | 1 + 5 files changed, 97 insertions(+), 35 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index a784102ce..586e88d61 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -3382,8 +3382,7 @@ void SV_ResetServer(void) // Copy our unlocks to a place where net material can grab at/overwrite them safely. // (permits all unlocks in dedicated) - for (i = 0; i < MAXUNLOCKABLES; i++) - netUnlocked[i] = (dedicated || gamedata->unlocked[i]); + M_SetNetUnlocked(); expectChallenge = false; diff --git a/src/d_main.cpp b/src/d_main.cpp index 3b139029b..5130cca6f 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -1538,6 +1538,19 @@ void D_SRB2Main(void) // for dedicated server dedicated = M_CheckParm("-dedicated") != 0; + if (dedicated) + { + p = M_CheckParm("-spoilers"); + if (p && M_IsNextParm()) + { + usedTourney = M_TryExactPassword(M_GetNextParm(), "XpsOixVTZSW0cwbiYAVgzokAmWfeYNq5mEckVsktheq4GOUWQecF5lWTkGNBJtoYX9vUMprFzraSovOSCeQ96Q=="); + + if (usedTourney) + { + CONS_Printf(M_GetText("Spoiler mode ON.\n")); + } + } + } if (devparm) CONS_Printf(M_GetText("Development mode ON.\n")); @@ -1932,7 +1945,7 @@ void D_SRB2Main(void) } { - if (!M_CheckParm("-server") && !M_CheckParm("-dedicated")) + if (!M_CheckParm("-server") && !dedicated) { G_SetUsedCheats(); diff --git a/src/g_game.c b/src/g_game.c index 8b509fd67..9b6950359 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3640,12 +3640,12 @@ static INT32 TOLMaps(UINT8 pgametype) // Not completed continue; } + } - if (M_MapLocked(i + 1) == true) - { - // We haven't earned this one. - continue; - } + if (M_MapLocked(i + 1) == true) + { + // We haven't earned this one. + continue; } num++; @@ -3753,12 +3753,12 @@ tryAgain: // Not completed continue; } + } - if (M_MapLocked(i + 1) == true) - { - // We haven't earned this one. - continue; - } + if (M_MapLocked(i + 1) == true) + { + // We haven't earned this one. + continue; } if (ignoreBuffers == false) @@ -4331,12 +4331,12 @@ void G_GetNextMap(void) // Not completed continue; } + } - if (M_MapLocked(cm + 1) == true) - { - // We haven't earned this one. - continue; - } + if (M_MapLocked(cm + 1) == true) + { + // We haven't earned this one. + continue; } // If the map is in multiple cups, only consider the first one valid. @@ -4416,12 +4416,12 @@ void G_GetNextMap(void) // Not completed continue; } + } - if (M_MapLocked(cm + 1) == true) - { - // We haven't earned this one. - continue; - } + if (M_MapLocked(cm + 1) == true) + { + // We haven't earned this one. + continue; } break; diff --git a/src/m_cond.c b/src/m_cond.c index cfe396886..fe095be8c 100644 --- a/src/m_cond.c +++ b/src/m_cond.c @@ -734,8 +734,7 @@ void M_ClearSecrets(void) memset(gamedata->collected, 0, sizeof(gamedata->collected)); memset(gamedata->unlocked, 0, sizeof(gamedata->unlocked)); memset(gamedata->unlockpending, 0, sizeof(gamedata->unlockpending)); - if (!dedicated) - memset(netUnlocked, 0, sizeof(netUnlocked)); + memset(netUnlocked, 0, sizeof(netUnlocked)); memset(gamedata->achieved, 0, sizeof(gamedata->achieved)); Z_Free(gamedata->spraycans); @@ -1281,6 +1280,66 @@ void M_FinaliseGameData(void) M_UpdateUnlockablesAndExtraEmblems(false, true); } +void M_SetNetUnlocked(void) +{ + UINT16 i; + + // Use your gamedata as baseline + for (i = 0; i < MAXUNLOCKABLES; i++) + { + netUnlocked[i] = gamedata->unlocked[i]; + } + + if (!dedicated) + { + return; + } + + // Dedicated spoiler password - tournament mode equivalent. + if (usedTourney) + { + for (i = 0; i < MAXUNLOCKABLES; i++) + { + if (unlockables[i].conditionset == 55) + continue; + + netUnlocked[i] = true; + } + + return; + } + + // Okay, now it's dedicated first-week spoilerless behaviour. + for (i = 0; i < MAXUNLOCKABLES; i++) + { + if (netUnlocked[i]) + continue; + + switch (unlockables[i].type) + { + case SECRET_CUP: + { + // Give the first seven Cups for free. + cupheader_t *cup = M_UnlockableCup(&unlockables[i]); + if (cup && cup->id < 7) + netUnlocked[i] = true; + + break; + } + case SECRET_ADDONS: + { + netUnlocked[i] = true; + break; + } + default: + { + // Most stuff isn't given to dedis for free + break; + } + } + } +} + // ---------------------- // Condition set checking // ---------------------- @@ -3404,11 +3463,6 @@ boolean M_SecretUnlocked(INT32 type, boolean local) boolean M_CupLocked(cupheader_t *cup) { - // Don't lock maps in dedicated servers. - // That just makes hosts' lives hell. - if (dedicated) - return false; - // No skipping over any part of your marathon. if (marathonmode) return false; @@ -3464,11 +3518,6 @@ boolean M_CupSecondRowLocked(void) boolean M_MapLocked(UINT16 mapnum) { - // Don't lock maps in dedicated servers. - // That just makes hosts' lives hell. - if (dedicated) - return false; - // No skipping over any part of your marathon. if (marathonmode) return false; diff --git a/src/m_cond.h b/src/m_cond.h index b23d267f1..d0881ae3b 100644 --- a/src/m_cond.h +++ b/src/m_cond.h @@ -443,6 +443,7 @@ void M_ClearConditionSet(UINT16 set); void M_ClearSecrets(void); void M_ClearStats(void); void M_FinaliseGameData(void); +void M_SetNetUnlocked(void); boolean M_NotFreePlay(void); UINT16 M_CheckCupEmeralds(UINT8 difficulty); From 12fe57a805814286dee3d46d0896941fdf55681d Mon Sep 17 00:00:00 2001 From: toaster Date: Fri, 12 Apr 2024 14:20:06 +0100 Subject: [PATCH 4/4] P_InitMapData: Don't print the base map names in the startup/dedicated log --- src/p_setup.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/p_setup.cpp b/src/p_setup.cpp index e8ce43e49..4bb950d8e 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -9142,15 +9142,19 @@ UINT8 P_InitMapData(void) // Okay, it does... { ret |= MAPRET_ADDED; - CONS_Printf("%s\n", name); - if (basenummapheaders && mapheaderinfo[i]->lumpnum != LUMPERROR) + if (basenummapheaders) { - G_SetGameModified(multiplayer, true); // oops, double-defined - no record attack privileges for you + CONS_Printf("%s\n", name); - //If you replaced the map you're on, end the level when done. - if (i == gamemap - 1) - ret |= MAPRET_CURRENTREPLACED; + if (mapheaderinfo[i]->lumpnum != LUMPERROR) + { + G_SetGameModified(multiplayer, true); // oops, double-defined - no record attack privileges for you + + //If you replaced the map you're on, end the level when done. + if (i == gamemap - 1) + ret |= MAPRET_CURRENTREPLACED; + } } mapheaderinfo[i]->lumpnum = maplump;