internal self-recover fix and bones name buffers

This commit is contained in:
nhmall
2019-11-21 23:41:11 -05:00
parent cb4d350424
commit 3545374e9c
5 changed files with 154 additions and 52 deletions

View File

@@ -7,6 +7,8 @@ hero polymorphed into a vampire can use #monster to shape-shift rather than
just do a one-shot polymorph into bat/cloud/wolf and shifted vampire just do a one-shot polymorph into bat/cloud/wolf and shifted vampire
hero can use #monster again to take on another form (randomly chosen hero can use #monster again to take on another form (randomly chosen
among the shiftable shapes and true vampire form) among the shiftable shapes and true vampire form)
adjust bones filename buffer sizes to accommodate suffix
fix internal self-recover to work with recent fields added to checkpoint file
Fixes to Pre-3.7.0 Problems that Were Exposed Via git Repository Fixes to Pre-3.7.0 Problems that Were Exposed Via git Repository

View File

@@ -10,7 +10,7 @@
#if !defined(MICRO) && !defined(VMS) && !defined(WIN32) #if !defined(MICRO) && !defined(VMS) && !defined(WIN32)
#define LOCKNAMESIZE (PL_NSIZ + 14) /* long enough for uid+name+.99 */ #define LOCKNAMESIZE (PL_NSIZ + 14) /* long enough for uid+name+.99 */
#define LOCKNAMEINIT "1lock" #define LOCKNAMEINIT "1lock"
#define BONESINIT "bonesnn.xxx" #define BONESINIT "bonesnn.xxx.le"
#define BONESSIZE sizeof(BONESINIT) #define BONESSIZE sizeof(BONESINIT)
#else #else
#if defined(MICRO) #if defined(MICRO)
@@ -22,13 +22,13 @@
#if defined(VMS) #if defined(VMS)
#define LOCKNAMESIZE (PL_NSIZ + 17) /* long enough for _uid+name+.99;1 */ #define LOCKNAMESIZE (PL_NSIZ + 17) /* long enough for _uid+name+.99;1 */
#define LOCKNAMEINIT "1lock" #define LOCKNAMEINIT "1lock"
#define BONESINIT "bonesnn.xxx;1" #define BONESINIT "bonesnn.xxx_le;1"
#define BONESSIZE sizeof(BONESINIT) #define BONESSIZE sizeof(BONESINIT)
#endif #endif
#if defined(WIN32) #if defined(WIN32)
#define LOCKNAMESIZE (PL_NSIZ + 25) /* long enough for username+-+name+.99 */ #define LOCKNAMESIZE (PL_NSIZ + 25) /* long enough for username+-+name+.99 */
#define LOCKNAMEINIT "" #define LOCKNAMEINIT ""
#define BONESINIT "bonesnn.xxx" #define BONESINIT "bonesnn.xxx.le"
#define BONESSIZE sizeof(BONESINIT) #define BONESSIZE sizeof(BONESINIT)
#endif #endif
#endif #endif
@@ -170,6 +170,7 @@ struct sinfo {
int exiting; /* an exit handler is executing */ int exiting; /* an exit handler is executing */
int in_moveloop; int in_moveloop;
int in_impossible; int in_impossible;
int in_self_recover;
#ifdef PANICLOG #ifdef PANICLOG
int in_paniclog; int in_paniclog;
#endif #endif

View File

@@ -757,12 +757,12 @@ d_level *lev;
char *dptr; char *dptr;
/* /*
* "bonD0.nn" = bones for level nn in the main dungeon; * "bonD0.nn.le" = bones for level nn in the main dungeon;
* "bonM0.T" = bones for Minetown; * "bonM0.T.le" = bones for Minetown;
* "bonQBar.n" = bones for level n in the Barbarian quest; * "bonQBar.n.le" = bones for level n in the Barbarian quest;
* "bon3D0.nn" = \ * "bon3D0.nn.le" = \
* "bon3M0.T" = > same as above, but for bones pool #3. * "bon3M0.T.le" = > same as above, but for bones pool #3.
* "bon3QBar.n" = / * "bon3QBar.n.le" = /
* *
* Return value for content validation skips "bon" and the * Return value for content validation skips "bon" and the
* pool number (if present), making it feasible for the admin * pool number (if present), making it feasible for the admin
@@ -1032,6 +1032,17 @@ boolean regularize_it;
if (idx > historical && idx <= ascii) if (idx > historical && idx <= ascii)
sfindicator = sfoprocs[idx].ext; sfindicator = sfoprocs[idx].ext;
#endif #endif
if (g.program_state.in_self_recover) {
/* self_recover needs to be done as historical
structlevel content until that process is
re-written to use something other than
copy_bytes() to retrieve data content from
level files (which are structlevel) and
place it into the save file.
*/
idx = historical;
sfindicator = sfoprocs[idx].ext;
}
#ifdef VMS #ifdef VMS
Sprintf(g.SAVEF, "[.save]%d%s", getuid(), g.plname); Sprintf(g.SAVEF, "[.save]%d%s", getuid(), g.plname);
regoffset = 7; regoffset = 7;
@@ -1108,7 +1119,7 @@ boolean regularize_it;
(idx == lendian) ? 'l' : (idx == lendian) ? 'l' :
(idx == ascii) ? 'a' : '\0'; (idx == ascii) ? 'a' : '\0';
} }
sfindicator = sfoprocs[idx].ext; sfindicator = (g.program_state.in_self_recover) ? "" : sfoprocs[idx].ext;
#endif #endif
#endif #endif
} else } else
@@ -1176,6 +1187,7 @@ create_savefile()
int failed = 0; int failed = 0;
const char *fq_save; const char *fq_save;
NHFILE *nhfp = (NHFILE *) 0; NHFILE *nhfp = (NHFILE *) 0;
boolean do_historical = TRUE;
fq_save = fqname(g.SAVEF, SAVEPREFIX, 0); fq_save = fqname(g.SAVEF, SAVEPREFIX, 0);
nhfp = new_nhfile(); nhfp = new_nhfile();
@@ -1186,7 +1198,21 @@ create_savefile()
nhfp->mode = WRITING; nhfp->mode = WRITING;
#ifdef SYSCF #ifdef SYSCF
if (sysopt.saveformat[0] > historical && if (sysopt.saveformat[0] > historical &&
sysopt.saveformat[0] <= ascii) { sysopt.saveformat[0] <= ascii)
do_historical = FALSE;
#endif /* SYSCF */
if (g.program_state.in_self_recover) {
do_historical = TRUE; /* force it */
nhfp->structlevel = TRUE;
nhfp->fieldlevel = FALSE;
nhfp->addinfo = FALSE;
nhfp->style.deflt = FALSE;
nhfp->style.binary = TRUE;
nhfp->fnidx = historical;
nhfp->fd = -1;
nhfp->fpdef = (FILE *) 0;
}
if (!do_historical) {
nhfp->structlevel = FALSE; nhfp->structlevel = FALSE;
nhfp->fieldlevel = TRUE; nhfp->fieldlevel = TRUE;
nhfp->addinfo = TRUE; nhfp->addinfo = TRUE;
@@ -1203,7 +1229,6 @@ create_savefile()
failed = errno; failed = errno;
} }
} }
#endif /* SYSCF */
if (nhfp->structlevel) { if (nhfp->structlevel) {
#if defined(MICRO) || defined(WIN32) #if defined(MICRO) || defined(WIN32)
nhfp->fd = open(fq_save, O_WRONLY | O_BINARY | O_CREAT | O_TRUNC, FCMASK); nhfp->fd = open(fq_save, O_WRONLY | O_BINARY | O_CREAT | O_TRUNC, FCMASK);
@@ -1240,6 +1265,7 @@ open_savefile()
int failed = 0; int failed = 0;
const char *fq_save; const char *fq_save;
NHFILE *nhfp = (NHFILE *) 0; NHFILE *nhfp = (NHFILE *) 0;
boolean do_historical = TRUE;
fq_save = fqname(g.SAVEF, SAVEPREFIX, 0); fq_save = fqname(g.SAVEF, SAVEPREFIX, 0);
nhfp = new_nhfile(); nhfp = new_nhfile();
@@ -1250,7 +1276,21 @@ open_savefile()
nhfp->mode = READING; nhfp->mode = READING;
#ifdef SYSCF #ifdef SYSCF
if (sysopt.saveformat[0] > historical && if (sysopt.saveformat[0] > historical &&
sysopt.saveformat[0] <= ascii) { sysopt.saveformat[0] <= ascii)
do_historical = FALSE;
#endif /* SYSCF */
if (g.program_state.in_self_recover) {
do_historical = TRUE; /* force it */
nhfp->structlevel = TRUE;
nhfp->fieldlevel = FALSE;
nhfp->addinfo = FALSE;
nhfp->style.deflt = FALSE;
nhfp->style.binary = TRUE;
nhfp->fnidx = historical;
nhfp->fd = -1;
nhfp->fpdef = (FILE *) 0;
}
if (!do_historical) {
nhfp->structlevel = FALSE; nhfp->structlevel = FALSE;
nhfp->fieldlevel = TRUE; nhfp->fieldlevel = TRUE;
nhfp->addinfo = TRUE; nhfp->addinfo = TRUE;
@@ -1267,7 +1307,6 @@ open_savefile()
failed = errno; failed = errno;
} }
} }
#endif /* SYSCF */
if (nhfp->structlevel) { if (nhfp->structlevel) {
#ifdef MAC #ifdef MAC
nhfp->fd = macopen(fq_save, O_RDONLY | O_BINARY, SAVE_TYPE); nhfp->fd = macopen(fq_save, O_RDONLY | O_BINARY, SAVE_TYPE);
@@ -3943,14 +3982,15 @@ boolean
recover_savefile() recover_savefile()
{ {
NHFILE *gnhfp, *lnhfp, *snhfp; NHFILE *gnhfp, *lnhfp, *snhfp;
int lev, savelev, hpid, pltmpsiz; int lev, savelev, hpid, pltmpsiz, filecmc;
xchar levc; xchar levc;
struct version_info version_data; struct version_info version_data;
int processed[256]; int processed[256];
char savename[SAVESIZE], errbuf[BUFSZ]; char savename[SAVESIZE], errbuf[BUFSZ], indicator;
struct savefile_info sfi; struct savefile_info sfi;
char tmpplbuf[PL_NSIZ]; char tmpplbuf[PL_NSIZ];
const char *savewrite_failure = (const char *) 0;
for (lev = 0; lev < 256; lev++) for (lev = 0; lev < 256; lev++)
processed[lev] = 0; processed[lev] = 0;
@@ -3985,6 +4025,10 @@ recover_savefile()
} }
if ((read(gnhfp->fd, (genericptr_t) savename, sizeof savename) if ((read(gnhfp->fd, (genericptr_t) savename, sizeof savename)
!= sizeof savename) != sizeof savename)
|| (read(gnhfp->fd, (genericptr_t) &indicator, sizeof indicator)
!= sizeof indicator)
|| (read(gnhfp->fd, (genericptr_t) &filecmc, sizeof filecmc)
!= sizeof filecmc)
|| (read(gnhfp->fd, (genericptr_t) &version_data, sizeof version_data) || (read(gnhfp->fd, (genericptr_t) &version_data, sizeof version_data)
!= sizeof version_data) != sizeof version_data)
|| (read(gnhfp->fd, (genericptr_t) &sfi, sizeof sfi) != sizeof sfi) || (read(gnhfp->fd, (genericptr_t) &sfi, sizeof sfi) != sizeof sfi)
@@ -3997,6 +4041,7 @@ recover_savefile()
} }
/* save file should contain: /* save file should contain:
* format indicator and cmc
* version info * version info
* savefile info * savefile info
* player name * player name
@@ -4004,6 +4049,22 @@ recover_savefile()
* (non-level-based) game state * (non-level-based) game state
* other levels * other levels
*/ */
/*
* Things are different now. We could be in a situation
* where the default save file format is not structlevel.
* self-recover is currently written to use copy_bytes()
* to move content from the level files into the savefile.
* Until the code is updated to use something other than
* copy_bytes, what we need to do is force the recovery
* save to be structlevel, finish creating it, then read
* it back in. The save after that can be fieldlevel again.
*
* Set a flag for the savefile routines to know the
* circumstances and act accordingly:
* g.program_state.in_self_recover
*/
g.program_state.in_self_recover = TRUE;
set_savefile_name(TRUE); set_savefile_name(TRUE);
snhfp = create_savefile(); snhfp = create_savefile();
if (!snhfp) { if (!snhfp) {
@@ -4021,47 +4082,66 @@ recover_savefile()
return FALSE; return FALSE;
} }
if (write(snhfp->fd, (genericptr_t) &version_data, sizeof version_data) /*
!= sizeof version_data) { * Our savefile output format might _not_ be structlevel.
raw_printf("\nError writing %s; recovery failed.", g.SAVEF); * We have to check and use the correct output routine here.
close_nhfile(gnhfp); */
close_nhfile(snhfp); /*store_formatindicator(snhfp); */
close_nhfile(lnhfp); store_version(snhfp);
delete_savefile(); #if 0
return FALSE; if (snhfp->structlevel) {
if (write(snhfp->fd, (genericptr_t) &version_data, sizeof version_data)
!= sizeof version_data)
savewrite_failure = "version_info";
} }
if (snhfp->fieldlevel) {
if (write(snhfp->fd, (genericptr_t) &sfi, sizeof sfi) != sizeof sfi) { sfo_version_info(snhfp, (struct version_info *) &version_data,
raw_printf("\nError writing %s; recovery failed (savefile_info).\n", "version", "version_info", 1);
g.SAVEF); savewrite_failure = (const char *) 0;
close_nhfile(gnhfp);
close_nhfile(snhfp);
close_nhfile(lnhfp);
delete_savefile();
return FALSE;
} }
if (savewrite_failure)
goto cleanup;
#endif
if (write(snhfp->fd, (genericptr_t) &pltmpsiz, sizeof pltmpsiz) if (snhfp->structlevel) {
!= sizeof pltmpsiz) { if (write(snhfp->fd, (genericptr_t) &sfi, sizeof sfi) != sizeof sfi)
raw_printf("Error writing %s; recovery failed (player name size).\n", savewrite_failure = "savefileinfo";
g.SAVEF);
close_nhfile(gnhfp);
close_nhfile(snhfp);
close_nhfile(lnhfp);
delete_savefile();
return FALSE;
} }
if (snhfp->fieldlevel) {
if (write(snhfp->fd, (genericptr_t) &tmpplbuf, pltmpsiz) != pltmpsiz) { sfo_savefile_info(snhfp, &sfsaveinfo, "savefileinfo", "savefile_info", 1);
raw_printf("Error writing %s; recovery failed (player name).\n", savewrite_failure = (const char *) 0;
g.SAVEF);
close_nhfile(gnhfp);
close_nhfile(snhfp);
close_nhfile(lnhfp);
delete_savefile();
return FALSE;
} }
if (savewrite_failure)
goto cleanup;
if (snhfp->structlevel) {
if (write(snhfp->fd, (genericptr_t) &pltmpsiz, sizeof pltmpsiz)
!= sizeof pltmpsiz)
savewrite_failure = "player name size";
}
if (snhfp->fieldlevel) {
sfo_int(snhfp, &pltmpsiz, "plname", "plname_size", 1);
savewrite_failure = (const char *) 0;
}
if (savewrite_failure)
goto cleanup;
if (snhfp->structlevel) {
if (write(snhfp->fd, (genericptr_t) &tmpplbuf, pltmpsiz) != pltmpsiz)
savewrite_failure = "player name";
}
if (snhfp->fieldlevel) {
sfo_str(snhfp, tmpplbuf, "plname", "tmpplbuf", pltmpsiz);
savewrite_failure = (const char *) 0;
}
if (savewrite_failure)
goto cleanup;
/*
* copy_bytes isn't good enough anymore.
* We could be reading from a structlevel file but
* writing into a fieldlevel save file. Yikes!
*/
if (!copy_bytes(lnhfp->fd, snhfp->fd)) { if (!copy_bytes(lnhfp->fd, snhfp->fd)) {
close_nhfile(gnhfp); close_nhfile(gnhfp);
close_nhfile(snhfp); close_nhfile(snhfp);
@@ -4116,6 +4196,20 @@ recover_savefile()
(void) unlink(fq_lock); (void) unlink(fq_lock);
} }
} }
cleanup:
if (savewrite_failure) {
raw_printf("\nError writing %s; recovery failed (%s).\n",
g.SAVEF, savewrite_failure);
close_nhfile(gnhfp);
close_nhfile(snhfp);
close_nhfile(lnhfp);
g.program_state.in_self_recover = FALSE;
delete_savefile();
return FALSE;
}
/* we don't clear g.program_state.in_self_recover here, we
leave it as a flag to reload the structlevel savefile
in the caller. The caller should then clear it. */
return TRUE; return TRUE;
} }

View File

@@ -2027,6 +2027,7 @@ $(O)vision.o: vision.c $(HACK_H) $(INCL)\vis_tab.h
$(O)weapon.o: weapon.c $(HACK_H) $(O)weapon.o: weapon.c $(HACK_H)
$(O)were.o: were.c $(HACK_H) $(O)were.o: were.c $(HACK_H)
$(O)wield.o: wield.c $(HACK_H) $(O)wield.o: wield.c $(HACK_H)
$(O)windmain.o: $(MSWSYS)\windmain.c $(HACK_H)
#$(O)windows.o: windows.c $(HACK_H) $(INCL)\wingem.h $(INCL)\winGnome.h #$(O)windows.o: windows.c $(HACK_H) $(INCL)\wingem.h $(INCL)\winGnome.h
$(O)wizard.o: wizard.c $(HACK_H) $(INCL)\qtext.h $(O)wizard.o: wizard.c $(HACK_H) $(INCL)\qtext.h
$(O)worm.o: worm.c $(HACK_H) $(INCL)\lev.h $(O)worm.o: worm.c $(HACK_H) $(INCL)\lev.h

View File

@@ -503,6 +503,10 @@ attempt_restore:
} }
} }
} }
if (g.program_state.in_self_recover) {
g.program_state.in_self_recover = FALSE;
set_savefile_name(TRUE);
}
} }
if (!resuming) { if (!resuming) {