예제 #1
0
파일: save.c 프로젝트: aalm/obsd-src
/*
 * Two passes on data: first to get checksum, second
 * to output the data using checksum to start random #s
 */
int
save(const char *outfile)	
{
	FILE   *out;
	struct savestruct *p;
	char   *s;
	long    sum;
	int     i;

	crc_start();
	for (p = save_array; p->address != NULL; p++)
		sum = crc(p->address, p->width);
	srandom_deterministic((int) sum);

	if ((out = fopen(outfile, "wb")) == NULL) {
		fprintf(stderr,
		   "Hmm.  The name \"%s\" appears to be magically blocked.\n",
		   outfile);
		return 1;
	}

	fwrite(&sum, sizeof(sum), 1, out);	/* Here's the random() key */
	for (p = save_array; p->address != NULL; p++) {
		for (s = p->address, i = 0; i < p->width; i++, s++)
			*s = (*s ^ random()) & 0xFF;	/* Slightly obfuscate */
		fwrite(p->address, p->width, 1, out);
	}
	fclose(out);
	return 0;
}
예제 #2
0
파일: save.c 프로젝트: aalm/obsd-src
int
restore(const char *infile)
{
	FILE   *in;
	struct savestruct *p;
	char   *s;
	long    sum, cksum;
	int     i;

	if ((in = fopen(infile, "rb")) == NULL) {
		fprintf(stderr,
		   "Hmm.  The file \"%s\" appears to be magically blocked.\n",
		   infile);
		return 1;
	}

	fread(&sum, sizeof(sum), 1, in);	/* Get the seed */
	srandom_deterministic((unsigned int) sum);
	for (p = save_array; p->address != NULL; p++) {
		fread(p->address, p->width, 1, in);
		for (s = p->address, i = 0; i < p->width; i++, s++)
			*s = (*s ^ random()) & 0xFF;	/* deobfuscate */
	}
	fclose(in);

	crc_start();			/* See if she cheated */
	for (p = save_array; p->address != NULL; p++)
		cksum = crc(p->address, p->width);
	if (sum != cksum)		/* Tsk tsk */
		return 2;		/* Altered the file */
	/* We successfully restored, so this really was a save file */
	/* Get rid of the file, but don't bother checking that we did */
	return 0;
}
예제 #3
0
파일: update.c 프로젝트: keith-dev/openbsd
void
setseed(const char *seed)
{
	seeded = 1;
	srandom_deterministic(atol(seed));
}
예제 #4
0
int
main(int argc, char **argv)
{
	extern char *__progname;
	int fd;
#ifdef CHDIR
	char *dir;
#endif

	hackpid = getpid();

#ifdef CHDIR			/* otherwise no chdir() */
	/*
	 * See if we must change directory to the playground.
	 * (Perhaps hack runs suid and playground is inaccessible
	 *  for the player.)
	 * The environment variable HACKDIR is overridden by a
	 *  -d command line option (must be the first option given)
	 */

	dir = getenv("HACKDIR");
	if(argc > 1 && !strncmp(argv[1], "-d", 2)) {
		argc--;
		argv++;
		dir = argv[0]+2;
		if(*dir == '=' || *dir == ':') dir++;
		if(!*dir && argc > 1) {
			argc--;
			argv++;
			dir = argv[0];
		}
		if(!*dir)
		    error("Flag -d must be followed by a directory name.");
	}
#endif

	/*
	 * Who am i? Algorithm: 1. Use name as specified in HACKOPTIONS
	 *			2. Use $LOGNAME or $USER	(if 1. fails)
	 *			3. Use getlogin()		(if 2. fails)
	 * The resulting name is overridden by command line options.
	 * If everything fails, or if the resulting name is some generic
	 * account like "games", "play", "player", "hack" then eventually
	 * we'll ask him.
	 * Note that we trust him here; it is possible to play under
	 * somebody else's name.
	 */
	{ char *s;

	  initoptions();
	  if(!*plname && (s = getenv("LOGNAME")))
		(void) strlcpy(plname, s, sizeof(plname));
	  if(!*plname && (s = getenv("USER")))
		(void) strlcpy(plname, s, sizeof(plname));
	  if(!*plname && (s = getlogin()))
		(void) strlcpy(plname, s, sizeof(plname));
	}

	/*
	 * Now we know the directory containing 'record' and
	 * may do a prscore().
	 */
	if(argc > 1 && !strncmp(argv[1], "-s", 2)) {
#ifdef CHDIR
		chdirx(dir,0);
#endif
		prscore(argc, argv);
		return 0;
	}

	/*
	 * It seems he really wants to play.
	 * Remember tty modes, to be restored on exit.
	 */
	gettty();
	setvbuf(stdout, obuf, _IOFBF, sizeof obuf);
	umask(007);
	startup();
	cls();
	u.uhp = 1;	/* prevent RIP on early quits */
	u.ux = FAR;	/* prevent nscr() */
	(void) signal(SIGHUP, hackhangup);

	/*
	 * Find the creation date of this game,
	 * so as to avoid restoring outdated savefiles.
	 */
	gethdate(__progname);

	/*
	 * We cannot do chdir earlier, otherwise gethdate will fail.
	 */
#ifdef CHDIR
	chdirx(dir,1);
#endif

	/*
	 * Process options.
	 */
	while(argc > 1 && argv[1][0] == '-'){
		argv++;
		argc--;
		switch(argv[0][1]){
#ifdef WIZARD
		case 'D':
/*			if(!strcmp(getlogin(), WIZARD)) */
				wizard = TRUE;
/*			else
				printf("Sorry.\n"); */
			break;
#endif
#ifdef NEWS
		case 'n':
			flags.nonews = TRUE;
			break;
#endif
		case 'u':
			if(argv[0][2]) {
			  (void) strlcpy(plname, argv[0]+2, sizeof(plname));
			} else if(argc > 1) {
			  argc--;
			  argv++;
			  (void) strlcpy(plname, argv[0], sizeof(plname));
			} else
				printf("Player name expected after -u\n");
			break;
		default:
			/* allow -T for Tourist, etc. */
			(void) strlcpy(pl_character, argv[0]+1, sizeof(pl_character));
			/* printf("Unknown option: %s\n", *argv); */
		}
	}

	if(argc > 1)
		locknum = atoi(argv[1]);
#ifdef MAX_NR_OF_PLAYERS
	if(!locknum || locknum > MAX_NR_OF_PLAYERS)
		locknum = MAX_NR_OF_PLAYERS;
#endif
#ifdef DEF_PAGER
	if(!(catmore = getenv("HACKPAGER")) && !(catmore = getenv("PAGER")))
		catmore = DEF_PAGER;
#endif
#ifdef MAIL
	getmailstatus();
#endif
#ifdef WIZARD
	if(wizard) (void) strlcpy(plname, "wizard", sizeof plname); else
#endif
	if(!*plname || !strncmp(plname, "player", 4)
		    || !strncmp(plname, "games", 4))
		askname();
	plnamesuffix();		/* strip suffix from name; calls askname() */
				/* again if suffix was whole name */
				/* accepts any suffix */
#ifdef WIZARD
	if(!wizard) {
#endif
		/*
		 * check for multiple games under the same name
		 * (if !locknum) or check max nr of players (otherwise)
		 */
		(void) signal(SIGQUIT,SIG_IGN);
		(void) signal(SIGINT,SIG_IGN);
		if(!locknum)
			(void) strlcpy(lock,plname,sizeof lock);
		getlock();	/* sets lock if locknum != 0 */
#ifdef WIZARD
	} else {
		char *sfoo;
		(void) strlcpy(lock,plname,sizeof lock);
		if ((sfoo = getenv("MAGIC")))
			while(*sfoo) {
				switch(*sfoo++) {
				case 'n': (void) srandom_deterministic(*sfoo++);
					break;
				}
			}
		if ((sfoo = getenv("GENOCIDED"))) {
			if(*sfoo == '!'){
				struct permonst *pm = mons;
				char *gp = genocided;

				while(pm < mons+CMNUM+2){
					if(!strchr(sfoo, pm->mlet))
						*gp++ = pm->mlet;
					pm++;
				}
				*gp = 0;
			} else
				strlcpy(genocided, sfoo, sizeof genocided);
			strlcpy(fut_geno, genocided, sizeof fut_geno);
		}
	}
#endif
	setftty();
	(void) snprintf(SAVEF, sizeof SAVEF, "save/%u%s", getuid(), plname);
	regularize(SAVEF+5);		/* avoid . or / in name */
	if((fd = open(SAVEF, O_RDONLY)) >= 0 &&
	   (uptodate(fd) || unlink(SAVEF) == 666)) {
		(void) signal(SIGINT,done1);
		pline("Restoring old save file...");
		(void) fflush(stdout);
		if(!dorecover(fd))
			goto not_recovered;
		pline("Hello %s, welcome to %s!", plname, gamename);
		flags.move = 0;
	} else {
not_recovered:
		fobj = fcobj = invent = 0;
		fmon = fallen_down = 0;
		ftrap = 0;
		fgold = 0;
		flags.ident = 1;
		init_objects();
		u_init();

		(void) signal(SIGINT,done1);
		mklev();
		u.ux = xupstair;
		u.uy = yupstair;
		(void) inshop();
		setsee();
		flags.botlx = 1;
		makedog();
		{ struct monst *mtmp;
		  if ((mtmp = m_at(u.ux, u.uy)))
			  mnexto(mtmp);	/* riv05!a3 */
		}
		seemons();
#ifdef NEWS
		if(flags.nonews || !readnews())
			/* after reading news we did docrt() already */
#endif
			docrt();

		/* give welcome message before pickup messages */
		pline("Hello %s, welcome to %s!", plname, gamename);

		pickup(1);
		read_engr_at(u.ux,u.uy);
		flags.move = 1;
	}

	flags.moonphase = phase_of_the_moon();
	if(flags.moonphase == FULL_MOON) {
		pline("You are lucky! Full moon tonight.");
		u.uluck++;
	} else if(flags.moonphase == NEW_MOON) {
		pline("Be careful! New moon tonight.");
	}

	initrack();

	for(;;) {
		if(flags.move) {	/* actual time passed */

			settrack();

			if(moves%2 == 0 ||
			  (!(Fast & ~INTRINSIC) && (!Fast || rn2(3)))) {
				extern struct monst *makemon();
				movemon();
				if(!rn2(70))
				    (void) makemon((struct permonst *)0, 0, 0);
			}
			if(Glib) glibr();
			hacktimeout();
			++moves;
			if(flags.time) flags.botl = 1;
			if(u.uhp < 1) {
				pline("You die...");
				done("died");
			}
			if(u.uhp*10 < u.uhpmax && moves-wailmsg > 50){
			    wailmsg = moves;
			    if(u.uhp == 1)
			    pline("You hear the wailing of the Banshee...");
			    else
			    pline("You hear the howling of the CwnAnnwn...");
			}
			if(u.uhp < u.uhpmax) {
				if(u.ulevel > 9) {
					if(Regeneration || !(moves%3)) {
					    flags.botl = 1;
					    u.uhp += rnd((int) u.ulevel-9);
					    if(u.uhp > u.uhpmax)
						u.uhp = u.uhpmax;
					}
				} else if(Regeneration ||
					(!(moves%(22-u.ulevel*2)))) {
					flags.botl = 1;
					u.uhp++;
				}
			}
			if(Teleportation && !rn2(85)) tele();
			if(Searching && multi >= 0) (void) dosearch();
			gethungry();
			invault();
			amulet();
		}
		if(multi < 0) {
			if(!++multi){
				pline("%s", nomovemsg ? nomovemsg :
					"You can move again.");
				nomovemsg = 0;
				if(afternmv) (*afternmv)();
				afternmv = 0;
			}
		}

		find_ac();
#ifndef QUEST
		if(!flags.mv || Blind)
#endif
		{
			seeobjs();
			seemons();
			nscr();
		}
		if(flags.botl || flags.botlx) bot();

		flags.move = 1;

		if(multi >= 0 && occupation) {
			if(monster_nearby())
				stop_occupation();
			else if ((*occupation)() == 0)
				occupation = 0;
			continue;
		}

		if(multi > 0) {
#ifdef QUEST
			if(flags.run >= 4) finddir();
#endif
			lookaround();
			if(!multi) {	/* lookaround may clear multi */
				flags.move = 0;
				continue;
			}
			if(flags.mv) {
				if(multi < COLNO && !--multi)
					flags.mv = flags.run = 0;
				domove();
			} else {
				--multi;
				rhack(save_cm);
			}
		} else if(multi == 0) {
#ifdef MAIL
			ckmailstatus();
#endif
			rhack(NULL);
		}
		if(multi && multi%7 == 0)
			(void) fflush(stdout);
	}
}