From 36b8ab1eac2edf407e05d98a04889a5f73238f64 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sun, 27 Feb 2022 10:11:55 -0500 Subject: [PATCH 01/25] Streamline cheats "cheats" is a proper cvar now. Enabling it allows for cheats to be used any time, even in multiplayer, and disables gamedata saving. Turning it off undoes as many cheat commands as reasonably possible. Based a little bit off of some vanilla work I also did. Many cheat commands are still SP-only, but can reasonably be allowed in netgames now if a net command is created for them. --- src/command.c | 81 ++++++++++------- src/command.h | 6 +- src/d_clisrv.c | 2 +- src/d_main.c | 21 +++-- src/d_netcmd.c | 233 +++++++++++++++---------------------------------- src/d_netcmd.h | 2 +- src/d_player.h | 12 ++- src/doomdef.h | 10 +-- src/doomstat.h | 3 +- src/f_finale.c | 17 +--- src/g_game.c | 108 +++++++++++++++-------- src/g_game.h | 1 + src/k_kart.c | 1 - src/m_cheat.c | 96 +++++++++----------- src/m_cond.c | 14 ++- src/m_menu.c | 4 +- src/p_inter.c | 2 +- src/p_map.c | 2 +- src/p_mobj.c | 44 ++++------ src/p_setup.c | 5 +- src/p_user.c | 2 +- src/r_skins.c | 2 +- 22 files changed, 303 insertions(+), 365 deletions(-) diff --git a/src/command.c b/src/command.c index a0f2967bf..8f72331f7 100644 --- a/src/command.c +++ b/src/command.c @@ -73,6 +73,15 @@ CV_PossibleValue_t CV_YesNo[] = {{0, "No"}, {1, "Yes"}, {0, NULL}}; CV_PossibleValue_t CV_Unsigned[] = {{0, "MIN"}, {999999999, "MAX"}, {0, NULL}}; CV_PossibleValue_t CV_Natural[] = {{1, "MIN"}, {999999999, "MAX"}, {0, NULL}}; +// Cheats +#ifdef DEVELOP + #define VALUE "On" +#else + #define VALUE "Off" +#endif +consvar_t cv_cheats = CVAR_INIT ("cheats", VALUE, CV_NETVAR|CV_CALL, CV_OnOff, CV_CheatsChanged); +#undef VALUE + // SRB2kart CV_PossibleValue_t kartspeed_cons_t[] = { {KARTSPEED_AUTO, "Auto"}, @@ -336,6 +345,9 @@ void COM_Init(void) // allocate command buffer VS_Alloc(&com_text, COM_BUF_SIZE); + // cheats is a special cvar, so register it ASAP + CV_RegisterVar(&cv_cheats); + // add standard commands COM_AddCommand("alias", COM_Alias_f); COM_AddCommand("echo", COM_Echo_f); @@ -1340,12 +1352,11 @@ static void Setvalue(consvar_t *var, const char *valstr, boolean stealth) boolean override = false; INT32 overrideval = 0; - // If we want messages informing us if cheats have been enabled or disabled, - // we need to rework the consvars a little bit. This call crashes the game - // on load because not all variables will be registered at that time. -/* boolean prevcheats = false; - if (var->flags & CV_CHEAT) - prevcheats = CV_CheatsEnabled(); */ + if ((var->flags & CV_CHEAT) && CV_CheatsEnabled() == false) + { + // Enforce to default value without cheats. + valstr = var->defaultvalue; + } if (var->PossibleValue) { @@ -1506,17 +1517,6 @@ found: } finish: - // See the note above. -/* if (var->flags & CV_CHEAT) - { - boolean newcheats = CV_CheatsEnabled(); - - if (!prevcheats && newcheats) - CONS_Printf(M_GetText("Cheats have been enabled.\n")); - else if (prevcheats && !newcheats) - CONS_Printf(M_GetText("Cheats have been disabled.\n")); - } */ - if (var->flags & CV_SHOWMODIFONETIME || var->flags & CV_SHOWMODIF) { CONS_Printf(M_GetText("%s set to %s\n"), var->name, var->string); @@ -1526,10 +1526,13 @@ finish: { DEBFILE(va("%s set to %s\n", var->name, var->string)); } + var->flags |= CV_MODIFIED; + // raise 'on change' code LUA_CVarChanged(var); // let consolelib know what cvar this is. - if (var->flags & CV_CALL && !stealth) + + if ((var->flags & CV_CALL) && !stealth) var->func(); return; @@ -1750,14 +1753,33 @@ void CV_LoadDemoVars(UINT8 **p) static void CV_SetCVar(consvar_t *var, const char *value, boolean stealth); -void CV_ResetCheatNetVars(void) +void CV_CheatsChanged(void) { - consvar_t *cvar; + if (CV_CheatsEnabled()) + { + G_SetUsedCheats(); + } + else + { + consvar_t *cvar; + UINT8 i; - // Stealthset everything back to default. - for (cvar = consvar_vars; cvar; cvar = cvar->next) - if (cvar->flags & CV_CHEAT) - CV_SetCVar(cvar, cvar->defaultvalue, true); + // Set everything back to default. + for (cvar = consvar_vars; cvar; cvar = cvar->next) + if (cvar->flags & CV_CHEAT) + CV_SetCVar(cvar, cvar->defaultvalue, false); + + // Reset any other cheat command effects here, as well. + cv_debug = 0; + + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + + players[i].cheats = 0; + } + } } // Returns true if the variable's current value is its default value @@ -1768,16 +1790,9 @@ boolean CV_IsSetToDefault(consvar_t *v) // If any cheats CVars are not at their default settings, return true. // Else return false. -// This returns a UINT8 because I'm too lazy to deal with the packet structure. -// Deal with it. =P -UINT8 CV_CheatsEnabled(void) +boolean CV_CheatsEnabled(void) { - consvar_t *cvar; - - for (cvar = consvar_vars; cvar; cvar = cvar->next) - if ((cvar->flags & CV_CHEAT) && strcmp(cvar->defaultvalue, cvar->string)) - return 1; - return 0; + return (boolean)cv_cheats.value; } /** Sets a value to a variable, performing some checks and calling the diff --git a/src/command.h b/src/command.h index a9558626b..d76cb0bd8 100644 --- a/src/command.h +++ b/src/command.h @@ -122,7 +122,7 @@ typedef enum CV_NOSHOWHELP = 512, // Don't show variable in the HELP list Tails 08-13-2002 CV_HIDEN = 1024, // variable is not part of the cvar list so cannot be accessed by the console // can only be set when we have the pointer to it - // used on menus + // used on menus CV_CHEAT = 2048, // Don't let this be used in multiplayer unless cheats are on. CV_NOLUA = 4096,/* don't let this be called from Lua */ } cvflags_t; @@ -223,10 +223,10 @@ void CV_RevertNetVars(void); void CV_LoadDemoVars(UINT8 **p); // reset cheat netvars after cheats is deactivated -void CV_ResetCheatNetVars(void); +void CV_CheatsChanged(void); boolean CV_IsSetToDefault(consvar_t *v); -UINT8 CV_CheatsEnabled(void); +boolean CV_CheatsEnabled(void); // Returns cvar by name. Exposed here for Lua. consvar_t *CV_FindVar(const char *name); diff --git a/src/d_clisrv.c b/src/d_clisrv.c index b03eb478e..2a1ec303b 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -901,7 +901,7 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime) strncpy(netbuffer->u.serverinfo.gametypename, Gametype_Names[gametype], sizeof netbuffer->u.serverinfo.gametypename); netbuffer->u.serverinfo.modifiedgame = (UINT8)modifiedgame; - netbuffer->u.serverinfo.cheatsenabled = CV_CheatsEnabled(); + netbuffer->u.serverinfo.cheatsenabled = (UINT8)CV_CheatsEnabled(); netbuffer->u.serverinfo.kartvars = (UINT8) ( (gamespeed & SV_SPEEDMASK) | diff --git a/src/d_main.c b/src/d_main.c index 9c5b6e254..cbd6a2a8d 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1548,6 +1548,12 @@ void D_SRB2Main(void) if (M_CheckParm("-noupload")) COM_BufAddText("downloading 0\n"); + if (M_CheckParm("-gamedata") && M_IsNextParm()) + { + // Moved from G_LoadGameData itself, as it would cause some crazy + // confusion issues when loading mods. + strlcpy(gamedatafilename, M_GetNextParm(), sizeof gamedatafilename); + } G_LoadGameData(); wipegamestate = gamestate; @@ -1631,7 +1637,7 @@ void D_SRB2Main(void) { if (!M_CheckParm("-server")) { - G_SetGameModified(true, true); + G_SetUsedCheats(); // Start up a "minor" grand prix session memset(&grandprixinfo, 0, sizeof(struct grandprixinfo)); @@ -1842,15 +1848,16 @@ void D_SRB2Main(void) { // Prevent warping to nonexistent levels if (W_CheckNumForName(G_BuildMapName(pstartmap)) == LUMPERROR) + { I_Error("Could not warp to %s (map not found)\n", G_BuildMapName(pstartmap)); - // Prevent warping to locked levels - // ... unless you're in a dedicated server. Yes, technically this means you can view any level by - // running a dedicated server and joining it yourself, but that's better than making dedicated server's - // lives hell. - else if (!dedicated && M_MapLocked(pstartmap)) - I_Error("You need to unlock this level before you can warp to it!\n"); + } else { + if (M_MapLocked(pstartmap)) + { + G_SetUsedCheats(); + } + D_MapChange(pstartmap, gametype, (cv_kartencore.value == 1), true, 0, false, false); } } diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 28b816b3a..fe411f139 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -62,12 +62,6 @@ #include "doomstat.h" #include "deh_tables.h" -#ifdef NETGAME_DEVMODE -#define CV_RESTRICT CV_NETVAR -#else -#define CV_RESTRICT 0 -#endif - #ifdef HAVE_DISCORDRPC #include "discord.h" #endif @@ -148,10 +142,6 @@ static void KartEncore_OnChange(void); static void KartComeback_OnChange(void); static void KartEliminateLast_OnChange(void); -#ifdef NETGAME_DEVMODE -static void Fishcake_OnChange(void); -#endif - static void Command_Playdemo_f(void); static void Command_Timedemo_f(void); static void Command_Stopdemo_f(void); @@ -213,7 +203,6 @@ static void Command_ShowScores_f(void); static void Command_ShowTime_f(void); static void Command_Isgamemodified_f(void); -static void Command_Cheats_f(void); #ifdef _DEBUG static void Command_Togglemodified_f(void); static void Command_Archivetest_f(void); @@ -245,9 +234,6 @@ static CV_PossibleValue_t pause_cons_t[] = {{0, "Server"}, {1, "All"}, {0, NULL} consvar_t cv_showinputjoy = CVAR_INIT ("showinputjoy", "Off", 0, CV_OnOff, NULL); -#ifdef NETGAME_DEVMODE -static consvar_t cv_fishcake = CVAR_INIT ("fishcake", "Off", CV_CALL|CV_NOSHOWHELP|CV_RESTRICT, CV_OnOff, Fishcake_OnChange); -#endif static consvar_t cv_dummyconsvar = CVAR_INIT ("dummyconsvar", "Off", CV_CALL|CV_NOSHOWHELP, CV_OnOff, DummyConsvar_OnChange); consvar_t cv_restrictskinchange = CVAR_INIT ("restrictskinchange", "No", CV_NETVAR|CV_CHEAT, CV_YesNo, NULL); @@ -341,35 +327,35 @@ consvar_t cv_joyscale[MAXSPLITSCREENPLAYERS] = { //Alam: Dummy for save #endif // SRB2kart -consvar_t cv_superring = CVAR_INIT ("superring", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL); -consvar_t cv_sneaker = CVAR_INIT ("sneaker", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL); -consvar_t cv_rocketsneaker = CVAR_INIT ("rocketsneaker", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL); -consvar_t cv_invincibility = CVAR_INIT ("invincibility", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL); -consvar_t cv_banana = CVAR_INIT ("banana", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL); -consvar_t cv_eggmanmonitor = CVAR_INIT ("eggmanmonitor", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL); -consvar_t cv_orbinaut = CVAR_INIT ("orbinaut", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL); -consvar_t cv_jawz = CVAR_INIT ("jawz", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL); -consvar_t cv_mine = CVAR_INIT ("mine", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL); -consvar_t cv_landmine = CVAR_INIT ("landmine", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL); -consvar_t cv_droptarget = CVAR_INIT ("droptarget", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL); -consvar_t cv_ballhog = CVAR_INIT ("ballhog", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL); -consvar_t cv_selfpropelledbomb = CVAR_INIT ("selfpropelledbomb", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL); -consvar_t cv_grow = CVAR_INIT ("grow", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL); -consvar_t cv_shrink = CVAR_INIT ("shrink", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL); -consvar_t cv_lightningshield = CVAR_INIT ("lightningshield", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL); -consvar_t cv_bubbleshield = CVAR_INIT ("bubbleshield", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL); -consvar_t cv_flameshield = CVAR_INIT ("flameshield", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL); -consvar_t cv_hyudoro = CVAR_INIT ("hyudoro", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL); -consvar_t cv_pogospring = CVAR_INIT ("pogospring", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL); -consvar_t cv_kitchensink = CVAR_INIT ("kitchensink", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL); +consvar_t cv_superring = CVAR_INIT ("superring", "On", CV_NETVAR, CV_OnOff, NULL); +consvar_t cv_sneaker = CVAR_INIT ("sneaker", "On", CV_NETVAR, CV_OnOff, NULL); +consvar_t cv_rocketsneaker = CVAR_INIT ("rocketsneaker", "On", CV_NETVAR, CV_OnOff, NULL); +consvar_t cv_invincibility = CVAR_INIT ("invincibility", "On", CV_NETVAR, CV_OnOff, NULL); +consvar_t cv_banana = CVAR_INIT ("banana", "On", CV_NETVAR, CV_OnOff, NULL); +consvar_t cv_eggmanmonitor = CVAR_INIT ("eggmanmonitor", "On", CV_NETVAR, CV_OnOff, NULL); +consvar_t cv_orbinaut = CVAR_INIT ("orbinaut", "On", CV_NETVAR, CV_OnOff, NULL); +consvar_t cv_jawz = CVAR_INIT ("jawz", "On", CV_NETVAR, CV_OnOff, NULL); +consvar_t cv_mine = CVAR_INIT ("mine", "On", CV_NETVAR, CV_OnOff, NULL); +consvar_t cv_landmine = CVAR_INIT ("landmine", "On", CV_NETVAR, CV_OnOff, NULL); +consvar_t cv_droptarget = CVAR_INIT ("droptarget", "On", CV_NETVAR, CV_OnOff, NULL); +consvar_t cv_ballhog = CVAR_INIT ("ballhog", "On", CV_NETVAR, CV_OnOff, NULL); +consvar_t cv_selfpropelledbomb = CVAR_INIT ("selfpropelledbomb", "On", CV_NETVAR, CV_OnOff, NULL); +consvar_t cv_grow = CVAR_INIT ("grow", "On", CV_NETVAR, CV_OnOff, NULL); +consvar_t cv_shrink = CVAR_INIT ("shrink", "On", CV_NETVAR, CV_OnOff, NULL); +consvar_t cv_lightningshield = CVAR_INIT ("lightningshield", "On", CV_NETVAR, CV_OnOff, NULL); +consvar_t cv_bubbleshield = CVAR_INIT ("bubbleshield", "On", CV_NETVAR, CV_OnOff, NULL); +consvar_t cv_flameshield = CVAR_INIT ("flameshield", "On", CV_NETVAR, CV_OnOff, NULL); +consvar_t cv_hyudoro = CVAR_INIT ("hyudoro", "On", CV_NETVAR, CV_OnOff, NULL); +consvar_t cv_pogospring = CVAR_INIT ("pogospring", "On", CV_NETVAR, CV_OnOff, NULL); +consvar_t cv_kitchensink = CVAR_INIT ("kitchensink", "On", CV_NETVAR, CV_OnOff, NULL); -consvar_t cv_dualsneaker = CVAR_INIT ("dualsneaker", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL); -consvar_t cv_triplesneaker = CVAR_INIT ("triplesneaker", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL); -consvar_t cv_triplebanana = CVAR_INIT ("triplebanana", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL); -consvar_t cv_decabanana = CVAR_INIT ("decabanana", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL); -consvar_t cv_tripleorbinaut = CVAR_INIT ("tripleorbinaut", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL); -consvar_t cv_quadorbinaut = CVAR_INIT ("quadorbinaut", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL); -consvar_t cv_dualjawz = CVAR_INIT ("dualjawz", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL); +consvar_t cv_dualsneaker = CVAR_INIT ("dualsneaker", "On", CV_NETVAR, CV_OnOff, NULL); +consvar_t cv_triplesneaker = CVAR_INIT ("triplesneaker", "On", CV_NETVAR, CV_OnOff, NULL); +consvar_t cv_triplebanana = CVAR_INIT ("triplebanana", "On", CV_NETVAR, CV_OnOff, NULL); +consvar_t cv_decabanana = CVAR_INIT ("decabanana", "On", CV_NETVAR, CV_OnOff, NULL); +consvar_t cv_tripleorbinaut = CVAR_INIT ("tripleorbinaut", "On", CV_NETVAR, CV_OnOff, NULL); +consvar_t cv_quadorbinaut = CVAR_INIT ("quadorbinaut", "On", CV_NETVAR, CV_OnOff, NULL); +consvar_t cv_dualjawz = CVAR_INIT ("dualjawz", "On", CV_NETVAR, CV_OnOff, NULL); static CV_PossibleValue_t kartminimap_cons_t[] = {{0, "MIN"}, {10, "MAX"}, {0, NULL}}; consvar_t cv_kartminimap = CVAR_INIT ("kartminimap", "4", CV_SAVE, kartminimap_cons_t, NULL); @@ -378,9 +364,9 @@ static CV_PossibleValue_t kartinvinsfx_cons_t[] = {{0, "Music"}, {1, "SFX"}, {0, consvar_t cv_kartinvinsfx = CVAR_INIT ("kartinvinsfx", "SFX", CV_SAVE, kartinvinsfx_cons_t, NULL); consvar_t cv_kartspeed = CVAR_INIT ("kartspeed", "Auto", CV_NETVAR|CV_CALL|CV_NOINIT, kartspeed_cons_t, KartSpeed_OnChange); static CV_PossibleValue_t kartbumpers_cons_t[] = {{1, "MIN"}, {12, "MAX"}, {0, NULL}}; -consvar_t cv_kartbumpers = CVAR_INIT ("kartbumpers", "3", CV_NETVAR|CV_CHEAT, kartbumpers_cons_t, NULL); -consvar_t cv_kartfrantic = CVAR_INIT ("kartfrantic", "Off", CV_NETVAR|CV_CHEAT|CV_CALL|CV_NOINIT, CV_OnOff, KartFrantic_OnChange); -consvar_t cv_kartcomeback = CVAR_INIT ("kartcomeback", "On", CV_NETVAR|CV_CHEAT|CV_CALL|CV_NOINIT, CV_OnOff, KartComeback_OnChange); +consvar_t cv_kartbumpers = CVAR_INIT ("kartbumpers", "3", CV_NETVAR, kartbumpers_cons_t, NULL); +consvar_t cv_kartfrantic = CVAR_INIT ("kartfrantic", "Off", CV_NETVAR|CV_CALL|CV_NOINIT, CV_OnOff, KartFrantic_OnChange); +consvar_t cv_kartcomeback = CVAR_INIT ("kartcomeback", "On", CV_NETVAR|CV_CALL|CV_NOINIT, CV_OnOff, KartComeback_OnChange); static CV_PossibleValue_t kartencore_cons_t[] = {{-1, "Auto"}, {0, "Off"}, {1, "On"}, {0, NULL}}; consvar_t cv_kartencore = CVAR_INIT ("kartencore", "Auto", CV_NETVAR|CV_CALL|CV_NOINIT, kartencore_cons_t, KartEncore_OnChange); static CV_PossibleValue_t kartvoterulechanges_cons_t[] = {{0, "Never"}, {1, "Sometimes"}, {2, "Frequent"}, {3, "Always"}, {0, NULL}}; @@ -409,9 +395,9 @@ static CV_PossibleValue_t kartbot_cons_t[] = { }; consvar_t cv_kartbot = CVAR_INIT ("kartbot", "0", CV_NETVAR, kartbot_cons_t, NULL); -consvar_t cv_karteliminatelast = CVAR_INIT ("karteliminatelast", "Yes", CV_NETVAR|CV_CHEAT|CV_CALL, CV_YesNo, KartEliminateLast_OnChange); +consvar_t cv_karteliminatelast = CVAR_INIT ("karteliminatelast", "Yes", CV_NETVAR|CV_CALL, CV_YesNo, KartEliminateLast_OnChange); -consvar_t cv_kartusepwrlv = CVAR_INIT ("kartusepwrlv", "Yes", CV_NETVAR|CV_CHEAT, CV_YesNo, NULL); +consvar_t cv_kartusepwrlv = CVAR_INIT ("kartusepwrlv", "Yes", CV_NETVAR, CV_YesNo, NULL); static CV_PossibleValue_t kartdebugitem_cons_t[] = { @@ -420,37 +406,30 @@ static CV_PossibleValue_t kartdebugitem_cons_t[] = #undef FOREACH {0} }; -consvar_t cv_kartdebugitem = CVAR_INIT ("kartdebugitem", "0", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, kartdebugitem_cons_t, NULL); +consvar_t cv_kartdebugitem = CVAR_INIT ("kartdebugitem", "0", CV_NETVAR|CV_CHEAT, kartdebugitem_cons_t, NULL); static CV_PossibleValue_t kartdebugamount_cons_t[] = {{1, "MIN"}, {255, "MAX"}, {0, NULL}}; -consvar_t cv_kartdebugamount = CVAR_INIT ("kartdebugamount", "1", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, kartdebugamount_cons_t, NULL); -#ifdef DEVELOP -#define VALUE "Yes" -#else -#define VALUE "No" -#endif -consvar_t cv_kartallowgiveitem = CVAR_INIT ("kartallowgiveitem", VALUE, CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, CV_YesNo, NULL); -#undef VALUE +consvar_t cv_kartdebugamount = CVAR_INIT ("kartdebugamount", "1", CV_NETVAR|CV_CHEAT, kartdebugamount_cons_t, NULL); -consvar_t cv_kartdebugdistribution = CVAR_INIT ("kartdebugdistribution", "Off", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, CV_OnOff, NULL); -consvar_t cv_kartdebughuddrop = CVAR_INIT ("kartdebughuddrop", "Off", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, CV_OnOff, NULL); +consvar_t cv_kartdebugdistribution = CVAR_INIT ("kartdebugdistribution", "Off", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL); +consvar_t cv_kartdebughuddrop = CVAR_INIT ("kartdebughuddrop", "Off", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL); static CV_PossibleValue_t kartdebugwaypoint_cons_t[] = {{0, "Off"}, {1, "Forwards"}, {2, "Backwards"}, {0, NULL}}; -consvar_t cv_kartdebugwaypoints = CVAR_INIT ("kartdebugwaypoints", "Off", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, kartdebugwaypoint_cons_t, NULL); -consvar_t cv_kartdebugbotpredict = CVAR_INIT ("kartdebugbotpredict", "Off", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, CV_OnOff, NULL); +consvar_t cv_kartdebugwaypoints = CVAR_INIT ("kartdebugwaypoints", "Off", CV_NETVAR|CV_CHEAT, kartdebugwaypoint_cons_t, NULL); +consvar_t cv_kartdebugbotpredict = CVAR_INIT ("kartdebugbotpredict", "Off", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL); -consvar_t cv_kartdebugcheckpoint = CVAR_INIT ("kartdebugcheckpoint", "Off", CV_NOSHOWHELP, CV_OnOff, NULL); -consvar_t cv_kartdebugnodes = CVAR_INIT ("kartdebugnodes", "Off", CV_NOSHOWHELP, CV_OnOff, NULL); -consvar_t cv_kartdebugcolorize = CVAR_INIT ("kartdebugcolorize", "Off", CV_NOSHOWHELP, CV_OnOff, NULL); -consvar_t cv_kartdebugdirector = CVAR_INIT ("kartdebugdirector", "Off", CV_NOSHOWHELP, CV_OnOff, NULL); +consvar_t cv_kartdebugcheckpoint = CVAR_INIT ("kartdebugcheckpoint", "Off", CV_CHEAT, CV_OnOff, NULL); +consvar_t cv_kartdebugnodes = CVAR_INIT ("kartdebugnodes", "Off", CV_CHEAT, CV_OnOff, NULL); +consvar_t cv_kartdebugcolorize = CVAR_INIT ("kartdebugcolorize", "Off", CV_CHEAT, CV_OnOff, NULL); +consvar_t cv_kartdebugdirector = CVAR_INIT ("kartdebugdirector", "Off", CV_CHEAT, CV_OnOff, NULL); static CV_PossibleValue_t votetime_cons_t[] = {{10, "MIN"}, {3600, "MAX"}, {0, NULL}}; consvar_t cv_votetime = CVAR_INIT ("votetime", "20", CV_NETVAR, votetime_cons_t, NULL); -consvar_t cv_gravity = CVAR_INIT ("gravity", "0.8", CV_RESTRICT|CV_FLOAT|CV_CALL, NULL, Gravity_OnChange); // change DEFAULT_GRAVITY if you change this +consvar_t cv_gravity = CVAR_INIT ("gravity", "0.8", CV_CHEAT|CV_FLOAT|CV_CALL, NULL, Gravity_OnChange); // change DEFAULT_GRAVITY if you change this consvar_t cv_soundtest = CVAR_INIT ("soundtest", "0", CV_CALL, NULL, SoundTest_OnChange); static CV_PossibleValue_t minitimelimit_cons_t[] = {{15, "MIN"}, {9999, "MAX"}, {0, NULL}}; -consvar_t cv_countdowntime = CVAR_INIT ("countdowntime", "30", CV_NETVAR|CV_CHEAT, minitimelimit_cons_t, NULL); +consvar_t cv_countdowntime = CVAR_INIT ("countdowntime", "30", CV_NETVAR, minitimelimit_cons_t, NULL); consvar_t cv_autobalance = CVAR_INIT ("autobalance", "Off", CV_SAVE|CV_NETVAR|CV_CALL, CV_OnOff, AutoBalance_OnChange); consvar_t cv_teamscramble = CVAR_INIT ("teamscramble", "Off", CV_SAVE|CV_NETVAR|CV_CALL|CV_NOINIT, teamscramble_cons_t, TeamScramble_OnChange); @@ -459,7 +438,7 @@ consvar_t cv_scrambleonchange = CVAR_INIT ("scrambleonchange", "Off", CV_SAVE|CV consvar_t cv_itemfinder = CVAR_INIT ("itemfinder", "Off", CV_CALL|CV_NOSHOWHELP, CV_OnOff, ItemFinder_OnChange); // Scoring type options -consvar_t cv_overtime = CVAR_INIT ("overtime", "Yes", CV_NETVAR|CV_CHEAT, CV_YesNo, NULL); +consvar_t cv_overtime = CVAR_INIT ("overtime", "Yes", CV_NETVAR, CV_YesNo, NULL); consvar_t cv_rollingdemos = CVAR_INIT ("rollingdemos", "On", CV_SAVE, CV_OnOff, NULL); @@ -470,7 +449,7 @@ consvar_t cv_timelimit = CVAR_INIT ("timelimit", "None", CV_SAVE|CV_NETVAR|CV_CA static CV_PossibleValue_t numlaps_cons_t[] = {{1, "MIN"}, {99, "MAX"}, {0, NULL}}; consvar_t cv_numlaps = CVAR_INIT ("numlaps", "3", CV_NETVAR|CV_CALL|CV_NOINIT, numlaps_cons_t, NumLaps_OnChange); static CV_PossibleValue_t basenumlaps_cons_t[] = {{1, "MIN"}, {99, "MAX"}, {0, "Map default"}, {0, NULL}}; -consvar_t cv_basenumlaps = CVAR_INIT ("basenumlaps", "Map default", CV_SAVE|CV_NETVAR|CV_CALL|CV_CHEAT, basenumlaps_cons_t, BaseNumLaps_OnChange); +consvar_t cv_basenumlaps = CVAR_INIT ("basenumlaps", "Map default", CV_SAVE|CV_NETVAR|CV_CALL, basenumlaps_cons_t, BaseNumLaps_OnChange); // Point and time limits for every gametype INT32 pointlimits[NUMGAMETYPES]; @@ -671,7 +650,6 @@ void D_RegisterServerCommands(void) COM_AddCommand("isgamemodified", Command_Isgamemodified_f); // test COM_AddCommand("showscores", Command_ShowScores_f); COM_AddCommand("showtime", Command_ShowTime_f); - COM_AddCommand("cheats", Command_Cheats_f); // test #ifdef _DEBUG COM_AddCommand("togglemodified", Command_Togglemodified_f); COM_AddCommand("archivetest", Command_Archivetest_f); @@ -883,10 +861,6 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_netstat); CV_RegisterVar(&cv_netticbuffer); -#ifdef NETGAME_DEVMODE - CV_RegisterVar(&cv_fishcake); -#endif - // HUD CV_RegisterVar(&cv_itemfinder); CV_RegisterVar(&cv_showinputjoy); @@ -2577,7 +2551,8 @@ static void Command_Map_f(void) const char *gametypename; boolean newresetplayers; - boolean mustmodifygame; + boolean usingcheats; + boolean ischeating; INT32 newmapnum; @@ -2601,20 +2576,8 @@ static void Command_Map_f(void) option_skill = COM_CheckPartialParm("-s"); newresetplayers = ! COM_CheckParm("-noresetplayers"); - mustmodifygame = !(netgame || multiplayer) && !majormods; - - if (mustmodifygame && !option_force) - { - /* May want to be more descriptive? */ - CONS_Printf(M_GetText("Sorry, level change disabled in single player.\n")); - return; - } - - if (!newresetplayers && !cv_debug) - { - CONS_Printf(M_GetText("DEVMODE must be enabled.\n")); - return; - } + usingcheats = CV_CheatsEnabled(); + ischeating = (!(netgame || multiplayer)) || (!newresetplayers); if (option_gametype) { @@ -2657,9 +2620,15 @@ static void Command_Map_f(void) return; } - if (mustmodifygame && option_force) + if (M_MapLocked(newmapnum)) { - G_SetGameModified(multiplayer, true); + ischeating = true; + } + + if (ischeating && !usingcheats) + { + CONS_Printf(M_GetText("Cheats must be enabled.\n")); + return; } // new gametype value @@ -2716,7 +2685,7 @@ static void Command_Map_f(void) { newencoremode = !newencoremode; - if (!M_SecretUnlocked(SECRET_ENCORE) && newencoremode == true && !option_force) + if (!M_SecretUnlocked(SECRET_ENCORE) && newencoremode == true && !usingcheats) { CONS_Alert(CONS_NOTICE, M_GetText("You haven't unlocked Encore Mode yet!\n")); return; @@ -2728,10 +2697,12 @@ static void Command_Map_f(void) // don't use a gametype the map doesn't support if (cv_debug || option_force || cv_skipmapcheck.value) + { fromlevelselect = false; // The player wants us to trek on anyway. Do so. - // G_TOLFlag handles both multiplayer gametype and ignores it for !multiplayer + } else { + // G_TOLFlag handles both multiplayer gametype and ignores it for !multiplayer if (!( mapheaderinfo[newmapnum-1] && mapheaderinfo[newmapnum-1]->typeoflevel & G_TOLFlag(newgametype) @@ -2829,18 +2800,6 @@ static void Command_Map_f(void) } } - // Prevent warping to locked levels - // ... unless you're in a dedicated server. Yes, technically this means you can view any level by - // running a dedicated server and joining it yourself, but that's better than making dedicated server's - // lives hell. - if (!dedicated && M_MapLocked(newmapnum)) - { - CONS_Alert(CONS_NOTICE, M_GetText("You need to unlock this level before you can warp to it!\n")); - Z_Free(realmapname); - Z_Free(mapname); - return; - } - if (tutorialmode && tutorialgcs) { G_CopyControls(gamecontrol[0], gamecontroldefault[0][gcs_custom], gcl_full, num_gcl_full); // using gcs_custom as temp storage @@ -4625,23 +4584,12 @@ void D_GameTypeChanged(INT32 lastgametype) static void Gravity_OnChange(void) { - if (!M_SecretUnlocked(SECRET_PANDORA) && !netgame && !cv_debug - && strcmp(cv_gravity.string, cv_gravity.defaultvalue)) + if (netgame) { - CONS_Printf(M_GetText("You haven't earned this yet.\n")); - CV_StealthSet(&cv_gravity, cv_gravity.defaultvalue); + // TODO: multiplayer support return; } -#ifndef NETGAME_GRAVITY - if(netgame) - { - CV_StealthSet(&cv_gravity, cv_gravity.defaultvalue); - return; - } -#endif - if (!CV_IsSetToDefault(&cv_gravity)) - G_SetGameModified(multiplayer, true); gravity = cv_gravity.value; } @@ -4860,7 +4808,7 @@ static void Command_Mapmd5_f(void) static void Command_ExitLevel_f(void) { - if (!(netgame || multiplayer) && !cv_debug) + if (!(netgame || multiplayer) && !CV_CheatsEnabled()) CONS_Printf(M_GetText("This only works in a netgame.\n")); else if (!(server || (IsPlayerAdmin(consoleplayer)))) CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n")); @@ -4953,7 +4901,7 @@ static void Got_GiveItemcmd(UINT8 **cp, INT32 playernum) amt = READUINT8 (*cp); if ( - ( netgame && ! cv_kartallowgiveitem.value ) || + ( !CV_CheatsEnabled() ) || ( item < KITEM_SAD || item >= NUMKARTITEMS ) ) { @@ -5052,23 +5000,6 @@ void Command_Retry_f(void) } } -#ifdef NETGAME_DEVMODE -// Allow the use of devmode in netgames. -static void Fishcake_OnChange(void) -{ - cv_debug = cv_fishcake.value; - // consvar_t's get changed to default when registered - // so don't make modifiedgame always on! - if (cv_debug) - { - G_SetGameModified(multiplayer, true); - } - - else if (cv_debug != cv_fishcake.value) - CV_SetValue(&cv_fishcake, cv_debug); -} -#endif - /** Reports to the console whether or not the game has been modified. * * \todo Make it obvious, so a console command won't be necessary. @@ -5087,27 +5018,6 @@ static void Command_Isgamemodified_f(void) CONS_Printf("The game has not been modified. You can play Record Attack, earn medals and unlock extras.\n"); } -static void Command_Cheats_f(void) -{ - if (COM_CheckParm("off")) - { - if (!(server || (IsPlayerAdmin(consoleplayer)))) - CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n")); - else - CV_ResetCheatNetVars(); - return; - } - - if (CV_CheatsEnabled()) - { - CONS_Printf(M_GetText("At least one CHEAT-marked variable has been changed -- Cheats are enabled.\n")); - if (server || (IsPlayerAdmin(consoleplayer))) - CONS_Printf(M_GetText("Type CHEATS OFF to reset all cheat variables to default.\n")); - } - else - CONS_Printf(M_GetText("No CHEAT-marked variables are changed -- Cheats are disabled.\n")); -} - #ifdef _DEBUG static void Command_Togglemodified_f(void) { @@ -5160,8 +5070,6 @@ static void Command_Archivetest_f(void) #endif /** Give yourself an, optional quantity or one of, an item. - * - * \sa cv_kartallowgiveitem */ static void Command_KartGiveItem_f(void) { @@ -5175,8 +5083,7 @@ static void Command_KartGiveItem_f(void) int i; - /* Allow always in local games. */ - if (! netgame || cv_kartallowgiveitem.value) + if (CV_CheatsEnabled()) { ac = COM_Argc(); if (ac < 2) @@ -5516,7 +5423,7 @@ static void Skin_OnChange(void) if (!Playing()) return; // do whatever you want - if (!(cv_debug || devparm) && !(multiplayer || netgame) // In single player. + if (!CV_CheatsEnabled() && !(multiplayer || netgame) // In single player. && (gamestate != GS_WAITINGPLAYERS)) // allows command line -warp x +skin y { CV_StealthSet(&cv_skin[0], skins[players[consoleplayer].skin].name); @@ -5592,7 +5499,7 @@ static void Color_OnChange(void) } else { - if (!(cv_debug || devparm) && !(multiplayer || netgame)) // In single player. + if (!CV_CheatsEnabled() && !(multiplayer || netgame)) // In single player. { CV_StealthSet(&cv_skin[0], skins[players[consoleplayer].skin].name); return; diff --git a/src/d_netcmd.h b/src/d_netcmd.h index f6d172bcc..0d1ce4d43 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -86,7 +86,7 @@ extern consvar_t cv_kartusepwrlv; extern consvar_t cv_votetime; -extern consvar_t cv_kartdebugitem, cv_kartdebugamount, cv_kartallowgiveitem, cv_kartdebugdistribution, cv_kartdebughuddrop; +extern consvar_t cv_kartdebugitem, cv_kartdebugamount, cv_kartdebugdistribution, cv_kartdebughuddrop; extern consvar_t cv_kartdebugcheckpoint, cv_kartdebugnodes, cv_kartdebugcolorize, cv_kartdebugdirector; extern consvar_t cv_kartdebugwaypoints, cv_kartdebugbotpredict; diff --git a/src/d_player.h b/src/d_player.h index c6328c3ca..adeb14ea1 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -66,8 +66,8 @@ typedef enum // Accessibility and cheats PF_KICKSTARTACCEL = 1<<4, // Is accelerate in kickstart mode? - PF_GODMODE = 1<<5, - PF_NOCLIP = 1<<6, + // 1<<5 free + // 1<<6 free PF_WANTSTOJOIN = 1<<7, // Spectator that wants to join @@ -105,6 +105,13 @@ typedef enum // up to 1<<31 is free } pflags_t; +typedef enum +{ + PC_GODMODE = 1, + PC_NOCLIP = 1<<1, + // up to 1<<31 is free +} pcheats_t; + typedef enum { // Are animation frames playing? @@ -350,6 +357,7 @@ typedef struct player_s // Bit flags. // See pflags_t, above. pflags_t pflags; + pcheats_t cheats; // playing animation. panim_t panim; diff --git a/src/doomdef.h b/src/doomdef.h index f36e780e6..54067f806 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -122,7 +122,7 @@ extern char logfilename[1024]; #endif /* A mod name to further distinguish versions. */ -#define SRB2APPLICATION "SRB2Kart" +#define SRB2APPLICATION "RingRacers" //#define DEVELOP // Disable this for release builds to remove excessive cheat commands and enable MD5 checking and stuff, all in one go. :3 #ifdef DEVELOP @@ -146,7 +146,7 @@ extern char logfilename[1024]; #define VERSIONSTRINGW WSTRING (VERSIONSTRING) /* A custom URL protocol for server links. */ -#define SERVER_URL_PROTOCOL "srb2kart://" +#define SERVER_URL_PROTOCOL "ringracers://" // Does this version require an added patch file? // Comment or uncomment this as necessary. @@ -619,12 +619,6 @@ extern const char *compdate, *comptime, *comprevision, *compbranch; // None of these that are disabled in the normal build are guaranteed to work perfectly // Compile them at your own risk! -/// Allows the use of devmode in multiplayer. AKA "fishcake" -//#define NETGAME_DEVMODE - -/// Allows gravity changes in netgames, no questions asked. -//#define NETGAME_GRAVITY - /// Dumps the contents of a network save game upon consistency failure for debugging. //#define DUMPCONSISTENCY diff --git a/src/doomstat.h b/src/doomstat.h index 4b3f75d13..5908a6b69 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -95,6 +95,7 @@ extern boolean modifiedgame; extern boolean majormods; extern UINT16 mainwads; extern boolean savemoddata; // This mod saves time/emblem data. +extern boolean usedCheats; extern boolean imcontinuing; // Temporary flag while continuing extern boolean metalrecording; @@ -685,8 +686,6 @@ extern INT16 scrambleteams[MAXPLAYERS]; //for CTF team scramble extern INT16 scrambletotal; //for CTF team scramble extern INT16 scramblecount; //for CTF team scramble -extern INT32 cheats; - // SRB2kart extern UINT8 gamespeed; extern boolean franticitems; diff --git a/src/f_finale.c b/src/f_finale.c index 52f2556f4..81ca4c816 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -1035,7 +1035,7 @@ void F_GameEvaluationDrawer(void) { V_DrawString(8, 16, V_YELLOWMAP, "Unlocked:"); - if (!(netgame) && (!modifiedgame || savemoddata)) + if (!usedCheats) { INT32 startcoord = 32; @@ -1050,10 +1050,8 @@ void F_GameEvaluationDrawer(void) } } } - else if (netgame) - V_DrawString(8, 96, V_YELLOWMAP, "Multiplayer games\ncan't unlock\nextras!"); else - V_DrawString(8, 96, V_YELLOWMAP, "Modified games\ncan't unlock\nextras!"); + V_DrawString(8, 96, V_YELLOWMAP, "Cheated games\ncan't unlock\nextras!"); } #endif @@ -1107,14 +1105,7 @@ void F_GameEvaluationTicker(void) if (finalecount == 5*TICRATE) { - if (netgame || multiplayer) // modify this when we finally allow unlocking stuff in 2P - { - HU_SetCEchoFlags(V_YELLOWMAP); - HU_SetCEchoDuration(6); - HU_DoCEcho("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\Multiplayer games can't unlock extras!"); - S_StartSound(NULL, sfx_s3k68); - } - else if (!modifiedgame || savemoddata) + if (!usedCheats) { ++timesBeaten; @@ -1127,7 +1118,7 @@ void F_GameEvaluationTicker(void) { HU_SetCEchoFlags(V_YELLOWMAP); HU_SetCEchoDuration(6); - HU_DoCEcho("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\Modified games can't unlock extras!"); + HU_DoCEcho("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\Cheated games can't unlock extras!"); S_StartSound(NULL, sfx_s3k68); } } diff --git a/src/g_game.c b/src/g_game.c index 896ea00ea..91c130333 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -122,6 +122,7 @@ UINT16 mainwads = 0; boolean modifiedgame = false; // Set if homebrew PWAD stuff has been added. boolean majormods = false; // Set if Lua/Gameplay SOC/replacement map has been added. boolean savemoddata = false; +boolean usedCheats = false; // Set when a "cheats on" is ever used. UINT8 paused; UINT8 modeattacking = ATTACKING_NONE; boolean imcontinuing = false; @@ -297,8 +298,6 @@ INT16 scrambleteams[MAXPLAYERS]; //for CTF team scramble INT16 scrambletotal; //for CTF team scramble INT16 scramblecount; //for CTF team scramble -INT32 cheats; //for multiplayer cheat commands - // SRB2Kart // Cvars that we don't want changed mid-game UINT8 gamespeed; // Game's current speed (or difficulty, or cc, or etc); 0 for easy, 1 for normal, 2 for hard @@ -658,6 +657,22 @@ void G_SetGameModified(boolean silent, boolean major) Command_ExitGame_f(); } +// for consistency among messages: this sets cheats as used. +void G_SetUsedCheats(void) +{ + if (usedCheats) + return; + + usedCheats = true; + CONS_Alert(CONS_NOTICE, M_GetText("Cheats activated -- game must be restarted to save progress.\n")); + + // If in record attack recording, cancel it. + if (modeattacking) + M_EndModeAttackRun(); + else if (marathonmode) + Command_ExitGame_f(); +} + /** Builds an original game map name from a map number. * The complexity is due to MAPA0-MAPZZ. * @@ -2188,6 +2203,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) UINT32 followitem; INT32 pflags; + INT32 cheats; UINT8 ctfteam; @@ -2266,6 +2282,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) botrival = players[player].botvars.rival; pflags = (players[player].pflags & (PF_WANTSTOJOIN|PF_KICKSTARTACCEL|PF_SHRINKME|PF_SHRINKACTIVE)); + cheats = 0; // SRB2kart if (betweenmaps || leveltime < introtime) @@ -2339,7 +2356,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) // As long as we're not in multiplayer, carry over cheatcodes from map to map if (!(netgame || multiplayer)) - pflags |= (players[player].pflags & (PF_GODMODE|PF_NOCLIP)); + cheats = players[player].cheats; if (!betweenmaps) { @@ -2356,6 +2373,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) p->roundscore = roundscore; p->lives = lives; p->pflags = pflags; + p->cheats = cheats; p->ctfteam = ctfteam; p->jointime = jointime; p->splitscreenindex = splitscreenindex; @@ -3407,7 +3425,7 @@ tryagain: if ((mapheaderinfo[ix]->typeoflevel & tolflags) != tolflags || ix == pprevmap - || (!dedicated && M_MapLocked(ix+1)) + || M_MapLocked(ix+1) || (usehellmaps != (mapheaderinfo[ix]->menuflags & LF2_HIDEINMENU))) // this is bad continue; //isokmap = false; @@ -3528,11 +3546,8 @@ void G_AddMapToBuffer(INT16 map) // static void G_UpdateVisited(void) { - boolean spec = G_IsSpecialStage(gamemap); // Update visitation flags? - if ((!modifiedgame || savemoddata) // Not modified - && !multiplayer && !demo.playback // SP/RA/NiGHTS mode - && !(spec && stagefailed)) // Not failed the special stage + if (!demo.playback) // Not watching a demo { UINT8 earnedEmblems; @@ -3575,14 +3590,16 @@ static void G_HandleSaveLevel(void) remove(liveeventbackup); cursaveslot = 0; } - else if ((!modifiedgame || savemoddata) && !(netgame || multiplayer || ultimatemode || demo.recording || metalrecording || modeattacking)) + else if (!usedCheats && !(netgame || multiplayer || ultimatemode || demo.recording || metalrecording || modeattacking)) G_SaveGame((UINT32)cursaveslot, spstage_start); } } // and doing THIS here means you don't lose your progress if you close the game mid-intermission - else if (!(ultimatemode || netgame || multiplayer || demo.playback || demo.recording || metalrecording || modeattacking) - && (!modifiedgame || savemoddata) && cursaveslot > 0 && CanSaveLevel(lastmap+1)) + else if (!(ultimatemode || demo.playback || demo.recording || metalrecording || modeattacking) + && cursaveslot > 0 && CanSaveLevel(lastmap+1)) + { G_SaveGame((UINT32)cursaveslot, lastmap+1); // not nextmap+1 to route around special stages + } } // @@ -3943,7 +3960,7 @@ static void G_DoContinued(void) tokenlist = 0; token = 0; - if (!(netgame || multiplayer || demo.playback || demo.recording || metalrecording || modeattacking) && (!modifiedgame || savemoddata) && cursaveslot > 0) + if (!(netgame || multiplayer || demo.playback || demo.recording || metalrecording || modeattacking) && !usedCheats && cursaveslot > 0) G_SaveGameOver((UINT32)cursaveslot, true); // Reset # of lives @@ -4012,19 +4029,25 @@ void G_LoadGameSettings(void) S_InitRuntimeSounds(); } +#define GAMEDATA_ID 0x61688195 // Change every major version, as usual + // G_LoadGameData // Loads the main data file, which stores information such as emblems found, etc. void G_LoadGameData(void) { size_t length; INT32 i, j; - UINT8 modded = false; + + UINT32 versionID; UINT8 rtemp; //For records tic_t rectime; tic_t reclap; + // Stop saving, until we successfully load it again. + gamedataloaded = false; + // Clear things so previously read gamedata doesn't transfer // to new gamedata G_ClearRecords(); // main and nights records @@ -4037,27 +4060,31 @@ void G_LoadGameData(void) vspowerlevel[i] = PWRLVRECORD_START; if (M_CheckParm("-nodata")) - return; // Don't load. - - // Allow saving of gamedata beyond this point - gamedataloaded = true; - - if (M_CheckParm("-gamedata") && M_IsNextParm()) { - strlcpy(gamedatafilename, M_GetNextParm(), sizeof gamedatafilename); + // Don't load at all. + return; } if (M_CheckParm("-resetdata")) - return; // Don't load (essentially, reset). + { + // Don't load, but do save. (essentially, reset) + gamedataloaded = true; + return; + } length = FIL_ReadFile(va(pandf, srb2home, gamedatafilename), &savebuffer); - if (!length) // Aw, no game data. Their loss! + if (!length) + { + // No gamedata. We can save a new one. + gamedataloaded = true; return; + } save_p = savebuffer; // Version check - if (READUINT32(save_p) != 0xFCAFE211) + versionID = READUINT32(save_p); + if (versionID != GAMEDATA_ID) { const char *gdfolder = "the Ring Racers folder"; if (strcmp(srb2home,".")) @@ -4065,7 +4092,7 @@ void G_LoadGameData(void) Z_Free(savebuffer); save_p = NULL; - I_Error("Game data is from another version of SRB2.\nDelete %s(maybe in %s) and try again.", gamedatafilename, gdfolder); + I_Error("Game data is not for Ring Racers v2.0.\nDelete %s(maybe in %s) and try again.", gamedatafilename, gdfolder); } totalplaytime = READUINT32(save_p); @@ -4078,13 +4105,17 @@ void G_LoadGameData(void) goto datacorrupt; } - modded = READUINT8(save_p); + { + // Quick & dirty hash for what mod this save file is for. + UINT32 modID = READUINT32(save_p); + UINT32 expectedID = quickncasehash(timeattackfolder, 64); - // Aha! Someone's been screwing with the save file! - if ((modded && !savemoddata)) - goto datacorrupt; - else if (modded != true && modded != false) - goto datacorrupt; + if (modID != expectedID) + { + // Aha! Someone's been screwing with the save file! + goto datacorrupt; + } + } // TODO put another cipher on these things? meh, I don't care... for (i = 0; i < NUMMAPS; i++) @@ -4141,6 +4172,12 @@ void G_LoadGameData(void) Z_Free(savebuffer); save_p = NULL; + // Don't consider loaded until it's a success! + // It used to do this much earlier, but this would cause the gamedata to + // save over itself when it I_Errors from the corruption landing point below, + // which can accidentally delete players' legitimate data if the code ever has any tiny mistakes! + gamedataloaded = true; + // Silent update unlockables in case they're out of sync with conditions M_SilentUpdateUnlockablesAndEmblems(); @@ -4178,18 +4215,15 @@ void G_SaveGameData(void) return; } -#if 0 - // SRB2Kart: Let players unlock stuff with addons. - if (modifiedgame && !savemoddata) + if (usedCheats) { free(savebuffer); save_p = savebuffer = NULL; return; } -#endif // Version test - WRITEUINT32(save_p, 0xFCAFE211); + WRITEUINT32(save_p, GAMEDATA_ID); WRITEUINT32(save_p, totalplaytime); WRITEUINT32(save_p, matchesplayed); @@ -4197,7 +4231,7 @@ void G_SaveGameData(void) for (i = 0; i < PWRLV_NUMTYPES; i++) WRITEUINT16(save_p, vspowerlevel[i]); - WRITEUINT8(save_p, (UINT8)savemoddata); + WRITEUINT32(save_p, quickncasehash(timeattackfolder, 64)); // TODO put another cipher on these things? meh, I don't care... for (i = 0; i < NUMMAPS; i++) @@ -4605,7 +4639,7 @@ void G_InitNew(UINT8 pencoremode, const char *mapname, boolean resetplayer, bool memset(&players[i].respawn, 0, sizeof (players[i].respawn)); // Clear cheatcodes too, just in case. - players[i].pflags &= ~(PF_GODMODE|PF_NOCLIP); + players[i].cheats = 0; players[i].roundscore = 0; diff --git a/src/g_game.h b/src/g_game.h index 52c7c7a0d..6a40543f2 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -243,6 +243,7 @@ void G_LoadGameData(void); void G_LoadGameSettings(void); void G_SetGameModified(boolean silent, boolean major); +void G_SetUsedCheats(void); void G_SetGamestate(gamestate_t newstate); diff --git a/src/k_kart.c b/src/k_kart.c index 0c530ae9e..54e9ca821 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -257,7 +257,6 @@ void K_RegisterKartStuff(void) CV_RegisterVar(&cv_kartdebugitem); CV_RegisterVar(&cv_kartdebugamount); - CV_RegisterVar(&cv_kartallowgiveitem); CV_RegisterVar(&cv_kartdebugdistribution); CV_RegisterVar(&cv_kartdebughuddrop); CV_RegisterVar(&cv_kartdebugwaypoints); diff --git a/src/m_cheat.c b/src/m_cheat.c index ce925e931..dc4ad96cc 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -97,7 +97,7 @@ static UINT8 cheatf_warp(void) if (success) { - G_SaveGameData(); //G_SetGameModified(false); + G_SaveGameData(); //G_SetUsedCheats(); S_StartSound(0, sfx_kc42); } @@ -121,7 +121,7 @@ static UINT8 cheatf_devmode(void) S_StartSound(0, sfx_itemup); // Just unlock all the things and turn on -debug and console devmode. - G_SetGameModified(false, false); // might need to revist the latter later + G_SetUsedCheats(); for (i = 0; i < MAXUNLOCKABLES; i++) unlockables[i].unlocked = true; devparm = true; @@ -264,11 +264,8 @@ boolean cht_Responder(event_t *ev) } // Console cheat commands rely on these a lot... -#define REQUIRE_PANDORA if (!M_SecretUnlocked(SECRET_PANDORA) && !cv_debug)\ -{ CONS_Printf(M_GetText("You haven't earned this yet.\n")); return; } - -#define REQUIRE_DEVMODE if (!cv_debug)\ -{ CONS_Printf(M_GetText("DEVMODE must be enabled.\n")); return; } +#define REQUIRE_CHEATS if (!CV_CheatsEnabled())\ +{ CONS_Printf(M_GetText("Cheats must be enabled.\n")); return; } #define REQUIRE_OBJECTPLACE if (!objectplacing)\ { CONS_Printf(M_GetText("OBJECTPLACE must be enabled.\n")); return; } @@ -284,37 +281,35 @@ void Command_CheatNoClip_f(void) { player_t *plyr; + REQUIRE_CHEATS; REQUIRE_INLEVEL; - REQUIRE_SINGLEPLAYER; + REQUIRE_SINGLEPLAYER; // TODO: make netplay compatible plyr = &players[consoleplayer]; if (!plyr->mo || P_MobjWasRemoved(plyr->mo)) return; - plyr->pflags ^= PF_NOCLIP; - CONS_Printf(M_GetText("No Clipping %s\n"), plyr->pflags & PF_NOCLIP ? M_GetText("On") : M_GetText("Off")); + plyr->cheats ^= PC_NOCLIP; + CONS_Printf(M_GetText("No Clipping %s\n"), plyr->cheats & PC_NOCLIP ? M_GetText("On") : M_GetText("Off")); - if (plyr->pflags & PF_NOCLIP) + if (plyr->cheats & PC_NOCLIP) plyr->mo->flags |= MF_NOCLIP; else plyr->mo->flags &= ~MF_NOCLIP; - - G_SetGameModified(multiplayer, true); } void Command_CheatGod_f(void) { player_t *plyr; + REQUIRE_CHEATS; REQUIRE_INLEVEL; - REQUIRE_SINGLEPLAYER; + REQUIRE_SINGLEPLAYER; // TODO: make multiplayer compatible plyr = &players[consoleplayer]; - plyr->pflags ^= PF_GODMODE; - CONS_Printf(M_GetText("Cheese Mode %s\n"), plyr->pflags & PF_GODMODE ? M_GetText("On") : M_GetText("Off")); - - G_SetGameModified(multiplayer, true); + plyr->cheats ^= PC_GODMODE; + CONS_Printf(M_GetText("Cheese Mode %s\n"), plyr->cheats & PC_GODMODE ? M_GetText("On") : M_GetText("Off")); } void Command_Scale_f(void) @@ -322,9 +317,9 @@ void Command_Scale_f(void) const double scaled = atof(COM_Argv(1)); fixed_t scale = FLOAT_TO_FIXED(scaled); - REQUIRE_DEVMODE; + REQUIRE_CHEATS; REQUIRE_INLEVEL; - REQUIRE_SINGLEPLAYER; + REQUIRE_SINGLEPLAYER; // TODO: make multiplayer compatible if (scale < FRACUNIT/100 || scale > 100*FRACUNIT) //COM_Argv(1) will return a null string if they did not give a paramater, so... { @@ -342,9 +337,9 @@ void Command_Scale_f(void) void Command_Gravflip_f(void) { - REQUIRE_DEVMODE; + REQUIRE_CHEATS; REQUIRE_INLEVEL; - REQUIRE_SINGLEPLAYER; + REQUIRE_SINGLEPLAYER; // TODO: make multiplayer compatible if (players[consoleplayer].mo) players[consoleplayer].mo->flags2 ^= MF2_OBJECTFLIP; @@ -352,9 +347,9 @@ void Command_Gravflip_f(void) void Command_Hurtme_f(void) { - REQUIRE_DEVMODE; + REQUIRE_CHEATS; REQUIRE_INLEVEL; - REQUIRE_SINGLEPLAYER; + REQUIRE_SINGLEPLAYER; // TODO: make multiplayer compatible if (COM_Argc() < 2) { @@ -372,9 +367,9 @@ void Command_RTeleport_f(void) player_t *p = &players[consoleplayer]; subsector_t *ss; - REQUIRE_DEVMODE; + REQUIRE_CHEATS; REQUIRE_INLEVEL; - REQUIRE_SINGLEPLAYER; + REQUIRE_SINGLEPLAYER; // TODO: make multiplayer compatible if (COM_Argc() < 3 || COM_Argc() > 7) { @@ -434,9 +429,9 @@ void Command_Teleport_f(void) player_t *p = &players[consoleplayer]; subsector_t *ss; - REQUIRE_DEVMODE; + REQUIRE_CHEATS; REQUIRE_INLEVEL; - REQUIRE_SINGLEPLAYER; + REQUIRE_SINGLEPLAYER; // TODO: make multiplayer compatible if (COM_Argc() < 3 || COM_Argc() > 11) { @@ -650,9 +645,9 @@ void Command_Teleport_f(void) void Command_Skynum_f(void) { - REQUIRE_DEVMODE; + REQUIRE_CHEATS; REQUIRE_INLEVEL; - REQUIRE_SINGLEPLAYER; + REQUIRE_SINGLEPLAYER; // TODO: make multiplayer compatible if (COM_Argc() != 2) { @@ -668,9 +663,9 @@ void Command_Skynum_f(void) void Command_Weather_f(void) { - REQUIRE_DEVMODE; + REQUIRE_CHEATS; REQUIRE_INLEVEL; - REQUIRE_SINGLEPLAYER; + REQUIRE_SINGLEPLAYER; // TODO: make multiplayer compatible if (COM_Argc() != 2) { @@ -688,9 +683,9 @@ void Command_Toggletwod_f(void) { player_t *p = &players[consoleplayer]; - REQUIRE_DEVMODE; + REQUIRE_CHEATS; REQUIRE_INLEVEL; - REQUIRE_SINGLEPLAYER; + REQUIRE_SINGLEPLAYER; // TODO: make multiplayer compatible if (p->mo) p->mo->flags2 ^= MF2_TWOD; @@ -703,6 +698,9 @@ void Command_Toggletwod_f(void) // Don't enable this for normal builds... void Command_CauseCfail_f(void) { + REQUIRE_CHEATS; + REQUIRE_INLEVEL; + if (consoleplayer == serverplayer) { CONS_Printf(M_GetText("Only remote players can use this command.\n")); @@ -745,9 +743,9 @@ void Command_Dumplua_f(void) void Command_Savecheckpoint_f(void) { - REQUIRE_DEVMODE; + REQUIRE_CHEATS; REQUIRE_INLEVEL; - REQUIRE_SINGLEPLAYER; + REQUIRE_SINGLEPLAYER; // TODO: make multiplayer compatible players[consoleplayer].respawn.pointx = players[consoleplayer].mo->x; players[consoleplayer].respawn.pointy = players[consoleplayer].mo->y; @@ -760,8 +758,8 @@ void Command_Savecheckpoint_f(void) /* void Command_Getallemeralds_f(void) { + REQUIRE_CHEATS; REQUIRE_SINGLEPLAYER; - REQUIRE_PANDORA; emeralds = EMERALD_ALL; @@ -770,6 +768,7 @@ void Command_Getallemeralds_f(void) void Command_Resetemeralds_f(void) { + REQUIRE_CHEATS; REQUIRE_SINGLEPLAYER; emeralds = 0; @@ -780,9 +779,8 @@ void Command_Resetemeralds_f(void) void Command_Devmode_f(void) { -#ifndef _DEBUG - REQUIRE_SINGLEPLAYER; -#endif + REQUIRE_CHEATS; + REQUIRE_SINGLEPLAYER; // TODO: make multiplayer compatible if (COM_Argc() > 1) { @@ -799,15 +797,12 @@ void Command_Devmode_f(void) CONS_Printf(M_GetText("devmode : enable debugging tools and info, prepend with 0x to use hexadecimal\n")); return; } - - G_SetGameModified(multiplayer, true); } void Command_Setrings_f(void) { + REQUIRE_CHEATS; REQUIRE_INLEVEL; - REQUIRE_SINGLEPLAYER; - REQUIRE_PANDORA; if (COM_Argc() > 1) { @@ -815,16 +810,13 @@ void Command_Setrings_f(void) players[consoleplayer].rings = 0; P_GivePlayerRings(&players[consoleplayer], atoi(COM_Argv(1))); players[consoleplayer].totalring -= atoi(COM_Argv(1)); //undo totalring addition done in P_GivePlayerRings - - G_SetGameModified(multiplayer, true); } } void Command_Setlives_f(void) { + REQUIRE_CHEATS; REQUIRE_INLEVEL; - REQUIRE_SINGLEPLAYER; - REQUIRE_PANDORA; if (COM_Argc() > 1) { @@ -839,8 +831,6 @@ void Command_Setlives_f(void) players[consoleplayer].lives = 0; P_GivePlayerLives(&players[consoleplayer], atoi(COM_Argv(1))); } - - G_SetGameModified(multiplayer, true); } } @@ -1149,7 +1139,6 @@ void OP_ObjectplaceMovement(player_t *player) void Command_Writethings_f(void) { REQUIRE_INLEVEL; - REQUIRE_SINGLEPLAYER; REQUIRE_OBJECTPLACE; P_WriteThings(); @@ -1161,9 +1150,8 @@ void Command_ObjectPlace_f(void) size_t silent; REQUIRE_INLEVEL; - REQUIRE_SINGLEPLAYER; - - G_SetGameModified(multiplayer, true); + REQUIRE_CHEATS; + REQUIRE_SINGLEPLAYER; // this one will very likely never be multiplayer compatible... silent = COM_CheckParm("-silent"); diff --git a/src/m_cond.c b/src/m_cond.c index ceff3c167..5aa3157a5 100644 --- a/src/m_cond.c +++ b/src/m_cond.c @@ -382,17 +382,23 @@ UINT8 M_SecretUnlocked(INT32 type) UINT8 M_MapLocked(INT32 mapnum) { - #ifdef DEVELOP - if (1) + (void)mapnum; + return false; +#else + // Don't lock maps in dedicated servers. + // That just makes hosts' lives hell. + if (dedicated) return false; -#endif - + if (!mapheaderinfo[mapnum-1] || mapheaderinfo[mapnum-1]->unlockrequired < 0) return false; + if (!unlockables[mapheaderinfo[mapnum-1]->unlockrequired].unlocked) return true; + return false; +#endif } INT32 M_CountEmblems(void) diff --git a/src/m_menu.c b/src/m_menu.c index dc753db68..f517e117e 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -6376,7 +6376,7 @@ static void M_GetAllEmeralds(INT32 choice) emeralds = EMERALD_ALL; M_StartMessage(M_GetText("You now have all 7 emeralds.\nUse them wisely.\nWith great power comes great ring drain.\n"),NULL,MM_NOTHING); - G_SetGameModified(multiplayer, true); + G_SetUsedCheats(); } static void M_DestroyRobotsResponse(INT32 ch) @@ -6387,7 +6387,7 @@ static void M_DestroyRobotsResponse(INT32 ch) // Destroy all robots P_DestroyRobots(); - G_SetGameModified(multiplayer, true); + G_SetUsedCheats(); } static void M_DestroyRobots(INT32 choice) diff --git a/src/p_inter.c b/src/p_inter.c index 27455872d..38754a7db 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1893,7 +1893,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da if (player) // Player is the target { - if (player->pflags & PF_GODMODE) + if (player->cheats & PC_GODMODE) return false; if (!force) diff --git a/src/p_map.c b/src/p_map.c index 473ded5fe..1c75246a3 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -2239,7 +2239,7 @@ boolean P_TryCameraMove(fixed_t x, fixed_t y, camera_t *thiscam) fixed_t tryy = thiscam->y; #ifndef NOCLIPCAM - if ((players[displayplayers[i]].pflags & PF_NOCLIP) || (leveltime < introtime)) // Noclipping player camera noclips too!! + if ((players[displayplayers[i]].cheats & PC_NOCLIP) || (leveltime < introtime)) // Noclipping player camera noclips too!! #else if (!(players[displayplayers[i]].pflags & PF_NOCONTEST)) // Time Over should not clip through walls #endif diff --git a/src/p_mobj.c b/src/p_mobj.c index 5219fb707..c164ccf3a 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -2040,7 +2040,7 @@ boolean P_CheckDeathPitCollide(mobj_t *mo) I_Assert(mo != NULL); I_Assert(!P_MobjWasRemoved(mo)); - if (mo->player && mo->player->pflags & PF_GODMODE) + if (mo->player && mo->player->cheats & PC_GODMODE) return false; if (((mo->z <= mo->subsector->sector->floorheight @@ -3531,7 +3531,7 @@ boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled player->karthud[khud_timeovercam] = (2*TICRATE)+1; } - if (!resetcalled && !(player->pflags & PF_NOCLIP || leveltime < introtime) && !P_CheckSight(&dummy, player->mo)) // TODO: "P_CheckCameraSight" instead. + if (!resetcalled && !(player->cheats & PC_NOCLIP || leveltime < introtime) && !P_CheckSight(&dummy, player->mo)) // TODO: "P_CheckCameraSight" instead. { P_ResetCamera(player, thiscam); } @@ -10583,7 +10583,7 @@ void P_RemoveSavegameMobj(mobj_t *mobj) static CV_PossibleValue_t respawnitemtime_cons_t[] = {{1, "MIN"}, {300, "MAX"}, {0, NULL}}; consvar_t cv_itemrespawntime = CVAR_INIT ("respawnitemtime", "2", CV_NETVAR|CV_CHEAT, respawnitemtime_cons_t, NULL); -consvar_t cv_itemrespawn = CVAR_INIT ("respawnitem", "On", CV_NETVAR, CV_OnOff, NULL); +consvar_t cv_itemrespawn = CVAR_INIT ("respawnitem", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL); void P_SpawnPrecipitation(void) { @@ -11417,31 +11417,23 @@ static boolean P_AllowMobjSpawn(mapthing_t* mthing, mobjtype_t i) switch (i) { - case MT_EMBLEM: - if (netgame || multiplayer) - return false; // Single player only + case MT_ITEMCAPSULE: + { + boolean isRingCapsule = (mthing->angle < 1 || mthing->angle == KITEM_SUPERRING || mthing->angle >= NUMKARTITEMS); - if (modifiedgame && !savemoddata) - return false; // No cheating!! + // don't spawn ring capsules in GTR_SPHERES gametypes + if (isRingCapsule && (gametyperules & GTR_SPHERES)) + return false; - break; - case MT_ITEMCAPSULE: - { - boolean isRingCapsule = (mthing->angle < 1 || mthing->angle == KITEM_SUPERRING || mthing->angle >= NUMKARTITEMS); - - // don't spawn ring capsules in GTR_SPHERES gametypes - if (isRingCapsule && (gametyperules & GTR_SPHERES)) - return false; - - // in record attack, only spawn ring capsules - // (behavior can be inverted with the Extra flag, i.e. item capsule spawns and ring capsule does not) - if (modeattacking - && (!(mthing->options & MTF_EXTRA) == !isRingCapsule)) - return false; - } - break; - default: - break; + // in record attack, only spawn ring capsules + // (behavior can be inverted with the Extra flag, i.e. item capsule spawns and ring capsule does not) + if (modeattacking + && (!(mthing->options & MTF_EXTRA) == !isRingCapsule)) + return false; + } + break; + default: + break; } // No bosses outside of a combat situation. diff --git a/src/p_setup.c b/src/p_setup.c index a47077ba5..c281d5497 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -4133,9 +4133,6 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate) // Initialize sector node list. P_Initsecnode(); - if (netgame || multiplayer) - cv_debug = 0; - if (metalplayback) G_StopMetalDemo(); @@ -4476,7 +4473,7 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate) { // I'd love to do this in the menu code instead of here, but everything's a mess and I can't guarantee saving proper player struct info before the first act's started. You could probably refactor it, but it'd be a lot of effort. Easier to just work off known good code. ~toast 22/06/2020 if (!(ultimatemode || netgame || multiplayer || demo.playback || demo.recording || metalrecording || modeattacking || marathonmode) - && (!modifiedgame || savemoddata) && cursaveslot > 0) + && !usedCheats && cursaveslot > 0) G_SaveGame((UINT32)cursaveslot, gamemap); // If you're looking for saving sp file progression (distinct from G_SaveGameOver), check G_DoCompleted. } diff --git a/src/p_user.c b/src/p_user.c index ffc53012b..eb1541486 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -3084,7 +3084,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall } #ifndef NOCLIPCAM - cameranoclip = ((player->pflags & PF_NOCLIP) + cameranoclip = ((player->cheats & PC_NOCLIP) || (mo->flags & (MF_NOCLIP|MF_NOCLIPHEIGHT)) // Noclipping player camera noclips too!! || (leveltime < introtime)); // Kart intro cam #endif diff --git a/src/r_skins.c b/src/r_skins.c index ae5e0363c..bf71570e0 100644 --- a/src/r_skins.c +++ b/src/r_skins.c @@ -298,7 +298,7 @@ void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum) player->kartweight = skin->kartweight; #if 0 - if (!(cv_debug || devparm) && !(netgame || multiplayer || demo.playback)) + if (!CV_CheatsEnabled() && !(netgame || multiplayer || demo.playback)) { for (i = 0; i <= r_splitscreen; i++) { From e1c8f8095b03ac40cc85ad465b3f200b17f2c225 Mon Sep 17 00:00:00 2001 From: toaster Date: Mon, 12 Sep 2022 22:24:40 +0100 Subject: [PATCH 02/25] Clean up recent IP handling a bunch. --- src/d_clisrv.c | 8 ++++---- src/k_menudraw.c | 19 ++++++++++++------- src/m_misc.c | 19 +++++++++++++------ 3 files changed, 29 insertions(+), 17 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 1e5787583..4da5f40b1 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -2094,10 +2094,10 @@ static void CL_ConnectToServer(void) // @TODO: Save the proper server name, right now it doesn't seem like we can consistently retrieve it from the serverlist....? // It works... sometimes but not always which is weird. - if (*joinedIP && strlen(joinedIP)) // false if we have "" which is \0 + if (joinedIP[0]) // false if we have "" which is \0 M_AddToJoinedIPs(joinedIP, netbuffer->u.serverinfo.servername); - strcpy(joinedIP, ""); // And empty this for good measure regardless of whether or not we actually used it. + joinedIP[0] = '\0'; // And empty this for good measure regardless of whether or not we actually used it. } @@ -2387,7 +2387,7 @@ static void Command_connect(void) { // By default, clear the saved address that we'd save after succesfully joining just to be sure: - strcpy(joinedIP, ""); + joinedIP[0] = '\0'; if (COM_Argc() < 2 || *COM_Argv(1) == 0) { @@ -3905,7 +3905,7 @@ void SV_StartSinglePlayerServer(void) server = true; netgame = false; multiplayer = false; - strcpy(joinedIP, ""); // Make sure to empty this so that we don't save garbage when we start our own game. (because yes we use this for netgames too....) + joinedIP[0] = '\0'; // Make sure to empty this so that we don't save garbage when we start our own game. (because yes we use this for netgames too....) if ((modeattacking == ATTACKING_CAPSULES) || (bossinfo.boss == true)) { diff --git a/src/k_menudraw.c b/src/k_menudraw.c index 76a001544..8c4ecc121 100644 --- a/src/k_menudraw.c +++ b/src/k_menudraw.c @@ -2339,7 +2339,7 @@ void M_DrawMPHost(void) case IT_CV_STRING: V_DrawThinString(xp + 96, yp, V_ALLOWLOWERCASE|V_6WIDTHSPACE, cv->string); if (skullAnimCounter < 4 && i == itemOn) - V_DrawString(xp + 94 + V_ThinStringWidth(cv->string, V_6WIDTHSPACE), yp+1, 0, "_"); + V_DrawString(xp + 96 + V_ThinStringWidth(cv->string, V_ALLOWLOWERCASE|V_6WIDTHSPACE), yp+1, 0, "_"); break; @@ -2404,15 +2404,20 @@ void M_DrawMPJoinIP(void) if (currentMenu->numitems - i <= NUMLOGIP) { UINT8 index = NUMLOGIP - (currentMenu->numitems - i); - if (strlen(joinedIPlist[index][1])) // Try drawing server name + if (index == 0) + { + xp += 8; + } + + if (joinedIPlist[index][1][0]) // Try drawing server name strcpy(str, joinedIPlist[index][1]); - else if (strlen(joinedIPlist[index][0])) // If that fails, get the address + else if (joinedIPlist[index][0][0]) // If that fails, get the address strcpy(str, joinedIPlist[index][0]); else strcpy(str, "---"); // If that fails too then there's nothing! } - V_DrawString(xp, yp, V_ALLOWLOWERCASE | ((i == itemOn || currentMenu->menuitems[i].status & IT_SPACE) ? highlightflags : 0), str); + V_DrawThinString(xp, yp, V_ALLOWLOWERCASE | ((i == itemOn || currentMenu->menuitems[i].status & IT_SPACE) ? highlightflags : 0)|V_ALLOWLOWERCASE|V_6WIDTHSPACE, str); // Cvar specific handling switch (currentMenu->menuitems[i].status & IT_TYPE) @@ -2427,10 +2432,10 @@ void M_DrawMPJoinIP(void) //colormap = R_GetTranslationColormap(TC_DEFAULT, SKINCOLOR_MOSS, GTC_CACHE); colormapc = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_PLAGUE, GTC_CACHE); - V_DrawFixedPatch((xp + 20)<string); + V_DrawFixedPatch((xp + 12)<string); if (skullAnimCounter < 4 && i == itemOn) - V_DrawCharacter(xp + 24 + V_ThinStringWidth(cv->string, 0), yp, '_' | 0x80, false); + V_DrawString(xp + 18 + V_ThinStringWidth(cv->string, V_ALLOWLOWERCASE|V_6WIDTHSPACE), yp+1, 0, "_"); /*// On this specific menu the only time we'll ever see this is for the connect by IP typefield. // Draw the small GO button here (and the text which is a separate graphic) diff --git a/src/m_misc.c b/src/m_misc.c index 0628ef3b6..796fcb90d 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -190,8 +190,7 @@ void M_InitJoinedIPArray(void) UINT8 i; for (i=0; i < NUMLOGIP; i++) { - strcpy(joinedIPlist[i][0], ""); - strcpy(joinedIPlist[i][1], ""); + joinedIPlist[i][0][0] = joinedIPlist[i][1][0] = '\0'; } } @@ -564,10 +563,18 @@ void M_LoadJoinedIPs(void) s = strtok(NULL, IPLOGFILESEP); // Let's get rid of this awful \n while we're here! - if (strlen(s)) - s[strlen(s)-1] = '\0'; // Remove the \n - - strcpy(joinedIPlist[i][1], s); + if (s) + { + //strcpy(joinedIPlist[i][1], s); -- get rid of \n too... + char *c = joinedIPlist[i][1]; + while (*s && *s != '\n') + { + *c = *s; + s++; + c++; + } + *c = '\0'; + } i++; } From 08cd0393c0b72d5168ccbcfe2996e01cf49cb24d Mon Sep 17 00:00:00 2001 From: SteelT Date: Fri, 23 Sep 2022 04:18:01 -0400 Subject: [PATCH 03/25] Properly check for duplicate recent IP Clean up M_AddToJoinedIPs a bit --- src/m_misc.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/m_misc.c b/src/m_misc.c index 796fcb90d..e1d45a6cd 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -197,24 +197,22 @@ void M_InitJoinedIPArray(void) // This adds an entry to the above array void M_AddToJoinedIPs(char *address, char *servname) { - UINT8 i = 0; - UINT8 dupeindex = 0; // Check for dupes... - for (; i < NUMLOGIP && !dupeindex; i++) + for (i = 0; i < NUMLOGIP; i++) { // I don't care about the server name (this is broken anyway...) but definitely check the addresses if (strcmp(joinedIPlist[i][0], address) == 0) - dupeindex = i; + { + return; + } } CONS_Printf("Adding %s (%s) to list of manually joined IPs\n", servname, address); // Start by moving every IP up 1 slot (dropping the last IP in the table) - // If we found duplicates, start here instead and pull the rest up. - i = dupeindex ? dupeindex : NUMLOGIP; - for (; i; i--) + for (i = NUMLOGIP; i; i--) { strcpy(joinedIPlist[i][0], joinedIPlist[i-1][0]); strcpy(joinedIPlist[i][1], joinedIPlist[i-1][1]); From 1af7af8c62575cde2d57d2e6946ff64cf567fa11 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sat, 24 Sep 2022 15:05:55 -0400 Subject: [PATCH 04/25] Remove unused jump --- src/command.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/command.c b/src/command.c index e9a4aeeda..5f03e804d 100644 --- a/src/command.c +++ b/src/command.c @@ -1653,7 +1653,6 @@ static void Setvalue(consvar_t *var, const char *valstr, boolean stealth) var->value = atoi(var->string); } -finish: if (var->flags & CV_SHOWMODIFONETIME || var->flags & CV_SHOWMODIF) { CONS_Printf(M_GetText("%s set to %s\n"), var->name, var->string); From b5e9de2e698a4ce694025b9d5963fd34ddf43adc Mon Sep 17 00:00:00 2001 From: SteelT Date: Sat, 24 Sep 2022 18:20:58 -0400 Subject: [PATCH 05/25] Grab server name from connectedservername, instead of netbuffer->u.serverinfo.servername (fixes garbage server name) Yeah it will be blank, but preparation for whenever the server's name is stored in that variable --- src/d_clisrv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 4da5f40b1..6aae1d83d 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -2095,7 +2095,7 @@ static void CL_ConnectToServer(void) // It works... sometimes but not always which is weird. if (joinedIP[0]) // false if we have "" which is \0 - M_AddToJoinedIPs(joinedIP, netbuffer->u.serverinfo.servername); + M_AddToJoinedIPs(joinedIP, connectedservername); joinedIP[0] = '\0'; // And empty this for good measure regardless of whether or not we actually used it. From 6144c049094bf5e10b4243a73f40b92fd8161068 Mon Sep 17 00:00:00 2001 From: VelocitOni Date: Sun, 25 Sep 2022 14:34:18 -0400 Subject: [PATCH 06/25] Changed i to unsigned to match "numgamedatamapheaders" --- src/g_game.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/g_game.c b/src/g_game.c index 15dd37082..cf9e91960 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -4150,7 +4150,7 @@ void G_LoadGameSettings(void) void G_LoadGameData(void) { size_t length; - INT32 i, j; + UINT32 i, j; UINT32 versionID; UINT8 rtemp; From 73aaa6baf84db66ef072f45a1b011601f4c8a003 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sun, 25 Sep 2022 18:16:07 -0400 Subject: [PATCH 07/25] As per jart suggestion --- src/command.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/command.c b/src/command.c index b2326cf59..a1c95e5df 100644 --- a/src/command.c +++ b/src/command.c @@ -1601,7 +1601,8 @@ static void Setvalue(consvar_t *var, const char *valstr, boolean stealth) // Enforce to default value without cheats. overridestr = var->defaultvalue; } - else if (CV_CompleteValue(var, &overridestr, &overrideval)) + + if (CV_CompleteValue(var, &overridestr, &overrideval)) { if (overridestr) { From 8fe6971e9adda1c717c04b50b94058efaf380cdc Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 25 Sep 2022 16:49:22 -0700 Subject: [PATCH 08/25] Fix -Wbad-function-cast --- src/d_clisrv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index acf9bdb1c..5e24839e8 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -924,7 +924,7 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime) strncpy(netbuffer->u.serverinfo.gametypename, Gametype_Names[prefgametype], sizeof netbuffer->u.serverinfo.gametypename); netbuffer->u.serverinfo.modifiedgame = (UINT8)modifiedgame; - netbuffer->u.serverinfo.cheatsenabled = (UINT8)CV_CheatsEnabled(); + netbuffer->u.serverinfo.cheatsenabled = CV_CheatsEnabled(); netbuffer->u.serverinfo.kartvars = (UINT8) ( (gamespeed & SV_SPEEDMASK) | From 839f59a896f79910769c739219eba3ae5e736c64 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 25 Sep 2022 16:50:32 -0700 Subject: [PATCH 09/25] Make CV_CHEAT cheats disabled cvar override always work for real --- src/command.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/command.c b/src/command.c index a1c95e5df..74de35543 100644 --- a/src/command.c +++ b/src/command.c @@ -1600,6 +1600,7 @@ static void Setvalue(consvar_t *var, const char *valstr, boolean stealth) { // Enforce to default value without cheats. overridestr = var->defaultvalue; + valstr = overridestr; } if (CV_CompleteValue(var, &overridestr, &overrideval)) From 0db0a1646aa0c5045ea79283d2456a19f1135fce Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sun, 25 Sep 2022 19:57:21 -0400 Subject: [PATCH 10/25] cv_renderhitbox is a cheat --- src/r_bbox.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/r_bbox.c b/src/r_bbox.c index 7c8887398..66732d08a 100644 --- a/src/r_bbox.c +++ b/src/r_bbox.c @@ -34,7 +34,7 @@ static CV_PossibleValue_t renderhitbox_cons_t[] = { {RENDERHITBOX_RINGS, "Rings"}, {0}}; -consvar_t cv_renderhitbox = CVAR_INIT ("renderhitbox", "Off", 0, renderhitbox_cons_t, NULL); +consvar_t cv_renderhitbox = CVAR_INIT ("renderhitbox", "Off", CV_CHEAT, renderhitbox_cons_t, NULL); struct bbox_col { INT32 x; From 90578b26286fb884837f2f55b6b1341a58f8901a Mon Sep 17 00:00:00 2001 From: toaster Date: Mon, 26 Sep 2022 17:15:34 +0100 Subject: [PATCH 11/25] Fix G_UpdateVisited, this time in a forward-thinking way - Check for if a single local player isn't spectator or no-contested. - Clean up code to return early if exclusionary conditions are met, rather than one long if conditional bundling them together --- src/g_game.c | 49 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 14 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 13a47ed1c..97000c367 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3621,25 +3621,46 @@ void G_AddMapToBuffer(INT16 map) // static void G_UpdateVisited(void) { - // Update visitation flags? - if (!demo.playback) // Not watching a demo + UINT8 i; + UINT8 earnedEmblems; + + // No demos. + if (demo.playback) + return; + + // Check if every local player wiped out. + for (i = 0; i < MAXPLAYERS; i++) { - UINT8 earnedEmblems; + if (!playeringame[i]) // Not here. + continue; - // Update visitation flags - mapheaderinfo[gamemap-1]->mapvisited |= MV_BEATEN; + if (!P_IsLocalPlayer(&players[i])) // Not local. + continue; - if (encoremode == true) - { - mapheaderinfo[gamemap-1]->mapvisited |= MV_ENCORE; - } + if (players[i].spectator) // Not playing. + continue; - if (modeattacking) - G_UpdateRecordReplays(); - - if ((earnedEmblems = M_CompletionEmblems())) - CONS_Printf(M_GetText("\x82" "Earned %hu emblem%s for level completion.\n"), (UINT16)earnedEmblems, earnedEmblems > 1 ? "s" : ""); + if (players[i].pflags & PF_NOCONTEST) // Sonic after not surviving. + continue; + break; } + + if (i == MAXPLAYERS) // Not a single living local soul? + return; + + // Update visitation flags + mapheaderinfo[gamemap-1]->mapvisited |= MV_BEATEN; + + if (encoremode == true) + { + mapheaderinfo[gamemap-1]->mapvisited |= MV_ENCORE; + } + + if (modeattacking) + G_UpdateRecordReplays(); + + if ((earnedEmblems = M_CompletionEmblems())) + CONS_Printf(M_GetText("\x82" "Earned %hu emblem%s for level completion.\n"), (UINT16)earnedEmblems, earnedEmblems > 1 ? "s" : ""); } static boolean CanSaveLevel(INT32 mapnum) From 710b2da729dad234eb822715076c2de9349eb44b Mon Sep 17 00:00:00 2001 From: toaster Date: Mon, 26 Sep 2022 20:14:17 +0100 Subject: [PATCH 12/25] Don't strcpy into beyond the end of the joinedIPlist array --- src/m_misc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/m_misc.c b/src/m_misc.c index e1d45a6cd..2deff3067 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -212,7 +212,7 @@ void M_AddToJoinedIPs(char *address, char *servname) CONS_Printf("Adding %s (%s) to list of manually joined IPs\n", servname, address); // Start by moving every IP up 1 slot (dropping the last IP in the table) - for (i = NUMLOGIP; i; i--) + for (i = NUMLOGIP-1; i; i--) { strcpy(joinedIPlist[i][0], joinedIPlist[i-1][0]); strcpy(joinedIPlist[i][1], joinedIPlist[i-1][1]); From 5779ac6a05af40486b43bcc196a8441fc20b0d68 Mon Sep 17 00:00:00 2001 From: toaster Date: Mon, 26 Sep 2022 20:41:14 +0100 Subject: [PATCH 13/25] Re-order IPs on successful connection to recent server --- src/m_misc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/m_misc.c b/src/m_misc.c index 29e4a35e2..afcd6749b 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -198,19 +198,19 @@ void M_AddToJoinedIPs(char *address, char *servname) UINT8 i = 0; // Check for dupes... - for (i = 0; i < NUMLOGIP; i++) + for (i = 0; i < NUMLOGIP-1; i++) { - // I don't care about the server name (this is broken anyway...) but definitely check the addresses + // Check the addresses if (strcmp(joinedIPlist[i][0], address) == 0) { - return; + break; } } CONS_Printf("Adding %s (%s) to list of manually joined IPs\n", servname, address); // Start by moving every IP up 1 slot (dropping the last IP in the table) - for (i = NUMLOGIP-1; i; i--) + for (; i; i--) { strcpy(joinedIPlist[i][0], joinedIPlist[i-1][0]); strcpy(joinedIPlist[i][1], joinedIPlist[i-1][1]); From dfce8634490fdb1c266026b00e85d6d38d78ab21 Mon Sep 17 00:00:00 2001 From: toaster Date: Mon, 26 Sep 2022 20:42:13 +0100 Subject: [PATCH 14/25] Dummy out connectedservername usage for now, as it's only ever written to when YOU host --- src/d_clisrv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index e9aaa3407..0776fe6a8 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -2045,8 +2045,9 @@ static void CL_ConnectToServer(void) // @TODO: Save the proper server name, right now it doesn't seem like we can consistently retrieve it from the serverlist....? // It works... sometimes but not always which is weird. + tmpsave[0] = '\0'; // TEMPORARY -- connectedservername is currently only set for YOUR server if (joinedIP[0]) // false if we have "" which is \0 - M_AddToJoinedIPs(joinedIP, connectedservername); + M_AddToJoinedIPs(joinedIP, tmpsave); //connectedservername); -- as above joinedIP[0] = '\0'; // And empty this for good measure regardless of whether or not we actually used it. From 52f0217baccad85cc6af3b0de043f254e73925a4 Mon Sep 17 00:00:00 2001 From: toaster Date: Mon, 26 Sep 2022 20:59:00 +0100 Subject: [PATCH 15/25] Completely rewrite how joined IPs are saved and written... again - Use strlcpy instead of strcpy to prevent footguns - Use fprintf instead of raw fputs - Enforce consistent MAX_LOGIP (255) length for each component instead of a combination of magic number 255 and MAXSTRINGLENGTH (32!?) depending on where you look - Fix fun memory leak in waiting - Avoid pointless strlens --- src/d_clisrv.c | 2 +- src/k_menudraw.c | 6 ++--- src/k_menufunc.c | 2 +- src/m_misc.c | 65 +++++++++++++++++++++--------------------------- src/m_misc.h | 6 ++--- 5 files changed, 37 insertions(+), 44 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 0776fe6a8..0613ba13d 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -2425,7 +2425,7 @@ static void Command_connect(void) // Last IPs joined: // Keep the address we typed in memory so that we can save it if we *succesfully* join the server - strcpy(joinedIP, COM_Argv(1)); + strlcpy(joinedIP, COM_Argv(1), MAX_LOGIP); } else { diff --git a/src/k_menudraw.c b/src/k_menudraw.c index b3f4e390c..92e47cb2f 100644 --- a/src/k_menudraw.c +++ b/src/k_menudraw.c @@ -2417,7 +2417,7 @@ void M_DrawMPJoinIP(void) case IT_STRING: { - char str[MAXSTRINGLENGTH]; + char str[MAX_LOGIP]; strcpy(str, currentMenu->menuitems[i].text); // The last 3 options of this menu are to be the joined IP addresses... @@ -2430,9 +2430,9 @@ void M_DrawMPJoinIP(void) } if (joinedIPlist[index][1][0]) // Try drawing server name - strcpy(str, joinedIPlist[index][1]); + strlcpy(str, joinedIPlist[index][1], MAX_LOGIP); else if (joinedIPlist[index][0][0]) // If that fails, get the address - strcpy(str, joinedIPlist[index][0]); + strlcpy(str, joinedIPlist[index][0], MAX_LOGIP); else strcpy(str, "---"); // If that fails too then there's nothing! } diff --git a/src/k_menufunc.c b/src/k_menufunc.c index b37d7b57b..e143d5670 100644 --- a/src/k_menufunc.c +++ b/src/k_menufunc.c @@ -3875,7 +3875,7 @@ boolean M_JoinIPInputs(INT32 ch) M_SetMenuDelay(pid); // Is there an address at this part of the table? - if (strlen(joinedIPlist[index][0])) + if (*joinedIPlist[index][0]) M_JoinIP(joinedIPlist[index][0]); else S_StartSound(NULL, sfx_lose); diff --git a/src/m_misc.c b/src/m_misc.c index afcd6749b..c6aaceab5 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -179,8 +179,8 @@ boolean takescreenshot = false; // Take a screenshot this tic moviemode_t moviemode = MM_OFF; -char joinedIPlist[NUMLOGIP][2][255]; -char joinedIP[255]; +char joinedIPlist[NUMLOGIP][2][MAX_LOGIP]; +char joinedIP[MAX_LOGIP]; // This initializes the above array to have NULL evrywhere it should. void M_InitJoinedIPArray(void) @@ -198,7 +198,7 @@ void M_AddToJoinedIPs(char *address, char *servname) UINT8 i = 0; // Check for dupes... - for (i = 0; i < NUMLOGIP-1; i++) + for (i = 0; i < NUMLOGIP-1; i++) // intentionally not < NUMLOGIP { // Check the addresses if (strcmp(joinedIPlist[i][0], address) == 0) @@ -212,13 +212,13 @@ void M_AddToJoinedIPs(char *address, char *servname) // Start by moving every IP up 1 slot (dropping the last IP in the table) for (; i; i--) { - strcpy(joinedIPlist[i][0], joinedIPlist[i-1][0]); - strcpy(joinedIPlist[i][1], joinedIPlist[i-1][1]); + strlcpy(joinedIPlist[i][0], joinedIPlist[i-1][0], MAX_LOGIP); + strlcpy(joinedIPlist[i][1], joinedIPlist[i-1][1], MAX_LOGIP); } // and add the new IP at the start of the table! - strcpy(joinedIPlist[0][0], address); - strcpy(joinedIPlist[0][1], servname); + strlcpy(joinedIPlist[0][0], address, MAX_LOGIP); + strlcpy(joinedIPlist[0][1], servname, MAX_LOGIP); } // ========================================================================== @@ -471,34 +471,24 @@ void M_SaveJoinedIPs(void) { FILE *f = NULL; UINT8 i; - char *filepath; + const char *filepath = va("%s"PATHSEP"%s", srb2home, IPLOGFILE); - if (!strlen(joinedIPlist[0][0])) + if (!*joinedIPlist[0][0]) return; // Don't bother, there's nothing to save. - // append srb2home to beginning of filename - // but check if srb2home isn't already there, first - if (!strstr(IPLOGFILE, srb2home)) - filepath = va(pandf,srb2home, IPLOGFILE); - else - filepath = Z_StrDup(IPLOGFILE); - f = fopen(filepath, "w"); - if (f == NULL) - return; // Uh I guess you don't have disk space????????? - - for (i=0; i < NUMLOGIP; i++) + if (!f) { - if (strlen(joinedIPlist[i][0])) - { - char savestring[MAXSTRINGLENGTH]; - strcpy(savestring, joinedIPlist[i][0]); - strcat(savestring, IPLOGFILESEP); - strcat(savestring, joinedIPlist[i][1]); + CONS_Alert(CONS_WARNING, "Could not save recent IP list into %s\n", IPLOGFILE); + return; + } - fputs(savestring, f); - fputs("\n", f); // Because this won't do it automatically now will it... + for (i = 0; i < NUMLOGIP; i++) + { + if (*joinedIPlist[i][0]) + { + fprintf(f, "%s%s%s\n", joinedIPlist[i][0], IPLOGFILESEP, joinedIPlist[i][1]); } } @@ -513,7 +503,7 @@ void M_LoadJoinedIPs(void) UINT8 i = 0; char *filepath; char *s; - char content[255]; // 255 is more than long enough! + char buffer[2*(MAX_LOGIP+1)]; filepath = va("%s"PATHSEP"%s", srb2home, IPLOGFILE); f = fopen(filepath, "r"); @@ -521,27 +511,30 @@ void M_LoadJoinedIPs(void) if (f == NULL) return; // File doesn't exist? sure, just do nothing then. - while (fgets(content, 255, f) && i < NUMLOGIP && content[0] && content[0] != '\n') // Don't let us write more than we can chew! + for (i = 0; fgets(buffer, (int)sizeof(buffer), f); i++) // Don't let us write more than we can chew! { + if (i >= NUMLOGIP) + break; - // Now we have garbage under the form of "address;string" - // Now you might ask yourself, but what do we do if the player fucked with their file and now there's a bunch of garbage? - // ...Well that's not my problem lol. + if (!*buffer || *buffer == '\n') + break; - s = strtok(content, IPLOGFILESEP); // We got the address - strcpy(joinedIPlist[i][0], s); + s = strtok(buffer, IPLOGFILESEP); // We got the address + strlcpy(joinedIPlist[i][0], s, MAX_LOGIP); s = strtok(NULL, IPLOGFILESEP); // Let's get rid of this awful \n while we're here! if (s) { + UINT16 j = 1; //strcpy(joinedIPlist[i][1], s); -- get rid of \n too... char *c = joinedIPlist[i][1]; - while (*s && *s != '\n') + while (*s && *s != '\n' && j < MAX_LOGIP) { *c = *s; s++; c++; + j++; } *c = '\0'; } diff --git a/src/m_misc.h b/src/m_misc.h index 12f51edcf..f4beb8501 100644 --- a/src/m_misc.h +++ b/src/m_misc.h @@ -46,15 +46,15 @@ void M_StopMovie(void); #define IPLOGFILE "ringsavedips.txt" #define IPLOGFILESEP ";" #define NUMLOGIP 3 +#define MAX_LOGIP 255 // Array where we'll store addresses to display for last servers joined // {address, servame} -// 255 is long enough to store the text -extern char joinedIPlist[NUMLOGIP][2][255]; +extern char joinedIPlist[NUMLOGIP][2][MAX_LOGIP]; // Keep the address we're joining in mind until we've finished joining. // Since we don't wanna add an IP address we aren't even sure worked out. -extern char joinedIP[255]; +extern char joinedIP[MAX_LOGIP]; void M_InitJoinedIPArray(void); void M_AddToJoinedIPs(char *address, char *servname); From 3d2f6770a56dd4aaa4d0ba8ec2c60ed15eace89a Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 26 Sep 2022 20:44:09 -0700 Subject: [PATCH 16/25] Divide G_PlayerInputAnalog values by JOYAXISRANGE Previously right shifted by 10, which should've been equivalent to divide by 1024. It returned -799 or 800 for a full turn in either direction though. This commit lets turning values reach KART_FULLTURN in either direction. --- src/g_game.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 998e242b6..159bbb48b 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1100,7 +1100,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) if (joystickvector.xaxis != 0) { - cmd->turning -= (joystickvector.xaxis * KART_FULLTURN) >> 10; + cmd->turning -= (joystickvector.xaxis * KART_FULLTURN) / JOYAXISRANGE; } if (player->spectator || objectplacing) // SRB2Kart: spectators need special controls @@ -1132,20 +1132,20 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) if (value != 0) { cmd->buttons |= BT_ACCELERATE; - forward += ((value * MAXPLMOVE) >> 10); + forward += ((value * MAXPLMOVE) / JOYAXISRANGE); } value = G_PlayerInputAnalog(forplayer, gc_brake, 0); if (value != 0) { cmd->buttons |= BT_BRAKE; - forward -= ((value * MAXPLMOVE) >> 10); + forward -= ((value * MAXPLMOVE) / JOYAXISRANGE); } // But forward/backward IS used for aiming. if (joystickvector.yaxis != 0) { - cmd->throwdir -= (joystickvector.yaxis * KART_FULLTURN) >> 10; + cmd->throwdir -= (joystickvector.yaxis * KART_FULLTURN) / JOYAXISRANGE; } } From 562f5398a0ad1ca7b4cf8c9a545df7c716fdae51 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 27 Sep 2022 14:25:08 -0400 Subject: [PATCH 17/25] Properly say when a cvar is a cheat --- src/command.c | 9 +++++++-- src/d_netcmd.c | 3 +-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/command.c b/src/command.c index 74de35543..6eb0fe9bc 100644 --- a/src/command.c +++ b/src/command.c @@ -1599,8 +1599,13 @@ static void Setvalue(consvar_t *var, const char *valstr, boolean stealth) if ((var->flags & CV_CHEAT) && CV_CheatsEnabled() == false) { // Enforce to default value without cheats. - overridestr = var->defaultvalue; - valstr = overridestr; + if (stricmp(var->defaultvalue, valstr) != 0) + { + // Warn the user about this. + CONS_Printf("This cannot be used without cheats enabled.\n"); + } + + valstr = overridestr = var->defaultvalue; } if (CV_CompleteValue(var, &overridestr, &overrideval)) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 7562f6435..24c4f2a63 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -5621,8 +5621,7 @@ static void Command_KartGiveItem_f(void) } else { - CONS_Alert(CONS_NOTICE, - "The server does not allow this.\n"); + CONS_Printf("This cannot be used without cheats enabled.\n"); } } From e03a97c18ad03f2ea8a88e4a74280463d4c07255 Mon Sep 17 00:00:00 2001 From: toaster Date: Tue, 27 Sep 2022 19:52:37 +0100 Subject: [PATCH 18/25] Fix double i++ in M_LoadJoinedIPs --- src/m_misc.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/m_misc.c b/src/m_misc.c index c6aaceab5..eeb287751 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -538,8 +538,6 @@ void M_LoadJoinedIPs(void) } *c = '\0'; } - - i++; } fclose(f); // We're done here } From e2b2b7785cae92f070c6e9f3199d684b282323d2 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 27 Sep 2022 15:22:59 -0400 Subject: [PATCH 19/25] Cheater warning --- src/command.c | 14 ++++++++++++++ src/command.h | 1 + src/d_netcmd.c | 7 +++++++ 3 files changed, 22 insertions(+) diff --git a/src/command.c b/src/command.c index 6eb0fe9bc..f94703f1f 100644 --- a/src/command.c +++ b/src/command.c @@ -1774,6 +1774,11 @@ static void Got_NetVar(UINT8 **p, INT32 playernum) if (cvar) Setvalue(cvar, svalue, stealth); + + if ((cvar->flags & CV_CHEAT) && stricmp(svalue, cvar->defaultvalue) != 0) + { + CV_CheaterWarning(playernum, va("%s %s", cvar->name, svalue)); + } } void CV_SaveVars(UINT8 **p, boolean in_demo) @@ -1917,6 +1922,15 @@ boolean CV_CheatsEnabled(void) return (boolean)cv_cheats.value; } +// Consistent print about cheaters in multiplayer. +void CV_CheaterWarning(UINT8 playerID, const char *command) +{ + if (netgame) + { + CONS_Printf("\x85" "%s cheats:" "\x80" " %s\n", player_names[playerID], command); + } +} + /** Sets a value to a variable, performing some checks and calling the * callback function if there is one. * Does as if " " is entered at the console. diff --git a/src/command.h b/src/command.h index c6a38adeb..35330d5d4 100644 --- a/src/command.h +++ b/src/command.h @@ -233,6 +233,7 @@ void CV_CheatsChanged(void); boolean CV_IsSetToDefault(consvar_t *v); boolean CV_CheatsEnabled(void); +void CV_CheaterWarning(UINT8 playerID, const char *command); // Returns cvar by name. Exposed here for Lua. consvar_t *CV_FindVar(const char *name); diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 24c4f2a63..949a0df49 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -5306,6 +5306,13 @@ static void Got_GiveItemcmd(UINT8 **cp, INT32 playernum) players[playernum].itemtype = item; players[playernum].itemamount = amt; + + CV_CheaterWarning( + playernum, + (amt != 1) // FIXME: we should have actual KITEM_ name array + ? va("kartgiveitem %s %d", cv_kartdebugitem.PossibleValue[item+1].strvalue, amt) + : va("kartgiveitem %s", cv_kartdebugitem.PossibleValue[item+1].strvalue) + ); } static void Got_ScheduleTaskcmd(UINT8 **cp, INT32 playernum) From fd7cadd566118005476b8917901d7ef25c7b6da2 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 27 Sep 2022 15:23:26 -0400 Subject: [PATCH 20/25] Strip items when using kartgiveitem Fixes some annoyances I have when using this command --- src/d_netcmd.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 949a0df49..cd305267c 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -5304,6 +5304,9 @@ static void Got_GiveItemcmd(UINT8 **cp, INT32 playernum) return; } + K_StripItems(&players[playernum]); + player->itemroulette = 0; + players[playernum].itemtype = item; players[playernum].itemamount = amt; From fa343d4ecdadefc3f2d4680f367425f5fcaf18be Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 27 Sep 2022 15:23:26 -0400 Subject: [PATCH 21/25] Strip items when using kartgiveitem Fixes some annoyances I have when using this command --- src/d_netcmd.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 949a0df49..befc9f300 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -5304,6 +5304,9 @@ static void Got_GiveItemcmd(UINT8 **cp, INT32 playernum) return; } + K_StripItems(&players[playernum]); + players[playernum].itemroulette = 0; + players[playernum].itemtype = item; players[playernum].itemamount = amt; From 9d383dd38f604686c6536febf5d2506012c43c98 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 27 Sep 2022 15:55:08 -0400 Subject: [PATCH 22/25] Use cvar->value instead of svalue for the check --- src/command.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/command.c b/src/command.c index f94703f1f..794c73bae 100644 --- a/src/command.c +++ b/src/command.c @@ -1775,9 +1775,9 @@ static void Got_NetVar(UINT8 **p, INT32 playernum) if (cvar) Setvalue(cvar, svalue, stealth); - if ((cvar->flags & CV_CHEAT) && stricmp(svalue, cvar->defaultvalue) != 0) + if ((cvar->flags & CV_CHEAT) && stricmp(cvar->value, cvar->defaultvalue) != 0) // use cvar->value to compare what it is now { - CV_CheaterWarning(playernum, va("%s %s", cvar->name, svalue)); + CV_CheaterWarning(playernum, va("%s %s", cvar->name, svalue)); // but use svalue to show what they inputted } } From d61c9aefe1bc95c82a39b8b689687f5f2826309c Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 27 Sep 2022 15:55:08 -0400 Subject: [PATCH 23/25] Use cvar->string instead of svalue for the check --- src/command.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/command.c b/src/command.c index f94703f1f..d5f184493 100644 --- a/src/command.c +++ b/src/command.c @@ -1775,9 +1775,9 @@ static void Got_NetVar(UINT8 **p, INT32 playernum) if (cvar) Setvalue(cvar, svalue, stealth); - if ((cvar->flags & CV_CHEAT) && stricmp(svalue, cvar->defaultvalue) != 0) + if ((cvar->flags & CV_CHEAT) && stricmp(cvar->string, cvar->defaultvalue) != 0) // use cvar->string to compare what it is now { - CV_CheaterWarning(playernum, va("%s %s", cvar->name, svalue)); + CV_CheaterWarning(playernum, va("%s %s", cvar->name, svalue)); // but use svalue to show what they inputted } } From b7bfa5a5c70b289f9bf0454a9d60c680c5361164 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 27 Sep 2022 16:16:04 -0400 Subject: [PATCH 24/25] Don't try cheater warning if NULL netvar --- src/command.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/command.c b/src/command.c index d5f184493..0015bcf1c 100644 --- a/src/command.c +++ b/src/command.c @@ -1773,11 +1773,13 @@ static void Got_NetVar(UINT8 **p, INT32 playernum) cvar = ReadNetVar(p, &svalue, &stealth); if (cvar) + { Setvalue(cvar, svalue, stealth); - if ((cvar->flags & CV_CHEAT) && stricmp(cvar->string, cvar->defaultvalue) != 0) // use cvar->string to compare what it is now - { - CV_CheaterWarning(playernum, va("%s %s", cvar->name, svalue)); // but use svalue to show what they inputted + if ((cvar->flags & CV_CHEAT) && stricmp(cvar->string, cvar->defaultvalue) != 0) // use cvar->string to compare what it is now + { + CV_CheaterWarning(playernum, va("%s %s", cvar->name, svalue)); // but use svalue to show what they inputted + } } } From 9159f5da05aa1cfe0e5b80787158152e2fbcbe2b Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 27 Sep 2022 16:16:45 -0400 Subject: [PATCH 25/25] kartdebugitem defaultvalue = None Should remove console spam --- src/d_netcmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 81742b15b..dcc351fb9 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -441,7 +441,7 @@ static CV_PossibleValue_t kartdebugitem_cons_t[] = #undef FOREACH {0} }; -consvar_t cv_kartdebugitem = CVAR_INIT ("kartdebugitem", "0", CV_NETVAR|CV_CHEAT, kartdebugitem_cons_t, NULL); +consvar_t cv_kartdebugitem = CVAR_INIT ("kartdebugitem", "None", CV_NETVAR|CV_CHEAT, kartdebugitem_cons_t, NULL); static CV_PossibleValue_t kartdebugamount_cons_t[] = {{1, "MIN"}, {255, "MAX"}, {0, NULL}}; consvar_t cv_kartdebugamount = CVAR_INIT ("kartdebugamount", "1", CV_NETVAR|CV_CHEAT, kartdebugamount_cons_t, NULL);