[net.games.rogue] **** BIGGEST SPOILER EVER ****

lee@unmvax.UUCP (05/07/84)

 Ha, I know how to piss some people off. What follows here (in shar format)
is a program to diddle with rogue 5.3 score files. Add new postings! Delete
your enemies! Relace them if you'ld like! 

 Go ahead, flame me. See if I care...

			--Lee (Ward)
			{ucbvax,convex,rice,gatech,pur-ee}!unmvax!lee

   To install, remove the first line through and
 including the dashed line. Get the .signature at the end too. Then type:

   % sh <thisfilename>

-------------------------------------------
: Run this with sh NOT csh!
echo extracting README
cat << //*FUNKYSTUFF*// > README
----------------- 5.3 rogue score file manipulation -----------

Just type make to make the mess. The binary will be called "score". It prompts
for commands with an asterisk. Invoke the binary with:

score    location_of_scorefile    number_of_entries_kept_in_the_score_file

(e.g. I use: score /usr/games/lib/rogue_roll 10)


The commands:
	add		add a posting (if legal)
	replace		a position with a new postng (no checks)
	delete		delete an entry
	list		list the score file out
	write		update the score file from in core copy. No locks!
	quit		back to shell


				--Lee
//*FUNKYSTUFF*//
echo extracting Makefile
cat << //*FUNKYSTUFF*// > Makefile
CFLAGS= -g

OBJ= main.o encread.o data.o encwrite.o

SRC= main.c encread.c data.c encwrite.c

score: \$(OBJ)
	cc \$(CFLAGS) -o score \$(OBJ)

clean:
	-rm -f \$(OBJ) score

main.o: rogue.h
//*FUNKYSTUFF*//
echo extracting rogue.h
cat << //*FUNKYSTUFF*// > rogue.h
struct scorefilefmt {
	int	sc_uid;
	int	sc_gold;
	int	sc_space1;
	short	sc_killindex;
	char	sc_name[80];
	short	sc_level;
	int	sc_space2;
};
//*FUNKYSTUFF*//
echo extracting main.c
cat << //*FUNKYSTUFF*// > main.c
# include <stdio.h>
# include <fcntl.h>
# include <pwd.h>
# include "rogue.h"

# define PROMPTSTR	"* "

extern int errno;

char *malloc();
struct passwd *getpwuid();
struct scorefilefmt *buildent();

main (argc, argv)
	int argc;
	char *argv[];
{
	char *file;
	int fd;
	char cbuf[BUFSIZ];
	struct scorefilefmt *buf;
	int numscores;
	int x,y;
	int done = 0;

	if (argc != 3) {
		fprintf (stderr, "Usage: %s rogue_roll numscores\\n", argv[0]);
		exit (1);
	}
	file = argv[1];
	numscores = atoi(argv[2]);

	if ((fd = open(file, O_RDONLY)) < 0) {
		perror(file);
		exit (errno);
	}

	if ((buf =
	    (struct scorefilefmt *)malloc(sizeof(struct scorefilefmt) *
	    numscores)) == NULL) {
		fprintf(stderr, "malloc failed!\\n");
		exit (errno);
	}

	encread ((char *)buf, sizeof(struct scorefilefmt) * numscores, fd);

	while (!done) {
		fputs(PROMPTSTR, stdout);
		if (gets(cbuf) == NULL)
			exit (0);
		printf ("command is \\"%s\\"\\n", cbuf);
		if (strcmp(cbuf, "list") == 0) {
			report (buf, numscores);
		} else if (strcmp(cbuf, "replace") == 0) {
			struct scorefilefmt *newent;

			newent = buildent();
			do {
				getstring("Position? ", cbuf);
			} while ((x = atoi(cbuf)) <= 0 || x >= numscores);
			bcopy((char *)newent, (char *)(buf + x - 1),
			    sizeof(*newent));
		} else if (strcmp(cbuf, "delete") == 0) {
			do {
				getstring("Position? ",  cbuf);
			} while ((x = atoi(cbuf)) <= 0 || x >= numscores);
			if (x != numscores) {
				bcopy((char *)(buf + x), (char *)(buf + x - 1),
				    (numscores - x) * sizeof(*buf));
			}
			(buf + numscores)->sc_uid = -1;
		} else if (strcmp(cbuf, "add") == 0) {
			struct scorefilefmt *newent;

			newent = buildent();
			x = 0;
			while (x < numscores  &&
			    (buf + x)->sc_gold > newent->sc_gold &&
			    (buf + x)->sc_uid != newent->sc_uid)
				++x;
			if (x < numscores &&
			    (buf + x)->sc_uid == newent->sc_uid &&
			    (buf + x)->sc_gold > newent->sc_gold)
				x = numscores;
			y = x;
			while (y < numscores) {
				if ( (buf + y)->sc_uid == newent->sc_uid) {
					if (y < numscores - 1)
						bcopy((char *)(buf + y + 1),
						    (char *)(buf + y),
						    sizeof(*buf) * (numscores
						    - 1 - y));
					break;
				}
				++y;
			}
			if (x < numscores) {
				if (x < numscores - 1 &&
				    (buf + x)->sc_uid != newent->sc_uid)
					for (y = numscores - 2; y >= x ; y--)
						bcopy((char *)(buf + y),
						    (char *)(buf + y + 1),
						    sizeof(*buf));
				bcopy((char *)newent, (char *)(buf + x),
				    sizeof(*buf));
			}
		} else if (strcmp (cbuf, "quit") == 0) {
			++done;
		} else if (strcmp (cbuf, "write") == 0) {
			FILE *sd;

			getstring ("File? ", cbuf);
			file = *cbuf == NULL ? file : cbuf;
			if ((sd = fopen(file, "w")) != NULL) {
				encwrite ((char *)buf,
				    sizeof(struct scorefilefmt) * numscores,
				    sd);
				fclose(sd);
			} else
				perror(file);
		} else {
			printf ("Illegal command.\\n");
		}
		fflush (stdout);
	}
}

struct scorefilefmt *buildent ()
{
	static struct scorefilefmt ent;
	struct passwd *pwent;
	char buf[BUFSIZ];
	int x;


	for (x = 0; x < sizeof(ent.sc_name); x++)
		ent.sc_name[x] = NULL;
	do {
		getstring("User name? ", buf);
	} while ((pwent = getpwnam(buf)) == NULL);
	ent.sc_uid = pwent->pw_uid;
	getstring("Rogue name? ", buf);
	strncpy(ent.sc_name, buf, sizeof(ent.sc_name) - 1);
	do {
		getstring("Died where? ", buf);
	} while ((ent.sc_level = atoi(buf)) <= 0);
	getstring("How? ", buf);
	ent.sc_killindex = atoi(buf);
	do {
		getstring("Gold? ", buf);
	} while ((ent.sc_gold = atoi(buf)) <= 0);
	return (&ent);
}

getstring(prompt, bufp)
	char *prompt;
	char *bufp;
{

	fputs(prompt, stdout);
	fflush(stdout);
	while (gets(bufp) == NULL)
		;
}

report (scores, numscores)
	struct scorefilefmt *scores;
	int numscores;
{
	struct passwd *pwent;

	while (numscores--) {
		if ((pwent = getpwuid(scores->sc_uid)) != NULL) {
			printf ("%8s (\\"%s\\"):",
			    pwent->pw_name, scores->sc_name);
			printf ("\\n\\tkilled on level: %d", scores->sc_level);
			printf ("\\n\\twith %d pieces of gold", scores->sc_gold);
			printf ("\\n\\tby monster number %d\\n",
			    scores->sc_killindex);
		} else
			printf ("**** Inactive record ****\\n");
		++scores;
	}
}

bcopy (src, dst, count)
	register char *src;
	register char *dst;
	register int count;
{

	while (count--)
		*dst++ = *src++;
}
//*FUNKYSTUFF*//
echo extracting data.c
cat << //*FUNKYSTUFF*// > data.c
/* encstr, Frob and statlist as ripped from the rogue 5.3 binary
 */

char Frob = 0;

char encstr[] = {
	0xc0,	0x6b,
	0x7c,	0x7c,
	0x60,	0xa9,
	0x59,	0x2e,
	0x27,	0xc5,
	0xd1,	0x81,
	0x2b,	0xbf,
	0x7e,	0x72,
	0x22,	0x5d,
	0x13,	0x38,
	0x5f,	0x93,
	0x3d,	0x31,
	0xe1,	0x29,
	0x92,	0x8a,
	0xa1,	0x74,
	0x3b,	0x9,
	0x24,	0xb8,
	0xcc,	0x2f,
	0x3c,	0x23,
	0x81,	0xac,
	0,	0,
	0,	0,
};

char statlist[] = {
	0xed,	0x6b,
	0x6c,	0x7b,
	0x2b,	0x84,
	0xad,	0xcb,
	0x69,	0x64,
	0x4a,	0xf1,
	0x8c,	0x3d,
	0x34,	0x3a,
	0xc9,	0xb9,
	0xe1,	0x77,
	0x4b,	0x3c,
	0xca,	0x19,
	0x39,	0x8b,
	0x2c,	0x2c,
	0x37,	0xb9,
	0x2f,	0x52,
	0x6b,	0x25,
	0x08,	0xca,
	0x0c,	0xa6,
	0,	0,
};
//*FUNKYSTUFF*//
echo extracting encread.c
cat << //*FUNKYSTUFF*// > encread.c
/* This is a C version of encread from Rogue. The 5.3 binary was
 * disassembled and then turned into this mess.
 */

extern char Frob;
extern char encstr[];
extern char statlist[];

encread (bufp,numbytes,fd)
	char *bufp;
	int numbytes;
	int fd;
{
	char x;
	char *encptr;
	char *statp;
	int rtn;

	x = Frob;
	rtn = read (fd, bufp, numbytes);
	if ( rtn == 0 || rtn == -1)
		return (rtn);
	encptr = encstr;
	while (1) {
		statp = statlist;
		while (*statp) {
			if (numbytes-- == 0)
				return (0);
			*(bufp++) ^= *encptr ^ *statp ^ x;
			x = (char )((int )x +
			    ((int )*encptr++ * (int )*statp++));
			if (*encptr == 0)
				encptr = encstr;
		}
	}
}
//*FUNKYSTUFF*//
echo extracting encwrite.c
cat << //*FUNKYSTUFF*// > encwrite.c
/* Encwrite, to write (encrypted) the rogue score file for 5.3
 */

# include <stdio.h>

extern char Frob;
extern char encstr[];
extern char statlist[];

encwrite (bufp,numbytes,sd)
	char *bufp;
	int numbytes;
	FILE *sd;
{
	char x;
	char *encptr;
	char *statp;

	x = Frob;
	encptr = encstr;
	while (1) {
		statp = statlist;
		while (*statp) {
			if (numbytes-- == 0) {
				fflush(sd);
				return (0);
			}
			fputc (*bufp++ ^ *encptr ^ *statp ^ x, sd);
			x = (char )((int )x +
			    ((int )*encptr++ * (int )*statp++));
			if (*encptr == 0)
				encptr = encstr;
		}
	}
}
//*FUNKYSTUFF*//
-- 
			--Lee (Ward)
			{ucbvax,convex,gatech,pur-ee}!unmvax!lee