Follow-ups on EXPLORERS authorization

I realized that failed explore-mode authorization on a special-mode
saved game cannot downgrade the game mode further down to a normal game,
because this would dump the player back into a state where she has
completed some part of the game in explore mode but is eligible for the
topten list.  This is even more true when the game was formerly a
wizard-mode game.  Unforunately, that was the state my previous commits
left the game in.

Instead, if restoring an explore-mode or wizard-mode savegame, and the
player is authorized via sysconf for neither of those modes, fail
restoration entirely and start a new game instead.  That's sort of
clunky and there could probably be more explanation provided, but it
should be an exceedingly rare occurance and I'm not sure what
alternative exists that would still honor the EXPLORERS and WIZARDS
restrictions.  This shouldn't affect the way they default 'down a mode'
in other circumstances, i.e. the overwhelming majority of situations in
which EXPLORERS authorization is needed/checked.

For the same reason, I realized that the player can't be prompted
whether or not to enter explore mode, if being downgraded from a
no-longer-authorized wizmode save while explore mode is authorized.  The
change from wizard mode to explore mode must be mandatory.  I have also
switched that up so that it will force the change -- unfortunately, this
has the side effect of allowing the preservation of the save, but it's
more important to make sure a wizard mode game doesn't get reverted to
normal mode.  They won't be able to load the save into wizard mode
anyway.
This commit is contained in:
Michael Meyer
2023-10-23 21:44:41 -04:00
committed by PatR
parent 1e237e4b8f
commit b993edca74
5 changed files with 23 additions and 14 deletions

View File

@@ -412,6 +412,8 @@ struct instance_flags {
chosen_windowport[], but do not switch to
it in the midst of options processing */
genericptr_t returning_missile; /* 'struct obj *'; Mjollnir or aklys */
boolean wiz_error_flag; /* flag for tracking failed wizmode auth */
boolean explore_error_flag; /* ditto for explore mode */
boolean obsolete; /* obsolete options can point at this, it isn't used */
};

View File

@@ -10262,6 +10262,7 @@ set_playmode(void)
set iflags.deferred_X and prompt to activate explore mode after the
save file has already been deleted */
discover = !wizard;
iflags.deferred_X = FALSE;
}
if (discover && !authorize_explore_mode()) {
discover = iflags.deferred_X = FALSE;

View File

@@ -512,7 +512,7 @@ restgamestate(NHFILE *nhfp)
struct obj *bc_obj;
char timebuf[15];
unsigned long uid = 0;
boolean defer_perm_invent;
boolean defer_perm_invent, restoring_special;
if (nhfp->structlevel)
Mread(nhfp->fd, &uid, sizeof uid);
@@ -557,10 +557,11 @@ restgamestate(NHFILE *nhfp)
in the discover case, we don't want to set that for a normal
game until after the save file has been removed */
iflags.deferred_X = (newgameflags.explore && !discover);
restoring_special = (wizard || discover);
if (newgameflags.debug) {
/* authorized by startup code; wizard mode exists and is allowed */
wizard = TRUE, discover = iflags.deferred_X = FALSE;
} else if (wizard || discover) {
} else if (restoring_special) {
/* specified by save file; check authorization now. */
set_playmode();
}
@@ -572,6 +573,13 @@ restgamestate(NHFILE *nhfp)
Mread(nhfp->fd, &u, sizeof u);
gy.youmonst.cham = u.mcham;
if (restoring_special && iflags.explore_error_flag) {
/* savefile has wizard or explore mode, but player is no longer
authorized to access either; can't downgrade mode any further, so
fail restoration. */
u.uhp = 0;
}
if (nhfp->structlevel)
Mread(nhfp->fd, timebuf, 14);
timebuf[14] = '\0';

View File

@@ -50,7 +50,6 @@ extern void init_linux_cons(void);
#endif
static void wd_message(void);
static boolean wiz_error_flag = FALSE, explore_error_flag = FALSE;
static struct passwd *get_unix_pw(void);
#ifdef __EMSCRIPTEN__
@@ -601,7 +600,7 @@ authorize_wizard_mode(void)
if (check_user_string(sysopt.wizards))
return TRUE;
}
wiz_error_flag = TRUE; /* not being allowed into wizard mode */
iflags.wiz_error_flag = TRUE; /* not being allowed into wizard mode */
return FALSE;
}
@@ -614,7 +613,7 @@ authorize_explore_mode(void)
if (check_user_string(sysopt.explorers))
return TRUE;
}
explore_error_flag = TRUE; /* not being allowed into explore mode */
iflags.explore_error_flag = TRUE; /* not allowed into explore mode */
return FALSE;
#else
return TRUE; /* if sysconf disabled, no restrictions on explore mode */
@@ -624,7 +623,7 @@ authorize_explore_mode(void)
static void
wd_message(void)
{
if (wiz_error_flag) {
if (iflags.wiz_error_flag) {
if (sysopt.wizards && sysopt.wizards[0]) {
char *tmp = build_english_list(sysopt.wizards);
pline("Only user%s %s may access debug (wizard) mode.",
@@ -634,9 +633,9 @@ wd_message(void)
You("cannot access debug (wizard) mode.");
}
wizard = FALSE; /* (paranoia) */
if (!explore_error_flag)
if (!iflags.explore_error_flag)
pline("Entering explore/discovery mode instead.");
} else if (explore_error_flag) {
} else if (iflags.explore_error_flag) {
You("cannot access explore mode."); /* same as enter_explore_mode */
discover = iflags.deferred_X = FALSE; /* (more paranoia) */
} else if (discover)

View File

@@ -53,7 +53,6 @@ extern void init_linux_cons(void);
#endif
static void wd_message(void);
static boolean wiz_error_flag = FALSE, explore_error_flag = FALSE;
static struct passwd *get_unix_pw(void);
int
@@ -960,7 +959,7 @@ authorize_wizard_mode(void)
if (check_user_string(sysopt.wizards))
return TRUE;
}
wiz_error_flag = TRUE; /* not being allowed into wizard mode */
iflags.wiz_error_flag = TRUE; /* not being allowed into wizard mode */
return FALSE;
}
@@ -973,7 +972,7 @@ authorize_explore_mode(void)
if (check_user_string(sysopt.explorers))
return TRUE;
}
explore_error_flag = TRUE; /* not being allowed into explore mode */
iflags.explore_error_flag = TRUE; /* not allowed into explore mode */
return FALSE;
#else
return TRUE; /* if sysconf disabled, no restrictions on explore mode */
@@ -983,7 +982,7 @@ authorize_explore_mode(void)
static void
wd_message(void)
{
if (wiz_error_flag) {
if (iflags.wiz_error_flag) {
if (sysopt.wizards && sysopt.wizards[0]) {
char *tmp = build_english_list(sysopt.wizards);
pline("Only user%s %s may access debug (wizard) mode.",
@@ -993,9 +992,9 @@ wd_message(void)
You("cannot access debug (wizard) mode.");
}
wizard = FALSE; /* (paranoia) */
if (!explore_error_flag)
if (!iflags.explore_error_flag)
pline("Entering explore/discovery mode instead.");
} else if (explore_error_flag) {
} else if (iflags.explore_error_flag) {
You("cannot access explore mode."); /* same as enter_explore_mode */
discover = iflags.deferred_X = FALSE; /* (more paranoia) */
} else if (discover)