From d6cb6f0d8d258f4125fd3a0cc3899541ea2efd5b Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Mon, 26 Jun 2017 15:03:37 -0400 Subject: [PATCH] Create a cheater to test strange save/resume cases. Patch due to Aaron Traas, but needed modification because of code drift since submission. --- .gitignore | 1 + .gitlab-ci.yml | 4 ++- Makefile | 10 ++++++- advent.h | 1 + cheat.c | 64 +++++++++++++++++++++++++++++++++++++++++++ newdungeon.py | 2 +- saveresume.c | 22 ++++++++++----- tests/Makefile | 2 ++ tests/cheatresume.chk | 24 ++++++++++++++++ tests/cheatresume.log | 4 +++ 10 files changed, 124 insertions(+), 10 deletions(-) create mode 100644 cheat.c create mode 100644 tests/cheatresume.chk create mode 100644 tests/cheatresume.log diff --git a/.gitignore b/.gitignore index 1e3ef43..123e27f 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ MANIFEST .*~ newdb.h newdb.c +cheat \ No newline at end of file diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 93f0af1..4553126 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -21,6 +21,7 @@ binary:debug: artifacts: paths: - advent + - cheat - "*.gcda" - "*.gcno" # cache outputs to reduce the build time @@ -35,10 +36,11 @@ binary:release: - apk add make gcc musl-dev python3 - pip3 install PyYAML script: - - make advent + - make advent cheat artifacts: paths: - advent + - cheat # cache outputs to reduce the build time cache: paths: diff --git a/Makefile b/Makefile index 9021f68..a435d07 100644 --- a/Makefile +++ b/Makefile @@ -37,6 +37,7 @@ ifeq ($(UNAME_S),Linux) endif OBJS=main.o init.o actions.o score.o misc.o saveresume.o common.o +CHEAT_OBJS=cheat.o init.o actions.o score.o misc.o saveresume.o common.o SOURCES=$(OBJS:.o=.c) dungeon.c advent.h common.h adventure.text Makefile control linenoise/linenoise.[ch] newdungeon.py .c.o: @@ -55,6 +56,8 @@ score.o: advent.h database.h common.h newdb.h misc.o: advent.h database.h common.h newdb.h +cheat.o: advent.h database.h common.h newdb.h + saveresume.o: advent.h database.h common.h newdb.h common.o: common.h @@ -84,7 +87,11 @@ clean: rm -f .*~ cd tests; $(MAKE) --quiet clean -check: advent + +cheat: $(CHEAT_OBJS) linenoise.o newdb.o + $(CC) $(CCFLAGS) $(DBX) -o cheat $(CHEAT_OBJS) linenoise.o newdb.o $(LDFLAGS) $(LIBS) + +check: advent cheat cd tests; $(MAKE) --quiet .SUFFIXES: .adoc .html .6 @@ -144,3 +151,4 @@ linty: advent debug: CCFLAGS += -O0 --coverage -ggdb debug: linty +debug: cheat diff --git a/advent.h b/advent.h index 4447b67..754ea16 100644 --- a/advent.h +++ b/advent.h @@ -127,6 +127,7 @@ extern unsigned long get_next_lcg_value(void); extern long randrange(long); extern long score(enum termination); extern void terminate(enum termination) __attribute__((noreturn)); +extern int savefile(FILE *); extern int suspend(void); extern int resume(void); extern int restore(FILE *); diff --git a/cheat.c b/cheat.c new file mode 100644 index 0000000..9e23911 --- /dev/null +++ b/cheat.c @@ -0,0 +1,64 @@ +#define DEFINE_GLOBALS_FROM_INCLUDES +#include +#include +#include +#include +#include "advent.h" +#include "database.h" +#include "linenoise/linenoise.h" +#include "newdb.h" + +struct game_t game; + +long LNLENG, LNPOSN; +char rawbuf[LINESIZE], INLINE[LINESIZE + 1]; + +long AMBER, AXE, BACK, BATTERY, BEAR, BIRD, BLOOD, + BOTTLE, CAGE, CAVE, CAVITY, CHAIN, CHASM, CHEST, + CLAM, COINS, DOOR, DPRSSN, DRAGON, DWARF, EGGS, + EMERALD, ENTER, ENTRNC, FIND, FISSURE, FOOD, + GRATE, HINT, INVENT, JADE, KEYS, + KNIFE, LAMP, LOCK, LOOK, MAGAZINE, + MESSAG, MIRROR, NUGGET, NUL, OGRE, OIL, OYSTER, + PEARL, PILLOW, PLANT, PLANT2, PYRAMID, RESER, ROD, ROD2, + RUBY, RUG, SAPPH, SAY, SIGN, SNAKE, + STEPS, STREAM, THROW, TRIDENT, TROLL, TROLL2, + URN, VASE, VEND, VOLCANO, WATER; + +FILE *logfp = NULL, *rfp = NULL; +bool oldstyle = false; +bool editline = true; +bool prompt = true; + +int main(int argc, char *argv[]) +{ + FILE *fp = NULL; + + game.lcg_a = 1093; + game.lcg_c = 221587; + game.lcg_m = 1048576; + srand(time(NULL)); + long seedval = (long)rand(); + set_seed(seedval); + + /* Initialize game variables */ + initialise(); + + game.zzword = rndvoc(3, 0); + game.newloc = LOC_START; + game.loc = LOC_START; + game.limit = GAMELIMIT; + game.numdie = -1000; + game.saved = 1; + + fp = fopen("cheat_numdie.adv", WRITE_MODE); + if (fp == NULL) + { + printf("Can't open file. Exiting.\n"); + exit(0); + } + + savefile(fp); + printf("cheat: tests/cheat_numdie.adv created.\n"); + return 0; +} diff --git a/newdungeon.py b/newdungeon.py index e516921..bbfc0c8 100755 --- a/newdungeon.py +++ b/newdungeon.py @@ -442,7 +442,7 @@ if __name__ == "__main__": len(db["locations"])-1, len(db["objects"])-1, len(db["hints"]), - len(db["classes"]), + len(db["classes"])-1, len(db["obituaries"]), len(db["turn_thresholds"]), len(db["actspk"]), diff --git a/saveresume.c b/saveresume.c index 3386158..3546378 100644 --- a/saveresume.c +++ b/saveresume.c @@ -27,6 +27,20 @@ struct save_t { }; struct save_t save; +int savefile(FILE *fp) + /* Save game to file. No input or output from user. */ +{ + long i, k; + datime(&i, &k); + k = i + 650 * k; + save.savetime = k; + save.mode = -1; + save.version = VRSION; + memcpy(&save.game, &game, sizeof(struct game_t)); + IGNORE(fwrite(&save, sizeof(struct save_t), 1, fp)); + return(0); +} + /* Suspend and resume */ int suspend(void) { @@ -38,7 +52,6 @@ int suspend(void) #ifdef ADVENT_NOSAVE return GO_UNKNOWN; #endif - long i, k; FILE *fp = NULL; rspeak(SUSPEND_WARNING); @@ -55,12 +68,7 @@ int suspend(void) linenoiseFree(name); } - datime(&i, &k); - k = i + 650 * k; - save.savetime = k; - save.mode = -1; - save.version = VRSION; - memcpy(&save.game, &game, sizeof(struct game_t)); + savefile(fp); IGNORE(fwrite(&save, sizeof(struct save_t), 1, fp)); fclose(fp); rspeak(RESUME_HELP); diff --git a/tests/Makefile b/tests/Makefile index cffab9a..412ec6a 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -37,6 +37,8 @@ buildregress: done; \ rm -f scratch.tmp regress: + $(ECHO) -n "Generate cheat file: " + ../cheat @for file in $(TESTLOADS); do \ $(ECHO) -n " $${file} "; grep '##' $${file}.log || echo ' ## (no description)'; \ OPTS=`sed -n /#options:/s///p <$${file}.log`; \ diff --git a/tests/cheatresume.chk b/tests/cheatresume.chk new file mode 100644 index 0000000..8901e8b --- /dev/null +++ b/tests/cheatresume.chk @@ -0,0 +1,24 @@ + +Welcome to Adventure!! Would you like instructions? + +> n + +You are standing at the end of a road before a small brick building. +Around you is a forest. A small stream flows out of the building and +down a gully. + +> resume + +You are standing at the end of a road before a small brick building. +Around you is a forest. A small stream flows out of the building and +down a gully. + + +Now let's see you do it without suspending in mid-Adventure. + +You scored 10031 out of a possible 430, using 0 turn. + +You just went off my scale!! + +To achieve the next higher rating would be a neat trick! +Congratulations!! diff --git a/tests/cheatresume.log b/tests/cheatresume.log new file mode 100644 index 0000000..e820ba0 --- /dev/null +++ b/tests/cheatresume.log @@ -0,0 +1,4 @@ +## Resume from absurd save file with numdie = -1000 +n +resume +cheat_numdie.adv -- 2.31.1